From 3e985ad212442256c17405f3d04e877e52aa5a88 Mon Sep 17 00:00:00 2001 From: cyberosa Date: Wed, 8 Jan 2025 12:32:15 +0100 Subject: [PATCH] updating hashes and removing backup folders --- packages/packages.json | 53 +- packages/valory/agents/trader/aea-config.yaml | 44 +- packages/valory/services/trader/service.yaml | 2 +- .../valory/services/trader_pearl/service.yaml | 2 +- .../skills/check_stop_trading_abci/skill.yaml | 6 +- .../skills/decision_maker_abci/skill.yaml | 16 +- .../skills/market_manager_abci/skill.yaml | 2 +- .../valory/skills/staking_abci/skill.yaml | 6 +- packages/valory/skills/trader_abci/skill.yaml | 22 +- .../tx_settlement_multiplexer_abci/skill.yaml | 8 +- trader_backup/.certs/acn_cosmos_9005.txt | 1 - trader_backup/README.md | 8 - trader_backup/__init__.py | 20 - trader_backup/aea-config.yaml | 407 -- trader_backup/data/available_tools_store.json | 1 - trader_backup/data/benchmarking_40.csv | 560 -- trader_backup/data/bets.json | 6272 ----------------- trader_backup/data/multi_bets.json | 1 - trader_backup/data/policy_store.json | 79 - ...icy_store_multi_bet_failure_adjusting.json | 132 - trader_backup/data/utilized_tools.json | 1 - .../vendor/jhehemann/customs/__init__.py | 0 .../customs/kelly_criterion/__init__.py | 20 - .../customs/kelly_criterion/component.yaml | 14 - .../kelly_criterion/kelly_criterion.py | 161 - .../vendor/open_aea/protocols/__init__.py | 0 .../open_aea/protocols/signing/README.md | 65 - .../open_aea/protocols/signing/__init__.py | 30 - .../protocols/signing/custom_types.py | 68 - .../open_aea/protocols/signing/dialogues.py | 136 - .../open_aea/protocols/signing/message.py | 319 - .../open_aea/protocols/signing/protocol.yaml | 24 - .../protocols/signing/serialization.py | 162 - .../open_aea/protocols/signing/signing.proto | 68 - .../open_aea/protocols/signing/signing_pb2.py | 50 - .../protocols/signing/tests/__init__.py | 20 - .../protocols/signing/tests/test_signing.py | 144 - .../signing/tests/test_signing_dialogues.py | 58 - .../signing/tests/test_signing_messages.py | 109 - .../vendor/valory/connections/__init__.py | 0 .../vendor/valory/connections/abci/Makefile | 24 - .../valory/connections/abci/__init__.py | 20 - .../connections/abci/check_dependencies.py | 160 - .../valory/connections/abci/connection.py | 1497 ---- .../valory/connections/abci/connection.yaml | 84 - .../valory/connections/abci/dialogues.py | 59 - .../connections/abci/gogoproto/__init__.py | 20 - .../connections/abci/gogoproto/gogo_pb2.py | 31 - .../abci/protos/gogoproto/gogo.proto | 144 - .../abci/protos/tendermint/abci/types.proto | 407 -- .../abci/protos/tendermint/crypto/keys.proto | 17 - .../abci/protos/tendermint/crypto/proof.proto | 41 - .../abci/protos/tendermint/types/params.proto | 80 - .../abci/protos/tendermint/types/types.proto | 157 - .../protos/tendermint/types/validator.proto | 25 - .../protos/tendermint/version/types.proto | 24 - .../vendor/valory/connections/abci/readme.md | 8 - .../connections/abci/scripts/genproto.py | 127 - .../connections/abci/tendermint/__init__.py | 20 - .../abci/tendermint/abci/types_pb2.py | 211 - .../abci/tendermint/abci/types_pb2_grpc.py | 719 -- .../abci/tendermint/crypto/keys_pb2.py | 39 - .../abci/tendermint/crypto/proof_pb2.py | 47 - .../abci/tendermint/types/params_pb2.py | 69 - .../abci/tendermint/types/types_pb2.py | 158 - .../abci/tendermint/types/validator_pb2.py | 46 - .../abci/tendermint/version/types_pb2.py | 41 - .../connections/abci/tendermint_decoder.py | 472 -- .../connections/abci/tendermint_encoder.py | 418 -- .../valory/connections/abci/tests/__init__.py | 27 - .../valory/connections/abci/tests/helper.py | 533 -- .../connections/abci/tests/test_abci.py | 661 -- .../connections/abci/tests/test_abci_fuzz.py | 339 - .../connections/abci/tests/test_abci_spec.py | 220 - .../abci/tests/test_fuzz/__init__.py | 19 - .../connections/abci/tests/test_fuzz/base.py | 373 - .../tests/test_fuzz/mock_node/__init__.py | 19 - .../test_fuzz/mock_node/channels/__init__.py | 19 - .../test_fuzz/mock_node/channels/base.py | 189 - .../mock_node/channels/grpc_channel.py | 213 - .../mock_node/channels/tcp_channel.py | 535 -- .../abci/tests/test_fuzz/mock_node/node.py | 520 -- .../abci/tests/test_fuzz/test_fuzz.py | 53 - .../abci/tests/test_tendermint_decoder.py | 121 - .../abci/tests/test_tendermint_encoder.py | 124 - .../valory/connections/abci/version.txt | 6 - .../valory/connections/http_client/README.md | 7 - .../connections/http_client/__init__.py | 21 - .../connections/http_client/connection.py | 446 -- .../connections/http_client/connection.yaml | 32 - .../connections/http_client/tests/__init__.py | 21 - .../http_client/tests/test_http_client.py | 362 - .../valory/connections/http_server/README.md | 7 - .../connections/http_server/__init__.py | 21 - .../connections/http_server/connection.py | 645 -- .../connections/http_server/connection.yaml | 43 - .../connections/http_server/tests/__init__.py | 20 - .../http_server/tests/data/certs/server.crt | 17 - .../http_server/tests/data/certs/server.csr | 15 - .../http_server/tests/data/certs/server.key | 27 - .../http_server/tests/data/petstore_sim.yaml | 111 - .../http_server/tests/test_http_server.py | 597 -- .../valory/connections/ipfs/__init__.py | 20 - .../valory/connections/ipfs/connection.py | 323 - .../valory/connections/ipfs/connection.yaml | 31 - .../vendor/valory/connections/ipfs/readme.md | 2 - .../valory/connections/ipfs/tests/__init__.py | 20 - .../connections/ipfs/tests/test_connection.py | 282 - .../valory/connections/ledger/README.md | 11 - .../valory/connections/ledger/__init__.py | 20 - .../vendor/valory/connections/ledger/base.py | 217 - .../valory/connections/ledger/connection.py | 193 - .../valory/connections/ledger/connection.yaml | 115 - .../connections/ledger/contract_dispatcher.py | 451 -- .../connections/ledger/ledger_dispatcher.py | 474 -- .../connections/ledger/tests/__init__.py | 21 - .../connections/ledger/tests/conftest.py | 148 - .../ledger/tests/test_contract_dispatcher.py | 281 - .../connections/ledger/tests/test_ledger.py | 623 -- .../ledger/tests/test_ledger_api.py | 682 -- .../connections/p2p_libp2p_client/README.md | 15 - .../connections/p2p_libp2p_client/__init__.py | 21 - .../p2p_libp2p_client/connection.py | 688 -- .../p2p_libp2p_client/connection.yaml | 51 - .../vendor/valory/contracts/__init__.py | 0 .../contracts/agent_registry/__init__.py | 20 - .../agent_registry/build/AgentRegistry.json | 1046 --- .../contracts/agent_registry/contract.py | 64 - .../contracts/agent_registry/contract.yaml | 23 - .../contracts/conditional_tokens/__init__.py | 20 - .../build/ConditionalTokens.json | 708 -- .../contracts/conditional_tokens/contract.py | 420 -- .../conditional_tokens/contract.yaml | 24 - .../vendor/valory/contracts/erc20/README.md | 1 - .../vendor/valory/contracts/erc20/__init__.py | 20 - .../valory/contracts/erc20/build/ERC20.json | 288 - .../vendor/valory/contracts/erc20/contract.py | 101 - .../valory/contracts/erc20/contract.yaml | 32 - .../valory/contracts/gnosis_safe/README.md | 6 - .../valory/contracts/gnosis_safe/__init__.py | 20 - .../gnosis_safe/build/GnosisSafe_V1_3_0.json | 1179 ---- .../valory/contracts/gnosis_safe/contract.py | 1004 --- .../contracts/gnosis_safe/contract.yaml | 40 - .../valory/contracts/gnosis_safe/encode.py | 155 - .../contracts/gnosis_safe/tests/__init__.py | 20 - .../gnosis_safe/tests/test_contract.py | 845 --- .../gnosis_safe_proxy_factory/README.md | 6 - .../gnosis_safe_proxy_factory/__init__.py | 20 - .../build/ProxyFactory_V1_3_0.json | 172 - .../gnosis_safe_proxy_factory/contract.py | 178 - .../gnosis_safe_proxy_factory/contract.yaml | 26 - .../tests/__init__.py | 20 - .../tests/test_contract.py | 103 - .../valory/contracts/market_maker/README.md | 1 - .../valory/contracts/market_maker/__init__.py | 20 - .../build/FixedProductMarketMaker.json | 662 -- .../valory/contracts/market_maker/contract.py | 186 - .../contracts/market_maker/contract.yaml | 32 - .../vendor/valory/contracts/mech/README.md | 1 - .../vendor/valory/contracts/mech/__init__.py | 20 - .../valory/contracts/mech/build/mech.json | 746 -- .../vendor/valory/contracts/mech/contract.py | 401 -- .../valory/contracts/mech/contract.yaml | 23 - .../contracts/mech_activity/__init__.py | 20 - .../mech_activity/build/MechActivity.json | 111 - .../contracts/mech_activity/contract.py | 44 - .../contracts/mech_activity/contract.yaml | 23 - .../contracts/mech_marketplace/README.md | 1 - .../contracts/mech_marketplace/__init__.py | 20 - .../mech_marketplace/build/mech.json | 837 --- .../contracts/mech_marketplace/contract.py | 260 - .../contracts/mech_marketplace/contract.yaml | 23 - .../valory/contracts/multisend/README.md | 6 - .../valory/contracts/multisend/__init__.py | 20 - .../contracts/multisend/build/MultiSend.json | 358 - .../valory/contracts/multisend/contract.py | 191 - .../valory/contracts/multisend/contract.yaml | 23 - .../contracts/multisend/tests/__init__.py | 20 - .../multisend/tests/test_contract.py | 125 - .../valory/contracts/realitio/__init__.py | 20 - .../contracts/realitio/build/Realitio.json | 1069 --- .../valory/contracts/realitio/contract.py | 428 -- .../valory/contracts/realitio/contract.yaml | 25 - .../contracts/realitio_proxy/__init__.py | 20 - .../realitio_proxy/build/Realitio.json | 102 - .../contracts/realitio_proxy/contract.py | 54 - .../contracts/realitio_proxy/contract.yaml | 19 - .../contracts/service_registry/__init__.py | 20 - .../build/ServiceRegistry.json | 1988 ------ .../build/ServiceRegistryL2.json | 1899 ----- .../contracts/service_registry/contract.py | 402 -- .../contracts/service_registry/contract.yaml | 26 - .../service_registry/tests/__init__.py | 20 - .../service_registry/tests/test_contract.py | 239 - .../service_staking_token/__init__.py | 20 - .../build/ServiceStakingToken.json | 1355 ---- .../service_staking_token/contract.py | 192 - .../service_staking_token/contract.yaml | 23 - .../contracts/staking_token/__init__.py | 20 - .../staking_token/build/StakingToken.json | 1336 ---- .../contracts/staking_token/contract.py | 192 - .../contracts/staking_token/contract.yaml | 23 - .../transfer_nft_condition/README.md | 1 - .../transfer_nft_condition/__init__.py | 20 - .../build/TransferNFTCondition.json | 1148 --- .../transfer_nft_condition/contract.py | 120 - .../transfer_nft_condition/contract.yaml | 32 - .../vendor/valory/customs/__init__.py | 0 .../bet_amount_per_threshold/__init__.py | 20 - .../bet_amount_per_threshold.py | 65 - .../bet_amount_per_threshold/component.yaml | 15 - .../kelly_criterion_no_conf/__init__.py | 20 - .../kelly_criterion_no_conf/component.yaml | 15 - .../kelly_criterion_no_conf.py | 186 - .../valory/customs/mike_strat/__init__.py | 20 - .../valory/customs/mike_strat/component.yaml | 15 - .../valory/customs/mike_strat/mike_strat.py | 65 - .../vendor/valory/protocols/__init__.py | 0 .../vendor/valory/protocols/abci/README.md | 414 -- .../vendor/valory/protocols/abci/__init__.py | 30 - .../vendor/valory/protocols/abci/abci.proto | 407 -- .../vendor/valory/protocols/abci/abci_pb2.py | 177 - .../valory/protocols/abci/custom_types.py | 1622 ----- .../vendor/valory/protocols/abci/dialogues.py | 253 - .../vendor/valory/protocols/abci/message.py | 1273 ---- .../valory/protocols/abci/protocol.yaml | 25 - .../valory/protocols/abci/serialization.py | 617 -- .../valory/protocols/abci/tests/__init__.py | 20 - .../valory/protocols/abci/tests/conftest.py | 20 - .../valory/protocols/abci/tests/test_abci.py | 910 --- .../abci/tests/test_abci_dialogues.py | 45 - .../abci/tests/test_abci_messages.py | 491 -- .../vendor/valory/protocols/acn/README.md | 76 - .../vendor/valory/protocols/acn/__init__.py | 30 - .../vendor/valory/protocols/acn/acn.proto | 71 - .../vendor/valory/protocols/acn/acn_pb2.py | 42 - .../valory/protocols/acn/custom_types.py | 224 - .../vendor/valory/protocols/acn/dialogues.py | 126 - .../vendor/valory/protocols/acn/message.py | 274 - .../vendor/valory/protocols/acn/protocol.yaml | 24 - .../valory/protocols/acn/serialization.py | 149 - .../valory/protocols/acn/tests/__init__.py | 20 - .../valory/protocols/acn/tests/test_acn.py | 256 - .../protocols/acn/tests/test_acn_dialogues.py | 53 - .../protocols/acn/tests/test_acn_messages.py | 117 - .../valory/protocols/contract_api/README.md | 81 - .../valory/protocols/contract_api/__init__.py | 30 - .../protocols/contract_api/contract_api.proto | 88 - .../contract_api/contract_api_pb2.py | 62 - .../protocols/contract_api/custom_types.py | 96 - .../protocols/contract_api/dialogues.py | 152 - .../valory/protocols/contract_api/message.py | 472 -- .../protocols/contract_api/protocol.yaml | 24 - .../protocols/contract_api/serialization.py | 250 - .../protocols/contract_api/tests/__init__.py | 20 - .../contract_api/tests/test_contract_api.py | 734 -- .../tests/test_contract_api_dialogues.py | 52 - .../tests/test_contract_api_messages.py | 147 - .../vendor/valory/protocols/http/README.md | 46 - .../vendor/valory/protocols/http/__init__.py | 30 - .../vendor/valory/protocols/http/dialogues.py | 115 - .../vendor/valory/protocols/http/http.proto | 29 - .../vendor/valory/protocols/http/http_pb2.py | 30 - .../vendor/valory/protocols/http/message.py | 297 - .../valory/protocols/http/protocol.yaml | 23 - .../valory/protocols/http/serialization.py | 145 - .../valory/protocols/http/tests/__init__.py | 20 - .../valory/protocols/http/tests/test_http.py | 394 -- .../http/tests/test_http_dialogues.py | 49 - .../http/tests/test_http_messages.py | 75 - .../vendor/valory/protocols/ipfs/README.md | 47 - .../vendor/valory/protocols/ipfs/__init__.py | 30 - .../vendor/valory/protocols/ipfs/dialogues.py | 125 - .../vendor/valory/protocols/ipfs/ipfs.proto | 40 - .../vendor/valory/protocols/ipfs/ipfs_pb2.py | 45 - .../vendor/valory/protocols/ipfs/message.py | 298 - .../valory/protocols/ipfs/protocol.yaml | 21 - .../valory/protocols/ipfs/serialization.py | 153 - .../ipfs/tests/test_ipfs_dialogues.py | 46 - .../ipfs/tests/test_ipfs_messages.py | 87 - .../valory/protocols/ledger_api/README.md | 103 - .../valory/protocols/ledger_api/__init__.py | 30 - .../protocols/ledger_api/custom_types.py | 284 - .../valory/protocols/ledger_api/dialogues.py | 163 - .../protocols/ledger_api/ledger_api.proto | 132 - .../protocols/ledger_api/ledger_api_pb2.py | 96 - .../valory/protocols/ledger_api/message.py | 594 -- .../valory/protocols/ledger_api/protocol.yaml | 24 - .../protocols/ledger_api/serialization.py | 309 - .../protocols/ledger_api/tests/__init__.py | 20 - .../ledger_api/tests/test_ledger_api.py | 963 --- .../tests/test_ledger_api_dialogues.py | 49 - .../tests/test_ledger_api_messages.py | 180 - .../valory/protocols/tendermint/README.md | 55 - .../valory/protocols/tendermint/__init__.py | 30 - .../protocols/tendermint/custom_types.py | 54 - .../valory/protocols/tendermint/dialogues.py | 138 - .../valory/protocols/tendermint/message.py | 313 - .../valory/protocols/tendermint/protocol.yaml | 25 - .../protocols/tendermint/serialization.py | 156 - .../protocols/tendermint/tendermint.proto | 49 - .../protocols/tendermint/tendermint_pb2.py | 53 - .../protocols/tendermint/tests/__init__.py | 20 - .../tendermint/tests/test_tendermint.py | 217 - .../tests/test_tendermint_dialogues.py | 48 - .../tests/test_tendermint_messages.py | 80 - .../vendor/valory/skills/__init__.py | 0 .../valory/skills/abstract_abci/README.md | 20 - .../valory/skills/abstract_abci/__init__.py | 25 - .../valory/skills/abstract_abci/dialogues.py | 61 - .../valory/skills/abstract_abci/handlers.py | 408 -- .../valory/skills/abstract_abci/skill.yaml | 34 - .../skills/abstract_abci/tests/__init__.py | 20 - .../abstract_abci/tests/test_dialogues.py | 47 - .../abstract_abci/tests/test_handlers.py | 398 -- .../skills/abstract_round_abci/README.md | 46 - .../skills/abstract_round_abci/__init__.py | 25 - .../abstract_round_abci/abci_app_chain.py | 291 - .../valory/skills/abstract_round_abci/base.py | 3850 ---------- .../abstract_round_abci/behaviour_utils.py | 2356 ------- .../skills/abstract_round_abci/behaviours.py | 409 -- .../skills/abstract_round_abci/common.py | 231 - .../skills/abstract_round_abci/dialogues.py | 368 - .../skills/abstract_round_abci/handlers.py | 790 --- .../abstract_round_abci/io_/__init__.py | 20 - .../skills/abstract_round_abci/io_/ipfs.py | 85 - .../skills/abstract_round_abci/io_/load.py | 124 - .../skills/abstract_round_abci/io_/paths.py | 34 - .../skills/abstract_round_abci/io_/store.py | 153 - .../skills/abstract_round_abci/models.py | 893 --- .../skills/abstract_round_abci/skill.yaml | 164 - .../test_tools/__init__.py | 20 - .../test_tools/abci_app.py | 203 - .../abstract_round_abci/test_tools/base.py | 444 -- .../abstract_round_abci/test_tools/common.py | 432 -- .../test_tools/integration.py | 301 - .../abstract_round_abci/test_tools/rounds.py | 599 -- .../abstract_round_abci/tests/__init__.py | 27 - .../abstract_round_abci/tests/conftest.py | 116 - .../tests/data/__init__.py | 20 - .../tests/data/dummy_abci/__init__.py | 28 - .../tests/data/dummy_abci/behaviours.py | 158 - .../tests/data/dummy_abci/dialogues.py | 81 - .../tests/data/dummy_abci/handlers.py | 47 - .../tests/data/dummy_abci/models.py | 44 - .../tests/data/dummy_abci/payloads.py | 53 - .../tests/data/dummy_abci/rounds.py | 152 - .../tests/data/dummy_abci/skill.yaml | 148 - .../tests/test_abci_app_chain.py | 508 -- .../abstract_round_abci/tests/test_base.py | 3420 --------- .../tests/test_base_rounds.py | 668 -- .../tests/test_behaviours.py | 951 --- .../tests/test_behaviours_utils.py | 2681 ------- .../abstract_round_abci/tests/test_common.py | 407 -- .../tests/test_dialogues.py | 100 - .../tests/test_handlers.py | 596 -- .../tests/test_io/__init__.py | 20 - .../tests/test_io/test_ipfs.py | 110 - .../tests/test_io/test_load.py | 114 - .../tests/test_io/test_store.py | 104 - .../abstract_round_abci/tests/test_models.py | 901 --- .../tests/test_tools/__init__.py | 20 - .../tests/test_tools/base.py | 86 - .../tests/test_tools/test_base.py | 189 - .../tests/test_tools/test_common.py | 183 - .../tests/test_tools/test_integration.py | 143 - .../tests/test_tools/test_rounds.py | 659 -- .../abstract_round_abci/tests/test_utils.py | 307 - .../skills/abstract_round_abci/utils.py | 504 -- .../skills/check_stop_trading_abci/README.md | 5 - .../check_stop_trading_abci/__init__.py | 25 - .../check_stop_trading_abci/behaviours.py | 185 - .../check_stop_trading_abci/dialogues.py | 81 - .../fsm_specification.yaml | 23 - .../check_stop_trading_abci/handlers.py | 50 - .../skills/check_stop_trading_abci/models.py | 62 - .../check_stop_trading_abci/payloads.py | 31 - .../skills/check_stop_trading_abci/rounds.py | 147 - .../skills/check_stop_trading_abci/skill.yaml | 146 - .../check_stop_trading_abci/tests/__init__.py | 20 - .../tests/test_dialogues.py | 28 - .../tests/test_handlers.py | 76 - .../tests/test_payloads.py | 33 - .../tests/test_rounds.py | 285 - .../skills/decision_maker_abci/README.md | 5 - .../skills/decision_maker_abci/__init__.py | 25 - .../behaviours/__init__.py | 20 - .../decision_maker_abci/behaviours/base.py | 875 --- .../behaviours/bet_placement.py | 225 - .../behaviours/blacklisting.py | 86 - .../behaviours/check_benchmarking.py | 44 - .../behaviours/claim_subscription.py | 109 - .../behaviours/decision_receive.py | 612 -- .../behaviours/decision_request.py | 110 - .../behaviours/handle_failed_tx.py | 55 - .../behaviours/order_subscription.py | 381 - .../behaviours/randomness.py | 44 - .../decision_maker_abci/behaviours/reedem.py | 993 --- .../behaviours/round_behaviour.py | 85 - .../behaviours/sampling.py | 258 - .../behaviours/sell_outcome_token.py | 186 - .../behaviours/storage_manager.py | 471 -- .../behaviours/tool_selection.py | 81 - .../skills/decision_maker_abci/dialogues.py | 91 - .../fsm_specification.yaml | 133 - .../skills/decision_maker_abci/handlers.py | 366 - .../decision_maker_abci/io_/__init__.py | 19 - .../skills/decision_maker_abci/io_/loader.py | 67 - .../skills/decision_maker_abci/models.py | 623 -- .../skills/decision_maker_abci/payloads.py | 129 - .../skills/decision_maker_abci/policy.py | 291 - .../skills/decision_maker_abci/redeem_info.py | 145 - .../skills/decision_maker_abci/rounds.py | 381 - .../skills/decision_maker_abci/skill.yaml | 446 -- .../decision_maker_abci/states/__init__.py | 20 - .../skills/decision_maker_abci/states/base.py | 318 - .../states/bet_placement.py | 51 - .../states/blacklisting.py | 59 - .../states/check_benchmarking.py | 34 - .../states/claim_subscription.py | 44 - .../states/decision_receive.py | 81 - .../states/decision_request.py | 61 - .../states/final_states.py | 69 - .../states/handle_failed_tx.py | 66 - .../states/order_subscription.py | 75 - .../decision_maker_abci/states/randomness.py | 38 - .../decision_maker_abci/states/redeem.py | 107 - .../decision_maker_abci/states/sampling.py | 73 - .../states/sell_outcome_token.py | 28 - .../states/tool_selection.py | 47 - .../decision_maker_abci/tests/__init__.py | 25 - .../tests/behaviours/__init__.py | 20 - .../tests/behaviours/data/.gitkeep | 1 - .../behaviours/dummy_strategy/__init__.py | 20 - .../dummy_strategy/dummy_strategy.py | 29 - .../tests/behaviours/test_base.py | 275 - .../decision_maker_abci/tests/conftest.py | 34 - .../tests/states/test_base.py | 257 - .../tests/states/test_bet_placement.py | 42 - .../tests/states/test_blacklising.py | 121 - .../tests/states/test_check_benchmarking.py | 51 - .../tests/states/test_claim_subscription.py | 227 - .../tests/states/test_decision_receive.py | 224 - .../tests/states/test_decision_request.py | 157 - .../tests/states/test_final_states.py | 174 - .../tests/states/test_handle_failed_tx.py | 94 - .../tests/states/test_order_subscription.py | 174 - .../tests/states/test_randomness.py | 69 - .../tests/states/test_redeem.py | 170 - .../tests/states/test_sampling.py | 118 - .../tests/states/test_tool_selection.py | 149 - .../tests/test_dialogues.py | 28 - .../tests/test_handlers.py | 381 - .../tests/test_payloads.py | 136 - .../decision_maker_abci/tests/test_rounds.py | 212 - .../decision_maker_abci/utils/__init__.py | 19 - .../decision_maker_abci/utils/nevermined.py | 373 - .../decision_maker_abci/utils/scaling.py | 65 - .../skills/market_manager_abci/README.md | 5 - .../skills/market_manager_abci/__init__.py | 25 - .../skills/market_manager_abci/behaviours.py | 236 - .../valory/skills/market_manager_abci/bets.py | 388 - .../skills/market_manager_abci/dialogues.py | 90 - .../fsm_specification.yaml | 21 - .../graph_tooling/__init__.py | 20 - .../graph_tooling/queries/__init__.py | 20 - .../queries/conditional_tokens.py | 49 - .../graph_tooling/queries/network.py | 41 - .../graph_tooling/queries/omen.py | 96 - .../graph_tooling/queries/realitio.py | 43 - .../graph_tooling/queries/trades.py | 76 - .../graph_tooling/requests.py | 414 -- .../graph_tooling/utils.py | 130 - .../skills/market_manager_abci/handlers.py | 50 - .../skills/market_manager_abci/models.py | 108 - .../skills/market_manager_abci/payloads.py | 32 - .../skills/market_manager_abci/rounds.py | 156 - .../skills/market_manager_abci/skill.yaml | 197 - .../market_manager_abci/tests/__init__.py | 20 - .../tests/test_dialogues.py | 28 - .../tests/test_handlers.py | 77 - .../tests/test_payloads.py | 30 - .../market_manager_abci/tests/test_rounds.py | 324 - .../skills/mech_interact_abci/__init__.py | 25 - .../mech_interact_abci/behaviours/__init__.py | 20 - .../mech_interact_abci/behaviours/base.py | 221 - .../mech_interact_abci/behaviours/request.py | 499 -- .../mech_interact_abci/behaviours/response.py | 270 - .../behaviours/round_behaviour.py | 40 - .../skills/mech_interact_abci/dialogues.py | 91 - .../mech_interact_abci/fsm_specification.yaml | 30 - .../skills/mech_interact_abci/handlers.py | 51 - .../skills/mech_interact_abci/models.py | 135 - .../skills/mech_interact_abci/payloads.py | 44 - .../skills/mech_interact_abci/rounds.py | 119 - .../skills/mech_interact_abci/skill.yaml | 200 - .../mech_interact_abci/states/__init__.py | 20 - .../skills/mech_interact_abci/states/base.py | 148 - .../mech_interact_abci/states/final_states.py | 38 - .../mech_interact_abci/states/request.py | 45 - .../mech_interact_abci/states/response.py | 35 - .../mech_interact_abci/tests/__init__.py | 20 - .../tests/test_behaviours.py | 132 - .../tests/test_dialogues.py | 26 - .../mech_interact_abci/tests/test_handlers.py | 26 - .../mech_interact_abci/tests/test_models.py | 31 - .../mech_interact_abci/tests/test_payloads.py | 46 - .../mech_interact_abci/tests/test_rounds.py | 109 - .../valory/skills/registration_abci/README.md | 25 - .../skills/registration_abci/__init__.py | 25 - .../skills/registration_abci/behaviours.py | 492 -- .../skills/registration_abci/dialogues.py | 90 - .../registration_abci/fsm_specification.yaml | 18 - .../skills/registration_abci/handlers.py | 51 - .../valory/skills/registration_abci/models.py | 41 - .../skills/registration_abci/payloads.py | 31 - .../valory/skills/registration_abci/rounds.py | 178 - .../skills/registration_abci/skill.yaml | 151 - .../registration_abci/tests/__init__.py | 20 - .../tests/test_behaviours.py | 644 -- .../registration_abci/tests/test_dialogues.py | 28 - .../registration_abci/tests/test_handlers.py | 28 - .../registration_abci/tests/test_models.py | 35 - .../registration_abci/tests/test_payloads.py | 46 - .../registration_abci/tests/test_rounds.py | 371 - .../valory/skills/reset_pause_abci/README.md | 23 - .../skills/reset_pause_abci/__init__.py | 25 - .../skills/reset_pause_abci/behaviours.py | 99 - .../skills/reset_pause_abci/dialogues.py | 91 - .../reset_pause_abci/fsm_specification.yaml | 19 - .../skills/reset_pause_abci/handlers.py | 51 - .../valory/skills/reset_pause_abci/models.py | 55 - .../skills/reset_pause_abci/payloads.py | 31 - .../valory/skills/reset_pause_abci/rounds.py | 115 - .../valory/skills/reset_pause_abci/skill.yaml | 141 - .../skills/reset_pause_abci/tests/__init__.py | 20 - .../reset_pause_abci/tests/test_behaviours.py | 154 - .../reset_pause_abci/tests/test_dialogues.py | 28 - .../reset_pause_abci/tests/test_handlers.py | 28 - .../reset_pause_abci/tests/test_payloads.py | 34 - .../reset_pause_abci/tests/test_rounds.py | 106 - .../valory/skills/staking_abci/README.md | 5 - .../valory/skills/staking_abci/__init__.py | 25 - .../valory/skills/staking_abci/behaviours.py | 551 -- .../valory/skills/staking_abci/dialogues.py | 90 - .../staking_abci/fsm_specification.yaml | 27 - .../valory/skills/staking_abci/handlers.py | 50 - .../valory/skills/staking_abci/models.py | 82 - .../valory/skills/staking_abci/payloads.py | 42 - .../valory/skills/staking_abci/rounds.py | 226 - .../valory/skills/staking_abci/skill.yaml | 152 - .../skills/staking_abci/tests/__init__.py | 20 - .../staking_abci/tests/test_dialogues.py | 28 - .../skills/staking_abci/tests/test_handers.py | 76 - .../staking_abci/tests/test_payloads.py | 60 - .../skills/staking_abci/tests/test_rounds.py | 381 - .../skills/termination_abci/__init__.py | 25 - .../skills/termination_abci/behaviours.py | 568 -- .../skills/termination_abci/dialogues.py | 91 - .../skills/termination_abci/handlers.py | 51 - .../valory/skills/termination_abci/models.py | 59 - .../skills/termination_abci/payloads.py | 31 - .../valory/skills/termination_abci/rounds.py | 192 - .../valory/skills/termination_abci/skill.yaml | 155 - .../skills/termination_abci/tests/__init__.py | 20 - .../termination_abci/tests/test_behaviours.py | 649 -- .../termination_abci/tests/test_dialogues.py | 28 - .../termination_abci/tests/test_handlers.py | 28 - .../termination_abci/tests/test_models.py | 35 - .../termination_abci/tests/test_payloads.py | 32 - .../termination_abci/tests/test_rounds.py | 178 - .../valory/skills/trader_abci/README.md | 5 - .../valory/skills/trader_abci/__init__.py | 25 - .../valory/skills/trader_abci/behaviours.py | 79 - .../valory/skills/trader_abci/composition.py | 168 - .../valory/skills/trader_abci/dialogues.py | 90 - .../skills/trader_abci/fsm_specification.yaml | 258 - .../valory/skills/trader_abci/handlers.py | 50 - .../valory/skills/trader_abci/models.py | 150 - .../valory/skills/trader_abci/skill.yaml | 424 -- .../skills/trader_abci/tests/__init__.py | 19 - .../trader_abci/tests/tests_handlers.py | 76 - .../transaction_settlement_abci/README.md | 53 - .../transaction_settlement_abci/__init__.py | 25 - .../transaction_settlement_abci/behaviours.py | 984 --- .../transaction_settlement_abci/dialogues.py | 91 - .../fsm_specification.yaml | 88 - .../transaction_settlement_abci/handlers.py | 51 - .../transaction_settlement_abci/models.py | 123 - .../payload_tools.py | 183 - .../transaction_settlement_abci/payloads.py | 82 - .../transaction_settlement_abci/rounds.py | 831 --- .../transaction_settlement_abci/skill.yaml | 174 - .../test_tools/__init__.py | 20 - .../test_tools/integration.py | 338 - .../tests/__init__.py | 24 - .../tests/test_behaviours.py | 1392 ---- .../tests/test_dialogues.py | 28 - .../tests/test_handlers.py | 28 - .../tests/test_models.py | 95 - .../tests/test_payload_tools.py | 101 - .../tests/test_payloads.py | 126 - .../tests/test_rounds.py | 1023 --- .../tests/test_tools/__init__.py | 20 - .../tests/test_tools/test_integration.py | 214 - .../tx_settlement_multiplexer_abci/README.md | 6 - .../__init__.py | 25 - .../behaviours.py | 184 - .../dialogues.py | 90 - .../fsm_specification.yaml | 52 - .../handlers.py | 50 - .../tx_settlement_multiplexer_abci/models.py | 59 - .../tx_settlement_multiplexer_abci/rounds.py | 265 - .../tx_settlement_multiplexer_abci/skill.yaml | 144 - .../tests/__init__.py | 19 - .../tests/test_handlers.py | 75 - .../vendor/w1kke/customs/__init__.py | 0 .../w1kke/customs/always_blue/__init__.py | 20 - .../w1kke/customs/always_blue/always_blue.py | 32 - .../w1kke/customs/always_blue/component.yaml | 14 - trader_old/.certs/acn_cosmos_9005.txt | 1 - .../0.json | 1 - trader_old/README.md | 8 - trader_old/__init__.py | 20 - trader_old/aea-config.yaml | 408 -- trader_old/data/available_tools_store.json | 1 - trader_old/data/benchmarking_results.csv | 159 - trader_old/data/bets.json | 1322 ---- trader_old/data/markets_test.csv | 161 - trader_old/data/markets_test2.csv | 161 - trader_old/data/multi_bets.json | 1 - trader_old/data/policy_store.json | 1 - ...icy_store_multi_bet_failure_adjusting.json | 1 - trader_old/data/utilized_tools.json | 1 - .../vendor/jhehemann/customs/__init__.py | 0 .../customs/kelly_criterion/__init__.py | 20 - .../customs/kelly_criterion/component.yaml | 14 - .../kelly_criterion/kelly_criterion.py | 161 - .../vendor/open_aea/protocols/__init__.py | 0 .../open_aea/protocols/signing/README.md | 65 - .../open_aea/protocols/signing/__init__.py | 30 - .../protocols/signing/custom_types.py | 68 - .../open_aea/protocols/signing/dialogues.py | 136 - .../open_aea/protocols/signing/message.py | 319 - .../open_aea/protocols/signing/protocol.yaml | 24 - .../protocols/signing/serialization.py | 162 - .../open_aea/protocols/signing/signing.proto | 68 - .../open_aea/protocols/signing/signing_pb2.py | 50 - .../protocols/signing/tests/__init__.py | 20 - .../protocols/signing/tests/test_signing.py | 144 - .../signing/tests/test_signing_dialogues.py | 58 - .../signing/tests/test_signing_messages.py | 109 - .../vendor/valory/connections/__init__.py | 0 .../vendor/valory/connections/abci/Makefile | 24 - .../valory/connections/abci/__init__.py | 20 - .../connections/abci/check_dependencies.py | 160 - .../valory/connections/abci/connection.py | 1497 ---- .../valory/connections/abci/connection.yaml | 84 - .../valory/connections/abci/dialogues.py | 59 - .../connections/abci/gogoproto/__init__.py | 20 - .../connections/abci/gogoproto/gogo_pb2.py | 31 - .../abci/protos/gogoproto/gogo.proto | 144 - .../abci/protos/tendermint/abci/types.proto | 407 -- .../abci/protos/tendermint/crypto/keys.proto | 17 - .../abci/protos/tendermint/crypto/proof.proto | 41 - .../abci/protos/tendermint/types/params.proto | 80 - .../abci/protos/tendermint/types/types.proto | 157 - .../protos/tendermint/types/validator.proto | 25 - .../protos/tendermint/version/types.proto | 24 - .../vendor/valory/connections/abci/readme.md | 8 - .../connections/abci/scripts/genproto.py | 127 - .../connections/abci/tendermint/__init__.py | 20 - .../abci/tendermint/abci/types_pb2.py | 211 - .../abci/tendermint/abci/types_pb2_grpc.py | 719 -- .../abci/tendermint/crypto/keys_pb2.py | 39 - .../abci/tendermint/crypto/proof_pb2.py | 47 - .../abci/tendermint/types/params_pb2.py | 69 - .../abci/tendermint/types/types_pb2.py | 158 - .../abci/tendermint/types/validator_pb2.py | 46 - .../abci/tendermint/version/types_pb2.py | 41 - .../connections/abci/tendermint_decoder.py | 472 -- .../connections/abci/tendermint_encoder.py | 418 -- .../valory/connections/abci/tests/__init__.py | 27 - .../valory/connections/abci/tests/helper.py | 533 -- .../connections/abci/tests/test_abci.py | 661 -- .../connections/abci/tests/test_abci_fuzz.py | 339 - .../connections/abci/tests/test_abci_spec.py | 220 - .../abci/tests/test_fuzz/__init__.py | 19 - .../connections/abci/tests/test_fuzz/base.py | 373 - .../tests/test_fuzz/mock_node/__init__.py | 19 - .../test_fuzz/mock_node/channels/__init__.py | 19 - .../test_fuzz/mock_node/channels/base.py | 189 - .../mock_node/channels/grpc_channel.py | 213 - .../mock_node/channels/tcp_channel.py | 535 -- .../abci/tests/test_fuzz/mock_node/node.py | 520 -- .../abci/tests/test_fuzz/test_fuzz.py | 53 - .../abci/tests/test_tendermint_decoder.py | 121 - .../abci/tests/test_tendermint_encoder.py | 124 - .../valory/connections/abci/version.txt | 6 - .../valory/connections/http_client/README.md | 7 - .../connections/http_client/__init__.py | 21 - .../connections/http_client/connection.py | 446 -- .../connections/http_client/connection.yaml | 32 - .../connections/http_client/tests/__init__.py | 21 - .../http_client/tests/test_http_client.py | 362 - .../valory/connections/http_server/README.md | 7 - .../connections/http_server/__init__.py | 21 - .../connections/http_server/connection.py | 645 -- .../connections/http_server/connection.yaml | 43 - .../connections/http_server/tests/__init__.py | 20 - .../http_server/tests/data/certs/server.crt | 17 - .../http_server/tests/data/certs/server.csr | 15 - .../http_server/tests/data/certs/server.key | 27 - .../http_server/tests/data/petstore_sim.yaml | 111 - .../http_server/tests/test_http_server.py | 597 -- .../valory/connections/ipfs/__init__.py | 20 - .../valory/connections/ipfs/connection.py | 323 - .../valory/connections/ipfs/connection.yaml | 31 - .../vendor/valory/connections/ipfs/readme.md | 2 - .../valory/connections/ipfs/tests/__init__.py | 20 - .../connections/ipfs/tests/test_connection.py | 282 - .../valory/connections/ledger/README.md | 11 - .../valory/connections/ledger/__init__.py | 20 - .../vendor/valory/connections/ledger/base.py | 217 - .../valory/connections/ledger/connection.py | 193 - .../valory/connections/ledger/connection.yaml | 115 - .../connections/ledger/contract_dispatcher.py | 451 -- .../connections/ledger/ledger_dispatcher.py | 474 -- .../connections/ledger/tests/__init__.py | 21 - .../connections/ledger/tests/conftest.py | 148 - .../ledger/tests/test_contract_dispatcher.py | 281 - .../connections/ledger/tests/test_ledger.py | 623 -- .../ledger/tests/test_ledger_api.py | 682 -- .../connections/p2p_libp2p_client/README.md | 15 - .../connections/p2p_libp2p_client/__init__.py | 21 - .../p2p_libp2p_client/connection.py | 688 -- .../p2p_libp2p_client/connection.yaml | 51 - .../vendor/valory/contracts/__init__.py | 0 .../contracts/agent_registry/__init__.py | 20 - .../agent_registry/build/AgentRegistry.json | 1046 --- .../contracts/agent_registry/contract.py | 64 - .../contracts/agent_registry/contract.yaml | 23 - .../contracts/conditional_tokens/__init__.py | 20 - .../build/ConditionalTokens.json | 708 -- .../contracts/conditional_tokens/contract.py | 420 -- .../conditional_tokens/contract.yaml | 24 - .../vendor/valory/contracts/erc20/README.md | 1 - .../vendor/valory/contracts/erc20/__init__.py | 20 - .../valory/contracts/erc20/build/ERC20.json | 288 - .../vendor/valory/contracts/erc20/contract.py | 101 - .../valory/contracts/erc20/contract.yaml | 32 - .../valory/contracts/gnosis_safe/README.md | 6 - .../valory/contracts/gnosis_safe/__init__.py | 20 - .../gnosis_safe/build/GnosisSafe_V1_3_0.json | 1179 ---- .../valory/contracts/gnosis_safe/contract.py | 1004 --- .../contracts/gnosis_safe/contract.yaml | 40 - .../valory/contracts/gnosis_safe/encode.py | 155 - .../contracts/gnosis_safe/tests/__init__.py | 20 - .../gnosis_safe/tests/test_contract.py | 845 --- .../gnosis_safe_proxy_factory/README.md | 6 - .../gnosis_safe_proxy_factory/__init__.py | 20 - .../build/ProxyFactory_V1_3_0.json | 172 - .../gnosis_safe_proxy_factory/contract.py | 178 - .../gnosis_safe_proxy_factory/contract.yaml | 26 - .../tests/__init__.py | 20 - .../tests/test_contract.py | 103 - .../valory/contracts/market_maker/README.md | 1 - .../valory/contracts/market_maker/__init__.py | 20 - .../build/FixedProductMarketMaker.json | 662 -- .../valory/contracts/market_maker/contract.py | 186 - .../contracts/market_maker/contract.yaml | 32 - .../vendor/valory/contracts/mech/README.md | 1 - .../vendor/valory/contracts/mech/__init__.py | 20 - .../valory/contracts/mech/build/mech.json | 746 -- .../vendor/valory/contracts/mech/contract.py | 401 -- .../valory/contracts/mech/contract.yaml | 23 - .../contracts/mech_activity/__init__.py | 20 - .../mech_activity/build/MechActivity.json | 111 - .../contracts/mech_activity/contract.py | 44 - .../contracts/mech_activity/contract.yaml | 23 - .../contracts/mech_marketplace/README.md | 1 - .../contracts/mech_marketplace/__init__.py | 20 - .../mech_marketplace/build/mech.json | 837 --- .../contracts/mech_marketplace/contract.py | 260 - .../contracts/mech_marketplace/contract.yaml | 23 - .../valory/contracts/multisend/README.md | 6 - .../valory/contracts/multisend/__init__.py | 20 - .../contracts/multisend/build/MultiSend.json | 358 - .../valory/contracts/multisend/contract.py | 191 - .../valory/contracts/multisend/contract.yaml | 23 - .../contracts/multisend/tests/__init__.py | 20 - .../multisend/tests/test_contract.py | 125 - .../valory/contracts/realitio/__init__.py | 20 - .../contracts/realitio/build/Realitio.json | 1069 --- .../valory/contracts/realitio/contract.py | 428 -- .../valory/contracts/realitio/contract.yaml | 25 - .../contracts/realitio_proxy/__init__.py | 20 - .../realitio_proxy/build/Realitio.json | 102 - .../contracts/realitio_proxy/contract.py | 54 - .../contracts/realitio_proxy/contract.yaml | 19 - .../contracts/service_registry/__init__.py | 20 - .../build/ServiceRegistry.json | 1988 ------ .../build/ServiceRegistryL2.json | 1899 ----- .../contracts/service_registry/contract.py | 402 -- .../contracts/service_registry/contract.yaml | 26 - .../service_registry/tests/__init__.py | 20 - .../service_registry/tests/test_contract.py | 239 - .../service_staking_token/__init__.py | 20 - .../build/ServiceStakingToken.json | 1355 ---- .../service_staking_token/contract.py | 192 - .../service_staking_token/contract.yaml | 23 - .../contracts/staking_token/__init__.py | 20 - .../staking_token/build/StakingToken.json | 1336 ---- .../contracts/staking_token/contract.py | 192 - .../contracts/staking_token/contract.yaml | 23 - .../transfer_nft_condition/README.md | 1 - .../transfer_nft_condition/__init__.py | 20 - .../build/TransferNFTCondition.json | 1148 --- .../transfer_nft_condition/contract.py | 120 - .../transfer_nft_condition/contract.yaml | 32 - trader_old/vendor/valory/customs/__init__.py | 0 .../bet_amount_per_threshold/__init__.py | 20 - .../bet_amount_per_threshold.py | 65 - .../bet_amount_per_threshold/component.yaml | 15 - .../kelly_criterion_no_conf/__init__.py | 20 - .../kelly_criterion_no_conf/component.yaml | 15 - .../kelly_criterion_no_conf.py | 186 - .../valory/customs/mike_strat/__init__.py | 20 - .../valory/customs/mike_strat/component.yaml | 15 - .../valory/customs/mike_strat/mike_strat.py | 65 - .../vendor/valory/protocols/__init__.py | 0 .../vendor/valory/protocols/abci/README.md | 414 -- .../vendor/valory/protocols/abci/__init__.py | 30 - .../vendor/valory/protocols/abci/abci.proto | 407 -- .../vendor/valory/protocols/abci/abci_pb2.py | 177 - .../valory/protocols/abci/custom_types.py | 1622 ----- .../vendor/valory/protocols/abci/dialogues.py | 253 - .../vendor/valory/protocols/abci/message.py | 1273 ---- .../valory/protocols/abci/protocol.yaml | 25 - .../valory/protocols/abci/serialization.py | 617 -- .../valory/protocols/abci/tests/__init__.py | 20 - .../valory/protocols/abci/tests/conftest.py | 20 - .../valory/protocols/abci/tests/test_abci.py | 910 --- .../abci/tests/test_abci_dialogues.py | 45 - .../abci/tests/test_abci_messages.py | 491 -- .../vendor/valory/protocols/acn/README.md | 76 - .../vendor/valory/protocols/acn/__init__.py | 30 - .../vendor/valory/protocols/acn/acn.proto | 71 - .../vendor/valory/protocols/acn/acn_pb2.py | 42 - .../valory/protocols/acn/custom_types.py | 224 - .../vendor/valory/protocols/acn/dialogues.py | 126 - .../vendor/valory/protocols/acn/message.py | 274 - .../vendor/valory/protocols/acn/protocol.yaml | 24 - .../valory/protocols/acn/serialization.py | 149 - .../valory/protocols/acn/tests/__init__.py | 20 - .../valory/protocols/acn/tests/test_acn.py | 256 - .../protocols/acn/tests/test_acn_dialogues.py | 53 - .../protocols/acn/tests/test_acn_messages.py | 117 - .../valory/protocols/contract_api/README.md | 81 - .../valory/protocols/contract_api/__init__.py | 30 - .../protocols/contract_api/contract_api.proto | 88 - .../contract_api/contract_api_pb2.py | 62 - .../protocols/contract_api/custom_types.py | 96 - .../protocols/contract_api/dialogues.py | 152 - .../valory/protocols/contract_api/message.py | 472 -- .../protocols/contract_api/protocol.yaml | 24 - .../protocols/contract_api/serialization.py | 250 - .../protocols/contract_api/tests/__init__.py | 20 - .../contract_api/tests/test_contract_api.py | 734 -- .../tests/test_contract_api_dialogues.py | 52 - .../tests/test_contract_api_messages.py | 147 - .../vendor/valory/protocols/http/README.md | 46 - .../vendor/valory/protocols/http/__init__.py | 30 - .../vendor/valory/protocols/http/dialogues.py | 115 - .../vendor/valory/protocols/http/http.proto | 29 - .../vendor/valory/protocols/http/http_pb2.py | 30 - .../vendor/valory/protocols/http/message.py | 297 - .../valory/protocols/http/protocol.yaml | 23 - .../valory/protocols/http/serialization.py | 145 - .../valory/protocols/http/tests/__init__.py | 20 - .../valory/protocols/http/tests/test_http.py | 394 -- .../http/tests/test_http_dialogues.py | 49 - .../http/tests/test_http_messages.py | 75 - .../vendor/valory/protocols/ipfs/README.md | 47 - .../vendor/valory/protocols/ipfs/__init__.py | 30 - .../vendor/valory/protocols/ipfs/dialogues.py | 125 - .../vendor/valory/protocols/ipfs/ipfs.proto | 40 - .../vendor/valory/protocols/ipfs/ipfs_pb2.py | 45 - .../vendor/valory/protocols/ipfs/message.py | 298 - .../valory/protocols/ipfs/protocol.yaml | 21 - .../valory/protocols/ipfs/serialization.py | 153 - .../ipfs/tests/test_ipfs_dialogues.py | 46 - .../ipfs/tests/test_ipfs_messages.py | 87 - .../valory/protocols/ledger_api/README.md | 103 - .../valory/protocols/ledger_api/__init__.py | 30 - .../protocols/ledger_api/custom_types.py | 284 - .../valory/protocols/ledger_api/dialogues.py | 163 - .../protocols/ledger_api/ledger_api.proto | 132 - .../protocols/ledger_api/ledger_api_pb2.py | 96 - .../valory/protocols/ledger_api/message.py | 594 -- .../valory/protocols/ledger_api/protocol.yaml | 24 - .../protocols/ledger_api/serialization.py | 309 - .../protocols/ledger_api/tests/__init__.py | 20 - .../ledger_api/tests/test_ledger_api.py | 963 --- .../tests/test_ledger_api_dialogues.py | 49 - .../tests/test_ledger_api_messages.py | 180 - .../valory/protocols/tendermint/README.md | 55 - .../valory/protocols/tendermint/__init__.py | 30 - .../protocols/tendermint/custom_types.py | 54 - .../valory/protocols/tendermint/dialogues.py | 138 - .../valory/protocols/tendermint/message.py | 313 - .../valory/protocols/tendermint/protocol.yaml | 25 - .../protocols/tendermint/serialization.py | 156 - .../protocols/tendermint/tendermint.proto | 49 - .../protocols/tendermint/tendermint_pb2.py | 53 - .../protocols/tendermint/tests/__init__.py | 20 - .../tendermint/tests/test_tendermint.py | 217 - .../tests/test_tendermint_dialogues.py | 48 - .../tests/test_tendermint_messages.py | 80 - trader_old/vendor/valory/skills/__init__.py | 0 .../valory/skills/abstract_abci/README.md | 20 - .../valory/skills/abstract_abci/__init__.py | 25 - .../valory/skills/abstract_abci/dialogues.py | 61 - .../valory/skills/abstract_abci/handlers.py | 408 -- .../valory/skills/abstract_abci/skill.yaml | 34 - .../skills/abstract_abci/tests/__init__.py | 20 - .../abstract_abci/tests/test_dialogues.py | 47 - .../abstract_abci/tests/test_handlers.py | 398 -- .../skills/abstract_round_abci/README.md | 46 - .../skills/abstract_round_abci/__init__.py | 25 - .../abstract_round_abci/abci_app_chain.py | 291 - .../valory/skills/abstract_round_abci/base.py | 3850 ---------- .../abstract_round_abci/behaviour_utils.py | 2356 ------- .../skills/abstract_round_abci/behaviours.py | 409 -- .../skills/abstract_round_abci/common.py | 231 - .../skills/abstract_round_abci/dialogues.py | 368 - .../skills/abstract_round_abci/handlers.py | 790 --- .../abstract_round_abci/io_/__init__.py | 20 - .../skills/abstract_round_abci/io_/ipfs.py | 85 - .../skills/abstract_round_abci/io_/load.py | 124 - .../skills/abstract_round_abci/io_/paths.py | 34 - .../skills/abstract_round_abci/io_/store.py | 153 - .../skills/abstract_round_abci/models.py | 893 --- .../skills/abstract_round_abci/skill.yaml | 164 - .../test_tools/__init__.py | 20 - .../test_tools/abci_app.py | 203 - .../abstract_round_abci/test_tools/base.py | 444 -- .../abstract_round_abci/test_tools/common.py | 432 -- .../test_tools/integration.py | 301 - .../abstract_round_abci/test_tools/rounds.py | 599 -- .../abstract_round_abci/tests/__init__.py | 27 - .../abstract_round_abci/tests/conftest.py | 116 - .../tests/data/__init__.py | 20 - .../tests/data/dummy_abci/__init__.py | 28 - .../tests/data/dummy_abci/behaviours.py | 158 - .../tests/data/dummy_abci/dialogues.py | 81 - .../tests/data/dummy_abci/handlers.py | 47 - .../tests/data/dummy_abci/models.py | 44 - .../tests/data/dummy_abci/payloads.py | 53 - .../tests/data/dummy_abci/rounds.py | 152 - .../tests/data/dummy_abci/skill.yaml | 148 - .../tests/test_abci_app_chain.py | 508 -- .../abstract_round_abci/tests/test_base.py | 3420 --------- .../tests/test_base_rounds.py | 668 -- .../tests/test_behaviours.py | 951 --- .../tests/test_behaviours_utils.py | 2681 ------- .../abstract_round_abci/tests/test_common.py | 407 -- .../tests/test_dialogues.py | 100 - .../tests/test_handlers.py | 596 -- .../tests/test_io/__init__.py | 20 - .../tests/test_io/test_ipfs.py | 110 - .../tests/test_io/test_load.py | 114 - .../tests/test_io/test_store.py | 104 - .../abstract_round_abci/tests/test_models.py | 901 --- .../tests/test_tools/__init__.py | 20 - .../tests/test_tools/base.py | 86 - .../tests/test_tools/test_base.py | 189 - .../tests/test_tools/test_common.py | 183 - .../tests/test_tools/test_integration.py | 143 - .../tests/test_tools/test_rounds.py | 659 -- .../abstract_round_abci/tests/test_utils.py | 307 - .../skills/abstract_round_abci/utils.py | 504 -- .../skills/check_stop_trading_abci/README.md | 5 - .../check_stop_trading_abci/__init__.py | 25 - .../check_stop_trading_abci/behaviours.py | 185 - .../check_stop_trading_abci/dialogues.py | 81 - .../fsm_specification.yaml | 23 - .../check_stop_trading_abci/handlers.py | 50 - .../skills/check_stop_trading_abci/models.py | 62 - .../check_stop_trading_abci/payloads.py | 31 - .../skills/check_stop_trading_abci/rounds.py | 147 - .../skills/check_stop_trading_abci/skill.yaml | 146 - .../check_stop_trading_abci/tests/__init__.py | 20 - .../tests/test_dialogues.py | 28 - .../tests/test_handlers.py | 76 - .../tests/test_payloads.py | 33 - .../tests/test_rounds.py | 285 - .../skills/decision_maker_abci/README.md | 5 - .../skills/decision_maker_abci/__init__.py | 25 - .../behaviours/__init__.py | 20 - .../decision_maker_abci/behaviours/base.py | 879 --- .../behaviours/bet_placement.py | 225 - .../behaviours/blacklisting.py | 86 - .../behaviours/check_benchmarking.py | 44 - .../behaviours/claim_subscription.py | 109 - .../behaviours/decision_receive.py | 612 -- .../behaviours/decision_request.py | 110 - .../behaviours/handle_failed_tx.py | 55 - .../behaviours/order_subscription.py | 381 - .../behaviours/randomness.py | 44 - .../decision_maker_abci/behaviours/reedem.py | 993 --- .../behaviours/round_behaviour.py | 85 - .../behaviours/sampling.py | 258 - .../behaviours/sell_outcome_token.py | 186 - .../behaviours/storage_manager.py | 471 -- .../behaviours/tool_selection.py | 81 - .../skills/decision_maker_abci/dialogues.py | 91 - .../fsm_specification.yaml | 133 - .../skills/decision_maker_abci/handlers.py | 366 - .../decision_maker_abci/io_/__init__.py | 19 - .../skills/decision_maker_abci/io_/loader.py | 67 - .../skills/decision_maker_abci/models.py | 626 -- .../skills/decision_maker_abci/payloads.py | 129 - .../skills/decision_maker_abci/policy.py | 290 - .../skills/decision_maker_abci/redeem_info.py | 145 - .../skills/decision_maker_abci/rounds.py | 381 - .../skills/decision_maker_abci/skill.yaml | 447 -- .../decision_maker_abci/states/__init__.py | 20 - .../skills/decision_maker_abci/states/base.py | 318 - .../states/bet_placement.py | 51 - .../states/blacklisting.py | 59 - .../states/check_benchmarking.py | 34 - .../states/claim_subscription.py | 44 - .../states/decision_receive.py | 81 - .../states/decision_request.py | 61 - .../states/final_states.py | 69 - .../states/handle_failed_tx.py | 66 - .../states/order_subscription.py | 75 - .../decision_maker_abci/states/randomness.py | 38 - .../decision_maker_abci/states/redeem.py | 107 - .../decision_maker_abci/states/sampling.py | 73 - .../states/sell_outcome_token.py | 28 - .../states/tool_selection.py | 47 - .../decision_maker_abci/tests/__init__.py | 25 - .../tests/behaviours/__init__.py | 20 - .../tests/behaviours/data/.gitkeep | 1 - .../behaviours/dummy_strategy/__init__.py | 20 - .../dummy_strategy/dummy_strategy.py | 29 - .../tests/behaviours/test_base.py | 275 - .../decision_maker_abci/tests/conftest.py | 34 - .../tests/states/test_base.py | 257 - .../tests/states/test_bet_placement.py | 42 - .../tests/states/test_blacklising.py | 121 - .../tests/states/test_check_benchmarking.py | 51 - .../tests/states/test_claim_subscription.py | 227 - .../tests/states/test_decision_receive.py | 224 - .../tests/states/test_decision_request.py | 157 - .../tests/states/test_final_states.py | 174 - .../tests/states/test_handle_failed_tx.py | 94 - .../tests/states/test_order_subscription.py | 174 - .../tests/states/test_randomness.py | 69 - .../tests/states/test_redeem.py | 170 - .../tests/states/test_sampling.py | 118 - .../tests/states/test_tool_selection.py | 149 - .../tests/test_dialogues.py | 28 - .../tests/test_handlers.py | 381 - .../tests/test_payloads.py | 136 - .../decision_maker_abci/tests/test_rounds.py | 212 - .../decision_maker_abci/utils/__init__.py | 19 - .../decision_maker_abci/utils/nevermined.py | 373 - .../decision_maker_abci/utils/scaling.py | 65 - .../skills/market_manager_abci/README.md | 5 - .../skills/market_manager_abci/__init__.py | 25 - .../skills/market_manager_abci/behaviours.py | 236 - .../valory/skills/market_manager_abci/bets.py | 387 - .../skills/market_manager_abci/dialogues.py | 90 - .../fsm_specification.yaml | 21 - .../graph_tooling/__init__.py | 20 - .../graph_tooling/queries/__init__.py | 20 - .../queries/conditional_tokens.py | 49 - .../graph_tooling/queries/network.py | 41 - .../graph_tooling/queries/omen.py | 96 - .../graph_tooling/queries/realitio.py | 43 - .../graph_tooling/queries/trades.py | 76 - .../graph_tooling/requests.py | 414 -- .../graph_tooling/utils.py | 130 - .../skills/market_manager_abci/handlers.py | 50 - .../skills/market_manager_abci/models.py | 108 - .../skills/market_manager_abci/payloads.py | 32 - .../skills/market_manager_abci/rounds.py | 156 - .../skills/market_manager_abci/skill.yaml | 197 - .../market_manager_abci/tests/__init__.py | 20 - .../tests/test_dialogues.py | 28 - .../tests/test_handlers.py | 77 - .../tests/test_payloads.py | 30 - .../market_manager_abci/tests/test_rounds.py | 324 - .../skills/mech_interact_abci/__init__.py | 25 - .../mech_interact_abci/behaviours/__init__.py | 20 - .../mech_interact_abci/behaviours/base.py | 221 - .../mech_interact_abci/behaviours/request.py | 499 -- .../mech_interact_abci/behaviours/response.py | 270 - .../behaviours/round_behaviour.py | 40 - .../skills/mech_interact_abci/dialogues.py | 91 - .../mech_interact_abci/fsm_specification.yaml | 30 - .../skills/mech_interact_abci/handlers.py | 51 - .../skills/mech_interact_abci/models.py | 135 - .../skills/mech_interact_abci/payloads.py | 44 - .../skills/mech_interact_abci/rounds.py | 119 - .../skills/mech_interact_abci/skill.yaml | 200 - .../mech_interact_abci/states/__init__.py | 20 - .../skills/mech_interact_abci/states/base.py | 148 - .../mech_interact_abci/states/final_states.py | 38 - .../mech_interact_abci/states/request.py | 45 - .../mech_interact_abci/states/response.py | 35 - .../mech_interact_abci/tests/__init__.py | 20 - .../tests/test_behaviours.py | 132 - .../tests/test_dialogues.py | 26 - .../mech_interact_abci/tests/test_handlers.py | 26 - .../mech_interact_abci/tests/test_models.py | 31 - .../mech_interact_abci/tests/test_payloads.py | 46 - .../mech_interact_abci/tests/test_rounds.py | 109 - .../valory/skills/registration_abci/README.md | 25 - .../skills/registration_abci/__init__.py | 25 - .../skills/registration_abci/behaviours.py | 492 -- .../skills/registration_abci/dialogues.py | 90 - .../registration_abci/fsm_specification.yaml | 18 - .../skills/registration_abci/handlers.py | 51 - .../valory/skills/registration_abci/models.py | 41 - .../skills/registration_abci/payloads.py | 31 - .../valory/skills/registration_abci/rounds.py | 178 - .../skills/registration_abci/skill.yaml | 151 - .../registration_abci/tests/__init__.py | 20 - .../tests/test_behaviours.py | 644 -- .../registration_abci/tests/test_dialogues.py | 28 - .../registration_abci/tests/test_handlers.py | 28 - .../registration_abci/tests/test_models.py | 35 - .../registration_abci/tests/test_payloads.py | 46 - .../registration_abci/tests/test_rounds.py | 371 - .../valory/skills/reset_pause_abci/README.md | 23 - .../skills/reset_pause_abci/__init__.py | 25 - .../skills/reset_pause_abci/behaviours.py | 99 - .../skills/reset_pause_abci/dialogues.py | 91 - .../reset_pause_abci/fsm_specification.yaml | 19 - .../skills/reset_pause_abci/handlers.py | 51 - .../valory/skills/reset_pause_abci/models.py | 55 - .../skills/reset_pause_abci/payloads.py | 31 - .../valory/skills/reset_pause_abci/rounds.py | 115 - .../valory/skills/reset_pause_abci/skill.yaml | 141 - .../skills/reset_pause_abci/tests/__init__.py | 20 - .../reset_pause_abci/tests/test_behaviours.py | 154 - .../reset_pause_abci/tests/test_dialogues.py | 28 - .../reset_pause_abci/tests/test_handlers.py | 28 - .../reset_pause_abci/tests/test_payloads.py | 34 - .../reset_pause_abci/tests/test_rounds.py | 106 - .../valory/skills/staking_abci/README.md | 5 - .../valory/skills/staking_abci/__init__.py | 25 - .../valory/skills/staking_abci/behaviours.py | 551 -- .../valory/skills/staking_abci/dialogues.py | 90 - .../staking_abci/fsm_specification.yaml | 27 - .../valory/skills/staking_abci/handlers.py | 50 - .../valory/skills/staking_abci/models.py | 82 - .../valory/skills/staking_abci/payloads.py | 42 - .../valory/skills/staking_abci/rounds.py | 226 - .../valory/skills/staking_abci/skill.yaml | 152 - .../skills/staking_abci/tests/__init__.py | 20 - .../staking_abci/tests/test_dialogues.py | 28 - .../skills/staking_abci/tests/test_handers.py | 76 - .../staking_abci/tests/test_payloads.py | 60 - .../skills/staking_abci/tests/test_rounds.py | 381 - .../skills/termination_abci/__init__.py | 25 - .../skills/termination_abci/behaviours.py | 568 -- .../skills/termination_abci/dialogues.py | 91 - .../skills/termination_abci/handlers.py | 51 - .../valory/skills/termination_abci/models.py | 59 - .../skills/termination_abci/payloads.py | 31 - .../valory/skills/termination_abci/rounds.py | 192 - .../valory/skills/termination_abci/skill.yaml | 155 - .../skills/termination_abci/tests/__init__.py | 20 - .../termination_abci/tests/test_behaviours.py | 649 -- .../termination_abci/tests/test_dialogues.py | 28 - .../termination_abci/tests/test_handlers.py | 28 - .../termination_abci/tests/test_models.py | 35 - .../termination_abci/tests/test_payloads.py | 32 - .../termination_abci/tests/test_rounds.py | 178 - .../valory/skills/trader_abci/README.md | 5 - .../valory/skills/trader_abci/__init__.py | 25 - .../valory/skills/trader_abci/behaviours.py | 79 - .../valory/skills/trader_abci/composition.py | 168 - .../valory/skills/trader_abci/dialogues.py | 90 - .../skills/trader_abci/fsm_specification.yaml | 258 - .../valory/skills/trader_abci/handlers.py | 50 - .../valory/skills/trader_abci/models.py | 150 - .../valory/skills/trader_abci/skill.yaml | 425 -- .../skills/trader_abci/tests/__init__.py | 19 - .../trader_abci/tests/tests_handlers.py | 76 - .../transaction_settlement_abci/README.md | 53 - .../transaction_settlement_abci/__init__.py | 25 - .../transaction_settlement_abci/behaviours.py | 984 --- .../transaction_settlement_abci/dialogues.py | 91 - .../fsm_specification.yaml | 88 - .../transaction_settlement_abci/handlers.py | 51 - .../transaction_settlement_abci/models.py | 123 - .../payload_tools.py | 183 - .../transaction_settlement_abci/payloads.py | 82 - .../transaction_settlement_abci/rounds.py | 831 --- .../transaction_settlement_abci/skill.yaml | 174 - .../test_tools/__init__.py | 20 - .../test_tools/integration.py | 338 - .../tests/__init__.py | 24 - .../tests/test_behaviours.py | 1392 ---- .../tests/test_dialogues.py | 28 - .../tests/test_handlers.py | 28 - .../tests/test_models.py | 95 - .../tests/test_payload_tools.py | 101 - .../tests/test_payloads.py | 126 - .../tests/test_rounds.py | 1023 --- .../tests/test_tools/__init__.py | 20 - .../tests/test_tools/test_integration.py | 214 - .../tx_settlement_multiplexer_abci/README.md | 6 - .../__init__.py | 25 - .../behaviours.py | 184 - .../dialogues.py | 90 - .../fsm_specification.yaml | 52 - .../handlers.py | 50 - .../tx_settlement_multiplexer_abci/models.py | 59 - .../tx_settlement_multiplexer_abci/rounds.py | 265 - .../tx_settlement_multiplexer_abci/skill.yaml | 144 - .../tests/__init__.py | 19 - .../tests/test_handlers.py | 75 - trader_old/vendor/w1kke/customs/__init__.py | 0 .../w1kke/customs/always_blue/__init__.py | 20 - .../w1kke/customs/always_blue/always_blue.py | 32 - .../w1kke/customs/always_blue/component.yaml | 14 - 1233 files changed, 80 insertions(+), 242864 deletions(-) delete mode 100644 trader_backup/.certs/acn_cosmos_9005.txt delete mode 100644 trader_backup/README.md delete mode 100644 trader_backup/__init__.py delete mode 100644 trader_backup/aea-config.yaml delete mode 100644 trader_backup/data/available_tools_store.json delete mode 100644 trader_backup/data/benchmarking_40.csv delete mode 100644 trader_backup/data/bets.json delete mode 100644 trader_backup/data/multi_bets.json delete mode 100644 trader_backup/data/policy_store.json delete mode 100644 trader_backup/data/policy_store_multi_bet_failure_adjusting.json delete mode 100644 trader_backup/data/utilized_tools.json delete mode 100644 trader_backup/vendor/jhehemann/customs/__init__.py delete mode 100644 trader_backup/vendor/jhehemann/customs/kelly_criterion/__init__.py delete mode 100644 trader_backup/vendor/jhehemann/customs/kelly_criterion/component.yaml delete mode 100644 trader_backup/vendor/jhehemann/customs/kelly_criterion/kelly_criterion.py delete mode 100644 trader_backup/vendor/open_aea/protocols/__init__.py delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/README.md delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/__init__.py delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/custom_types.py delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/dialogues.py delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/message.py delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/protocol.yaml delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/serialization.py delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/signing.proto delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/signing_pb2.py delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/tests/__init__.py delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/tests/test_signing.py delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/tests/test_signing_dialogues.py delete mode 100644 trader_backup/vendor/open_aea/protocols/signing/tests/test_signing_messages.py delete mode 100644 trader_backup/vendor/valory/connections/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/abci/Makefile delete mode 100644 trader_backup/vendor/valory/connections/abci/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/abci/check_dependencies.py delete mode 100644 trader_backup/vendor/valory/connections/abci/connection.py delete mode 100644 trader_backup/vendor/valory/connections/abci/connection.yaml delete mode 100644 trader_backup/vendor/valory/connections/abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/connections/abci/gogoproto/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/abci/gogoproto/gogo_pb2.py delete mode 100644 trader_backup/vendor/valory/connections/abci/protos/gogoproto/gogo.proto delete mode 100644 trader_backup/vendor/valory/connections/abci/protos/tendermint/abci/types.proto delete mode 100644 trader_backup/vendor/valory/connections/abci/protos/tendermint/crypto/keys.proto delete mode 100644 trader_backup/vendor/valory/connections/abci/protos/tendermint/crypto/proof.proto delete mode 100644 trader_backup/vendor/valory/connections/abci/protos/tendermint/types/params.proto delete mode 100644 trader_backup/vendor/valory/connections/abci/protos/tendermint/types/types.proto delete mode 100644 trader_backup/vendor/valory/connections/abci/protos/tendermint/types/validator.proto delete mode 100644 trader_backup/vendor/valory/connections/abci/protos/tendermint/version/types.proto delete mode 100644 trader_backup/vendor/valory/connections/abci/readme.md delete mode 100644 trader_backup/vendor/valory/connections/abci/scripts/genproto.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tendermint/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tendermint/abci/types_pb2.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tendermint/abci/types_pb2_grpc.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tendermint/crypto/keys_pb2.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tendermint/crypto/proof_pb2.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tendermint/types/params_pb2.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tendermint/types/types_pb2.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tendermint/types/validator_pb2.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tendermint/version/types_pb2.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tendermint_decoder.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tendermint_encoder.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/helper.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_abci.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_abci_fuzz.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_abci_spec.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_fuzz/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_fuzz/base.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/base.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/grpc_channel.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/tcp_channel.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/node.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_fuzz/test_fuzz.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_tendermint_decoder.py delete mode 100644 trader_backup/vendor/valory/connections/abci/tests/test_tendermint_encoder.py delete mode 100644 trader_backup/vendor/valory/connections/abci/version.txt delete mode 100644 trader_backup/vendor/valory/connections/http_client/README.md delete mode 100644 trader_backup/vendor/valory/connections/http_client/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/http_client/connection.py delete mode 100644 trader_backup/vendor/valory/connections/http_client/connection.yaml delete mode 100644 trader_backup/vendor/valory/connections/http_client/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/http_client/tests/test_http_client.py delete mode 100644 trader_backup/vendor/valory/connections/http_server/README.md delete mode 100644 trader_backup/vendor/valory/connections/http_server/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/http_server/connection.py delete mode 100644 trader_backup/vendor/valory/connections/http_server/connection.yaml delete mode 100644 trader_backup/vendor/valory/connections/http_server/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/http_server/tests/data/certs/server.crt delete mode 100644 trader_backup/vendor/valory/connections/http_server/tests/data/certs/server.csr delete mode 100644 trader_backup/vendor/valory/connections/http_server/tests/data/certs/server.key delete mode 100644 trader_backup/vendor/valory/connections/http_server/tests/data/petstore_sim.yaml delete mode 100644 trader_backup/vendor/valory/connections/http_server/tests/test_http_server.py delete mode 100644 trader_backup/vendor/valory/connections/ipfs/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/ipfs/connection.py delete mode 100644 trader_backup/vendor/valory/connections/ipfs/connection.yaml delete mode 100644 trader_backup/vendor/valory/connections/ipfs/readme.md delete mode 100644 trader_backup/vendor/valory/connections/ipfs/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/ipfs/tests/test_connection.py delete mode 100644 trader_backup/vendor/valory/connections/ledger/README.md delete mode 100644 trader_backup/vendor/valory/connections/ledger/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/ledger/base.py delete mode 100644 trader_backup/vendor/valory/connections/ledger/connection.py delete mode 100644 trader_backup/vendor/valory/connections/ledger/connection.yaml delete mode 100644 trader_backup/vendor/valory/connections/ledger/contract_dispatcher.py delete mode 100644 trader_backup/vendor/valory/connections/ledger/ledger_dispatcher.py delete mode 100644 trader_backup/vendor/valory/connections/ledger/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/ledger/tests/conftest.py delete mode 100644 trader_backup/vendor/valory/connections/ledger/tests/test_contract_dispatcher.py delete mode 100644 trader_backup/vendor/valory/connections/ledger/tests/test_ledger.py delete mode 100644 trader_backup/vendor/valory/connections/ledger/tests/test_ledger_api.py delete mode 100644 trader_backup/vendor/valory/connections/p2p_libp2p_client/README.md delete mode 100644 trader_backup/vendor/valory/connections/p2p_libp2p_client/__init__.py delete mode 100644 trader_backup/vendor/valory/connections/p2p_libp2p_client/connection.py delete mode 100644 trader_backup/vendor/valory/connections/p2p_libp2p_client/connection.yaml delete mode 100644 trader_backup/vendor/valory/contracts/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/agent_registry/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/agent_registry/build/AgentRegistry.json delete mode 100644 trader_backup/vendor/valory/contracts/agent_registry/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/agent_registry/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/conditional_tokens/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/conditional_tokens/build/ConditionalTokens.json delete mode 100644 trader_backup/vendor/valory/contracts/conditional_tokens/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/conditional_tokens/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/erc20/README.md delete mode 100644 trader_backup/vendor/valory/contracts/erc20/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/erc20/build/ERC20.json delete mode 100644 trader_backup/vendor/valory/contracts/erc20/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/erc20/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe/README.md delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe/build/GnosisSafe_V1_3_0.json delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe/encode.py delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe/tests/test_contract.py delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/README.md delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/build/ProxyFactory_V1_3_0.json delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/test_contract.py delete mode 100644 trader_backup/vendor/valory/contracts/market_maker/README.md delete mode 100644 trader_backup/vendor/valory/contracts/market_maker/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/market_maker/build/FixedProductMarketMaker.json delete mode 100644 trader_backup/vendor/valory/contracts/market_maker/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/market_maker/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/mech/README.md delete mode 100644 trader_backup/vendor/valory/contracts/mech/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/mech/build/mech.json delete mode 100644 trader_backup/vendor/valory/contracts/mech/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/mech/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/mech_activity/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/mech_activity/build/MechActivity.json delete mode 100644 trader_backup/vendor/valory/contracts/mech_activity/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/mech_activity/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/mech_marketplace/README.md delete mode 100644 trader_backup/vendor/valory/contracts/mech_marketplace/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/mech_marketplace/build/mech.json delete mode 100644 trader_backup/vendor/valory/contracts/mech_marketplace/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/mech_marketplace/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/multisend/README.md delete mode 100644 trader_backup/vendor/valory/contracts/multisend/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/multisend/build/MultiSend.json delete mode 100644 trader_backup/vendor/valory/contracts/multisend/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/multisend/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/multisend/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/multisend/tests/test_contract.py delete mode 100644 trader_backup/vendor/valory/contracts/realitio/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/realitio/build/Realitio.json delete mode 100644 trader_backup/vendor/valory/contracts/realitio/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/realitio/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/realitio_proxy/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/realitio_proxy/build/Realitio.json delete mode 100644 trader_backup/vendor/valory/contracts/realitio_proxy/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/realitio_proxy/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/service_registry/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/service_registry/build/ServiceRegistry.json delete mode 100644 trader_backup/vendor/valory/contracts/service_registry/build/ServiceRegistryL2.json delete mode 100644 trader_backup/vendor/valory/contracts/service_registry/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/service_registry/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/service_registry/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/service_registry/tests/test_contract.py delete mode 100644 trader_backup/vendor/valory/contracts/service_staking_token/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/service_staking_token/build/ServiceStakingToken.json delete mode 100644 trader_backup/vendor/valory/contracts/service_staking_token/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/service_staking_token/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/staking_token/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/staking_token/build/StakingToken.json delete mode 100644 trader_backup/vendor/valory/contracts/staking_token/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/staking_token/contract.yaml delete mode 100644 trader_backup/vendor/valory/contracts/transfer_nft_condition/README.md delete mode 100644 trader_backup/vendor/valory/contracts/transfer_nft_condition/__init__.py delete mode 100644 trader_backup/vendor/valory/contracts/transfer_nft_condition/build/TransferNFTCondition.json delete mode 100644 trader_backup/vendor/valory/contracts/transfer_nft_condition/contract.py delete mode 100644 trader_backup/vendor/valory/contracts/transfer_nft_condition/contract.yaml delete mode 100644 trader_backup/vendor/valory/customs/__init__.py delete mode 100644 trader_backup/vendor/valory/customs/bet_amount_per_threshold/__init__.py delete mode 100644 trader_backup/vendor/valory/customs/bet_amount_per_threshold/bet_amount_per_threshold.py delete mode 100644 trader_backup/vendor/valory/customs/bet_amount_per_threshold/component.yaml delete mode 100644 trader_backup/vendor/valory/customs/kelly_criterion_no_conf/__init__.py delete mode 100644 trader_backup/vendor/valory/customs/kelly_criterion_no_conf/component.yaml delete mode 100644 trader_backup/vendor/valory/customs/kelly_criterion_no_conf/kelly_criterion_no_conf.py delete mode 100644 trader_backup/vendor/valory/customs/mike_strat/__init__.py delete mode 100644 trader_backup/vendor/valory/customs/mike_strat/component.yaml delete mode 100644 trader_backup/vendor/valory/customs/mike_strat/mike_strat.py delete mode 100644 trader_backup/vendor/valory/protocols/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/abci/README.md delete mode 100644 trader_backup/vendor/valory/protocols/abci/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/abci/abci.proto delete mode 100644 trader_backup/vendor/valory/protocols/abci/abci_pb2.py delete mode 100644 trader_backup/vendor/valory/protocols/abci/custom_types.py delete mode 100644 trader_backup/vendor/valory/protocols/abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/abci/message.py delete mode 100644 trader_backup/vendor/valory/protocols/abci/protocol.yaml delete mode 100644 trader_backup/vendor/valory/protocols/abci/serialization.py delete mode 100644 trader_backup/vendor/valory/protocols/abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/abci/tests/conftest.py delete mode 100644 trader_backup/vendor/valory/protocols/abci/tests/test_abci.py delete mode 100644 trader_backup/vendor/valory/protocols/abci/tests/test_abci_dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/abci/tests/test_abci_messages.py delete mode 100644 trader_backup/vendor/valory/protocols/acn/README.md delete mode 100644 trader_backup/vendor/valory/protocols/acn/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/acn/acn.proto delete mode 100644 trader_backup/vendor/valory/protocols/acn/acn_pb2.py delete mode 100644 trader_backup/vendor/valory/protocols/acn/custom_types.py delete mode 100644 trader_backup/vendor/valory/protocols/acn/dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/acn/message.py delete mode 100644 trader_backup/vendor/valory/protocols/acn/protocol.yaml delete mode 100644 trader_backup/vendor/valory/protocols/acn/serialization.py delete mode 100644 trader_backup/vendor/valory/protocols/acn/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/acn/tests/test_acn.py delete mode 100644 trader_backup/vendor/valory/protocols/acn/tests/test_acn_dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/acn/tests/test_acn_messages.py delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/README.md delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/contract_api.proto delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/contract_api_pb2.py delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/custom_types.py delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/message.py delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/protocol.yaml delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/serialization.py delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/tests/test_contract_api.py delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/tests/test_contract_api_dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/contract_api/tests/test_contract_api_messages.py delete mode 100644 trader_backup/vendor/valory/protocols/http/README.md delete mode 100644 trader_backup/vendor/valory/protocols/http/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/http/dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/http/http.proto delete mode 100644 trader_backup/vendor/valory/protocols/http/http_pb2.py delete mode 100644 trader_backup/vendor/valory/protocols/http/message.py delete mode 100644 trader_backup/vendor/valory/protocols/http/protocol.yaml delete mode 100644 trader_backup/vendor/valory/protocols/http/serialization.py delete mode 100644 trader_backup/vendor/valory/protocols/http/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/http/tests/test_http.py delete mode 100644 trader_backup/vendor/valory/protocols/http/tests/test_http_dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/http/tests/test_http_messages.py delete mode 100644 trader_backup/vendor/valory/protocols/ipfs/README.md delete mode 100644 trader_backup/vendor/valory/protocols/ipfs/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/ipfs/dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/ipfs/ipfs.proto delete mode 100644 trader_backup/vendor/valory/protocols/ipfs/ipfs_pb2.py delete mode 100644 trader_backup/vendor/valory/protocols/ipfs/message.py delete mode 100644 trader_backup/vendor/valory/protocols/ipfs/protocol.yaml delete mode 100644 trader_backup/vendor/valory/protocols/ipfs/serialization.py delete mode 100644 trader_backup/vendor/valory/protocols/ipfs/tests/test_ipfs_dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/ipfs/tests/test_ipfs_messages.py delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/README.md delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/custom_types.py delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/ledger_api.proto delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/ledger_api_pb2.py delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/message.py delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/protocol.yaml delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/serialization.py delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/tests/test_ledger_api.py delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/tests/test_ledger_api_dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/ledger_api/tests/test_ledger_api_messages.py delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/README.md delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/custom_types.py delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/message.py delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/protocol.yaml delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/serialization.py delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/tendermint.proto delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/tendermint_pb2.py delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/tests/test_tendermint.py delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/tests/test_tendermint_dialogues.py delete mode 100644 trader_backup/vendor/valory/protocols/tendermint/tests/test_tendermint_messages.py delete mode 100644 trader_backup/vendor/valory/skills/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_abci/README.md delete mode 100644 trader_backup/vendor/valory/skills/abstract_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/abstract_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_abci/tests/test_dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_abci/tests/test_handlers.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/README.md delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/abci_app_chain.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/base.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/behaviour_utils.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/common.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/io_/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/io_/ipfs.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/io_/load.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/io_/paths.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/io_/store.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/abci_app.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/base.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/common.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/integration.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/rounds.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/conftest.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/payloads.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/rounds.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_abci_app_chain.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_base.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_base_rounds.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_behaviours_utils.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_common.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_handlers.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/test_ipfs.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/test_load.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/test_store.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_models.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/base.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_base.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_common.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_integration.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_rounds.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_utils.py delete mode 100644 trader_backup/vendor/valory/skills/abstract_round_abci/utils.py delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/README.md delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/fsm_specification.yaml delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/payloads.py delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/rounds.py delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_handlers.py delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_payloads.py delete mode 100644 trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_rounds.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/README.md delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/base.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/bet_placement.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/blacklisting.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/check_benchmarking.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/claim_subscription.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/decision_receive.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/decision_request.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/handle_failed_tx.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/order_subscription.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/randomness.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/reedem.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/round_behaviour.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/sampling.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/sell_outcome_token.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/storage_manager.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/tool_selection.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/fsm_specification.yaml delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/io_/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/io_/loader.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/payloads.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/policy.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/redeem_info.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/rounds.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/base.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/bet_placement.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/blacklisting.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/check_benchmarking.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/claim_subscription.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/decision_receive.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/decision_request.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/final_states.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/handle_failed_tx.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/order_subscription.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/randomness.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/redeem.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/sampling.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/sell_outcome_token.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/states/tool_selection.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/data/.gitkeep delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/dummy_strategy.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/test_base.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/conftest.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_base.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_bet_placement.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_blacklising.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_check_benchmarking.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_claim_subscription.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_receive.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_request.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_final_states.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_handle_failed_tx.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_order_subscription.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_randomness.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_redeem.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_sampling.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_tool_selection.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_handlers.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_payloads.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_rounds.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/utils/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/utils/nevermined.py delete mode 100644 trader_backup/vendor/valory/skills/decision_maker_abci/utils/scaling.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/README.md delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/bets.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/fsm_specification.yaml delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/conditional_tokens.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/network.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/omen.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/realitio.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/trades.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/requests.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/utils.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/payloads.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/rounds.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/tests/test_dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/tests/test_handlers.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/tests/test_payloads.py delete mode 100644 trader_backup/vendor/valory/skills/market_manager_abci/tests/test_rounds.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/base.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/request.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/response.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/round_behaviour.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/fsm_specification.yaml delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/payloads.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/rounds.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/states/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/states/base.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/states/final_states.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/states/request.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/states/response.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_handlers.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_models.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_payloads.py delete mode 100644 trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_rounds.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/README.md delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/fsm_specification.yaml delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/payloads.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/rounds.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/tests/test_behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/tests/test_dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/tests/test_handlers.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/tests/test_models.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/tests/test_payloads.py delete mode 100644 trader_backup/vendor/valory/skills/registration_abci/tests/test_rounds.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/README.md delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/fsm_specification.yaml delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/payloads.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/rounds.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_handlers.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_payloads.py delete mode 100644 trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_rounds.py delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/README.md delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/fsm_specification.yaml delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/payloads.py delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/rounds.py delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/tests/test_dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/tests/test_handers.py delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/tests/test_payloads.py delete mode 100644 trader_backup/vendor/valory/skills/staking_abci/tests/test_rounds.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/payloads.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/rounds.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/tests/test_behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/tests/test_dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/tests/test_handlers.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/tests/test_models.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/tests/test_payloads.py delete mode 100644 trader_backup/vendor/valory/skills/termination_abci/tests/test_rounds.py delete mode 100644 trader_backup/vendor/valory/skills/trader_abci/README.md delete mode 100644 trader_backup/vendor/valory/skills/trader_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/trader_abci/behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/trader_abci/composition.py delete mode 100644 trader_backup/vendor/valory/skills/trader_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/trader_abci/fsm_specification.yaml delete mode 100644 trader_backup/vendor/valory/skills/trader_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/trader_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/trader_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/trader_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/trader_abci/tests/tests_handlers.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/README.md delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/fsm_specification.yaml delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/payload_tools.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/payloads.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/rounds.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/test_tools/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/test_tools/integration.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_handlers.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_models.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_payload_tools.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_payloads.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_rounds.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/test_integration.py delete mode 100644 trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/README.md delete mode 100644 trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/behaviours.py delete mode 100644 trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/dialogues.py delete mode 100644 trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/fsm_specification.yaml delete mode 100644 trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/handlers.py delete mode 100644 trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/models.py delete mode 100644 trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/rounds.py delete mode 100644 trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/skill.yaml delete mode 100644 trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/__init__.py delete mode 100644 trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/test_handlers.py delete mode 100644 trader_backup/vendor/w1kke/customs/__init__.py delete mode 100644 trader_backup/vendor/w1kke/customs/always_blue/__init__.py delete mode 100644 trader_backup/vendor/w1kke/customs/always_blue/always_blue.py delete mode 100644 trader_backup/vendor/w1kke/customs/always_blue/component.yaml delete mode 100644 trader_old/.certs/acn_cosmos_9005.txt delete mode 100644 trader_old/0x4BAc760A2baB94A0bd3B47Ace29180Ab1E922965/0.json delete mode 100644 trader_old/README.md delete mode 100644 trader_old/__init__.py delete mode 100644 trader_old/aea-config.yaml delete mode 100644 trader_old/data/available_tools_store.json delete mode 100644 trader_old/data/benchmarking_results.csv delete mode 100644 trader_old/data/bets.json delete mode 100644 trader_old/data/markets_test.csv delete mode 100644 trader_old/data/markets_test2.csv delete mode 100644 trader_old/data/multi_bets.json delete mode 100644 trader_old/data/policy_store.json delete mode 100644 trader_old/data/policy_store_multi_bet_failure_adjusting.json delete mode 100644 trader_old/data/utilized_tools.json delete mode 100644 trader_old/vendor/jhehemann/customs/__init__.py delete mode 100644 trader_old/vendor/jhehemann/customs/kelly_criterion/__init__.py delete mode 100644 trader_old/vendor/jhehemann/customs/kelly_criterion/component.yaml delete mode 100644 trader_old/vendor/jhehemann/customs/kelly_criterion/kelly_criterion.py delete mode 100644 trader_old/vendor/open_aea/protocols/__init__.py delete mode 100644 trader_old/vendor/open_aea/protocols/signing/README.md delete mode 100644 trader_old/vendor/open_aea/protocols/signing/__init__.py delete mode 100644 trader_old/vendor/open_aea/protocols/signing/custom_types.py delete mode 100644 trader_old/vendor/open_aea/protocols/signing/dialogues.py delete mode 100644 trader_old/vendor/open_aea/protocols/signing/message.py delete mode 100644 trader_old/vendor/open_aea/protocols/signing/protocol.yaml delete mode 100644 trader_old/vendor/open_aea/protocols/signing/serialization.py delete mode 100644 trader_old/vendor/open_aea/protocols/signing/signing.proto delete mode 100644 trader_old/vendor/open_aea/protocols/signing/signing_pb2.py delete mode 100644 trader_old/vendor/open_aea/protocols/signing/tests/__init__.py delete mode 100644 trader_old/vendor/open_aea/protocols/signing/tests/test_signing.py delete mode 100644 trader_old/vendor/open_aea/protocols/signing/tests/test_signing_dialogues.py delete mode 100644 trader_old/vendor/open_aea/protocols/signing/tests/test_signing_messages.py delete mode 100644 trader_old/vendor/valory/connections/__init__.py delete mode 100644 trader_old/vendor/valory/connections/abci/Makefile delete mode 100644 trader_old/vendor/valory/connections/abci/__init__.py delete mode 100644 trader_old/vendor/valory/connections/abci/check_dependencies.py delete mode 100644 trader_old/vendor/valory/connections/abci/connection.py delete mode 100644 trader_old/vendor/valory/connections/abci/connection.yaml delete mode 100644 trader_old/vendor/valory/connections/abci/dialogues.py delete mode 100644 trader_old/vendor/valory/connections/abci/gogoproto/__init__.py delete mode 100644 trader_old/vendor/valory/connections/abci/gogoproto/gogo_pb2.py delete mode 100644 trader_old/vendor/valory/connections/abci/protos/gogoproto/gogo.proto delete mode 100644 trader_old/vendor/valory/connections/abci/protos/tendermint/abci/types.proto delete mode 100644 trader_old/vendor/valory/connections/abci/protos/tendermint/crypto/keys.proto delete mode 100644 trader_old/vendor/valory/connections/abci/protos/tendermint/crypto/proof.proto delete mode 100644 trader_old/vendor/valory/connections/abci/protos/tendermint/types/params.proto delete mode 100644 trader_old/vendor/valory/connections/abci/protos/tendermint/types/types.proto delete mode 100644 trader_old/vendor/valory/connections/abci/protos/tendermint/types/validator.proto delete mode 100644 trader_old/vendor/valory/connections/abci/protos/tendermint/version/types.proto delete mode 100644 trader_old/vendor/valory/connections/abci/readme.md delete mode 100644 trader_old/vendor/valory/connections/abci/scripts/genproto.py delete mode 100644 trader_old/vendor/valory/connections/abci/tendermint/__init__.py delete mode 100644 trader_old/vendor/valory/connections/abci/tendermint/abci/types_pb2.py delete mode 100644 trader_old/vendor/valory/connections/abci/tendermint/abci/types_pb2_grpc.py delete mode 100644 trader_old/vendor/valory/connections/abci/tendermint/crypto/keys_pb2.py delete mode 100644 trader_old/vendor/valory/connections/abci/tendermint/crypto/proof_pb2.py delete mode 100644 trader_old/vendor/valory/connections/abci/tendermint/types/params_pb2.py delete mode 100644 trader_old/vendor/valory/connections/abci/tendermint/types/types_pb2.py delete mode 100644 trader_old/vendor/valory/connections/abci/tendermint/types/validator_pb2.py delete mode 100644 trader_old/vendor/valory/connections/abci/tendermint/version/types_pb2.py delete mode 100644 trader_old/vendor/valory/connections/abci/tendermint_decoder.py delete mode 100644 trader_old/vendor/valory/connections/abci/tendermint_encoder.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/helper.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_abci.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_abci_fuzz.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_abci_spec.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_fuzz/__init__.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_fuzz/base.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/__init__.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/__init__.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/base.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/grpc_channel.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/tcp_channel.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/node.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_fuzz/test_fuzz.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_tendermint_decoder.py delete mode 100644 trader_old/vendor/valory/connections/abci/tests/test_tendermint_encoder.py delete mode 100644 trader_old/vendor/valory/connections/abci/version.txt delete mode 100644 trader_old/vendor/valory/connections/http_client/README.md delete mode 100644 trader_old/vendor/valory/connections/http_client/__init__.py delete mode 100644 trader_old/vendor/valory/connections/http_client/connection.py delete mode 100644 trader_old/vendor/valory/connections/http_client/connection.yaml delete mode 100644 trader_old/vendor/valory/connections/http_client/tests/__init__.py delete mode 100644 trader_old/vendor/valory/connections/http_client/tests/test_http_client.py delete mode 100644 trader_old/vendor/valory/connections/http_server/README.md delete mode 100644 trader_old/vendor/valory/connections/http_server/__init__.py delete mode 100644 trader_old/vendor/valory/connections/http_server/connection.py delete mode 100644 trader_old/vendor/valory/connections/http_server/connection.yaml delete mode 100644 trader_old/vendor/valory/connections/http_server/tests/__init__.py delete mode 100644 trader_old/vendor/valory/connections/http_server/tests/data/certs/server.crt delete mode 100644 trader_old/vendor/valory/connections/http_server/tests/data/certs/server.csr delete mode 100644 trader_old/vendor/valory/connections/http_server/tests/data/certs/server.key delete mode 100644 trader_old/vendor/valory/connections/http_server/tests/data/petstore_sim.yaml delete mode 100644 trader_old/vendor/valory/connections/http_server/tests/test_http_server.py delete mode 100644 trader_old/vendor/valory/connections/ipfs/__init__.py delete mode 100644 trader_old/vendor/valory/connections/ipfs/connection.py delete mode 100644 trader_old/vendor/valory/connections/ipfs/connection.yaml delete mode 100644 trader_old/vendor/valory/connections/ipfs/readme.md delete mode 100644 trader_old/vendor/valory/connections/ipfs/tests/__init__.py delete mode 100644 trader_old/vendor/valory/connections/ipfs/tests/test_connection.py delete mode 100644 trader_old/vendor/valory/connections/ledger/README.md delete mode 100644 trader_old/vendor/valory/connections/ledger/__init__.py delete mode 100644 trader_old/vendor/valory/connections/ledger/base.py delete mode 100644 trader_old/vendor/valory/connections/ledger/connection.py delete mode 100644 trader_old/vendor/valory/connections/ledger/connection.yaml delete mode 100644 trader_old/vendor/valory/connections/ledger/contract_dispatcher.py delete mode 100644 trader_old/vendor/valory/connections/ledger/ledger_dispatcher.py delete mode 100644 trader_old/vendor/valory/connections/ledger/tests/__init__.py delete mode 100644 trader_old/vendor/valory/connections/ledger/tests/conftest.py delete mode 100644 trader_old/vendor/valory/connections/ledger/tests/test_contract_dispatcher.py delete mode 100644 trader_old/vendor/valory/connections/ledger/tests/test_ledger.py delete mode 100644 trader_old/vendor/valory/connections/ledger/tests/test_ledger_api.py delete mode 100644 trader_old/vendor/valory/connections/p2p_libp2p_client/README.md delete mode 100644 trader_old/vendor/valory/connections/p2p_libp2p_client/__init__.py delete mode 100644 trader_old/vendor/valory/connections/p2p_libp2p_client/connection.py delete mode 100644 trader_old/vendor/valory/connections/p2p_libp2p_client/connection.yaml delete mode 100644 trader_old/vendor/valory/contracts/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/agent_registry/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/agent_registry/build/AgentRegistry.json delete mode 100644 trader_old/vendor/valory/contracts/agent_registry/contract.py delete mode 100644 trader_old/vendor/valory/contracts/agent_registry/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/conditional_tokens/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/conditional_tokens/build/ConditionalTokens.json delete mode 100644 trader_old/vendor/valory/contracts/conditional_tokens/contract.py delete mode 100644 trader_old/vendor/valory/contracts/conditional_tokens/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/erc20/README.md delete mode 100644 trader_old/vendor/valory/contracts/erc20/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/erc20/build/ERC20.json delete mode 100644 trader_old/vendor/valory/contracts/erc20/contract.py delete mode 100644 trader_old/vendor/valory/contracts/erc20/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe/README.md delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe/build/GnosisSafe_V1_3_0.json delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe/contract.py delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe/encode.py delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe/tests/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe/tests/test_contract.py delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/README.md delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/build/ProxyFactory_V1_3_0.json delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.py delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/test_contract.py delete mode 100644 trader_old/vendor/valory/contracts/market_maker/README.md delete mode 100644 trader_old/vendor/valory/contracts/market_maker/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/market_maker/build/FixedProductMarketMaker.json delete mode 100644 trader_old/vendor/valory/contracts/market_maker/contract.py delete mode 100644 trader_old/vendor/valory/contracts/market_maker/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/mech/README.md delete mode 100644 trader_old/vendor/valory/contracts/mech/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/mech/build/mech.json delete mode 100644 trader_old/vendor/valory/contracts/mech/contract.py delete mode 100644 trader_old/vendor/valory/contracts/mech/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/mech_activity/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/mech_activity/build/MechActivity.json delete mode 100644 trader_old/vendor/valory/contracts/mech_activity/contract.py delete mode 100644 trader_old/vendor/valory/contracts/mech_activity/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/mech_marketplace/README.md delete mode 100644 trader_old/vendor/valory/contracts/mech_marketplace/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/mech_marketplace/build/mech.json delete mode 100644 trader_old/vendor/valory/contracts/mech_marketplace/contract.py delete mode 100644 trader_old/vendor/valory/contracts/mech_marketplace/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/multisend/README.md delete mode 100644 trader_old/vendor/valory/contracts/multisend/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/multisend/build/MultiSend.json delete mode 100644 trader_old/vendor/valory/contracts/multisend/contract.py delete mode 100644 trader_old/vendor/valory/contracts/multisend/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/multisend/tests/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/multisend/tests/test_contract.py delete mode 100644 trader_old/vendor/valory/contracts/realitio/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/realitio/build/Realitio.json delete mode 100644 trader_old/vendor/valory/contracts/realitio/contract.py delete mode 100644 trader_old/vendor/valory/contracts/realitio/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/realitio_proxy/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/realitio_proxy/build/Realitio.json delete mode 100644 trader_old/vendor/valory/contracts/realitio_proxy/contract.py delete mode 100644 trader_old/vendor/valory/contracts/realitio_proxy/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/service_registry/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/service_registry/build/ServiceRegistry.json delete mode 100644 trader_old/vendor/valory/contracts/service_registry/build/ServiceRegistryL2.json delete mode 100644 trader_old/vendor/valory/contracts/service_registry/contract.py delete mode 100644 trader_old/vendor/valory/contracts/service_registry/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/service_registry/tests/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/service_registry/tests/test_contract.py delete mode 100644 trader_old/vendor/valory/contracts/service_staking_token/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/service_staking_token/build/ServiceStakingToken.json delete mode 100644 trader_old/vendor/valory/contracts/service_staking_token/contract.py delete mode 100644 trader_old/vendor/valory/contracts/service_staking_token/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/staking_token/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/staking_token/build/StakingToken.json delete mode 100644 trader_old/vendor/valory/contracts/staking_token/contract.py delete mode 100644 trader_old/vendor/valory/contracts/staking_token/contract.yaml delete mode 100644 trader_old/vendor/valory/contracts/transfer_nft_condition/README.md delete mode 100644 trader_old/vendor/valory/contracts/transfer_nft_condition/__init__.py delete mode 100644 trader_old/vendor/valory/contracts/transfer_nft_condition/build/TransferNFTCondition.json delete mode 100644 trader_old/vendor/valory/contracts/transfer_nft_condition/contract.py delete mode 100644 trader_old/vendor/valory/contracts/transfer_nft_condition/contract.yaml delete mode 100644 trader_old/vendor/valory/customs/__init__.py delete mode 100644 trader_old/vendor/valory/customs/bet_amount_per_threshold/__init__.py delete mode 100644 trader_old/vendor/valory/customs/bet_amount_per_threshold/bet_amount_per_threshold.py delete mode 100644 trader_old/vendor/valory/customs/bet_amount_per_threshold/component.yaml delete mode 100644 trader_old/vendor/valory/customs/kelly_criterion_no_conf/__init__.py delete mode 100644 trader_old/vendor/valory/customs/kelly_criterion_no_conf/component.yaml delete mode 100644 trader_old/vendor/valory/customs/kelly_criterion_no_conf/kelly_criterion_no_conf.py delete mode 100644 trader_old/vendor/valory/customs/mike_strat/__init__.py delete mode 100644 trader_old/vendor/valory/customs/mike_strat/component.yaml delete mode 100644 trader_old/vendor/valory/customs/mike_strat/mike_strat.py delete mode 100644 trader_old/vendor/valory/protocols/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/abci/README.md delete mode 100644 trader_old/vendor/valory/protocols/abci/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/abci/abci.proto delete mode 100644 trader_old/vendor/valory/protocols/abci/abci_pb2.py delete mode 100644 trader_old/vendor/valory/protocols/abci/custom_types.py delete mode 100644 trader_old/vendor/valory/protocols/abci/dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/abci/message.py delete mode 100644 trader_old/vendor/valory/protocols/abci/protocol.yaml delete mode 100644 trader_old/vendor/valory/protocols/abci/serialization.py delete mode 100644 trader_old/vendor/valory/protocols/abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/abci/tests/conftest.py delete mode 100644 trader_old/vendor/valory/protocols/abci/tests/test_abci.py delete mode 100644 trader_old/vendor/valory/protocols/abci/tests/test_abci_dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/abci/tests/test_abci_messages.py delete mode 100644 trader_old/vendor/valory/protocols/acn/README.md delete mode 100644 trader_old/vendor/valory/protocols/acn/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/acn/acn.proto delete mode 100644 trader_old/vendor/valory/protocols/acn/acn_pb2.py delete mode 100644 trader_old/vendor/valory/protocols/acn/custom_types.py delete mode 100644 trader_old/vendor/valory/protocols/acn/dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/acn/message.py delete mode 100644 trader_old/vendor/valory/protocols/acn/protocol.yaml delete mode 100644 trader_old/vendor/valory/protocols/acn/serialization.py delete mode 100644 trader_old/vendor/valory/protocols/acn/tests/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/acn/tests/test_acn.py delete mode 100644 trader_old/vendor/valory/protocols/acn/tests/test_acn_dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/acn/tests/test_acn_messages.py delete mode 100644 trader_old/vendor/valory/protocols/contract_api/README.md delete mode 100644 trader_old/vendor/valory/protocols/contract_api/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/contract_api/contract_api.proto delete mode 100644 trader_old/vendor/valory/protocols/contract_api/contract_api_pb2.py delete mode 100644 trader_old/vendor/valory/protocols/contract_api/custom_types.py delete mode 100644 trader_old/vendor/valory/protocols/contract_api/dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/contract_api/message.py delete mode 100644 trader_old/vendor/valory/protocols/contract_api/protocol.yaml delete mode 100644 trader_old/vendor/valory/protocols/contract_api/serialization.py delete mode 100644 trader_old/vendor/valory/protocols/contract_api/tests/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/contract_api/tests/test_contract_api.py delete mode 100644 trader_old/vendor/valory/protocols/contract_api/tests/test_contract_api_dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/contract_api/tests/test_contract_api_messages.py delete mode 100644 trader_old/vendor/valory/protocols/http/README.md delete mode 100644 trader_old/vendor/valory/protocols/http/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/http/dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/http/http.proto delete mode 100644 trader_old/vendor/valory/protocols/http/http_pb2.py delete mode 100644 trader_old/vendor/valory/protocols/http/message.py delete mode 100644 trader_old/vendor/valory/protocols/http/protocol.yaml delete mode 100644 trader_old/vendor/valory/protocols/http/serialization.py delete mode 100644 trader_old/vendor/valory/protocols/http/tests/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/http/tests/test_http.py delete mode 100644 trader_old/vendor/valory/protocols/http/tests/test_http_dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/http/tests/test_http_messages.py delete mode 100644 trader_old/vendor/valory/protocols/ipfs/README.md delete mode 100644 trader_old/vendor/valory/protocols/ipfs/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/ipfs/dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/ipfs/ipfs.proto delete mode 100644 trader_old/vendor/valory/protocols/ipfs/ipfs_pb2.py delete mode 100644 trader_old/vendor/valory/protocols/ipfs/message.py delete mode 100644 trader_old/vendor/valory/protocols/ipfs/protocol.yaml delete mode 100644 trader_old/vendor/valory/protocols/ipfs/serialization.py delete mode 100644 trader_old/vendor/valory/protocols/ipfs/tests/test_ipfs_dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/ipfs/tests/test_ipfs_messages.py delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/README.md delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/custom_types.py delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/ledger_api.proto delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/ledger_api_pb2.py delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/message.py delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/protocol.yaml delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/serialization.py delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/tests/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/tests/test_ledger_api.py delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/tests/test_ledger_api_dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/ledger_api/tests/test_ledger_api_messages.py delete mode 100644 trader_old/vendor/valory/protocols/tendermint/README.md delete mode 100644 trader_old/vendor/valory/protocols/tendermint/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/tendermint/custom_types.py delete mode 100644 trader_old/vendor/valory/protocols/tendermint/dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/tendermint/message.py delete mode 100644 trader_old/vendor/valory/protocols/tendermint/protocol.yaml delete mode 100644 trader_old/vendor/valory/protocols/tendermint/serialization.py delete mode 100644 trader_old/vendor/valory/protocols/tendermint/tendermint.proto delete mode 100644 trader_old/vendor/valory/protocols/tendermint/tendermint_pb2.py delete mode 100644 trader_old/vendor/valory/protocols/tendermint/tests/__init__.py delete mode 100644 trader_old/vendor/valory/protocols/tendermint/tests/test_tendermint.py delete mode 100644 trader_old/vendor/valory/protocols/tendermint/tests/test_tendermint_dialogues.py delete mode 100644 trader_old/vendor/valory/protocols/tendermint/tests/test_tendermint_messages.py delete mode 100644 trader_old/vendor/valory/skills/__init__.py delete mode 100644 trader_old/vendor/valory/skills/abstract_abci/README.md delete mode 100644 trader_old/vendor/valory/skills/abstract_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/abstract_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/abstract_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/abstract_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/abstract_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/abstract_abci/tests/test_dialogues.py delete mode 100644 trader_old/vendor/valory/skills/abstract_abci/tests/test_handlers.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/README.md delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/abci_app_chain.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/base.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/behaviour_utils.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/behaviours.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/common.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/io_/__init__.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/io_/ipfs.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/io_/load.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/io_/paths.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/io_/store.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/test_tools/__init__.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/test_tools/abci_app.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/test_tools/base.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/test_tools/common.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/test_tools/integration.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/test_tools/rounds.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/conftest.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/data/__init__.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/behaviours.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/payloads.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/rounds.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_abci_app_chain.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_base.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_base_rounds.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_behaviours.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_behaviours_utils.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_common.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_dialogues.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_handlers.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/__init__.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/test_ipfs.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/test_load.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/test_store.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_models.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/__init__.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/base.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_base.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_common.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_integration.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_rounds.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/tests/test_utils.py delete mode 100644 trader_old/vendor/valory/skills/abstract_round_abci/utils.py delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/README.md delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/behaviours.py delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/fsm_specification.yaml delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/payloads.py delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/rounds.py delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_dialogues.py delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_handlers.py delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_payloads.py delete mode 100644 trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_rounds.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/README.md delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/__init__.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/base.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/bet_placement.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/blacklisting.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/check_benchmarking.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/claim_subscription.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/decision_receive.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/decision_request.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/handle_failed_tx.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/order_subscription.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/randomness.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/reedem.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/round_behaviour.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/sampling.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/sell_outcome_token.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/storage_manager.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/behaviours/tool_selection.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/fsm_specification.yaml delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/io_/__init__.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/io_/loader.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/payloads.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/policy.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/redeem_info.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/rounds.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/__init__.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/base.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/bet_placement.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/blacklisting.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/check_benchmarking.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/claim_subscription.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/decision_receive.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/decision_request.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/final_states.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/handle_failed_tx.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/order_subscription.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/randomness.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/redeem.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/sampling.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/sell_outcome_token.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/states/tool_selection.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/__init__.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/data/.gitkeep delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/__init__.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/dummy_strategy.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/test_base.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/conftest.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_base.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_bet_placement.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_blacklising.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_check_benchmarking.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_claim_subscription.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_receive.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_request.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_final_states.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_handle_failed_tx.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_order_subscription.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_randomness.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_redeem.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_sampling.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_tool_selection.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/test_dialogues.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/test_handlers.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/test_payloads.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/tests/test_rounds.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/utils/__init__.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/utils/nevermined.py delete mode 100644 trader_old/vendor/valory/skills/decision_maker_abci/utils/scaling.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/README.md delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/behaviours.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/bets.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/fsm_specification.yaml delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/__init__.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/__init__.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/conditional_tokens.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/network.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/omen.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/realitio.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/trades.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/requests.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/utils.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/payloads.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/rounds.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/tests/test_dialogues.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/tests/test_handlers.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/tests/test_payloads.py delete mode 100644 trader_old/vendor/valory/skills/market_manager_abci/tests/test_rounds.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/behaviours/__init__.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/behaviours/base.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/behaviours/request.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/behaviours/response.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/behaviours/round_behaviour.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/fsm_specification.yaml delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/payloads.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/rounds.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/states/__init__.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/states/base.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/states/final_states.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/states/request.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/states/response.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/tests/test_behaviours.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/tests/test_dialogues.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/tests/test_handlers.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/tests/test_models.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/tests/test_payloads.py delete mode 100644 trader_old/vendor/valory/skills/mech_interact_abci/tests/test_rounds.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/README.md delete mode 100644 trader_old/vendor/valory/skills/registration_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/behaviours.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/fsm_specification.yaml delete mode 100644 trader_old/vendor/valory/skills/registration_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/payloads.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/rounds.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/registration_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/tests/test_behaviours.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/tests/test_dialogues.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/tests/test_handlers.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/tests/test_models.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/tests/test_payloads.py delete mode 100644 trader_old/vendor/valory/skills/registration_abci/tests/test_rounds.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/README.md delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/behaviours.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/fsm_specification.yaml delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/payloads.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/rounds.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/tests/test_behaviours.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/tests/test_dialogues.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/tests/test_handlers.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/tests/test_payloads.py delete mode 100644 trader_old/vendor/valory/skills/reset_pause_abci/tests/test_rounds.py delete mode 100644 trader_old/vendor/valory/skills/staking_abci/README.md delete mode 100644 trader_old/vendor/valory/skills/staking_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/staking_abci/behaviours.py delete mode 100644 trader_old/vendor/valory/skills/staking_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/staking_abci/fsm_specification.yaml delete mode 100644 trader_old/vendor/valory/skills/staking_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/staking_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/staking_abci/payloads.py delete mode 100644 trader_old/vendor/valory/skills/staking_abci/rounds.py delete mode 100644 trader_old/vendor/valory/skills/staking_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/staking_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/staking_abci/tests/test_dialogues.py delete mode 100644 trader_old/vendor/valory/skills/staking_abci/tests/test_handers.py delete mode 100644 trader_old/vendor/valory/skills/staking_abci/tests/test_payloads.py delete mode 100644 trader_old/vendor/valory/skills/staking_abci/tests/test_rounds.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/behaviours.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/payloads.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/rounds.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/termination_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/tests/test_behaviours.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/tests/test_dialogues.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/tests/test_handlers.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/tests/test_models.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/tests/test_payloads.py delete mode 100644 trader_old/vendor/valory/skills/termination_abci/tests/test_rounds.py delete mode 100644 trader_old/vendor/valory/skills/trader_abci/README.md delete mode 100644 trader_old/vendor/valory/skills/trader_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/trader_abci/behaviours.py delete mode 100644 trader_old/vendor/valory/skills/trader_abci/composition.py delete mode 100644 trader_old/vendor/valory/skills/trader_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/trader_abci/fsm_specification.yaml delete mode 100644 trader_old/vendor/valory/skills/trader_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/trader_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/trader_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/trader_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/trader_abci/tests/tests_handlers.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/README.md delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/behaviours.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/fsm_specification.yaml delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/payload_tools.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/payloads.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/rounds.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/test_tools/__init__.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/test_tools/integration.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_behaviours.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_dialogues.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_handlers.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_models.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_payload_tools.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_payloads.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_rounds.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/__init__.py delete mode 100644 trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/test_integration.py delete mode 100644 trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/README.md delete mode 100644 trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/__init__.py delete mode 100644 trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/behaviours.py delete mode 100644 trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/dialogues.py delete mode 100644 trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/fsm_specification.yaml delete mode 100644 trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/handlers.py delete mode 100644 trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/models.py delete mode 100644 trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/rounds.py delete mode 100644 trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/skill.yaml delete mode 100644 trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/__init__.py delete mode 100644 trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/test_handlers.py delete mode 100644 trader_old/vendor/w1kke/customs/__init__.py delete mode 100644 trader_old/vendor/w1kke/customs/always_blue/__init__.py delete mode 100644 trader_old/vendor/w1kke/customs/always_blue/always_blue.py delete mode 100644 trader_old/vendor/w1kke/customs/always_blue/component.yaml diff --git a/packages/packages.json b/packages/packages.json index d8a4f337d..d306a883c 100644 --- a/packages/packages.json +++ b/packages/packages.json @@ -5,6 +5,7 @@ "custom/jhehemann/kelly_criterion/0.1.0": "bafybeif55cu7cf6znyma7kxus4wxa2doarhau2xmndo57iegshxorivwmq", "custom/w1kke/always_blue/0.1.0": "bafybeieshu32h3es2fslduuhr7nimuvh2vuibyeqdunzrcggaeohekg3jm", "custom/valory/kelly_criterion_no_conf/0.1.0": "bafybeibxfp27rzrfnp7sxq62vwv32pdvrijxi7vzg7ihukkaka3bwzrgae", + "protocol/valory/acn_data_share/0.1.0": "bafybeidbvo3jdbt54pqk3foqfso4uim2vaea5abg6jzktomdeklh6sm2rq", "contract/valory/market_maker/0.1.0": "bafybeibhmqzu2u4cprrf2xgnsc6zy53q2ja7hojxhqq5itdtlydun7o64a", "contract/valory/realitio/0.1.0": "bafybeietgux6kkhdquspy35qera7gjwwqwrremmoeatjzwwokjb2lzsata", "contract/valory/realitio_proxy/0.1.0": "bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4", @@ -15,18 +16,17 @@ "contract/valory/mech_activity/0.1.0": "bafybeieadv7vnbguc7beu6xo3rs3mqbgzc7wayc7kvgb2tmitmjtpdcqkq", "contract/valory/staking_token/0.1.0": "bafybeiaynt6clwbthtbndtocnwul7dp76ctmu4jxinp7fnqks4pxt65yuy", "contract/valory/relayer/0.1.0": "bafybeicreijhjycqrutdpbdn3vdcpmo233y3p66l3ovmr2goa2y2e6bshy", - "skill/valory/market_manager_abci/0.1.0": "bafybeib2i7i26ozgh7bpvundz6w72ne6entxboqezqgwxmuyfeak6wwloq", - "skill/valory/decision_maker_abci/0.1.0": "bafybeih6hom4buikaik7t4dn5mmc7qufs3uprltzdqqwb3ggveyurkv44i", - "skill/valory/trader_abci/0.1.0": "bafybeif552cje6e3uhjs44vsfbtpynjnfgmum5cjbdajissx2a2ieuzxma", - "skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeibzv6gntw4c5iofqabhtc5jxarwbt4fr2faxwrgkkzks7ral4ff3i", - "skill/valory/staking_abci/0.1.0": "bafybeiaasclr4lf3u2layekmfwyasckxrslbs2g4me7kvozz5goswlznjq", - "skill/valory/check_stop_trading_abci/0.1.0": "bafybeic3bismocli2yyxmjhjsevjbzpuf3ladsvlkazfx23vq3q6uxrn7m", - "agent/valory/trader/0.1.0": "bafybeia3p2oynp6wnwes6o6uxg3rjv3zf37odmymxyiowx7wvjn4piit24", - "service/valory/trader/0.1.0": "bafybeif7yr4i6lt5ylhxzmosz5u5yjzqvjoruq3dxhynmtjjhpjukozmai", - "service/valory/trader_pearl/0.1.0": "bafybeiby6acfhecd6iv5gizrl2tki3vtvpvezl2qd7cnznd3g2ya52j7gi" + "skill/valory/market_manager_abci/0.1.0": "bafybeibo63iiziwvqn6fmx36ungyg35z3chfv432kf6spuiszm6na22vdy", + "skill/valory/decision_maker_abci/0.1.0": "bafybeigzwgigws4ydqgpwt4ymgafuw76hhsc7ecainx6lzcqrc3pjo6vpa", + "skill/valory/trader_abci/0.1.0": "bafybeihbnkekpwtisweg64cz4kdmekg4nkq2n6nkbsrudylnhlhpqalhgy", + "skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeifznhp32govm42jiiy2yxozufzomdmeunhfbzjlq4xfw5nk6xm7oy", + "skill/valory/staking_abci/0.1.0": "bafybeich2wka6i76w546ez7pi3g3pzlrjuunn33fq7dh55azjykyhwfjiu", + "skill/valory/check_stop_trading_abci/0.1.0": "bafybeiahe6n3ehiltghwx5dsl553lo3dlqfw7pk5nsgxlntetrwgn4qzqu", + "agent/valory/trader/0.1.0": "bafybeihvp3o24bwf4tb6mcnbohth6nvmvs5itepeflnaiv7p2bwjpmjrqe", + "service/valory/trader/0.1.0": "bafybeih5mlwb73ipqpduw53f6xu23zrpns5n5kwecwxub6cdvmtu23n22q", + "service/valory/trader_pearl/0.1.0": "bafybeidspol4npsxrf3ewohgq6kbnyzlbksra5phq2ch62afuqykwkr5yy" }, "third_party": { - "protocol/valory/acn_data_share/0.1.0": "bafybeidbvo3jdbt54pqk3foqfso4uim2vaea5abg6jzktomdeklh6sm2rq", "protocol/open_aea/signing/1.0.0": "bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi", "protocol/valory/abci/0.1.0": "bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u", "protocol/valory/contract_api/1.0.0": "bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i", @@ -35,26 +35,25 @@ "protocol/valory/acn/1.1.0": "bafybeidluaoeakae3exseupaea4i3yvvk5vivyt227xshjlffywwxzcxqe", "protocol/valory/tendermint/0.1.0": "bafybeig4mi3vmlv5zpbjbfuzcgida6j5f2nhrpedxicmrrfjweqc5r7cra", "protocol/valory/ipfs/0.1.0": "bafybeiftxi2qhreewgsc5wevogi7yc5g6hbcbo4uiuaibauhv3nhfcdtvm", - "contract/valory/agent_registry/0.1.0": "bafybeibboljpn2zevzxnpgflxj6ykxk4bpxegtzjts25ajliaoadz35mca", - "contract/valory/gnosis_safe_proxy_factory/0.1.0": "bafybeifr4xpmzeb5hvpgd6h4nxlsu3ef2c3f6l5bgs34vym5ok6vllwhmy", - "contract/valory/gnosis_safe/0.1.0": "bafybeihtqcpqthb37msgqabpzcc2xc3l3yzkp5pl2sodeghqyzzzyuevgi", - "contract/valory/mech/0.1.0": "bafybeielwbnikog4eqmu6bo537kzp2e7qpmkzt7l5zuuugp2w4r47dbvwu", - "contract/valory/service_registry/0.1.0": "bafybeidipx4cmchxdu5i2v67rno7muie7ckjhmasaj64tv2vtj4fveklxi", + "contract/valory/gnosis_safe_proxy_factory/0.1.0": "bafybeieg57u3z7cdlmdamad5e6lk7kmsli2zurzkg3sl4y7lhekcu4y3au", + "contract/valory/gnosis_safe/0.1.0": "bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge", + "contract/valory/mech/0.1.0": "bafybeiejfjfoxqggghcme43sx53q5gruefrws3k2jam2opkxl5uzffoarm", + "contract/valory/service_registry/0.1.0": "bafybeiaop64kwdoetxtedoehabmsalojmms7ihuoqcdwxtwb2hk5i6bzye", "contract/valory/multisend/0.1.0": "bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y", - "contract/valory/erc20/0.1.0": "bafybeientdgpccdi7prtu4x53m5g3yugh5tuh5hnroylfz3wwzyjniqure", - "contract/valory/mech_marketplace/0.1.0": "bafybeicfuigpr65k4l2r5dbazzwh43yc6pfuy5mrkjkagmhmcp6ioktfay", - "connection/valory/abci/0.1.0": "bafybeie2bc44r2ddspeg4v7minuievvjykomcukuf5ryevom6fajno25gy", + "contract/valory/erc20/0.1.0": "bafybeid2p2jyvjjlcsqugnawksdzsca6ljghpqbp2kfi3cxuxoy2233dbi", + "contract/valory/mech_marketplace/0.1.0": "bafybeiba7kh3wygwtpyf7oo3sili6givzo2gyadhbb66rvwsokswsywvuu", + "connection/valory/abci/0.1.0": "bafybeia6etkacvqend7xj6viejkqgo7ozu3yn4yg3qezfthf2xhrjjwse4", "connection/valory/http_client/0.23.0": "bafybeihi772xgzpqeipp3fhmvpct4y6e6tpjp4sogwqrnf3wqspgeilg4u", - "connection/valory/ledger/0.19.0": "bafybeigntoericenpzvwejqfuc3kqzo2pscs76qoygg5dbj6f4zxusru5e", + "connection/valory/ledger/0.19.0": "bafybeig7woeog4srdby75hpjkmx4rhpkzncbf4h2pm5r6varsp26pf2uhu", "connection/valory/p2p_libp2p_client/0.1.0": "bafybeid3xg5k2ol5adflqloy75ibgljmol6xsvzvezebsg7oudxeeolz7e", - "connection/valory/ipfs/0.1.0": "bafybeias6633a2337nhq6nn5ikq4jaig47v63nxv2ixkjr6qqrqaywqara", + "connection/valory/ipfs/0.1.0": "bafybeigcijdbwgdekow5c2ikeltetoteabfp52ewy3xfkd7ygaqbl7j3ke", "connection/valory/http_server/0.22.0": "bafybeihpgu56ovmq4npazdbh6y6ru5i7zuv6wvdglpxavsckyih56smu7m", - "skill/valory/abstract_abci/0.1.0": "bafybeif2naoydlrqkdpnig34uejedwgurjwyvmbpcz53tif7pyukfdophq", - "skill/valory/reset_pause_abci/0.1.0": "bafybeiezfedmmseox3ce5aucxsiszdmvskrwwbtpb2a3vw3sbmc5jt7nri", - "skill/valory/registration_abci/0.1.0": "bafybeiagi6e2h7kochmlemy5c5yk6hwn37tfxiqvk2en74jhowsdwlmrny", - "skill/valory/abstract_round_abci/0.1.0": "bafybeigjddhk7epta7xpnfvv426xedff5abh4xlkwi6cqgp4vkutgkvydm", - "skill/valory/transaction_settlement_abci/0.1.0": "bafybeifmgmwdkx4esemxjacjwzqkqymkuklb5nehkwqkx7v335fllgswcq", - "skill/valory/termination_abci/0.1.0": "bafybeiea67epwwgngp7b3wavs6hpkaxv6etyaps6g6325bchfnf354mibq", - "skill/valory/mech_interact_abci/0.1.0": "bafybeib4vn6m2yumwoclh5aatcdt5yxcjc5owxmxy5o7t3nfzormgwkr64" + "skill/valory/abstract_abci/0.1.0": "bafybeieeaseuy5rbbw465knz27vccvpkfge43q7isl7fkdlfapwd7bpi24", + "skill/valory/reset_pause_abci/0.1.0": "bafybeigrdlxed3xlsnxtjhnsbl3cojruihxcqx4jxhgivkd5i2fkjncgba", + "skill/valory/registration_abci/0.1.0": "bafybeibc7duasoaw5b4ene5oxfba2dmdzstsrws6ipi57ymgdtoxjadn54", + "skill/valory/abstract_round_abci/0.1.0": "bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u", + "skill/valory/transaction_settlement_abci/0.1.0": "bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae", + "skill/valory/termination_abci/0.1.0": "bafybeib5l7jhew5ic6iq24dd23nidcoimzqkrk556gqywhoziatj33zvwm", + "skill/valory/mech_interact_abci/0.1.0": "bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm" } } \ No newline at end of file diff --git a/packages/valory/agents/trader/aea-config.yaml b/packages/valory/agents/trader/aea-config.yaml index 8e6972444..c80b102eb 100644 --- a/packages/valory/agents/trader/aea-config.yaml +++ b/packages/valory/agents/trader/aea-config.yaml @@ -9,29 +9,29 @@ fingerprint: __init__.py: bafybeighcq4pmuzte6vhvvprrvo563vzghkoit2h6qdqxf2ma5bghevkee fingerprint_ignore_patterns: [] connections: -- valory/abci:0.1.0:bafybeie2bc44r2ddspeg4v7minuievvjykomcukuf5ryevom6fajno25gy +- valory/abci:0.1.0:bafybeia6etkacvqend7xj6viejkqgo7ozu3yn4yg3qezfthf2xhrjjwse4 - valory/http_client:0.23.0:bafybeihi772xgzpqeipp3fhmvpct4y6e6tpjp4sogwqrnf3wqspgeilg4u -- valory/ipfs:0.1.0:bafybeias6633a2337nhq6nn5ikq4jaig47v63nxv2ixkjr6qqrqaywqara -- valory/ledger:0.19.0:bafybeigntoericenpzvwejqfuc3kqzo2pscs76qoygg5dbj6f4zxusru5e +- valory/ipfs:0.1.0:bafybeigcijdbwgdekow5c2ikeltetoteabfp52ewy3xfkd7ygaqbl7j3ke +- valory/ledger:0.19.0:bafybeig7woeog4srdby75hpjkmx4rhpkzncbf4h2pm5r6varsp26pf2uhu - valory/p2p_libp2p_client:0.1.0:bafybeid3xg5k2ol5adflqloy75ibgljmol6xsvzvezebsg7oudxeeolz7e - valory/http_server:0.22.0:bafybeihpgu56ovmq4npazdbh6y6ru5i7zuv6wvdglpxavsckyih56smu7m contracts: -- valory/gnosis_safe:0.1.0:bafybeihtqcpqthb37msgqabpzcc2xc3l3yzkp5pl2sodeghqyzzzyuevgi -- valory/gnosis_safe_proxy_factory:0.1.0:bafybeifr4xpmzeb5hvpgd6h4nxlsu3ef2c3f6l5bgs34vym5ok6vllwhmy -- valory/service_registry:0.1.0:bafybeidipx4cmchxdu5i2v67rno7muie7ckjhmasaj64tv2vtj4fveklxi +- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge +- valory/gnosis_safe_proxy_factory:0.1.0:bafybeieg57u3z7cdlmdamad5e6lk7kmsli2zurzkg3sl4y7lhekcu4y3au +- valory/service_registry:0.1.0:bafybeiaop64kwdoetxtedoehabmsalojmms7ihuoqcdwxtwb2hk5i6bzye - valory/market_maker:0.1.0:bafybeibhmqzu2u4cprrf2xgnsc6zy53q2ja7hojxhqq5itdtlydun7o64a - valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y -- valory/mech:0.1.0:bafybeielwbnikog4eqmu6bo537kzp2e7qpmkzt7l5zuuugp2w4r47dbvwu +- valory/mech:0.1.0:bafybeiejfjfoxqggghcme43sx53q5gruefrws3k2jam2opkxl5uzffoarm - valory/conditional_tokens:0.1.0:bafybeibnzmqmeph4cj5vfh3s622mo2o5627vjjwc6bptrhj4dk65mzgvhe - valory/realitio:0.1.0:bafybeietgux6kkhdquspy35qera7gjwwqwrremmoeatjzwwokjb2lzsata - valory/realitio_proxy:0.1.0:bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4 - valory/agent_registry:0.1.0:bafybeibboljpn2zevzxnpgflxj6ykxk4bpxegtzjts25ajliaoadz35mca - valory/service_staking_token:0.1.0:bafybeieg664oohr26gpcfn3uied4minlz6dmgd32xboewscnxqnv5kk4zi - valory/transfer_nft_condition:0.1.0:bafybeicdtigdwlt47jg2tibxltwyyl4apysvlideo53lgiy3muuho3izpa -- valory/erc20:0.1.0:bafybeientdgpccdi7prtu4x53m5g3yugh5tuh5hnroylfz3wwzyjniqure +- valory/erc20:0.1.0:bafybeid2p2jyvjjlcsqugnawksdzsca6ljghpqbp2kfi3cxuxoy2233dbi - valory/staking_token:0.1.0:bafybeiaynt6clwbthtbndtocnwul7dp76ctmu4jxinp7fnqks4pxt65yuy - valory/mech_activity:0.1.0:bafybeieadv7vnbguc7beu6xo3rs3mqbgzc7wayc7kvgb2tmitmjtpdcqkq -- valory/mech_marketplace:0.1.0:bafybeicfuigpr65k4l2r5dbazzwh43yc6pfuy5mrkjkagmhmcp6ioktfay +- valory/mech_marketplace:0.1.0:bafybeiba7kh3wygwtpyf7oo3sili6givzo2gyadhbb66rvwsokswsywvuu - valory/relayer:0.1.0:bafybeicreijhjycqrutdpbdn3vdcpmo233y3p66l3ovmr2goa2y2e6bshy protocols: - open_aea/signing:1.0.0:bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi @@ -44,19 +44,19 @@ protocols: - valory/tendermint:0.1.0:bafybeig4mi3vmlv5zpbjbfuzcgida6j5f2nhrpedxicmrrfjweqc5r7cra - valory/acn_data_share:0.1.0:bafybeidbvo3jdbt54pqk3foqfso4uim2vaea5abg6jzktomdeklh6sm2rq skills: -- valory/abstract_abci:0.1.0:bafybeif2naoydlrqkdpnig34uejedwgurjwyvmbpcz53tif7pyukfdophq -- valory/abstract_round_abci:0.1.0:bafybeigjddhk7epta7xpnfvv426xedff5abh4xlkwi6cqgp4vkutgkvydm -- valory/registration_abci:0.1.0:bafybeiagi6e2h7kochmlemy5c5yk6hwn37tfxiqvk2en74jhowsdwlmrny -- valory/reset_pause_abci:0.1.0:bafybeiezfedmmseox3ce5aucxsiszdmvskrwwbtpb2a3vw3sbmc5jt7nri -- valory/termination_abci:0.1.0:bafybeiea67epwwgngp7b3wavs6hpkaxv6etyaps6g6325bchfnf354mibq -- valory/transaction_settlement_abci:0.1.0:bafybeifmgmwdkx4esemxjacjwzqkqymkuklb5nehkwqkx7v335fllgswcq -- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeibzv6gntw4c5iofqabhtc5jxarwbt4fr2faxwrgkkzks7ral4ff3i -- valory/market_manager_abci:0.1.0:bafybeib2i7i26ozgh7bpvundz6w72ne6entxboqezqgwxmuyfeak6wwloq -- valory/decision_maker_abci:0.1.0:bafybeih6hom4buikaik7t4dn5mmc7qufs3uprltzdqqwb3ggveyurkv44i -- valory/trader_abci:0.1.0:bafybeif552cje6e3uhjs44vsfbtpynjnfgmum5cjbdajissx2a2ieuzxma -- valory/staking_abci:0.1.0:bafybeiaasclr4lf3u2layekmfwyasckxrslbs2g4me7kvozz5goswlznjq -- valory/check_stop_trading_abci:0.1.0:bafybeic3bismocli2yyxmjhjsevjbzpuf3ladsvlkazfx23vq3q6uxrn7m -- valory/mech_interact_abci:0.1.0:bafybeib4vn6m2yumwoclh5aatcdt5yxcjc5owxmxy5o7t3nfzormgwkr64 +- valory/abstract_abci:0.1.0:bafybeieeaseuy5rbbw465knz27vccvpkfge43q7isl7fkdlfapwd7bpi24 +- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u +- valory/registration_abci:0.1.0:bafybeibc7duasoaw5b4ene5oxfba2dmdzstsrws6ipi57ymgdtoxjadn54 +- valory/reset_pause_abci:0.1.0:bafybeigrdlxed3xlsnxtjhnsbl3cojruihxcqx4jxhgivkd5i2fkjncgba +- valory/termination_abci:0.1.0:bafybeib5l7jhew5ic6iq24dd23nidcoimzqkrk556gqywhoziatj33zvwm +- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae +- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeifznhp32govm42jiiy2yxozufzomdmeunhfbzjlq4xfw5nk6xm7oy +- valory/market_manager_abci:0.1.0:bafybeibo63iiziwvqn6fmx36ungyg35z3chfv432kf6spuiszm6na22vdy +- valory/decision_maker_abci:0.1.0:bafybeigzwgigws4ydqgpwt4ymgafuw76hhsc7ecainx6lzcqrc3pjo6vpa +- valory/trader_abci:0.1.0:bafybeihbnkekpwtisweg64cz4kdmekg4nkq2n6nkbsrudylnhlhpqalhgy +- valory/staking_abci:0.1.0:bafybeich2wka6i76w546ez7pi3g3pzlrjuunn33fq7dh55azjykyhwfjiu +- valory/check_stop_trading_abci:0.1.0:bafybeiahe6n3ehiltghwx5dsl553lo3dlqfw7pk5nsgxlntetrwgn4qzqu +- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm customs: - valory/mike_strat:0.1.0:bafybeihjiol7f4ch4piwfikurdtfwzsh6qydkbsztpbwbwb2yrqdqf726m - valory/bet_amount_per_threshold:0.1.0:bafybeihufqu2ra7vud4h6g2nwahx7mvdido7ff6prwnib2tdlc4np7dw24 diff --git a/packages/valory/services/trader/service.yaml b/packages/valory/services/trader/service.yaml index 743d01bc2..bbaba9e52 100644 --- a/packages/valory/services/trader/service.yaml +++ b/packages/valory/services/trader/service.yaml @@ -7,7 +7,7 @@ license: Apache-2.0 fingerprint: README.md: bafybeigtuothskwyvrhfosps2bu6suauycolj67dpuxqvnicdrdu7yhtvq fingerprint_ignore_patterns: [] -agent: valory/trader:0.1.0:bafybeia3p2oynp6wnwes6o6uxg3rjv3zf37odmymxyiowx7wvjn4piit24 +agent: valory/trader:0.1.0:bafybeihvp3o24bwf4tb6mcnbohth6nvmvs5itepeflnaiv7p2bwjpmjrqe number_of_agents: 4 deployment: agent: diff --git a/packages/valory/services/trader_pearl/service.yaml b/packages/valory/services/trader_pearl/service.yaml index 8fbd6f31f..b11870564 100644 --- a/packages/valory/services/trader_pearl/service.yaml +++ b/packages/valory/services/trader_pearl/service.yaml @@ -8,7 +8,7 @@ license: Apache-2.0 fingerprint: README.md: bafybeibg7bdqpioh4lmvknw3ygnllfku32oca4eq5pqtvdrdsgw6buko7e fingerprint_ignore_patterns: [] -agent: valory/trader:0.1.0:bafybeia3p2oynp6wnwes6o6uxg3rjv3zf37odmymxyiowx7wvjn4piit24 +agent: valory/trader:0.1.0:bafybeihvp3o24bwf4tb6mcnbohth6nvmvs5itepeflnaiv7p2bwjpmjrqe number_of_agents: 1 deployment: agent: diff --git a/packages/valory/skills/check_stop_trading_abci/skill.yaml b/packages/valory/skills/check_stop_trading_abci/skill.yaml index 39c227653..a931e3be2 100644 --- a/packages/valory/skills/check_stop_trading_abci/skill.yaml +++ b/packages/valory/skills/check_stop_trading_abci/skill.yaml @@ -23,11 +23,11 @@ fingerprint: fingerprint_ignore_patterns: [] connections: [] contracts: -- valory/mech:0.1.0:bafybeielwbnikog4eqmu6bo537kzp2e7qpmkzt7l5zuuugp2w4r47dbvwu +- valory/mech:0.1.0:bafybeiejfjfoxqggghcme43sx53q5gruefrws3k2jam2opkxl5uzffoarm protocols: [] skills: -- valory/abstract_round_abci:0.1.0:bafybeigjddhk7epta7xpnfvv426xedff5abh4xlkwi6cqgp4vkutgkvydm -- valory/staking_abci:0.1.0:bafybeiaasclr4lf3u2layekmfwyasckxrslbs2g4me7kvozz5goswlznjq +- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u +- valory/staking_abci:0.1.0:bafybeich2wka6i76w546ez7pi3g3pzlrjuunn33fq7dh55azjykyhwfjiu behaviours: main: args: {} diff --git a/packages/valory/skills/decision_maker_abci/skill.yaml b/packages/valory/skills/decision_maker_abci/skill.yaml index 564902a2a..0d8d696f7 100644 --- a/packages/valory/skills/decision_maker_abci/skill.yaml +++ b/packages/valory/skills/decision_maker_abci/skill.yaml @@ -86,11 +86,11 @@ fingerprint_ignore_patterns: [] connections: - valory/http_server:0.22.0:bafybeihpgu56ovmq4npazdbh6y6ru5i7zuv6wvdglpxavsckyih56smu7m contracts: -- valory/gnosis_safe:0.1.0:bafybeihtqcpqthb37msgqabpzcc2xc3l3yzkp5pl2sodeghqyzzzyuevgi +- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge - valory/market_maker:0.1.0:bafybeibhmqzu2u4cprrf2xgnsc6zy53q2ja7hojxhqq5itdtlydun7o64a -- valory/erc20:0.1.0:bafybeientdgpccdi7prtu4x53m5g3yugh5tuh5hnroylfz3wwzyjniqure +- valory/erc20:0.1.0:bafybeid2p2jyvjjlcsqugnawksdzsca6ljghpqbp2kfi3cxuxoy2233dbi - valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y -- valory/mech:0.1.0:bafybeielwbnikog4eqmu6bo537kzp2e7qpmkzt7l5zuuugp2w4r47dbvwu +- valory/mech:0.1.0:bafybeiejfjfoxqggghcme43sx53q5gruefrws3k2jam2opkxl5uzffoarm - valory/conditional_tokens:0.1.0:bafybeibnzmqmeph4cj5vfh3s622mo2o5627vjjwc6bptrhj4dk65mzgvhe - valory/realitio:0.1.0:bafybeietgux6kkhdquspy35qera7gjwwqwrremmoeatjzwwokjb2lzsata - valory/realitio_proxy:0.1.0:bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4 @@ -102,11 +102,11 @@ protocols: - valory/ipfs:0.1.0:bafybeiftxi2qhreewgsc5wevogi7yc5g6hbcbo4uiuaibauhv3nhfcdtvm - valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae skills: -- valory/abstract_round_abci:0.1.0:bafybeigjddhk7epta7xpnfvv426xedff5abh4xlkwi6cqgp4vkutgkvydm -- valory/market_manager_abci:0.1.0:bafybeib2i7i26ozgh7bpvundz6w72ne6entxboqezqgwxmuyfeak6wwloq -- valory/transaction_settlement_abci:0.1.0:bafybeifmgmwdkx4esemxjacjwzqkqymkuklb5nehkwqkx7v335fllgswcq -- valory/mech_interact_abci:0.1.0:bafybeib4vn6m2yumwoclh5aatcdt5yxcjc5owxmxy5o7t3nfzormgwkr64 -- valory/staking_abci:0.1.0:bafybeiaasclr4lf3u2layekmfwyasckxrslbs2g4me7kvozz5goswlznjq +- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u +- valory/market_manager_abci:0.1.0:bafybeibo63iiziwvqn6fmx36ungyg35z3chfv432kf6spuiszm6na22vdy +- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae +- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm +- valory/staking_abci:0.1.0:bafybeich2wka6i76w546ez7pi3g3pzlrjuunn33fq7dh55azjykyhwfjiu behaviours: main: args: {} diff --git a/packages/valory/skills/market_manager_abci/skill.yaml b/packages/valory/skills/market_manager_abci/skill.yaml index cb4cd0fc2..7d1de7b60 100644 --- a/packages/valory/skills/market_manager_abci/skill.yaml +++ b/packages/valory/skills/market_manager_abci/skill.yaml @@ -36,7 +36,7 @@ contracts: [] protocols: - valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae skills: -- valory/abstract_round_abci:0.1.0:bafybeigjddhk7epta7xpnfvv426xedff5abh4xlkwi6cqgp4vkutgkvydm +- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u behaviours: main: args: {} diff --git a/packages/valory/skills/staking_abci/skill.yaml b/packages/valory/skills/staking_abci/skill.yaml index cfc6e54da..b7831b736 100644 --- a/packages/valory/skills/staking_abci/skill.yaml +++ b/packages/valory/skills/staking_abci/skill.yaml @@ -23,15 +23,15 @@ fingerprint: fingerprint_ignore_patterns: [] connections: [] contracts: -- valory/gnosis_safe:0.1.0:bafybeihtqcpqthb37msgqabpzcc2xc3l3yzkp5pl2sodeghqyzzzyuevgi +- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge - valory/service_staking_token:0.1.0:bafybeieg664oohr26gpcfn3uied4minlz6dmgd32xboewscnxqnv5kk4zi - valory/staking_token:0.1.0:bafybeiaynt6clwbthtbndtocnwul7dp76ctmu4jxinp7fnqks4pxt65yuy - valory/mech_activity:0.1.0:bafybeieadv7vnbguc7beu6xo3rs3mqbgzc7wayc7kvgb2tmitmjtpdcqkq protocols: - valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i skills: -- valory/abstract_round_abci:0.1.0:bafybeigjddhk7epta7xpnfvv426xedff5abh4xlkwi6cqgp4vkutgkvydm -- valory/transaction_settlement_abci:0.1.0:bafybeifmgmwdkx4esemxjacjwzqkqymkuklb5nehkwqkx7v335fllgswcq +- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u +- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae behaviours: main: args: {} diff --git a/packages/valory/skills/trader_abci/skill.yaml b/packages/valory/skills/trader_abci/skill.yaml index 149a2d3f0..599271a80 100644 --- a/packages/valory/skills/trader_abci/skill.yaml +++ b/packages/valory/skills/trader_abci/skill.yaml @@ -21,17 +21,17 @@ connections: [] contracts: [] protocols: [] skills: -- valory/abstract_round_abci:0.1.0:bafybeigjddhk7epta7xpnfvv426xedff5abh4xlkwi6cqgp4vkutgkvydm -- valory/registration_abci:0.1.0:bafybeiagi6e2h7kochmlemy5c5yk6hwn37tfxiqvk2en74jhowsdwlmrny -- valory/reset_pause_abci:0.1.0:bafybeiezfedmmseox3ce5aucxsiszdmvskrwwbtpb2a3vw3sbmc5jt7nri -- valory/transaction_settlement_abci:0.1.0:bafybeifmgmwdkx4esemxjacjwzqkqymkuklb5nehkwqkx7v335fllgswcq -- valory/termination_abci:0.1.0:bafybeiea67epwwgngp7b3wavs6hpkaxv6etyaps6g6325bchfnf354mibq -- valory/market_manager_abci:0.1.0:bafybeib2i7i26ozgh7bpvundz6w72ne6entxboqezqgwxmuyfeak6wwloq -- valory/decision_maker_abci:0.1.0:bafybeih6hom4buikaik7t4dn5mmc7qufs3uprltzdqqwb3ggveyurkv44i -- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeibzv6gntw4c5iofqabhtc5jxarwbt4fr2faxwrgkkzks7ral4ff3i -- valory/staking_abci:0.1.0:bafybeiaasclr4lf3u2layekmfwyasckxrslbs2g4me7kvozz5goswlznjq -- valory/check_stop_trading_abci:0.1.0:bafybeic3bismocli2yyxmjhjsevjbzpuf3ladsvlkazfx23vq3q6uxrn7m -- valory/mech_interact_abci:0.1.0:bafybeib4vn6m2yumwoclh5aatcdt5yxcjc5owxmxy5o7t3nfzormgwkr64 +- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u +- valory/registration_abci:0.1.0:bafybeibc7duasoaw5b4ene5oxfba2dmdzstsrws6ipi57ymgdtoxjadn54 +- valory/reset_pause_abci:0.1.0:bafybeigrdlxed3xlsnxtjhnsbl3cojruihxcqx4jxhgivkd5i2fkjncgba +- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae +- valory/termination_abci:0.1.0:bafybeib5l7jhew5ic6iq24dd23nidcoimzqkrk556gqywhoziatj33zvwm +- valory/market_manager_abci:0.1.0:bafybeibo63iiziwvqn6fmx36ungyg35z3chfv432kf6spuiszm6na22vdy +- valory/decision_maker_abci:0.1.0:bafybeigzwgigws4ydqgpwt4ymgafuw76hhsc7ecainx6lzcqrc3pjo6vpa +- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeifznhp32govm42jiiy2yxozufzomdmeunhfbzjlq4xfw5nk6xm7oy +- valory/staking_abci:0.1.0:bafybeich2wka6i76w546ez7pi3g3pzlrjuunn33fq7dh55azjykyhwfjiu +- valory/check_stop_trading_abci:0.1.0:bafybeiahe6n3ehiltghwx5dsl553lo3dlqfw7pk5nsgxlntetrwgn4qzqu +- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm behaviours: main: args: {} diff --git a/packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml b/packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml index e9f68560f..e01ab7fa1 100644 --- a/packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml +++ b/packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml @@ -22,10 +22,10 @@ contracts: [] protocols: - valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni skills: -- valory/abstract_round_abci:0.1.0:bafybeigjddhk7epta7xpnfvv426xedff5abh4xlkwi6cqgp4vkutgkvydm -- valory/decision_maker_abci:0.1.0:bafybeih6hom4buikaik7t4dn5mmc7qufs3uprltzdqqwb3ggveyurkv44i -- valory/staking_abci:0.1.0:bafybeiaasclr4lf3u2layekmfwyasckxrslbs2g4me7kvozz5goswlznjq -- valory/mech_interact_abci:0.1.0:bafybeib4vn6m2yumwoclh5aatcdt5yxcjc5owxmxy5o7t3nfzormgwkr64 +- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u +- valory/decision_maker_abci:0.1.0:bafybeigzwgigws4ydqgpwt4ymgafuw76hhsc7ecainx6lzcqrc3pjo6vpa +- valory/staking_abci:0.1.0:bafybeich2wka6i76w546ez7pi3g3pzlrjuunn33fq7dh55azjykyhwfjiu +- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm behaviours: main: args: {} diff --git a/trader_backup/.certs/acn_cosmos_9005.txt b/trader_backup/.certs/acn_cosmos_9005.txt deleted file mode 100644 index d678dc674..000000000 --- a/trader_backup/.certs/acn_cosmos_9005.txt +++ /dev/null @@ -1 +0,0 @@ -307834633362616433323932336531326335386336653037343535616663626537323630366534376533346434366237666666346635633534373934633763666438363464303261303335666531633232313062653138343762376265343362376433306135383838333438376332313861386435363234623563383665333561333163 \ No newline at end of file diff --git a/trader_backup/README.md b/trader_backup/README.md deleted file mode 100644 index c87f0282c..000000000 --- a/trader_backup/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Trader Agent - -This agent uses `trader_abci` skill, which: -1. Searches for new questions on the supported prediction markets -2. Selects a question to investigate its answer -3. Predicts the answer for the selected question -4. Decides whether answering this question is profitable -5. Submits the answer if it is profitable, otherwise temporarily blacklists the question diff --git a/trader_backup/__init__.py b/trader_backup/__init__.py deleted file mode 100644 index 1fc7bb6b7..000000000 --- a/trader_backup/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Implements the trader agent.""" diff --git a/trader_backup/aea-config.yaml b/trader_backup/aea-config.yaml deleted file mode 100644 index 8ac999392..000000000 --- a/trader_backup/aea-config.yaml +++ /dev/null @@ -1,407 +0,0 @@ -agent_name: trader -author: valory -version: 0.1.0 -license: Apache-2.0 -description: Trader agent. -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeiexvxghmwzokfocrlq6johtoz7dvpqm6gg6vmcapu43yjjfqc435q - __init__.py: bafybeighcq4pmuzte6vhvvprrvo563vzghkoit2h6qdqxf2ma5bghevkee -fingerprint_ignore_patterns: [] -connections: -- valory/abci:0.1.0:bafybeia6etkacvqend7xj6viejkqgo7ozu3yn4yg3qezfthf2xhrjjwse4 -- valory/http_client:0.23.0:bafybeihi772xgzpqeipp3fhmvpct4y6e6tpjp4sogwqrnf3wqspgeilg4u -- valory/http_server:0.22.0:bafybeihpgu56ovmq4npazdbh6y6ru5i7zuv6wvdglpxavsckyih56smu7m -- valory/ipfs:0.1.0:bafybeigcijdbwgdekow5c2ikeltetoteabfp52ewy3xfkd7ygaqbl7j3ke -- valory/ledger:0.19.0:bafybeig7woeog4srdby75hpjkmx4rhpkzncbf4h2pm5r6varsp26pf2uhu -- valory/p2p_libp2p_client:0.1.0:bafybeid3xg5k2ol5adflqloy75ibgljmol6xsvzvezebsg7oudxeeolz7e -contracts: -- valory/agent_registry:0.1.0:bafybeiblc4i5xjxbywnfccwtv3unhaghrgqls7panfbuqbpstbc34h42xq -- valory/conditional_tokens:0.1.0:bafybeibnzmqmeph4cj5vfh3s622mo2o5627vjjwc6bptrhj4dk65mzgvhe -- valory/erc20:0.1.0:bafybeid2p2jyvjjlcsqugnawksdzsca6ljghpqbp2kfi3cxuxoy2233dbi -- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge -- valory/gnosis_safe_proxy_factory:0.1.0:bafybeieg57u3z7cdlmdamad5e6lk7kmsli2zurzkg3sl4y7lhekcu4y3au -- valory/market_maker:0.1.0:bafybeibevdc5trbi2qgt2tvwbsr2h5xvonfhcjwfmozftzvef575fdvbjq -- valory/mech:0.1.0:bafybeiejfjfoxqggghcme43sx53q5gruefrws3k2jam2opkxl5uzffoarm -- valory/mech_activity:0.1.0:bafybeibmqmle5fnal3gxlpdmcos2kogzra4q3pr3o5nh7shplxuilji3t4 -- valory/mech_marketplace:0.1.0:bafybeiba7kh3wygwtpyf7oo3sili6givzo2gyadhbb66rvwsokswsywvuu -- valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y -- valory/realitio:0.1.0:bafybeietgux6kkhdquspy35qera7gjwwqwrremmoeatjzwwokjb2lzsata -- valory/realitio_proxy:0.1.0:bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4 -- valory/service_registry:0.1.0:bafybeiaop64kwdoetxtedoehabmsalojmms7ihuoqcdwxtwb2hk5i6bzye -- valory/service_staking_token:0.1.0:bafybeihhcs3ewwzhy7yto4y36uqmice3pdvyl54fvxxv6jsxonesie4dxu -- valory/staking_token:0.1.0:bafybeiep4r6qyilbfgzdvx6t7zvpgaioxqktmxm7puwtnbpb2ftlib43gy -- valory/transfer_nft_condition:0.1.0:bafybeid6z2tf7nc4rhwggktxk5f62bowxdczykrxc3y76sbt2ttlw5hmtq -protocols: -- open_aea/signing:1.0.0:bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi -- valory/abci:0.1.0:bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u -- valory/acn:1.1.0:bafybeidluaoeakae3exseupaea4i3yvvk5vivyt227xshjlffywwxzcxqe -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -- valory/ipfs:0.1.0:bafybeiftxi2qhreewgsc5wevogi7yc5g6hbcbo4uiuaibauhv3nhfcdtvm -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -- valory/tendermint:0.1.0:bafybeig4mi3vmlv5zpbjbfuzcgida6j5f2nhrpedxicmrrfjweqc5r7cra -skills: -- valory/abstract_abci:0.1.0:bafybeieeaseuy5rbbw465knz27vccvpkfge43q7isl7fkdlfapwd7bpi24 -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/check_stop_trading_abci:0.1.0:bafybeieduekpd4zbvjztyxyooppqnmjvup6jfp74uo6hhupvtvzzscdzkq -- valory/decision_maker_abci:0.1.0:bafybeigwqeptzd5pfvfuhau2m5gzicwimrb4weanykppgqqb3inureedeu -- valory/market_manager_abci:0.1.0:bafybeibo63iiziwvqn6fmx36ungyg35z3chfv432kf6spuiszm6na22vdy -- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm -- valory/registration_abci:0.1.0:bafybeibc7duasoaw5b4ene5oxfba2dmdzstsrws6ipi57ymgdtoxjadn54 -- valory/reset_pause_abci:0.1.0:bafybeigrdlxed3xlsnxtjhnsbl3cojruihxcqx4jxhgivkd5i2fkjncgba -- valory/staking_abci:0.1.0:bafybeicupccurmrg7qesivonlyt3nryarsmk5qf5yh6auno64wn45bybvq -- valory/termination_abci:0.1.0:bafybeib5l7jhew5ic6iq24dd23nidcoimzqkrk556gqywhoziatj33zvwm -- valory/trader_abci:0.1.0:bafybeibgpwhwg7yhxrblery25hoa4rdvrjauodak2rgl7f2shzrt3slmmu -- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae -- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeielsstfertfjl2qkysp7kakqsjiimgurfglaajvccjihnumljg62e -customs: -- jhehemann/kelly_criterion:0.1.0:bafybeif55cu7cf6znyma7kxus4wxa2doarhau2xmndo57iegshxorivwmq -- valory/bet_amount_per_threshold:0.1.0:bafybeihufqu2ra7vud4h6g2nwahx7mvdido7ff6prwnib2tdlc4np7dw24 -- valory/kelly_criterion_no_conf:0.1.0:bafybeibxfp27rzrfnp7sxq62vwv32pdvrijxi7vzg7ihukkaka3bwzrgae -- valory/mike_strat:0.1.0:bafybeihjiol7f4ch4piwfikurdtfwzsh6qydkbsztpbwbwb2yrqdqf726m -- w1kke/always_blue:0.1.0:bafybeieshu32h3es2fslduuhr7nimuvh2vuibyeqdunzrcggaeohekg3jm -default_ledger: ethereum -required_ledgers: -- ethereum -- cosmos -default_routing: {} -connection_private_key_paths: {} -private_key_paths: - ethereum: ethereum_private_key.txt -logging_config: - version: 1 - disable_existing_loggers: false - formatters: - standard: - format: '[%(asctime)s] [%(levelname)s] %(message)s' - handlers: - logfile: - class: logging.FileHandler - formatter: standard - filename: ${LOG_FILE:str:log.txt} - level: ${LOG_LEVEL:str:INFO} - console: - class: logging.StreamHandler - formatter: standard - stream: ext://sys.stdout - loggers: - aea: - handlers: - - logfile - - console - propagate: true -dependencies: - open-aea-ledger-cosmos: - version: ==1.53.0 - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 -skill_exception_policy: stop_and_exit -connection_exception_policy: just_log -default_connection: null ---- -public_id: valory/abci:0.1.0 -type: connection -config: - target_skill_id: valory/trader_abci:0.1.0 - host: ${str:localhost} - port: ${int:26658} - use_tendermint: ${bool:false} ---- -public_id: valory/trader_abci:0.1.0 -type: skill -models: - benchmark_tool: - args: - log_dir: ${str:./benchmarks} - params: - args: - setup: - all_participants: ${list:["0x0000000000000000000000000000000000000000"]} - consensus_threshold: ${int:null} - safe_contract_address: ${str:0x0000000000000000000000000000000000000000} - cleanup_history_depth: ${int:1} - cleanup_history_depth_current: ${int:null} - finalize_timeout: ${float:60.0} - genesis_config: - genesis_time: ${str:2022-09-26T00:00:00.000000000Z} - chain_id: ${str:chain-c4daS1} - consensus_params: - block: - max_bytes: ${str:22020096} - max_gas: ${str:-1} - time_iota_ms: ${str:1000} - evidence: - max_age_num_blocks: ${str:100000} - max_age_duration: ${str:172800000000000} - max_bytes: ${str:1048576} - validator: - pub_key_types: ${list:["ed25519"]} - version: ${dict:{}} - voting_power: ${str:10} - init_fallback_gas: ${int:0} - keeper_allowed_retries: ${int:3} - keeper_timeout: ${float:30.0} - max_attempts: ${int:10} - reset_tendermint_after: ${int:2} - retry_attempts: ${int:400} - retry_timeout: ${int:3} - request_retry_delay: ${float:1.0} - request_timeout: ${float:10.0} - service_id: ${str:trader} - tendermint_url: ${str:http://localhost:26657} - tendermint_com_url: ${str:http://localhost:8080} - tendermint_check_sleep_delay: ${int:3} - tendermint_max_retries: ${int:5} - tx_timeout: ${float:10.0} - round_timeout_seconds: ${float:350.0} - validate_timeout: ${int:1205} - history_check_timeout: ${int:1205} - reset_pause_duration: ${int:30} - max_healthcheck: ${int:43200} - multisend_address: ${str:0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761} - multisend_batch_size: ${int:1} - drand_public_key: ${str:868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31} - service_registry_address: ${str:null} - agent_registry_address: ${str:0xE49CB081e8d96920C38aA7AB90cb0294ab4Bc8EA} - share_tm_config_on_startup: ${bool:false} - sleep_time: ${int:10} - tendermint_p2p_url: ${str:localhost:26656} - termination_sleep: ${int:900} - termination_from_block: ${int:0} - use_termination: ${bool:false} - on_chain_service_id: ${int:null} - creator_per_subgraph: - omen_subgraph: ${list:["0x89c5cc945dd550BcFfb72Fe42BfF002429F46Fec"]} - slot_count: ${int:2} - opening_margin: ${int:86400} - languages: ${list:["en_US"]} - average_block_time: ${int:5} - abt_error_mult: ${int:5} - the_graph_error_message_key: ${str:message} - the_graph_payment_required_error: ${str:payment required for subsequent requests - for this API key} - mech_contract_address: ${str:0x77af31De935740567Cf4fF1986D04B2c964A786a} - mech_request_price: ${int:null} - mech_chain_id: ${str:gnosis} - mech_activity_checker_contract: ${str:0x0000000000000000000000000000000000000000} - mech_wrapped_native_token_address: ${str:0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d} - sample_bets_closing_days: ${int:10} - trading_strategy: ${str:kelly_criterion_no_conf} - use_fallback_strategy: ${bool:true} - bet_threshold: ${int:100000000000000000} - ipfs_address: ${str:https://gateway.autonolas.tech/ipfs/} - tools_accuracy_hash: ${str:QmR8etyW3TPFadNtNrW54vfnFqmh8vBrMARWV76EmxCZyk} - prompt_template: ${str:With the given question "@{question}" and the `yes` option - represented by `@{yes}` and the `no` option represented by `@{no}`, what are - the respective probabilities of `p_yes` and `p_no` occurring?} - dust_threshold: ${int:10000000000000} - conditional_tokens_address: ${str:0xCeAfDD6bc0bEF976fdCd1112955828E00543c0Ce} - realitio_proxy_address: ${str:0xAB16D643bA051C11962DA645f74632d3130c81E2} - realitio_address: ${str:0x79e32aE03fb27B07C89c0c568F80287C01ca2E57} - event_filtering_batch_size: ${int:5000} - reduce_factor: ${float:0.25} - minimum_batch_size: ${int:500} - use_subgraph_for_redeeming: ${bool:true} - max_filtering_retries: ${int:6} - redeeming_batch_size: ${int:5} - slippage: ${float:0.01} - redeem_round_timeout: ${float:3600.0} - policy_epsilon: ${float:0.1} - store_path: ${str:./data/} - irrelevant_tools: ${list:["openai-text-davinci-002", "openai-text-davinci-003", - "openai-gpt-3.5-turbo", "openai-gpt-4", "stabilityai-stable-diffusion-v1-5", - "stabilityai-stable-diffusion-xl-beta-v2-2-2", "stabilityai-stable-diffusion-512-v2-1", - "stabilityai-stable-diffusion-768-v2-1"]} - use_nevermined: ${bool:true} - mech_to_subscription_params: ${list:[["base_url", "https://marketplace-api.gnosis.nevermined.app/api/v1/metadata/assets/ddo"], - ["did", "did:nv:01706149da2f9f3f67cf79ec86c37d63cec87fc148f5633b12bf6695653d5b3c"], - ["escrow_payment_condition_address", "0x31B2D187d674C9ACBD2b25f6EDce3d2Db2B7f446"], - ["lock_payment_condition_address", "0x2749DDEd394196835199471027713773736bffF2"], - ["transfer_nft_condition_address", "0x659fCA7436936e9fe8383831b65B8B442eFc8Ea8"], - ["token_address", "0x1b5DeaD7309b56ca7663b3301A503e077Be18cba"], ["order_address", - "0x72201948087aE83f8Eac22cf7A9f2139e4cFA829"], ["nft_amount", "100"], ["payment_token", - "0x0000000000000000000000000000000000000000"], ["order_address", "0x72201948087aE83f8Eac22cf7A9f2139e4cFA829"], - ["price", "1000000000000000000"]]} - staking_contract_address: ${str:0x2Ef503950Be67a98746F484DA0bBAdA339DF3326} - staking_interaction_sleep_time: ${int:5} - disable_trading: ${bool:false} - stop_trading_if_staking_kpi_met: ${bool:true} - agent_balance_threshold: ${int:10000000000000000} - refill_check_interval: ${int:10} - tool_punishment_multiplier: ${int:1} - contract_timeout: ${float:300.0} - file_hash_to_strategies_json: ${list:[["bafybeihufqu2ra7vud4h6g2nwahx7mvdido7ff6prwnib2tdlc4np7dw24",["bet_amount_per_threshold"]],["bafybeibxfp27rzrfnp7sxq62vwv32pdvrijxi7vzg7ihukkaka3bwzrgae",["kelly_criterion_no_conf"]]]} - strategies_kwargs: ${list:[["bet_kelly_fraction",1.0],["floor_balance",500000000000000000],["bet_amount_per_threshold",{"0.0":0,"0.1":0,"0.2":0,"0.3":0,"0.4":0,"0.5":0,"0.6":60000000000000000,"0.7":90000000000000000,"0.8":100000000000000000,"0.9":1000000000000000000,"1.0":10000000000000000000}]]} - service_endpoint: ${str:https://trader.staging.autonolas.tech/} - rpc_sleep_time: ${int:10} - safe_voting_range: ${int:600} - rebet_chance: ${float:0.6} - mech_interaction_sleep_time: ${int:10} - use_mech_marketplace: ${bool:false} - policy_store_update_offset: ${int:259200} - mech_marketplace_config: - mech_marketplace_address: ${str:0x0000000000000000000000000000000000000000} - priority_mech_address: ${str:0x0000000000000000000000000000000000000000} - priority_mech_staking_instance_address: ${str:0x0000000000000000000000000000000000000000} - priority_mech_service_id: ${int:0} - requester_staking_instance_address: ${str:0x0000000000000000000000000000000000000000} - response_timeout: ${int:300} - expected_mech_response_time: ${int:300} - mech_invalid_response: ${str:Invalid Response} - mech_consecutive_failures_threshold: ${int:2} - tool_quarantine_duration: ${int:18000} - benchmarking_mode: - args: - enabled: ${bool:true} - native_balance: ${int:10000000000000000000} - collateral_balance: ${int:10000000000000000000} - mech_cost: ${int:10000000000000000} - pool_fee: ${int:20000000000000000} - sep: ${str:,} - dataset_filename: ${str:benchmarking_40.csv} - question_field: ${str:question} - question_id_field: ${str:question_id} - answer_field: ${str:answer} - p_yes_field_part: ${str:p_yes_} - p_no_field_part: ${str:p_no_} - confidence_field_part: ${str:confidence_} - part_prefix_mode: ${bool:true} - bet_amount_field: ${str:collateral_amount} - results_filename: ${str:benchmarking_results.csv} - randomness: ${str:benchmarking_randomness} - nr_mech_calls: ${int:60} - acc_info_fields: - args: - tool: ${str:tool} - requests: ${str:total_requests} - accuracy: ${str:tool_accuracy} - sep: ${str:,} - max: ${str:max} - datetime_format: ${str:%Y-%m-%d %H:%M:%S} - network_subgraph: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:POST} - response_key: ${str:data:blocks} - response_index: ${int:0} - response_type: ${str:dict} - error_key: ${str:errors} - error_index: ${int:0} - error_type: ${str:dict} - retries: ${int:5} - url: ${str:https://api.thegraph.com/subgraphs/name/stakewise/ethereum-gnosis} - omen_subgraph: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:POST} - response_key: ${str:data:fixedProductMarketMakers} - response_type: ${str:list} - error_key: ${str:errors} - error_index: ${int:0} - error_type: ${str:dict} - retries: ${int:5} - url: ${str:https://api.thegraph.com/subgraphs/name/protofire/omen-xdai} - randomness_api: - args: - method: ${str:GET} - response_key: ${str:null} - response_type: ${str:dict} - retries: ${int:5} - url: ${str:https://drand.cloudflare.com/public/latest} - mech_response: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:GET} - response_key: ${str:result} - response_type: ${str:str} - retries: ${int:5} - url: ${str:''} - agent_tools: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:GET} - response_key: ${str:tools} - response_type: ${str:list} - retries: ${int:5} - url: ${str:''} - trades_subgraph: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:POST} - response_key: ${str:data:fpmmTrades} - response_type: ${str:list} - error_key: ${str:errors} - error_index: ${int:0} - error_type: ${str:dict} - retries: ${int:5} - url: ${str:https://api.thegraph.com/subgraphs/name/protofire/omen-xdai} - conditional_tokens_subgraph: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:POST} - response_key: ${str:data:user:userPositions} - response_type: ${str:list} - error_key: ${str:errors} - error_index: ${int:0} - error_type: ${str:dict} - retries: ${int:5} - url: ${str:https://api.thegraph.com/subgraphs/name/gnosis/conditional-tokens-gc} - realitio_subgraph: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:POST} - response_key: ${str:data:answers} - response_type: ${str:list} - error_key: ${str:errors} - error_index: ${int:0} - error_type: ${str:dict} - retries: ${int:5} - url: ${str:https://api.thegraph.com/subgraphs/name/realityeth/realityeth-gnosis} ---- -public_id: valory/p2p_libp2p_client:0.1.0 -type: connection -config: - nodes: - - uri: ${str:acn.staging.autonolas.tech:9005} - public_key: ${str:02d3a830c9d6ea1ae91936951430dee11f4662f33118b02190693be835359a9d77} -cert_requests: -- identifier: acn - ledger_id: ethereum - message_format: '{public_key}' - not_after: '2024-01-01' - not_before: '2023-01-01' - public_key: ${str:02d3a830c9d6ea1ae91936951430dee11f4662f33118b02190693be835359a9d77} - save_path: .certs/acn_cosmos_9005.txt -is_abstract: true ---- -public_id: valory/ledger:0.19.0 -type: connection -config: - ledger_apis: - ethereum: - address: ${str:http://host.docker.internal:8545} - chain_id: ${int:1337} - default_gas_price_strategy: ${str:eip1559} - poa_chain: ${bool:false} - gnosis: - address: ${str:https://rpc.gnosischain.com} - chain_id: ${int:100} - poa_chain: ${bool:false} - default_gas_price_strategy: ${str:eip1559} ---- -public_id: valory/http_server:0.22.0:bafybeicblltx7ha3ulthg7bzfccuqqyjmihhrvfeztlgrlcoxhr7kf6nbq -type: connection -config: - host: ${str:0.0.0.0} - port: ${int:8716} - target_skill_id: valory/trader_abci:0.1.0 diff --git a/trader_backup/data/available_tools_store.json b/trader_backup/data/available_tools_store.json deleted file mode 100644 index b5f237842..000000000 --- a/trader_backup/data/available_tools_store.json +++ /dev/null @@ -1 +0,0 @@ -["prediction-online", "prediction-offline", "claude-prediction-offline", "claude-prediction-online", "prediction-online-sme", "prediction-offline-sme", "prediction-request-rag", "prediction-request-rag-claude", "prediction-request-reasoning", "prediction-request-reasoning-claude", "prediction-url-cot-claude", "superforcaster"] \ No newline at end of file diff --git a/trader_backup/data/benchmarking_40.csv b/trader_backup/data/benchmarking_40.csv deleted file mode 100644 index bb57ae171..000000000 --- a/trader_backup/data/benchmarking_40.csv +++ /dev/null @@ -1,560 +0,0 @@ -question_id,question,answer,p_yes,p_no,confidence,collateral_amount,l0_start,l1_start,l0_end,l1_end -20,"Title 20",no,0.32501656963725933,0.6749834303627407,0.8,237291064010715360,7790834981644233728,6289441390486066176,8053792557597813472,6084090153746785280 -11,"Title 11",no,0.32501656963725933,0.6749834303627407,0.8,207507423252475424,8100035237646221312,6049356399372756992,8340287470222355104,5875097252336512000 -5,"Title 5",no,0.32501656963725933,0.6749834303627407,0.8,191386535316339744,8263810620031015936,5929467923820365824,8490579565894703488,5771101915919278080 -37,"Title 37",no,0.6749834303627407,0.32501656963725933,0.8,399642460396294016,8340803845760637952,5874733527620976640,7888097783704631296,6211890539849169920 -4,"Title 4",no,0.6749834303627407,0.32501656963725933,0.8,408303717661433088,8512953316229938176,5755934301505159168,8039773321845083136,6094699195916480448 -36,"Title 36",no,0.6749834303627407,0.32501656963725933,0.8,411727350602071744,8584261825207214080,5708120394943475712,8102594105023819776,6047445961734492416 -3,"Title 3",no,0.32501656963725933,0.6749834303627407,0.8,157714011940121088,8598859870757257216,5698429877504774144,8794732606299768992,5571516746842391552 -22,"Title 22",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -10,"Title 10",no,0.6749834303627407,0.32501656963725933,0.8,430489936785442048,9007865773418682368,5439690292077190144,8475359602244790272,5781465601414931968 -40,"Title 40",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -2,"Title 2",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -14,"Title 14",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -25,"Title 25",no,0.6749834303627407,0.32501656963725933,0.8,455089828517687168,9671167011325687808,5066606743800122368,9057481872293691392,5409892141201866240 -24,"Title 24",no,0.6749834303627407,0.32501656963725933,0.8,461319211561435264,9863689419814088704,4967715214306043904,9226003869695291392,5311075162340933312 -6,"Title 6",no,0.6749834303627407,0.32501656963725933,0.8,472988171665592320,10256678737079947264,4777374943299646464,9569271098096420864,5120557197898530560 -8,"Title 8",no,0.6749834303627407,0.32501656963725933,0.8,481373894544583424,10570224480919758848,4635663139269139456,9842434671036794880,4978443000916395264 -19,"Title 19",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -38,"Title 38",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -16,"Title 16",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -29,"Title 29",no,0.6749834303627407,0.32501656963725933,0.8,503460875053420928,11558677932560506880,4239239148792979968,10699032826227460096,4579853225600176128 -32,"Title 32",no,0.6749834303627407,0.32501656963725933,0.8,506346946038656640,11710182389367572480,4184392554337177088,10829696279398006784,4524595956879760640 -33,"Title 33",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -15,"Title 15",no,0.6749834303627407,0.32501656963725933,0.8,510980010292071232,11966905935401406464,4094625650482009088,11050706479749150720,4434105646529875712 -12,"Title 12",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -17,"Title 17",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -18,"Title 18",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -42,"Title 42",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -41,"Title 41",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -49,"Title 49",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -50,"Title 50",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -44,"Title 44",no,0.6749834303627407,0.32501656963725933,0.8,511645919524681792,12016831254055174144,4077614053493891584,11093959756285458432,4416817896985634624 -45,"Title 45",no,0.6749834303627407,0.32501656963725933,0.8,526936493657588928,13004618776674914304,3767892072921538560,11938703595518078976,4104298227019820352 -47,"Title 47",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -26,"Title 26",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -48,"Title 48",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -31,"Title 31",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -35,"Title 35",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -39,"Title 39",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -30,"Title 30",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -23,"Title 23",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -46,"Title 46",no,0.6749834303627407,0.32501656963725933,0.8,551781455801612544,15330127508646088704,3196320446282285056,13895190353622009856,3526400053039024640 -21,"Title 21",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -13,"Title 13",no,0.6749834303627407,0.32501656963725933,0.8,554167564681795264,15629564487607744512,3135084156621943296,14143778973475606528,3464420653906686528 -27,"Title 27",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -34,"Title 34",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -43,"Title 43",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -28,"Title 28",no,0.6749834303627407,0.32501656963725933,0.8,562814130609114368,16867470973942423552,2904999811512777728,15162892110262820864,3231573478441815808 -20,"Title 20",no,0.32401656963725933,0.6759834303627407,0.8,238687212921694240,8053792557597813472,6084090153746785280,8327224905007858848,5884313268701579264 -11,"Title 11",no,0.32401656963725933,0.6759834303627407,0.8,209050472237947360,8340287470222355104,5875097252336512000,8589505271033898688,5704635884588261376 -37,"Title 37",no,0.6759834303627407,0.32401656963725933,0.8,400230125325017792,7888097783704631296,6211890539849169920,7459367483246631936,6568921575462204096 -36,"Title 36",no,0.6759834303627407,0.32401656963725933,0.8,412275802031600960,8102594105023819776,6047445961734492416,7647381437799948288,6407421991245236416 -25,"Title 25",no,0.6759834303627407,0.32401656963725933,0.8,455556622818114688,9057481872293691392,5409892141201866240,8482186121037668352,5776812640136407872 -24,"Title 24",no,0.6759834303627407,0.32401656963725933,0.8,461756143949024640,9226003869695291392,5311075162340933312,8629016189305241600,5678515247280489152 -29,"Title 29",no,0.6759834303627407,0.32401656963725933,0.8,503823689496977536,10699032826227460096,4579853225600176128,9902790730213357568,4948100119949145920 -32,"Title 32",no,0.6759834303627407,0.32401656963725933,0.8,506696883732067968,10829696279398006784,4524595956879760640,10014893319285080064,4892713126124233920 -15,"Title 15",no,0.6759834303627407,0.32401656963725933,0.8,511334915133990912,11050706479749150720,4434105646529875712,10204109645863735296,4801986817131299520 -22,"Title 22",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -40,"Title 40",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -14,"Title 14",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -19,"Title 19",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -38,"Title 38",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -16,"Title 16",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -33,"Title 33",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -12,"Title 12",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -17,"Title 17",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -18,"Title 18",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -56,"Title 56",no,0.6749834303627407,0.32501656963725933,0.8,325703565183003712,7211919973071383552,6794307227889562624,6894205483335988224,7107417978538367744 -60,"Title 60",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -52,"Title 52",no,0.6749834303627407,0.32501656963725933,0.8,511005750117101568,12037394010939934720,4070648510422386176,11113291050059880448,4409134951948908160 -51,"Title 51",no,0.6749834303627407,0.32501656963725933,0.8,511398080860620864,12061683852704937984,4062451030749850112,11134205330501349376,4400852916352103360 -55,"Title 55",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -53,"Title 53",no,0.6749834303627407,0.32501656963725933,0.8,527819730783912256,13149923766657468416,3726257343349993472,12064319028049711104,4061563680973149888 -57,"Title 57",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -59,"Title 59",no,0.6749834303627407,0.32501656963725933,0.8,543432672269146176,14515847701883136000,3375620976902592000,13217611162082392064,3707175177052205504 -54,"Title 54",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -58,"Title 58",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -44,"Title 44",no,0.6759834303627407,0.32401656963725933,0.8,511666094362506304,11093959756285458432,4416817896985634624,10241932150697545728,4784253525509126784 -45,"Title 45",no,0.6759834303627407,0.32401656963725933,0.8,526876696991104768,11938703595518078976,4104298227019820352,10960257408598300672,4470697920065234816 -46,"Title 46",no,0.6759834303627407,0.32401656963725933,0.8,551812746755485888,13895190353622009856,3526400053039024640,12594499947388655616,3890587177314622848 -28,"Title 28",no,0.6759834303627407,0.32401656963725933,0.8,562934864671646720,15162892110262820864,3231573478441815808,13630277674943653888,3594937767854575104 -37,"Title 37",no,0.6769834303627407,0.32301656963725933,0.8,401141666464844288,7459367483246631936,6568921575462204096,7053066252286877696,6947333010534574080 -36,"Title 36",no,0.6769834303627407,0.32301656963725933,0.8,413134744577843264,7647381437799948288,6407421991245236416,7216898391501085696,6789620324668060032 -25,"Title 25",no,0.6769834303627407,0.32301656963725933,0.8,456223889015836032,8482186121037668352,5776812640136407872,7942691962960402432,6169193042926055040 -24,"Title 24",no,0.6769834303627407,0.32301656963725933,0.8,462396200750845888,8629016189305241600,5678515247280489152,8069934017720236032,6071920773131989824 -29,"Title 29",no,0.6769834303627407,0.32301656963725933,0.8,504275120482529792,9902790730213357568,4948100119949145920,9165195304583875584,5346312694012442176 -32,"Title 32",no,0.6769834303627407,0.32301656963725933,0.8,507135895740727104,10014893319285080064,4892713126124233920,9260790686214115328,5291124879103773056 -22,"Title 22",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -42,"Title 42",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -40,"Title 40",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -41,"Title 41",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -49,"Title 49",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -38,"Title 38",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -33,"Title 33",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -50,"Title 50",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -47,"Title 47",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -26,"Title 26",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -48,"Title 48",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -31,"Title 31",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -35,"Title 35",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -39,"Title 39",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -30,"Title 30",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -23,"Title 23",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -21,"Title 21",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -27,"Title 27",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -34,"Title 34",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -43,"Title 43",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -67,"Title 67",no,0.32501656963725933,0.6749834303627407,0.8,196883110341074656,8197517645263373312,5977419277445874688,8428628889538494400,5813519688928073728 -69,"Title 69",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -70,"Title 70",no,0.6749834303627407,0.32501656963725933,0.8,469036429404564480,10196423869543354368,4805606419164532736,9519732733557899264,5147203327176474048 -68,"Title 68",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -64,"Title 64",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -63,"Title 63",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -62,"Title 62",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -66,"Title 66",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -65,"Title 65",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -61,"Title 61",no,0.6749834303627407,0.32501656963725933,0.8,558114507813032960,16444563612950865920,2979708136578960384,14821386169137852416,3306033554542374528 -56,"Title 56",no,0.6759834303627407,0.32401656963725933,0.8,326642359405542272,6894205483335988224,7107417978538367744,6589650861366906880,7435902300571325824 -52,"Title 52",no,0.6759834303627407,0.32401656963725933,0.8,510991069188204800,11113291050059880448,4409134951948908160,10260153505640419328,4775757007247769984 -51,"Title 51",no,0.6759834303627407,0.32401656963725933,0.8,511382254249851264,11134205330501349376,4400852916352103360,10278069369978984448,4767432310110997888 -53,"Title 53",no,0.6759834303627407,0.32401656963725933,0.8,527742654037778240,12064319028049711104,4061563680973149888,11068470880136237056,4426989105418044928 -59,"Title 59",no,0.6759834303627407,0.32401656963725933,0.8,543299973025132032,13217611162082392064,3707175177052205504,12035746303168745472,4071205786973042752 -44,"Title 44",no,0.6769834303627407,0.32301656963725933,0.8,511754813962051456,10241932150697545728,4784253525509126784,9455215234897207296,5182325180621095424 -45,"Title 45",no,0.6769834303627407,0.32301656963725933,0.8,526887754512069440,10960257408598300672,4470697920065234816,10061983270049314816,4869815292364310720 -46,"Title 46",no,0.6769834303627407,0.32301656963725933,0.8,551695575119210688,12594499947388655616,3890587177314622848,11415790485160816640,4292300219042581696 -37,"Title 37",no,0.6779834303627407,0.32201656963725933,0.8,401820841882672960,7053066252286877696,6947333010534574080,6668280720380707840,7348220936505875648 -36,"Title 36",no,0.6779834303627407,0.32201656963725933,0.8,413754854287674880,7216898391501085696,6789620324668060032,6810072505655057408,7195224420784154048 -32,"Title 32",no,0.6779834303627407,0.32201656963725933,0.8,507361784677247744,9260790686214115328,5291124879103773056,8563183359590140928,5722171059799108800 -42,"Title 42",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -40,"Title 40",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -60,"Title 60",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -41,"Title 41",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -49,"Title 49",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -38,"Title 38",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -33,"Title 33",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -50,"Title 50",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -55,"Title 55",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -47,"Title 47",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -48,"Title 48",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -57,"Title 57",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -31,"Title 31",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -35,"Title 35",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -39,"Title 39",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -54,"Title 54",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -58,"Title 58",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -34,"Title 34",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -43,"Title 43",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -79,"Title 79",no,0.32501656963725933,0.6749834303627407,0.8,286416420863449344,7234739436966579200,6772876953885845504,7527959826545808192,6509067679560607744 -75,"Title 75",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -78,"Title 78",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -73,"Title 73",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -80,"Title 80",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -77,"Title 77",no,0.6749834303627407,0.32501656963725933,0.8,519279953718736768,12685106274283008000,3862797751985692160,11671905672931244032,4198114804306356224 -71,"Title 71",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -72,"Title 72",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -74,"Title 74",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -76,"Title 76",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -67,"Title 67",no,0.32401656963725933,0.6759834303627407,0.8,198481470216459232,8428628889538494400,5813519688928073728,8668184945635040256,5652855852443999232 -70,"Title 70",no,0.6759834303627407,0.32401656963725933,0.8,469283865243376256,9519732733557899264,5147203327176474048,8887639406628313088,5513274983170030336 -61,"Title 61",no,0.6759834303627407,0.32401656963725933,0.8,558051845794466432,14821386169137852416,3306033554542374528,13358574154385088512,3668056143844906624 -56,"Title 56",no,0.6769834303627407,0.32301656963725933,0.8,327716428861320256,6589650861366906880,7435902300571325824,6297635292998300672,7780698265343836288 -52,"Title 52",no,0.6769834303627407,0.32301656963725933,0.8,511169012198012544,10260153505640419328,4775757007247769984,9472255822459379712,5173002177983579136 -51,"Title 51",no,0.6769834303627407,0.32301656963725933,0.8,511559018747957824,10278069369978984448,4767432310110997888,9487511607598303232,5164684063285589696 -53,"Title 53",no,0.6769834303627407,0.32301656963725933,0.8,527838641537065792,11068470880136237056,4426989105418044928,10154672472108472320,4825364888388749376 -59,"Title 59",no,0.6769834303627407,0.32301656963725933,0.8,543319020768578048,12035746303168745472,4071205786973042752,10959524621012686848,4470996844703678912 -44,"Title 44",no,0.6779834303627407,0.32201656963725933,0.8,511935694544464512,9455215234897207296,5182325180621095424,8728691683077958656,5613670614004475520 -45,"Title 45",no,0.6779834303627407,0.32201656963725933,0.8,526993927753055232,10061983270049314816,4869815292364310720,9237176785032722432,5304651100690872576 -46,"Title 46",no,0.6779834303627407,0.32201656963725933,0.8,551678421472191168,11415790485160816640,4292300219042581696,10347425635768592384,4735477376190908224 -42,"Title 42",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -69,"Title 69",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -60,"Title 60",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -41,"Title 41",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -68,"Title 68",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -49,"Title 49",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -50,"Title 50",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -55,"Title 55",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -47,"Title 47",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -48,"Title 48",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -57,"Title 57",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -64,"Title 64",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -63,"Title 63",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -54,"Title 54",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -62,"Title 62",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -66,"Title 66",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -65,"Title 65",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -58,"Title 58",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -43,"Title 43",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -82,"Title 82",no,0.32501656963725933,0.6749834303627407,0.8,188425402365820064,8276320206451292160,5920505584330230784,8499974432269035264,5764723222457933824 -85,"Title 85",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -88,"Title 88",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -81,"Title 81",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -90,"Title 90",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -83,"Title 83",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -86,"Title 86",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -87,"Title 87",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -84,"Title 84",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -89,"Title 89",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -79,"Title 79",no,0.32401656963725933,0.6759834303627407,0.8,287599139696851584,7527959826545808192,6509067679560607744,7834324181267787072,6254528006022670336 -77,"Title 77",no,0.6759834303627407,0.32401656963725933,0.8,519375885904005760,11671905672931244032,4198114804306356224,10739474221423917056,4562606975884451264 -67,"Title 67",no,0.32301656963725933,0.6769834303627407,0.8,200163824743152416,8668184945635040256,5652855852443999232,8916637813297370016,5495344885145651200 -70,"Title 70",no,0.6769834303627407,0.32301656963725933,0.8,469721105901106368,8887639406628313088,5513274983170030336,8297002662957863936,5905747170452469376 -61,"Title 61",no,0.6769834303627407,0.32301656963725933,0.8,558058505740430080,13358574154385088512,3668056143844906624,12040121700498868224,4069726305006513792 -56,"Title 56",no,0.6779834303627407,0.32201656963725933,0.8,328827106634083776,6297635292998300672,7780698265343836288,6017656405305380864,8142704850479640832 -52,"Title 52",no,0.6779834303627407,0.32201656963725933,0.8,511409431173598464,9472255822459379712,5173002177983579136,8744546543275619328,5603492388942686528 -51,"Title 51",no,0.6779834303627407,0.32201656963725933,0.8,511798246879732928,9487511607598303232,5164684063285589696,8757446134238537728,5595238526038683712 -53,"Title 53",no,0.6779834303627407,0.32201656963725933,0.8,527999338709570304,10154672472108472320,4825364888388749376,9316081904765796352,5259721898208434560 -59,"Title 59",no,0.6779834303627407,0.32201656963725933,0.8,543404908122179520,10959524621012686848,4470996844703678912,9979396301435740160,4910116656350279680 -75,"Title 75",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -69,"Title 69",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -60,"Title 60",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -78,"Title 78",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -68,"Title 68",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -73,"Title 73",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -80,"Title 80",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -55,"Title 55",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -71,"Title 71",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -57,"Title 57",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -72,"Title 72",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -64,"Title 64",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -74,"Title 74",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -63,"Title 63",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -54,"Title 54",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -62,"Title 62",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -66,"Title 66",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -76,"Title 76",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -65,"Title 65",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -58,"Title 58",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -100,"Title 100",no,0.32501656963725933,0.6749834303627407,0.8,191338244671530176,8243171459364809728,5944314059406423040,8469224664398373952,5785653580070756352 -91,"Title 91",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -97,"Title 97",no,0.6749834303627407,0.32501656963725933,0.8,503105666903774656,11807257176825604096,4149990066801756160,10921511484336023552,4486558483253655232 -92,"Title 92",no,0.6749834303627407,0.32501656963725933,0.8,504032955833970944,11859795866068922368,4131605683044666368,10966828413830012928,4468019207650521280 -93,"Title 93",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -96,"Title 96",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -95,"Title 95",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -98,"Title 98",no,0.6749834303627407,0.32501656963725933,0.8,545400295136234368,15171500643729242112,3229739835937252352,13774935604965179392,3557185413072852416 -94,"Title 94",no,0.6749834303627407,0.32501656963725933,0.8,545392198022729472,15173504132599259136,3229313385477437440,13776664812430288896,3556738925359402752 -99,"Title 99",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -82,"Title 82",no,0.32401656963725933,0.6759834303627407,0.8,190085280539403360,8499974432269035264,5764723222457933824,8731696011430864672,5611739109544465408 -79,"Title 79",no,0.32301656963725933,0.6769834303627407,0.8,288911245874444352,7834324181267787072,6254528006022670336,8154611205350369408,6008870167574675456 -77,"Title 77",no,0.6769834303627407,0.32301656963725933,0.8,519618203914721024,10739474221423917056,4562606975884451264,9881163467720761344,4958930206961001600 -67,"Title 67",no,0.32201656963725933,0.6779834303627407,0.8,201860760734197120,8916637813297370016,5495344885145651200,9174378680729432384,5340961138101194752 -70,"Title 70",no,0.6779834303627407,0.32201656963725933,0.8,470204024448095232,8297002662957863936,5905747170452469376,7745088091283166208,6326590404458775424 -61,"Title 61",no,0.6779834303627407,0.32201656963725933,0.8,558121186849297152,12040121700498868224,4069726305006513792,10851676374942615552,4515431377325710336 -85,"Title 85",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -75,"Title 75",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -88,"Title 88",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -69,"Title 69",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -78,"Title 78",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -68,"Title 68",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -73,"Title 73",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -80,"Title 80",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -81,"Title 81",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -90,"Title 90",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -71,"Title 71",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -72,"Title 72",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -64,"Title 64",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -74,"Title 74",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -83,"Title 83",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -63,"Title 63",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -62,"Title 62",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -86,"Title 86",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -87,"Title 87",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -66,"Title 66",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -76,"Title 76",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -65,"Title 65",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -84,"Title 84",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -89,"Title 89",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -106,"Title 106",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -103,"Title 103",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -105,"Title 105",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -110,"Title 110",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -107,"Title 107",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -102,"Title 102",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -109,"Title 109",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -108,"Title 108",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -101,"Title 101",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -104,"Title 104",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -100,"Title 100",no,0.32401656963725933,0.6759834303627407,0.8,192997543481345856,8469224664398373952,5785653580070756352,8703491054292898528,5629924784702490624 -97,"Title 97",no,0.6759834303627407,0.32401656963725933,0.8,503283903681319040,10921511484336023552,4486558483253655232,10101943353020090368,4850551848061086272 -92,"Title 92",no,0.6759834303627407,0.32401656963725933,0.8,504207302533643648,10966828413830012928,4468019207650521280,10140831639252604928,4831950844182575744 -98,"Title 98",no,0.6759834303627407,0.32401656963725933,0.8,545437043651354560,13774935604965179392,3557185413072852416,12506849420710223872,3917853198013273408 -94,"Title 94",no,0.6759834303627407,0.32401656963725933,0.8,545429750933610688,13776664812430288896,3556738925359402752,12508336153189015552,3917387524599536576 -82,"Title 82",no,0.32301656963725933,0.6769834303627407,0.8,191797384253261568,8731696011430864672,5611739109544465408,8971878676575845824,5461509430341634048 -79,"Title 79",no,0.32201656963725933,0.6779834303627407,0.8,290193117506619968,8154611205350369408,6008870167574675456,8489471554998230144,5771855136395496448 -77,"Title 77",no,0.6779834303627407,0.32201656963725933,0.8,519813311064011392,9881163467720761344,4958930206961001600,9091177050021970944,5389841131724696128 -85,"Title 85",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -75,"Title 75",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -88,"Title 88",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -78,"Title 78",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -91,"Title 91",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -73,"Title 73",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -80,"Title 80",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -93,"Title 93",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -81,"Title 81",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -90,"Title 90",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -96,"Title 96",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -71,"Title 71",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -72,"Title 72",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -95,"Title 95",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -74,"Title 74",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -83,"Title 83",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -86,"Title 86",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -87,"Title 87",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -76,"Title 76",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -99,"Title 99",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -84,"Title 84",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -89,"Title 89",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -111,"Title 111",no,0.32501656963725933,0.6749834303627407,0.8,295842743389433536,7104004906808017920,6897517758333975552,7401273180105410880,6620482558556517376 -112,"Title 112",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -114,"Title 114",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -119,"Title 119",no,0.6749834303627407,0.32501656963725933,0.8,454863412387138304,9858898453915510784,4970129292744607744,9229967494812794880,5308794427232578368 -113,"Title 113",no,0.6749834303627407,0.32501656963725933,0.8,465012083759438144,10202362212492615680,4802809288617527296,9530572555644680192,5141349033744958720 -118,"Title 118",no,0.6749834303627407,0.32501656963725933,0.8,523229894154246016,13234944940889776128,3702319897728699392,12147443516155355136,4033770557140933312 -115,"Title 115",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -116,"Title 116",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -120,"Title 120",no,0.6749834303627407,0.32501656963725933,0.8,553709412993698560,16517887382169937920,2966481055736736256,14894563631532220416,3289790907084084032 -117,"Title 117",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -100,"Title 100",no,0.32301656963725933,0.6769834303627407,0.8,194741873167672928,8703491054292898528,5629924784702490624,8946413352104257280,5477055225541850112 -97,"Title 97",no,0.6769834303627407,0.32301656963725933,0.8,503676023655255616,10101943353020090368,4850551848061086272,9343330684956381184,5244382506860695808 -92,"Title 92",no,0.6769834303627407,0.32301656963725933,0.8,504595747148004800,10140831639252604928,4831950844182575744,9376503004007161856,5225828859550224128 -98,"Title 98",no,0.6769834303627407,0.32301656963725933,0.8,545636102164905216,12506849420710223872,3917853198013273408,11355118591576872960,4315234544212314624 -94,"Title 94",no,0.6769834303627407,0.32301656963725933,0.8,545629459662050368,12508336153189015552,3917387524599536576,11356391519251191808,4314750853467486528 -82,"Title 82",no,0.32201656963725933,0.6779834303627407,0.8,193553027505018848,8971878676575845824,5461509430341634048,9220927063412491744,5313999304302708736 -106,"Title 106",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -85,"Title 85",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -88,"Title 88",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -91,"Title 91",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -103,"Title 103",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -105,"Title 105",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -110,"Title 110",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -107,"Title 107",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -93,"Title 93",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -81,"Title 81",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -90,"Title 90",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -96,"Title 96",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -102,"Title 102",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -95,"Title 95",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -109,"Title 109",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -83,"Title 83",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -86,"Title 86",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -108,"Title 108",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -87,"Title 87",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -99,"Title 99",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -101,"Title 101",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -84,"Title 84",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -104,"Title 104",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -89,"Title 89",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -130,"Title 130",no,0.32501656963725933,0.6749834303627407,0.8,296797390709481216,7087450401950873600,6913628628217614336,7384973533960578496,6635094868609661952 -127,"Title 127",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -125,"Title 125",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -121,"Title 121",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -122,"Title 122",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -126,"Title 126",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -128,"Title 128",no,0.6749834303627407,0.32501656963725933,0.8,508718231671293440,12286527214538981376,3988108205385893376,11338233068204034048,4321661030007522496 -124,"Title 124",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -123,"Title 123",no,0.6749834303627407,0.32501656963725933,0.8,525367025546955072,13477294399218255872,3635744575175431680,12355153918871894016,3965956257748832512 -129,"Title 129",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -111,"Title 111",no,0.32401656963725933,0.6759834303627407,0.8,297044941977259968,7401273180105410880,6620482558556517376,7712239234042235840,6353537346677653504 -119,"Title 119",no,0.6759834303627407,0.32401656963725933,0.8,455344930078725248,9229967494812794880,5308794427232578368,8640574561730020352,5670919179035381248 -113,"Title 113",no,0.6759834303627407,0.32401656963725933,0.8,465445438378270912,9530572555644680192,5141349033744958720,8902471595267934208,5504089451523294976 -118,"Title 118",no,0.6759834303627407,0.32401656963725933,0.8,523382073211623552,12147443516155355136,4033770557140933312,11149034488210706432,4394999410201299712 -120,"Title 120",no,0.6759834303627407,0.32401656963725933,0.8,553757609621154496,14894563631532220416,3289790907084084032,13430659920283152384,3648368754092237568 -100,"Title 100",no,0.32201656963725933,0.6779834303627407,0.8,196452154896841600,8946413352104257280,5477055225541850112,9198308793000606912,5327066214311726080 -97,"Title 97",no,0.6779834303627407,0.32201656963725933,0.8,503992513422776640,9343330684956381184,5244382506860695808,8641278821149504512,5670457002275248000 -92,"Title 92",no,0.6779834303627407,0.32201656963725933,0.8,504908489103462336,9376503004007161856,5225828859550224128,8669377901608602624,5652077987153847424 -98,"Title 98",no,0.6779834303627407,0.32201656963725933,0.8,545754079374863872,11355118591576872960,4315234544212314624,10309243088661403648,4753016257216064768 -94,"Title 94",no,0.6779834303627407,0.32201656963725933,0.8,545748140767885696,11356391519251191808,4314750853467486528,10310327719189071872,4752516247257944256 -112,"Title 112",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -106,"Title 106",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -114,"Title 114",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -91,"Title 91",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -103,"Title 103",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -105,"Title 105",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -110,"Title 110",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -107,"Title 107",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -93,"Title 93",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -96,"Title 96",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -102,"Title 102",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -95,"Title 95",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -109,"Title 109",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -108,"Title 108",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -115,"Title 115",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -116,"Title 116",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -99,"Title 99",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -101,"Title 101",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -104,"Title 104",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -117,"Title 117",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -136,"Title 136",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -139,"Title 139",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -131,"Title 131",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -137,"Title 137",no,0.6749834303627407,0.32501656963725933,0.8,528221965814412544,13780831210770843648,3555663606249128448,12613922139191943168,3884596674951331008 -135,"Title 135",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -134,"Title 134",no,0.6749834303627407,0.32501656963725933,0.8,538788573102651328,14819200625850836992,3306521130061743104,13488482989198520320,3632728753799730176 -138,"Title 138",no,0.6749834303627407,0.32501656963725933,0.8,540633175005209152,15027388154496901120,3260713005894966272,13662747034191409152,3586394440106086976 -132,"Title 132",no,0.6749834303627407,0.32501656963725933,0.8,543615382563203136,15381686148510375936,3185606540590178304,13958421244303314944,3510425652184539968 -140,"Title 140",no,0.6749834303627407,0.32501656963725933,0.8,549143479733772672,16107854147524327424,3041994268835056128,14560993152874414080,3365155074626701824 -133,"Title 133",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -130,"Title 130",no,0.32401656963725933,0.6759834303627407,0.8,298004099176861376,7384973533960578496,6635094868609661952,7696246788996648448,6366739703572846592 -128,"Title 128",no,0.6759834303627407,0.32401656963725933,0.8,509015254383864448,11338233068204034048,4321661030007522496,10462658320376338432,4683322201640766912 -123,"Title 123",no,0.6759834303627407,0.32401656963725933,0.8,525606498930180288,12355153918871894016,3965956257748832512,11326014749984110592,4326323166766910784 -111,"Title 111",no,0.32301656963725933,0.6769834303627407,0.8,298336903633848576,7712239234042235840,6353537346677653504,8037679928198168576,6096286545088202752 -119,"Title 119",no,0.6769834303627407,0.32301656963725933,0.8,455932053252377728,8640574561730020352,5670919179035381248,8088152215646332928,6058244045557241152 -113,"Title 113",no,0.6769834303627407,0.32301656963725933,0.8,465986837622109568,8902471595267934208,5504089451523294976,8315127452054125568,5892874196161033088 -118,"Title 118",no,0.6769834303627407,0.32301656963725933,0.8,523656771019380672,11149034488210706432,4394999410201299712,10232244174719862784,4788783297515622784 -120,"Title 120",no,0.6769834303627407,0.32301656963725933,0.8,553891582504553728,13430659920283152384,3648368754092237568,12110347188093468672,4046126773985087168 -112,"Title 112",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -106,"Title 106",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -114,"Title 114",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -127,"Title 127",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -103,"Title 103",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -125,"Title 125",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -105,"Title 105",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -110,"Title 110",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -107,"Title 107",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -121,"Title 121",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -122,"Title 122",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -126,"Title 126",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -124,"Title 124",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -102,"Title 102",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -129,"Title 129",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -109,"Title 109",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -108,"Title 108",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -115,"Title 115",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -116,"Title 116",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -101,"Title 101",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -104,"Title 104",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -117,"Title 117",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -142,"Title 142",no,0.6749834303627407,0.32501656963725933,0.8,452540629167658624,9851122380846798848,4974052509515973632,9225845059370037248,5311166585247837312 -147,"Title 147",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -144,"Title 144",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -141,"Title 141",no,0.6749834303627407,0.32501656963725933,0.8,503003564915713856,12032523120864309248,4072296351131405312,11122333350502473728,4405550387301268928 -145,"Title 145",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -148,"Title 148",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -150,"Title 150",no,0.6749834303627407,0.32501656963725933,0.8,532322866379054464,14239625104033593344,3441101829718817280,13003286346264690688,3768278164087010624 -146,"Title 146",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -149,"Title 149",no,0.6749834303627407,0.32501656963725933,0.8,533880896703812288,14397375858968385536,3403397985854277632,13136235806765076480,3730140104120643328 -143,"Title 143",no,0.6749834303627407,0.32501656963725933,0.8,539023948456985856,14945226534523643904,3278638827374709760,13596045331188692992,3603989160553641536 -137,"Title 137",no,0.6759834303627407,0.32401656963725933,0.8,528408951124798720,12613922139191943168,3884596674951331008,11545476478300008448,4244086425718041728 -134,"Title 134",no,0.6759834303627407,0.32401656963725933,0.8,538946161444443328,13488482989198520320,3632728753799730176,12276937167706716160,3991223489266501248 -138,"Title 138",no,0.6759834303627407,0.32401656963725933,0.8,540782690286051392,13662747034191409152,3586394440106086976,12421717377033363456,3944704142971130944 -132,"Title 132",no,0.6759834303627407,0.32401656963725933,0.8,543751459222903104,13958421244303314944,3510425652184539968,12666557427750457344,3868454414665868160 -140,"Title 140",no,0.6759834303627407,0.32401656963725933,0.8,549254101443175808,14560993152874414080,3365155074626701824,13162424874574190592,3722718303574375680 -130,"Title 130",no,0.32301656963725933,0.6769834303627407,0.8,299280358168169536,7696246788996648448,6366739703572846592,8022029344948545856,6108180099198363648 -128,"Title 128",no,0.6769834303627407,0.32301656963725933,0.8,509338372041449344,10462658320376338432,4683322201640766912,9654225009809059840,5075498028087612800 -123,"Title 123",no,0.6769834303627407,0.32301656963725933,0.8,525852832074572416,11326014749984110592,4326323166766910784,10382193812262152192,4719619079170657280 -111,"Title 111",no,0.32201656963725933,0.6779834303627407,0.8,299617720948975424,8037679928198168576,6096286545088202752,8378309690014730880,5848435043932334080 -119,"Title 119",no,0.6779834303627407,0.32201656963725933,0.8,456506344566249344,8088152215646332928,6058244045557241152,7570438522964114432,6472544470358454592 -113,"Title 113",no,0.6779834303627407,0.32201656963725933,0.8,466515307506865408,8315127452054125568,5892874196161033088,7765952511663468544,6309593050744033472 -118,"Title 118",no,0.6779834303627407,0.32201656963725933,0.8,523918002130273728,10232244174719862784,4788783297515622784,9390456746840549376,5218063542701075328 -120,"Title 120",no,0.6779834303627407,0.32201656963725933,0.8,554011816783647872,12110347188093468672,4046126773985087168,10919595932027172864,4487345530458962112 -112,"Title 112",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -114,"Title 114",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -127,"Title 127",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -125,"Title 125",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -136,"Title 136",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -121,"Title 121",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -122,"Title 122",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -126,"Title 126",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -139,"Title 139",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -131,"Title 131",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -124,"Title 124",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -129,"Title 129",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -135,"Title 135",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -115,"Title 115",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -116,"Title 116",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -133,"Title 133",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -117,"Title 117",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -159,"Title 159",no,0.6749834303627407,0.32501656963725933,0.8,352948495462377216,7671136858131465216,6387579951472200704,7304965552162642944,6707766059963621376 -154,"Title 154",no,0.32501656963725933,0.6749834303627407,0.8,216474191809947680,7961385257369954304,6154707807242474496,8207149332127438560,5970404341028156416 -158,"Title 158",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -153,"Title 153",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -157,"Title 157",no,0.6749834303627407,0.32501656963725933,0.8,516746870408128512,12986170187237163008,3773244866924453376,11941443566487363584,4103356493474062400 -155,"Title 155",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -156,"Title 156",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -152,"Title 152",no,0.6749834303627407,0.32501656963725933,0.8,544643635158565376,15718020553524785152,3117440891054929408,14242072698392461312,3440510453617524096 -160,"Title 160",no,0.6749834303627407,0.32501656963725933,0.8,544944291161714368,15760241558475399168,3109089401846713856,14277176952757250048,3432051039371405888 -151,"Title 151",no,0.6749834303627407,0.32501656963725933,0.8,546466958429956672,15967659292525522944,3068702751125016064,14449207493870123008,3391189449026015552 -142,"Title 142",no,0.6759834303627407,0.32401656963725933,0.8,453046966669553216,9225845059370037248,5311166585247837312,8639642205258778624,5671531162502848512 -141,"Title 141",no,0.6759834303627407,0.32401656963725933,0.8,503306319024266368,11122333350502473728,4405550387301268928,10280526026849230848,4766293074112034176 -150,"Title 150",no,0.6759834303627407,0.32401656963725933,0.8,532525962540591616,13003286346264690688,3768278164087010624,11873897920290648064,4126698774819902400 -149,"Title 149",no,0.6759834303627407,0.32401656963725933,0.8,534096635498009280,13136235806765076480,3730140104120643328,11985141249585977344,4088395704280305728 -143,"Title 143",no,0.6759834303627407,0.32401656963725933,0.8,539216394685592768,13596045331188692992,3603989160553641536,12368262903032989696,3961752784862297664 -137,"Title 137",no,0.6769834303627407,0.32301656963725933,0.8,528654614841739136,11545476478300008448,4244086425718041728,10567115969285939200,4637026804893779136 -134,"Title 134",no,0.6769834303627407,0.32301656963725933,0.8,539143446993559104,12276937167706716160,3991223489266501248,11173845923534340096,4385240349233405824 -138,"Title 138",no,0.6769834303627407,0.32301656963725933,0.8,540972020552901760,12421717377033363456,3944704142971130944,11293055158915123200,4338949851078848832 -132,"Title 132",no,0.6769834303627407,0.32301656963725933,0.8,543927570250349504,12666557427750457344,3868454414665868160,11493912175733379072,4263126362097290752 -140,"Title 140",no,0.6769834303627407,0.32301656963725933,0.8,549405204263165504,13162424874574190592,3722718303574375680,11897873243109947392,4118383092404843840 -130,"Title 130",no,0.32201656963725933,0.6779834303627407,0.8,300563752712606272,8022029344948545856,6108180099198363648,8363058474666466880,5859100489184872448 -128,"Title 128",no,0.6779834303627407,0.32201656963725933,0.8,509679233013503424,9654225009809059840,5075498028087612800,8907797461222512640,5500798622028301504 -123,"Title 123",no,0.6779834303627407,0.32201656963725933,0.8,526117735213750144,10382193812262152192,4719619079170657280,9516623982590197760,5148884739970924544 -127,"Title 127",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -147,"Title 147",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -144,"Title 144",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -125,"Title 125",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -136,"Title 136",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -121,"Title 121",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -122,"Title 122",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -126,"Title 126",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -145,"Title 145",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -139,"Title 139",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -131,"Title 131",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -124,"Title 124",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -148,"Title 148",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -146,"Title 146",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -129,"Title 129",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -135,"Title 135",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -133,"Title 133",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -166,"Title 166",no,0.32501656963725933,0.6749834303627407,0.8,279379823539297088,7267540224288700416,6742308743780746240,7554899390743414496,6485857384154828800 -170,"Title 170",no,0.32501656963725933,0.6749834303627407,0.8,254763950139964832,7543730464011589632,6495460068962072576,7816298750398138144,6268951784564797440 -161,"Title 161",no,0.6749834303627407,0.32501656963725933,0.8,419635743645878848,8967667682740025344,5464074019414188032,8450666762698712064,5798359037926601152 -168,"Title 168",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -164,"Title 164",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -165,"Title 165",no,0.6749834303627407,0.32501656963725933,0.8,529989827995739136,14163356610676645888,3459631875897464832,12942218107019892736,3786058896150287808 -167,"Title 167",no,0.6749834303627407,0.32501656963725933,0.8,535414937230010176,14715601305858682880,3329799372893567488,13407026376810393600,3654799999853313984 -163,"Title 163",no,0.6749834303627407,0.32501656963725933,0.8,540271169716176640,15269176675476613120,3209079378765555200,13870334179215032320,3532719498094534400 -162,"Title 162",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -169,"Title 169",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -159,"Title 159",no,0.6759834303627407,0.32401656963725933,0.8,353935755646832896,7304965552162642944,6707766059963621376,6955344262035572736,7044942443389495360 -154,"Title 154",no,0.32401656963725933,0.6759834303627407,0.8,218063849432810304,8207149332127438560,5970404341028156416,8462360480537713280,5790346572057923584 -157,"Title 157",no,0.6759834303627407,0.32401656963725933,0.8,517008237855946752,11941443566487363584,4103356493474062400,10980317539013502976,4462530325366370688 -152,"Title 152",no,0.6759834303627407,0.32401656963725933,0.8,544812904247803840,14242072698392461312,3440510453617524096,12904342167745286144,3797171476317226112 -160,"Title 160",no,0.6759834303627407,0.32401656963725933,0.8,545112747058491392,14277176952757250048,3432051039371405888,12933294942523981824,3788671039959865280 -151,"Title 151",no,0.6759834303627407,0.32401656963725933,0.8,546628937807438720,14449207493870123008,3391189449026015552,13074785012667248640,3747671564199893952 -142,"Title 142",no,0.6769834303627407,0.32301656963725933,0.8,453642449069383552,8639642205258778624,5671531162502848512,8090010572175313920,6056852406167429824 -141,"Title 141",no,0.6769834303627407,0.32301656963725933,0.8,503672239480821952,10280526026849230848,4766293074112034176,9501909058222727168,5156858448102758272 -150,"Title 150",no,0.6769834303627407,0.32301656963725933,0.8,532757526781256960,11873897920290648064,4126698774819902400,10842191997959016448,4519381321528339200 -149,"Title 149",no,0.6769834303627407,0.32301656963725933,0.8,534321491674771328,11985141249585977344,4088395704280305728,10934510758497878016,4481224728039991040 -143,"Title 143",no,0.6769834303627407,0.32301656963725933,0.8,539418109682256704,12368262903032989696,3961752784862297664,11250974525234911232,4355178290564737920 -137,"Title 137",no,0.6779834303627407,0.32201656963725933,0.8,528909168451718784,10567115969285939200,4637026804893779136,9671266842679148544,5066554443908400896 -134,"Title 134",no,0.6779834303627407,0.32201656963725933,0.8,539349951267092096,11173845923534340096,4385240349233405824,10169518203325898752,4818320693302339072 -138,"Title 138",no,0.6779834303627407,0.32201656963725933,0.8,541170611448470720,11293055158915123200,4338949851078848832,10266603012198787072,4772756864347258368 -132,"Title 132",no,0.6779834303627407,0.32201656963725933,0.8,544113020946415808,11493912175733379072,4263126362097290752,10429498941228642304,4698212280006960448 -140,"Title 140",no,0.6779834303627407,0.32201656963725933,0.8,549565808935779200,11897873243109947392,4118383092404843840,10754508652530231296,4556228609149120448 -147,"Title 147",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -144,"Title 144",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -158,"Title 158",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -136,"Title 136",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -153,"Title 153",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -145,"Title 145",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -139,"Title 139",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -131,"Title 131",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -155,"Title 155",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -148,"Title 148",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -146,"Title 146",no,0.32301656963725933,0.6769834303627407,0.8,None,None,None,None,None -135,"Title 135",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -156,"Title 156",no,0.32401656963725933,0.6759834303627407,0.8,None,None,None,None,None -133,"Title 133",no,0.32201656963725933,0.6779834303627407,0.8,None,None,None,None,None -173,"Title 173",no,0.32501656963725933,0.6749834303627407,0.8,212730115480725344,7994560981048842240,6129167081989218304,8237211967639698240,5948614675997043712 -177,"Title 177",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -178,"Title 178",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -174,"Title 174",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -171,"Title 171",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -179,"Title 179",no,0.6749834303627407,0.32501656963725933,0.8,483853061837172800,11145393978585733120,4396434984186869248,10358490929905666048,4730418777365887360 -175,"Title 175",no,0.6749834303627407,0.32501656963725933,0.8,510594201626150144,12656241851892482048,3871607430816680448,11662037257156685824,4201667248998881856 -172,"Title 172",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -176,"Title 176",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -180,"Title 180",no,0.32501656963725933,0.6749834303627407,0.8,None,None,None,None,None -166,"Title 166",no,0.32401656963725933,0.6759834303627407,0.8,280707407418644064,7554899390743414496,6485857384154828800,7855040256301418592,6238032957334818816 -170,"Title 170",no,0.32401656963725933,0.6759834303627407,0.8,256198313976230720,7816298750398138144,6268951784564797440,8100305462929005376,6049154593520970752 -161,"Title 161",no,0.6759834303627407,0.32401656963725933,0.8,420335517994455232,8450666762698712064,5798359037926601152,7962706280785418240,6153686733145051904 \ No newline at end of file diff --git a/trader_backup/data/bets.json b/trader_backup/data/bets.json deleted file mode 100644 index 64a48ad7f..000000000 --- a/trader_backup/data/bets.json +++ /dev/null @@ -1,6272 +0,0 @@ -[ - { - "id": "1", - "market": "omen_subgraph", - "title": "Title 1", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736964900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2813634805420204e+19, - 3.824051546971891e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2298427477220765, - 0.7701572522779235 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.890242063970029, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "2", - "market": "omen_subgraph", - "title": "Title 2", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736964900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.366094026345333e+18, - 5.23163656719341e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3583869789670622, - 0.6416130210329378 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.713372285646703, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "3", - "market": "omen_subgraph", - "title": "Title 3", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736964900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.598859870757257e+18, - 5.698429877504774e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3985671394956147, - 0.6014328605043854 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.854445963222702, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "4", - "market": "omen_subgraph", - "title": "Title 4", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736964900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.512953316229938e+18, - 5.755934301505159e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.4033905414148044, - 0.5966094585851957 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.8680896945458985, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "5", - "market": "omen_subgraph", - "title": "Title 5", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736964900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.263810620031016e+18, - 5.929467923820366e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.4177659097931992, - 0.5822340902068008 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.904676724071918, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "6", - "market": "omen_subgraph", - "title": "Title 6", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736964900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0256678737079947e+19, - 4.777374943299646e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3177702464595047, - 0.6822297535404953 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.518534660275712, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "7", - "market": "omen_subgraph", - "title": "Title 7", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736964900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.390394608455891e+19, - 3.5241793733950945e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.20221218752970924, - 0.7977878124702908 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.623094706107586, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "8", - "market": "omen_subgraph", - "title": "Title 8", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736964900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0570224480919759e+19, - 4.635663139269139e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3048597526864763, - 0.6951402473135236 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.44487204218747, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "9", - "market": "omen_subgraph", - "title": "Title 9", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736964900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5865383698375485e+19, - 3.0884850269973166e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.16294747377156216, - 0.837052526228438 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.170448388133618, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "10", - "market": "omen_subgraph", - "title": "Title 10", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736964900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.007865773418682e+18, - 5.43969029207719e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.37651283493326854, - 0.6234871650667314 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.783154158096456, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "11", - "market": "omen_subgraph", - "title": "Title 11", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737051300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.100035237646221e+18, - 6.049356399372757e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.4275347346769212, - 0.5724652653230787 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.926092832401579, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "12", - "market": "omen_subgraph", - "title": "Title 12", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737051300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2246997212151214e+19, - 4.000980742559753e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.24624484066337016, - 0.7537551593366297 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.031519754221828, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "13", - "market": "omen_subgraph", - "title": "Title 13", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737051300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5629564487607745e+19, - 3.1350841566219433e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1670739599798482, - 0.8329260400201518 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.222586463410066, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "14", - "market": "omen_subgraph", - "title": "Title 14", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737051300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.604561696515115e+18, - 5.101742437427311e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3469085360238398, - 0.6530914639761601 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.663808874577411, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "15", - "market": "omen_subgraph", - "title": "Title 15", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737051300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.1966905935401406e+19, - 4.094625650482009e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.25493369848245373, - 0.7450663015175464 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.1015351790070165, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "16", - "market": "omen_subgraph", - "title": "Title 16", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737051300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.12624346495566e+19, - 4.3507466657690317e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.27865856278107864, - 0.7213414372189214 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.276747705722528, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "17", - "market": "omen_subgraph", - "title": "Title 17", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737051300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2271335959240585e+19, - 3.993045269297018e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.24550858794989333, - 0.7544914120501067 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.025436727223811, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "18", - "market": "omen_subgraph", - "title": "Title 18", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737051300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2708385513869185e+19, - 3.85572187328786e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.23277571094941032, - 0.7672242890505898 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.916406946020174, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "19", - "market": "omen_subgraph", - "title": "Title 19", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737051300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.089733513856461e+19, - 4.49651216347323e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2920980100197551, - 0.7079019899802448 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.36617981698615, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "20", - "market": "omen_subgraph", - "title": "Title 20", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737051300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.790834981644234e+18, - 6.289441390486066e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.44668451273691123, - 0.5533154872630889 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.960090655178875, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "21", - "market": "omen_subgraph", - "title": "Title 21", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737137700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5625841572839385e+19, - 3.135831102061799e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.16714027349260932, - 0.8328597265073906 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.223414868073118, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "22", - "market": "omen_subgraph", - "title": "Title 22", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737137700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.63612693380032e+18, - 5.673839717225832e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.39649566316906604, - 0.6035043368309341 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.848373751658781, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "23", - "market": "omen_subgraph", - "title": "Title 23", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737137700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4991302802086074e+19, - 3.2685618219372856e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.17900252215654675, - 0.8209974778434532 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.366962023971828, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "24", - "market": "omen_subgraph", - "title": "Title 24", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737137700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.863689419814089e+18, - 4.967715214306044e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.334945700481912, - 0.6650542995180879 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.607600724111308, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "25", - "market": "omen_subgraph", - "title": "Title 25", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737137700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.671167011325688e+18, - 5.066606743800122e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.343783723918136, - 0.656216276081864 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.649579619575549, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "26", - "market": "omen_subgraph", - "title": "Title 26", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737137700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4135924365264607e+19, - 3.4663456547917645e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.19692605844826502, - 0.8030739415517348 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.567463735548703, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "27", - "market": "omen_subgraph", - "title": "Title 27", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737137700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5766323091329456e+19, - 3.107890134951446e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1646632947128067, - 0.8353367052871934 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.192269411449823, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "28", - "market": "omen_subgraph", - "title": "Title 28", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737137700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6867470973942424e+19, - 2.9049998115127777e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1469214365282927, - 0.8530785634717073 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 4.956386132181803, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "29", - "market": "omen_subgraph", - "title": "Title 29", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737137700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.1558677932560507e+19, - 4.23923914879298e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2683416507988016, - 0.7316583492011984 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.203349434949931, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "30", - "market": "omen_subgraph", - "title": "Title 30", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737137700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4808773192179548e+19, - 3.308849380303609e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1826315437947721, - 0.817368456205228 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.409098219588772, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "31", - "market": "omen_subgraph", - "title": "Title 31", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737224100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4346934595961868e+19, - 3.4153637261155205e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.19228163293882097, - 0.8077183670611789 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.517304023556024, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "32", - "market": "omen_subgraph", - "title": "Title 32", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737224100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.1710182389367572e+19, - 4.184392554337177e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2632591666752598, - 0.7367408333247402 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.165625714880419, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "33", - "market": "omen_subgraph", - "title": "Title 33", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737224100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.182209030828339e+19, - 4.144783090150068e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.25958639407491774, - 0.7404136059250823 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.1377075871106355, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "34", - "market": "omen_subgraph", - "title": "Title 34", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737224100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6279523091965841e+19, - 3.009916182629585e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1560395893204477, - 0.8439604106795523 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.08050019520619, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "35", - "market": "omen_subgraph", - "title": "Title 35", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737224100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4485777615611154e+19, - 3.3826282095614444e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.18930777835793697, - 0.810692221642063 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.484540756396962, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "36", - "market": "omen_subgraph", - "title": "Title 36", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737224100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.584261825207214e+18, - 5.708120394943476e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3993820139301657, - 0.6006179860698343 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.8567995517101945, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "37", - "market": "omen_subgraph", - "title": "Title 37", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737224100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.340803845760638e+18, - 5.874733527620977e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.4132614457910912, - 0.5867385542089089 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.893865312717869, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "38", - "market": "omen_subgraph", - "title": "Title 38", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737224100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.10845310752514e+19, - 4.420574913575102e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.28510446279830115, - 0.7148955372016988 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.320498555161253, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "39", - "market": "omen_subgraph", - "title": "Title 39", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737224100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4524391591750711e+19, - 3.3736352872660147e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.18849202261625803, - 0.811507977383742 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.475463896799326, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "40", - "market": "omen_subgraph", - "title": "Title 40", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737224100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.11362134992071e+18, - 5.376567460796066e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.37104882006917805, - 0.628951179930822 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.7631968968906975, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "41", - "market": "omen_subgraph", - "title": "Title 41", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737310500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.012328742313648e+19, - 4.840324881817731e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3234730212981512, - 0.6765269787018489 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.549220736463066, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "42", - "market": "omen_subgraph", - "title": "Title 42", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737310500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.001834178053283e+18, - 5.443335106023541e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3768273669193915, - 0.6231726330806086 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.784274941521607, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "43", - "market": "omen_subgraph", - "title": "Title 43", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737310500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6333430616782567e+19, - 2.999982131717791e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1551708521792404, - 0.8448291478207597 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.068944695633295, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "44", - "market": "omen_subgraph", - "title": "Title 44", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737310500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2016831254055174e+19, - 4.0776140534938916e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.25335536426230826, - 0.7466446357376917 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.089057319299679, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "45", - "market": "omen_subgraph", - "title": "Title 45", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737310500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.3004618776674914e+19, - 3.7678920729215386e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.22464687050789384, - 0.7753531294921062 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.842893820656428, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "46", - "market": "omen_subgraph", - "title": "Title 46", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737310500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5330127508646089e+19, - 3.196320446282285e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.17252742965399395, - 0.8274725703460061 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.289734990669391, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "47", - "market": "omen_subgraph", - "title": "Title 47", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737310500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.3068779519420635e+19, - 3.7493937308517903e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.22293703811090518, - 0.7770629618890947 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.827029995568191, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "48", - "market": "omen_subgraph", - "title": "Title 48", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737310500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4315891908879098e+19, - 3.4227696263624965e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.19295534894571623, - 0.8070446510542837 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.524655837493844, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "49", - "market": "omen_subgraph", - "title": "Title 49", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737310500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.1075469992930327e+19, - 4.4241914818312535e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.28543794256637517, - 0.7145620574336248 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.322718735475316, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "50", - "market": "omen_subgraph", - "title": "Title 50", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737310500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.186988312862734e+19, - 4.128094562432855e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2580385247530173, - 0.7419614752469826 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.125774263003456, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "51", - "market": "omen_subgraph", - "title": "Title 51", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737396900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2061683852704938e+19, - 4.06245103074985e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2519484648393999, - 0.7480515351606002 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.077845460134376, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "52", - "market": "omen_subgraph", - "title": "Title 52", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737396900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2037394010939935e+19, - 4.070648510422386e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2527090740556423, - 0.7472909259443576 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.083917389095131, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "53", - "market": "omen_subgraph", - "title": "Title 53", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737396900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.3149923766657468e+19, - 3.7262573433499935e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.22079979582231124, - 0.7792002041776889 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.807000965513854, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "54", - "market": "omen_subgraph", - "title": "Title 54", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737396900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5300849250584703e+19, - 3.20243662279906e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.17307394182379449, - 0.8269260581762055 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.296356586100693, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "55", - "market": "omen_subgraph", - "title": "Title 55", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737396900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2833887689076892e+19, - 3.818016893018676e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.22928409625430343, - 0.7707159037456967 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.885212680438452, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "56", - "market": "omen_subgraph", - "title": "Title 56", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737396900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.211919973071384e+18, - 6.794307227889563e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.48509189022889865, - 0.5149081097711012 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.996887783833491, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "57", - "market": "omen_subgraph", - "title": "Title 57", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737396900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4316395119805708e+19, - 3.4226493184874455e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.19294440184720413, - 0.8070555981527959 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.524536585998289, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "58", - "market": "omen_subgraph", - "title": "Title 58", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737396900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6156478665518563e+19, - 3.0328390866864236e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.15804830196935632, - 0.8419516980306437 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.107008037778682, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "59", - "market": "omen_subgraph", - "title": "Title 59", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737396900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4515847701883136e+19, - 3.375620976902592e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1886721005137568, - 0.8113278994862432 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.477470953304161, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "60", - "market": "omen_subgraph", - "title": "Title 60", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737396900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.832136567363832e+18, - 4.983657383548503e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3363746418221223, - 0.6636253581778777 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.614562832386401, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "61", - "market": "omen_subgraph", - "title": "Title 61", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737483300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6444563612950866e+19, - 2.9797081365789604e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.15340127933759398, - 0.846598720662406 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.045234192750219, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "62", - "market": "omen_subgraph", - "title": "Title 62", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737483300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5353343726203232e+19, - 3.1914872013431654e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.17209578312210694, - 0.8279042168778932 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.2844914242076655, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "63", - "market": "omen_subgraph", - "title": "Title 63", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737483300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.510536555669154e+19, - 3.2438804487120435e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1767854901371298, - 0.8232145098628703 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.340818907280465, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "64", - "market": "omen_subgraph", - "title": "Title 64", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737483300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.439650307141676e+19, - 3.4036043167514783e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1912125720664955, - 0.8087874279335044 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.505584762097602, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "65", - "market": "omen_subgraph", - "title": "Title 65", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737483300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6099148002944545e+19, - 3.043639327437568e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.15899666411729463, - 0.8410033358827054 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.119421655197577, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "66", - "market": "omen_subgraph", - "title": "Title 66", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737483300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.591380331573304e+19, - 3.0790879482314947e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.16211791587905783, - 0.8378820841209422 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.159825254511761, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "67", - "market": "omen_subgraph", - "title": "Title 67", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737483300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.197517645263373e+18, - 5.977419277445875e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.4216893034542981, - 0.5783106965457019 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.913611011770859, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "68", - "market": "omen_subgraph", - "title": "Title 68", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737483300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0725366646360545e+19, - 4.568608385674838e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.29871948764825657, - 0.7012805123517434 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.4077520588810435, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "69", - "market": "omen_subgraph", - "title": "Title 69", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737483300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.622571724610181e+18, - 5.092193792089925e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.34606013845825023, - 0.6539398615417498 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.659977006686086, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "70", - "market": "omen_subgraph", - "title": "Title 70", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737483300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0196423869543354e+19, - 4.805606419164533e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3203304037308697, - 0.6796695962691304 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.532449149483798, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "71", - "market": "omen_subgraph", - "title": "Title 71", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737569700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4230297673099176e+19, - 3.4433573440019564e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.19482995117139854, - 0.8051700488286014 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.544976401608757, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "72", - "market": "omen_subgraph", - "title": "Title 72", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737569700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.433951012886407e+19, - 3.417132074921281e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.19244246945477217, - 0.8075575305452278 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.51906147994064, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "73", - "market": "omen_subgraph", - "title": "Title 73", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737569700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.1618928879007537e+19, - 4.217256212707403e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.26630505947507244, - 0.7336949405249276 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.188359092321478, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "74", - "market": "omen_subgraph", - "title": "Title 74", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737569700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.459899913888433e+19, - 3.356394471555852e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1869295958850088, - 0.8130704041149913 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.4579700187144775, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "75", - "market": "omen_subgraph", - "title": "Title 75", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737569700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.403916639263824e+18, - 5.21059489143195e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3565356858139125, - 0.6434643141860875 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.705663736633582, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "76", - "market": "omen_subgraph", - "title": "Title 76", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737569700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5991034686921757e+19, - 3.064216979034795e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.16080695404874754, - 0.8391930459512524 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.142939160183509, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "77", - "market": "omen_subgraph", - "title": "Title 77", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737569700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2685106274283008e+19, - 3.862797751985692e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2334312397421303, - 0.7665687602578697 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.9222001677331155, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "78", - "market": "omen_subgraph", - "title": "Title 78", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737569700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0115849293119484e+19, - 4.843883946880113e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3237948076459312, - 0.6762051923540687 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.550918952081704, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "79", - "market": "omen_subgraph", - "title": "Title 79", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737569700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.234739436966579e+18, - 6.772876953885846e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.48351388022796116, - 0.5164861197720388 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.996193875211932, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "80", - "market": "omen_subgraph", - "title": "Title 80", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737569700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2172356628365158e+19, - 4.0255146555446497e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.24852121522557127, - 0.7514787847744286 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.050177722880693, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "81", - "market": "omen_subgraph", - "title": "Title 81", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737656100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2772581331289022e+19, - 3.8363427665138125e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.23098081151573904, - 0.769019188484261 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.900442402103834, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "82", - "market": "omen_subgraph", - "title": "Title 82", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737656100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.276320206451292e+18, - 5.920505584330231e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.4170302341932388, - 0.5829697658067612 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.902951507909233, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "83", - "market": "omen_subgraph", - "title": "Title 83", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737656100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4631628025628092e+19, - 3.3489096301637683e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1862519182837129, - 0.8137480817162871 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.450337574773934, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "84", - "market": "omen_subgraph", - "title": "Title 84", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737656100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6562678166337485e+19, - 2.9584587412674094e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1515515594849845, - 0.8484484405150154 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.020199410712698, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "85", - "market": "omen_subgraph", - "title": "Title 85", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737656100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.75943145808947e+18, - 5.593970366050157e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.38973132882284306, - 0.6102686711771569 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.827649723787646, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "86", - "market": "omen_subgraph", - "title": "Title 86", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737656100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.541912073838939e+19, - 3.1778725150003794e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.17088098445274924, - 0.8291190155472508 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.269669062343562, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "87", - "market": "omen_subgraph", - "title": "Title 87", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737656100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5832118406519757e+19, - 3.0949743263555635e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.16352085183054887, - 0.8364791481694511 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.1777629762324455, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "88", - "market": "omen_subgraph", - "title": "Title 88", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737656100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.612411128821383e+18, - 5.09757638778899e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3465384577677484, - 0.6534615422322516 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.6621402560226075, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "89", - "market": "omen_subgraph", - "title": "Title 89", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737656100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6873390232729129e+19, - 2.9039807249259986e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.14683350639190845, - 0.8531664936080916 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 4.955158105181196, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "90", - "market": "omen_subgraph", - "title": "Title 90", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737656100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2891696413255619e+19, - 3.800896207082318e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.22769957271055535, - 0.7723004272894446 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.870867529625007, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "91", - "market": "omen_subgraph", - "title": "Title 91", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737742500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0466476967394759e+19, - 4.681613512612232e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.30905634731923465, - 0.6909436526807654 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.469462281687848, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "92", - "market": "omen_subgraph", - "title": "Title 92", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737742500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.1859795866068922e+19, - 4.1316056830446664e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.25836420093357504, - 0.741635799066425 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.128293364344428, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "93", - "market": "omen_subgraph", - "title": "Title 93", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737742500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2644544459399416e+19, - 3.875189031707306e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.23457939159814448, - 0.7654206084018557 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.932299092643207, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "94", - "market": "omen_subgraph", - "title": "Title 94", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737742500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.517350413259926e+19, - 3.2293133854774374e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.17547929181525337, - 0.8245207081847467 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.325271519088677, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "95", - "market": "omen_subgraph", - "title": "Title 95", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737742500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4470231522861453e+19, - 3.3862623360645693e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.18963758298899536, - 0.8103624170110048 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.488199462573231, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "96", - "market": "omen_subgraph", - "title": "Title 96", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737742500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.305886174286081e+19, - 3.752241272237066e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.22320018316866044, - 0.7767998168313395 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.829480665961491, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "97", - "market": "omen_subgraph", - "title": "Title 97", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737742500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.1807257176825604e+19, - 4.149990066801756e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2600692966300365, - 0.7399307033699635 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.1414101382139705, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "98", - "market": "omen_subgraph", - "title": "Title 98", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737742500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5171500643729242e+19, - 3.2297398359372524e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.17551750598043314, - 0.8244824940195669 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.325727909935785, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "99", - "market": "omen_subgraph", - "title": "Title 99", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737742500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6073688465767225e+19, - 3.0484602276793687e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.15942038086567725, - 0.8405796191343228 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.124947074257709, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "100", - "market": "omen_subgraph", - "title": "Title 100", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737742500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.24317145936481e+18, - 5.944314059406423e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.4189829164260007, - 0.5810170835739993 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.907496037288482, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "101", - "market": "omen_subgraph", - "title": "Title 101", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737828900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6516875718149663e+19, - 2.9666627536681206e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.15226509075645003, - 0.84773490924355 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.029887160474129, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "102", - "market": "omen_subgraph", - "title": "Title 102", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737828900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4425703781235565e+19, - 3.396714693652412e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.19058663101410322, - 0.8094133689858967 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.498692567346193, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "103", - "market": "omen_subgraph", - "title": "Title 103", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737828900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0862770327316847e+19, - 4.5108198483013704e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2934135616191536, - 0.7065864383808464 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.3745682615777906, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "104", - "market": "omen_subgraph", - "title": "Title 104", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737828900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6760798118532549e+19, - 2.9234884671643597e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1485188937092919, - 0.8514811062907081 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 4.97859038849847, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "105", - "market": "omen_subgraph", - "title": "Title 105", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737828900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.1718715231986405e+19, - 4.1813457388446285e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.26297671100226516, - 0.7370232889977348 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.163498377759863, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "106", - "market": "omen_subgraph", - "title": "Title 106", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737828900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.740613142595386e+18, - 5.606014040503597e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3907548421630243, - 0.6092451578369757 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.830873817885832, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "107", - "market": "omen_subgraph", - "title": "Title 107", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737828900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2114245196037997e+19, - 4.044824849345596e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.25031297209464987, - 0.7496870279053501 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.064705439407211, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "108", - "market": "omen_subgraph", - "title": "Title 108", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737828900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5699923080280502e+19, - 3.1210343993051295e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.16582761013569025, - 0.8341723898643096 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.206961447434161, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "109", - "market": "omen_subgraph", - "title": "Title 109", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737828900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4586089034871407e+19, - 3.35936520631776e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.18719867221901815, - 0.8128013277809818 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.460993000392614, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "110", - "market": "omen_subgraph", - "title": "Title 110", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737828900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.1745445959628857e+19, - 4.171829674958408e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.26209445452419494, - 0.737905545475805 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.156832503864669, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "111", - "market": "omen_subgraph", - "title": "Title 111", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737915300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.104004906808018e+18, - 6.897517758333976e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.4926262609641696, - 0.5073737390358303 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.9992387502238955, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "112", - "market": "omen_subgraph", - "title": "Title 112", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737915300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.645419410711965e+18, - 5.667741224825641e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3959811092145099, - 0.60401889078549 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.846845535756756, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "113", - "market": "omen_subgraph", - "title": "Title 113", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737915300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0202362212492616e+19, - 4.802809288617527e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.32007693402652515, - 0.6799230659734747 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.5310816336054245, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "114", - "market": "omen_subgraph", - "title": "Title 114", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737915300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.761440958643188e+18, - 5.019750691276103e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.33960392437665954, - 0.6603960756233405 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.630047314252577, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "115", - "market": "omen_subgraph", - "title": "Title 115", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737915300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5770729252787823e+19, - 3.107021825977906e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.16458643897856984, - 0.8354135610214303 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.191296335623019, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "116", - "market": "omen_subgraph", - "title": "Title 116", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737915300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5856553156034275e+19, - 3.0902050097409004e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.16309940638409312, - 0.8369005936159069 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.172388814094017, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "117", - "market": "omen_subgraph", - "title": "Title 117", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737915300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6905262971506012e+19, - 2.8985056359424865e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.14636131604023664, - 0.8536386839597635 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 4.948553073031803, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "118", - "market": "omen_subgraph", - "title": "Title 118", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737915300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.3234944940889776e+19, - 3.7023198977286994e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.21859018755419587, - 0.7814098124458041 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.786058193797103, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "119", - "market": "omen_subgraph", - "title": "Title 119", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737915300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.85889845391551e+18, - 4.970129292744608e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.335162181746137, - 0.664837818253863 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.6086598308558795, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "120", - "market": "omen_subgraph", - "title": "Title 120", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1737915300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6517887382169938e+19, - 2.9664810557367363e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.15224927947705363, - 0.8477507205229464 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.029672904836978, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "121", - "market": "omen_subgraph", - "title": "Title 121", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1738001700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2133212531209667e+19, - 4.0385017466692936e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2497262613768472, - 0.7502737386231527 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.059963607819407, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "122", - "market": "omen_subgraph", - "title": "Title 122", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1738001700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2197399196974301e+19, - 4.0172498422577654e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2477543505590439, - 0.7522456494409562 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.0439174331115435, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "123", - "market": "omen_subgraph", - "title": "Title 123", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1738001700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.3477294399218256e+19, - 3.6357445751754317e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.21245464237039438, - 0.7875453576296055 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.726627523412867, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "124", - "market": "omen_subgraph", - "title": "Title 124", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1738001700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.3138389979151573e+19, - 3.7295285097911393e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.22110188119748897, - 0.7788981188025109 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.809845480593301, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "125", - "market": "omen_subgraph", - "title": "Title 125", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1738001700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.1307854911350925e+19, - 4.3332710212626944e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.27704342001539073, - 0.7229565799846093 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.265533595356986, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "126", - "market": "omen_subgraph", - "title": "Title 126", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1738001700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2285962109257791e+19, - 3.9882916424654464e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.24506755906046612, - 0.754932440939534 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.021781489650365, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "127", - "market": "omen_subgraph", - "title": "Title 127", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1738001700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.881088229090755e+18, - 4.958967966275201e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.33416099649432046, - 0.6658390035056796 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.6037485781625325, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "128", - "market": "omen_subgraph", - "title": "Title 128", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1738001700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2286527214538981e+19, - 3.9881082053858934e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.24505054045654945, - 0.7549494595434505 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.021640268513761, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "129", - "market": "omen_subgraph", - "title": "Title 129", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1738001700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4537933038676435e+19, - 3.3704928939789e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1882070990858518, - 0.8117929009141484 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.472284407827308, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "130", - "market": "omen_subgraph", - "title": "Title 130", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1738001700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.087450401950874e+18, - 6.913628628217614e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.49379255793933025, - 0.5062074420606698 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.999460526494913, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "131", - "market": "omen_subgraph", - "title": "Title 131", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736878500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.3008285900466096e+19, - 3.766829878657902e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.22454866650432187, - 0.7754513334956782 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.841986504913267, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "132", - "market": "omen_subgraph", - "title": "Title 132", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736878500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5381686148510376e+19, - 3.1856065405901783e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.17157086894311768, - 0.8284291310568823 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.278098516620485, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "133", - "market": "omen_subgraph", - "title": "Title 133", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736878500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6691061650422227e+19, - 2.9357030143592136e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.149576512711088, - 0.850423487288912 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 4.993181590231867, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "134", - "market": "omen_subgraph", - "title": "Title 134", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736878500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4819200625850837e+19, - 3.306521130061743e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.18242148779444667, - 0.8175785122055533 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.40668125218421, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "135", - "market": "omen_subgraph", - "title": "Title 135", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736878500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4593175228057758e+19, - 3.3577339567464054e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.18705091325339668, - 0.8129490867466033 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.459333507350098, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "136", - "market": "omen_subgraph", - "title": "Title 136", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736878500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.16225375017951e+19, - 4.2159468181911183e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.26618372901194287, - 0.7338162709880571 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.187460745617941, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "137", - "market": "omen_subgraph", - "title": "Title 137", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736878500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.3780831210770844e+19, - 3.5556636062491284e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.20509703049998218, - 0.7949029695000178 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.652815118301148, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "138", - "market": "omen_subgraph", - "title": "Title 138", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736878500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5027388154496901e+19, - 3.2607130058949663e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.17829696901267017, - 0.8217030309873298 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.3586755202474015, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "139", - "market": "omen_subgraph", - "title": "Title 139", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736878500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2976167858040846e+19, - 3.776153371015198e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.22541075468787294, - 0.774589245312127 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.849935579675013, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "140", - "market": "omen_subgraph", - "title": "Title 140", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736878500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6107854147524327e+19, - 3.041994268835056e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1588521330663032, - 0.8411478669336969 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.117533980910277, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "141", - "market": "omen_subgraph", - "title": "Title 141", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736792100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.203252312086431e+19, - 4.0722963511314053e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.25286196832026736, - 0.7471380316797327 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.085134960401751, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "142", - "market": "omen_subgraph", - "title": "Title 142", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736792100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.851122380846799e+18, - 4.974052509515974e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3355139177986627, - 0.6644860822013373 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.610377329423999, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "143", - "market": "omen_subgraph", - "title": "Title 143", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736792100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4945226534523644e+19, - 3.27863882737471e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1799090786869805, - 0.8200909213130194 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.377563873188727, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "144", - "market": "omen_subgraph", - "title": "Title 144", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736792100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0684931891134624e+19, - 4.5858972709648906e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.30030440536566105, - 0.699695594634339 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.417464235879542, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "145", - "market": "omen_subgraph", - "title": "Title 145", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736792100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.266322969320192e+19, - 3.8694709949314883e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.23404954023687483, - 0.7659504597631251 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.927646175215702, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "146", - "market": "omen_subgraph", - "title": "Title 146", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736792100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4370812096395373e+19, - 3.4096890051391503e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.19176563054484902, - 0.808234369455151 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.511655686213604, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "147", - "market": "omen_subgraph", - "title": "Title 147", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736792100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0457821517265463e+19, - 4.685488265323985e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.30940978772757993, - 0.6905902122724201 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.47150467150005, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "148", - "market": "omen_subgraph", - "title": "Title 148", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736792100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.394538596715735e+19, - 3.513706979168554e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.20125369570862958, - 0.7987463042913705 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.613120927947357, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "149", - "market": "omen_subgraph", - "title": "Title 149", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736792100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4397375858968386e+19, - 3.4033979858542776e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.19119382199466306, - 0.808806178005337 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.505378634339721, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "150", - "market": "omen_subgraph", - "title": "Title 150", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736792100, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4239625104033593e+19, - 3.4411018297188173e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.19462445422138006, - 0.8053755457786199 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.5427585283792, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "151", - "market": "omen_subgraph", - "title": "Title 151", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736705700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5967659292525523e+19, - 3.068702751125016e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.16120216373740187, - 0.8387978362625982 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.148042455553492, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "152", - "market": "omen_subgraph", - "title": "Title 152", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736705700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5718020553524785e+19, - 3.1174408910549294e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1655091328782941, - 0.8344908671217058 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.202951904754183, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "153", - "market": "omen_subgraph", - "title": "Title 153", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736705700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2589419643387486e+19, - 3.892157175468922e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.23615199068913986, - 0.7638480093108602 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.946033020813832, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "154", - "market": "omen_subgraph", - "title": "Title 154", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736705700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.961385257369954e+18, - 6.154707807242474e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.4360064629122972, - 0.5639935370877028 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.942430851895966, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "155", - "market": "omen_subgraph", - "title": "Title 155", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736705700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.314245572807728e+19, - 3.7283747431857336e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.22099532975193328, - 0.7790046702480667 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.808842674753246, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "156", - "market": "omen_subgraph", - "title": "Title 156", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736705700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4984224346210322e+19, - 3.2701058705379466e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1791413780571165, - 0.8208586219428835 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.368589196994225, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "157", - "market": "omen_subgraph", - "title": "Title 157", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736705700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2986170187237163e+19, - 3.7732448669244534e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.22514179968276993, - 0.7748582003172301 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.847459453882617, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "158", - "market": "omen_subgraph", - "title": "Title 158", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736705700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0775157562182339e+19, - 4.547497307322513e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.29678259714463334, - 0.7032174028553666 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.39575849189422, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "159", - "market": "omen_subgraph", - "title": "Title 159", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736705700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.671136858131465e+18, - 6.387579951472201e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.45435014005750324, - 0.5456498599424967 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.970764211784613, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "160", - "market": "omen_subgraph", - "title": "Title 160", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736705700, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.57602415584754e+19, - 3.109089401846714e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.16476945623479802, - 0.835230543765202 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.193612863438115, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "161", - "market": "omen_subgraph", - "title": "Title 161", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736619300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.967667682740025e+18, - 5.464074019414188e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3786150093441993, - 0.6213849906558008 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.790587166992577, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "162", - "market": "omen_subgraph", - "title": "Title 162", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736619300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5819086402181894e+19, - 3.0975240133489336e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.16374624974069452, - 0.8362537502593056 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.180632145362602, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "163", - "market": "omen_subgraph", - "title": "Title 163", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736619300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.5269176675476613e+19, - 3.209079378765555e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1736678704605799, - 0.82633212953942 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.303530793832762, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "164", - "market": "omen_subgraph", - "title": "Title 164", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736619300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.350351381462635e+19, - 3.628685146152521e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.21180498513119958, - 0.7881950148688005 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.720223085451764, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "165", - "market": "omen_subgraph", - "title": "Title 165", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736619300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4163356610676646e+19, - 3.459631875897465e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.19631357522211113, - 0.803686424777889 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.56091834677531, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "166", - "market": "omen_subgraph", - "title": "Title 166", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736619300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.2675402242887e+18, - 6.742308743780746e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.4812549199600568, - 0.5187450800399431 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.995078977893104, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "167", - "market": "omen_subgraph", - "title": "Title 167", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736619300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4715601305858683e+19, - 3.3297993728935675e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.18452343797576498, - 0.8154765620242351 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.430746689675401, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "168", - "market": "omen_subgraph", - "title": "Title 168", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736619300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.755240900272173e+18, - 5.022941053012119e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.33988897070629337, - 0.6601110292937066 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.631397577170888, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "169", - "market": "omen_subgraph", - "title": "Title 169", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736619300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.585770163802345e+19, - 3.089981203991646e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1630796351066126, - 0.8369203648933875 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.172136393516794, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "170", - "market": "omen_subgraph", - "title": "Title 170", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736619300, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.54373046401159e+18, - 6.495460068962073e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.46266628077354394, - 0.537333719226456 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.980459433884645, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "171", - "market": "omen_subgraph", - "title": "Title 171", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736532900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0440298613135503e+19, - 4.693352347063181e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.31012690588719405, - 0.689873094112806 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.475635010860154, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "172", - "market": "omen_subgraph", - "title": "Title 172", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736532900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.4324337186521469e+19, - 3.4207516453959706e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.19277173970767564, - 0.8072282602923243 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.522654799210191, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "173", - "market": "omen_subgraph", - "title": "Title 173", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736532900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.994560981048842e+18, - 6.129167081989218e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.4339624109606946, - 0.5660375890393053 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.938677915816504, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "174", - "market": "omen_subgraph", - "title": "Title 174", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736532900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0354158059101233e+19, - 4.732398300306933e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.313683135340276, - 0.686316864659724 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.495849527575322, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "175", - "market": "omen_subgraph", - "title": "Title 175", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736532900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.2656241851892482e+19, - 3.8716074308166804e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2342475033861191, - 0.7657524966138809 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.929386112113453, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "176", - "market": "omen_subgraph", - "title": "Title 176", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736532900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.641551029998487e+19, - 2.984981831484408e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.15386113977193955, - 0.8461388602280605 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.051418249387371, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "177", - "market": "omen_subgraph", - "title": "Title 177", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736532900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0155337524951618e+19, - 4.82504888484575e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3220910831572479, - 0.6779089168427521 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.541887326478223, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "178", - "market": "omen_subgraph", - "title": "Title 178", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736532900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0187167608983558e+19, - 4.809972887536408e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3207260003100288, - 0.6792739996899713 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.534579043434351, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "179", - "market": "omen_subgraph", - "title": "Title 179", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736532900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.1145393978585733e+19, - 4.396434984186869e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.2828775811854361, - 0.717122418814564 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.305564180042113, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "180", - "market": "omen_subgraph", - "title": "Title 180", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736532900, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6856537095375976e+19, - 2.9068841199561385e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.14708405433878163, - 0.8529159456612183 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 4.9586556361999365, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "181", - "market": "omen_subgraph", - "title": "Title 181", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736446500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.834311217403777e+18, - 6.254538355732845e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.4439353492465735, - 0.5560646507534265 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.955855372808989, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "182", - "market": "omen_subgraph", - "title": "Title 182", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736446500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9.096269571747347e+18, - 5.386823643858583e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.3719387539434002, - 0.6280612460565999 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.76651034009795, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "183", - "market": "omen_subgraph", - "title": "Title 183", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736446500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6146658380116236e+19, - 3.0346836383397407e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1582101833865335, - 0.8417898166134665 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.109131566795796, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "184", - "market": "omen_subgraph", - "title": "Title 184", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736446500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.895504689950172e+18, - 6.206063060461463e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.44009738280910665, - 0.5599026171908933 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.949581900008196, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "185", - "market": "omen_subgraph", - "title": "Title 185", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736446500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8.946495040890486e+18, - 5.477005215566833e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.37972788284278003, - 0.6202721171572199 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.79446724148155, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "186", - "market": "omen_subgraph", - "title": "Title 186", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736446500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6422994237260487e+19, - 2.9836215791167247e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.15374249726729022, - 0.8462575027327097 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.049824293285487, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "187", - "market": "omen_subgraph", - "title": "Title 187", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736446500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.0559676885354009e+19, - 4.640293498749161e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.30528306184084375, - 0.6947169381591562 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.447380983221713, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "188", - "market": "omen_subgraph", - "title": "Title 188", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736446500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.3538816177799127e+19, - 3.6192233764389176e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.21093455140945677, - 0.7890654485905433 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 5.7116082341583105, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "189", - "market": "omen_subgraph", - "title": "Title 189", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736446500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 1.6926134679132752e+19, - 2.8949314730674606e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.1460532673085354, - 0.8539467326914647 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 4.944234545583294, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "190", - "market": "omen_subgraph", - "title": "Title 190", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736446500, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7.680568098749135e+18, - 6.379736416630455e+18 - ], - "outcomeTokenMarginalPrices": [ - 0.453740984745537, - 0.546259015254463 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.969977065063178, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - } -] \ No newline at end of file diff --git a/trader_backup/data/multi_bets.json b/trader_backup/data/multi_bets.json deleted file mode 100644 index b1e0570c1..000000000 --- a/trader_backup/data/multi_bets.json +++ /dev/null @@ -1 +0,0 @@ -[{"id": "1", "market": "omen_subgraph", "title": "Title 1", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736964900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12813634805420204032, 3824051546971891200], "outcomeTokenMarginalPrices": [0.2298427477220765, 0.7701572522779235], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.890242063970029, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "2", "market": "omen_subgraph", "title": "Title 2", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736964900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9366094026345332736, 5231636567193409536], "outcomeTokenMarginalPrices": [0.3583869789670622, 0.6416130210329378], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.713372285646703, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "3", "market": "omen_subgraph", "title": "Title 3", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736964900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8598859870757257216, 5698429877504774144], "outcomeTokenMarginalPrices": [0.3985671394956147, 0.6014328605043854], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.854445963222702, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "4", "market": "omen_subgraph", "title": "Title 4", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736964900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8512953316229938176, 5755934301505159168], "outcomeTokenMarginalPrices": [0.4033905414148044, 0.5966094585851957], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.8680896945458985, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "5", "market": "omen_subgraph", "title": "Title 5", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736964900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8263810620031015936, 5929467923820365824], "outcomeTokenMarginalPrices": [0.4177659097931992, 0.5822340902068008], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.904676724071918, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "6", "market": "omen_subgraph", "title": "Title 6", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736964900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10256678737079947264, 4777374943299646464], "outcomeTokenMarginalPrices": [0.3177702464595047, 0.6822297535404953], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.518534660275712, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "7", "market": "omen_subgraph", "title": "Title 7", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736964900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13903946084558909440, 3524179373395094528], "outcomeTokenMarginalPrices": [0.20221218752970924, 0.7977878124702908], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.623094706107586, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "8", "market": "omen_subgraph", "title": "Title 8", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736964900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10570224480919758848, 4635663139269139456], "outcomeTokenMarginalPrices": [0.3048597526864763, 0.6951402473135236], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.44487204218747, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "9", "market": "omen_subgraph", "title": "Title 9", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736964900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15865383698375485440, 3088485026997316608], "outcomeTokenMarginalPrices": [0.16294747377156216, 0.837052526228438], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.170448388133618, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "10", "market": "omen_subgraph", "title": "Title 10", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736964900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9007865773418682368, 5439690292077190144], "outcomeTokenMarginalPrices": [0.37651283493326854, 0.6234871650667314], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.783154158096456, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "11", "market": "omen_subgraph", "title": "Title 11", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737051300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8100035237646221312, 6049356399372756992], "outcomeTokenMarginalPrices": [0.4275347346769212, 0.5724652653230787], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.926092832401579, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "12", "market": "omen_subgraph", "title": "Title 12", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737051300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12246997212151214080, 4000980742559753216], "outcomeTokenMarginalPrices": [0.24624484066337016, 0.7537551593366297], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.031519754221828, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "13", "market": "omen_subgraph", "title": "Title 13", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737051300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15629564487607744512, 3135084156621943296], "outcomeTokenMarginalPrices": [0.1670739599798482, 0.8329260400201518], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.222586463410066, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "14", "market": "omen_subgraph", "title": "Title 14", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737051300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9604561696515115008, 5101742437427310592], "outcomeTokenMarginalPrices": [0.3469085360238398, 0.6530914639761601], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.663808874577411, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "15", "market": "omen_subgraph", "title": "Title 15", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737051300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11966905935401406464, 4094625650482009088], "outcomeTokenMarginalPrices": [0.25493369848245373, 0.7450663015175464], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.1015351790070165, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "16", "market": "omen_subgraph", "title": "Title 16", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737051300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11262434649556600832, 4350746665769031680], "outcomeTokenMarginalPrices": [0.27865856278107864, 0.7213414372189214], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.276747705722528, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "17", "market": "omen_subgraph", "title": "Title 17", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737051300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12271335959240585216, 3993045269297017856], "outcomeTokenMarginalPrices": [0.24550858794989333, 0.7544914120501067], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.025436727223811, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "18", "market": "omen_subgraph", "title": "Title 18", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737051300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12708385513869185024, 3855721873287860224], "outcomeTokenMarginalPrices": [0.23277571094941032, 0.7672242890505898], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.916406946020174, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "19", "market": "omen_subgraph", "title": "Title 19", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737051300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10897335138564610048, 4496512163473229824], "outcomeTokenMarginalPrices": [0.2920980100197551, 0.7079019899802448], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.36617981698615, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "20", "market": "omen_subgraph", "title": "Title 20", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737051300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7790834981644233728, 6289441390486066176], "outcomeTokenMarginalPrices": [0.44668451273691123, 0.5533154872630889], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.960090655178875, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "21", "market": "omen_subgraph", "title": "Title 21", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737137700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15625841572839385088, 3135831102061798912], "outcomeTokenMarginalPrices": [0.16714027349260932, 0.8328597265073906], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.223414868073118, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "22", "market": "omen_subgraph", "title": "Title 22", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737137700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8636126933800320000, 5673839717225832448], "outcomeTokenMarginalPrices": [0.39649566316906604, 0.6035043368309341], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.848373751658781, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "23", "market": "omen_subgraph", "title": "Title 23", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737137700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14991302802086074368, 3268561821937285632], "outcomeTokenMarginalPrices": [0.17900252215654675, 0.8209974778434532], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.366962023971828, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "24", "market": "omen_subgraph", "title": "Title 24", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737137700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9863689419814088704, 4967715214306043904], "outcomeTokenMarginalPrices": [0.334945700481912, 0.6650542995180879], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.607600724111308, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "25", "market": "omen_subgraph", "title": "Title 25", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737137700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9671167011325687808, 5066606743800122368], "outcomeTokenMarginalPrices": [0.343783723918136, 0.656216276081864], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.649579619575549, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "26", "market": "omen_subgraph", "title": "Title 26", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737137700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14135924365264607232, 3466345654791764480], "outcomeTokenMarginalPrices": [0.19692605844826502, 0.8030739415517348], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.567463735548703, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "27", "market": "omen_subgraph", "title": "Title 27", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737137700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15766323091329456128, 3107890134951446016], "outcomeTokenMarginalPrices": [0.1646632947128067, 0.8353367052871934], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.192269411449823, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "28", "market": "omen_subgraph", "title": "Title 28", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737137700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16867470973942423552, 2904999811512777728], "outcomeTokenMarginalPrices": [0.1469214365282927, 0.8530785634717073], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 4.956386132181803, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "29", "market": "omen_subgraph", "title": "Title 29", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737137700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11558677932560506880, 4239239148792979968], "outcomeTokenMarginalPrices": [0.2683416507988016, 0.7316583492011984], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.203349434949931, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "30", "market": "omen_subgraph", "title": "Title 30", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737137700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14808773192179548160, 3308849380303608832], "outcomeTokenMarginalPrices": [0.1826315437947721, 0.817368456205228], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.409098219588772, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "31", "market": "omen_subgraph", "title": "Title 31", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737224100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14346934595961868288, 3415363726115520512], "outcomeTokenMarginalPrices": [0.19228163293882097, 0.8077183670611789], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.517304023556024, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "32", "market": "omen_subgraph", "title": "Title 32", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737224100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11710182389367572480, 4184392554337177088], "outcomeTokenMarginalPrices": [0.2632591666752598, 0.7367408333247402], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.165625714880419, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "33", "market": "omen_subgraph", "title": "Title 33", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737224100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11822090308283389952, 4144783090150068224], "outcomeTokenMarginalPrices": [0.25958639407491774, 0.7404136059250823], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.1377075871106355, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "34", "market": "omen_subgraph", "title": "Title 34", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737224100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16279523091965841408, 3009916182629584896], "outcomeTokenMarginalPrices": [0.1560395893204477, 0.8439604106795523], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.08050019520619, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "35", "market": "omen_subgraph", "title": "Title 35", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737224100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14485777615611154432, 3382628209561444352], "outcomeTokenMarginalPrices": [0.18930777835793697, 0.810692221642063], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.484540756396962, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "36", "market": "omen_subgraph", "title": "Title 36", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737224100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8584261825207214080, 5708120394943475712], "outcomeTokenMarginalPrices": [0.3993820139301657, 0.6006179860698343], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.8567995517101945, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "37", "market": "omen_subgraph", "title": "Title 37", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737224100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8340803845760637952, 5874733527620976640], "outcomeTokenMarginalPrices": [0.4132614457910912, 0.5867385542089089], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.893865312717869, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "38", "market": "omen_subgraph", "title": "Title 38", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737224100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11084531075251400704, 4420574913575101952], "outcomeTokenMarginalPrices": [0.28510446279830115, 0.7148955372016988], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.320498555161253, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "39", "market": "omen_subgraph", "title": "Title 39", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737224100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14524391591750711296, 3373635287266014720], "outcomeTokenMarginalPrices": [0.18849202261625803, 0.811507977383742], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.475463896799326, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "40", "market": "omen_subgraph", "title": "Title 40", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737224100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9113621349920709632, 5376567460796065792], "outcomeTokenMarginalPrices": [0.37104882006917805, 0.628951179930822], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.7631968968906975, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "41", "market": "omen_subgraph", "title": "Title 41", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737310500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10123287423136479232, 4840324881817731072], "outcomeTokenMarginalPrices": [0.3234730212981512, 0.6765269787018489], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.549220736463066, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "42", "market": "omen_subgraph", "title": "Title 42", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737310500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9001834178053282816, 5443335106023540736], "outcomeTokenMarginalPrices": [0.3768273669193915, 0.6231726330806086], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.784274941521607, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "43", "market": "omen_subgraph", "title": "Title 43", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737310500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16333430616782567424, 2999982131717791232], "outcomeTokenMarginalPrices": [0.1551708521792404, 0.8448291478207597], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.068944695633295, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "44", "market": "omen_subgraph", "title": "Title 44", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737310500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12016831254055174144, 4077614053493891584], "outcomeTokenMarginalPrices": [0.25335536426230826, 0.7466446357376917], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.089057319299679, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "45", "market": "omen_subgraph", "title": "Title 45", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737310500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13004618776674914304, 3767892072921538560], "outcomeTokenMarginalPrices": [0.22464687050789384, 0.7753531294921062], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.842893820656428, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "46", "market": "omen_subgraph", "title": "Title 46", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737310500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15330127508646088704, 3196320446282285056], "outcomeTokenMarginalPrices": [0.17252742965399395, 0.8274725703460061], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.289734990669391, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "47", "market": "omen_subgraph", "title": "Title 47", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737310500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13068779519420635136, 3749393730851790336], "outcomeTokenMarginalPrices": [0.22293703811090518, 0.7770629618890947], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.827029995568191, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "48", "market": "omen_subgraph", "title": "Title 48", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737310500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14315891908879097856, 3422769626362496512], "outcomeTokenMarginalPrices": [0.19295534894571623, 0.8070446510542837], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.524655837493844, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "49", "market": "omen_subgraph", "title": "Title 49", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737310500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11075469992930326528, 4424191481831253504], "outcomeTokenMarginalPrices": [0.28543794256637517, 0.7145620574336248], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.322718735475316, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "50", "market": "omen_subgraph", "title": "Title 50", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737310500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11869883128627339264, 4128094562432855040], "outcomeTokenMarginalPrices": [0.2580385247530173, 0.7419614752469826], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.125774263003456, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "51", "market": "omen_subgraph", "title": "Title 51", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737396900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12061683852704937984, 4062451030749850112], "outcomeTokenMarginalPrices": [0.2519484648393999, 0.7480515351606002], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.077845460134376, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "52", "market": "omen_subgraph", "title": "Title 52", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737396900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12037394010939934720, 4070648510422386176], "outcomeTokenMarginalPrices": [0.2527090740556423, 0.7472909259443576], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.083917389095131, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "53", "market": "omen_subgraph", "title": "Title 53", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737396900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13149923766657468416, 3726257343349993472], "outcomeTokenMarginalPrices": [0.22079979582231124, 0.7792002041776889], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.807000965513854, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "54", "market": "omen_subgraph", "title": "Title 54", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737396900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15300849250584702976, 3202436622799059968], "outcomeTokenMarginalPrices": [0.17307394182379449, 0.8269260581762055], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.296356586100693, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "55", "market": "omen_subgraph", "title": "Title 55", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737396900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12833887689076891648, 3818016893018676224], "outcomeTokenMarginalPrices": [0.22928409625430343, 0.7707159037456967], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.885212680438452, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "56", "market": "omen_subgraph", "title": "Title 56", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737396900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7211919973071383552, 6794307227889562624], "outcomeTokenMarginalPrices": [0.48509189022889865, 0.5149081097711012], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.996887783833491, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "57", "market": "omen_subgraph", "title": "Title 57", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737396900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14316395119805708288, 3422649318487445504], "outcomeTokenMarginalPrices": [0.19294440184720413, 0.8070555981527959], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.524536585998289, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "58", "market": "omen_subgraph", "title": "Title 58", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737396900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16156478665518563328, 3032839086686423552], "outcomeTokenMarginalPrices": [0.15804830196935632, 0.8419516980306437], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.107008037778682, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "59", "market": "omen_subgraph", "title": "Title 59", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737396900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14515847701883136000, 3375620976902592000], "outcomeTokenMarginalPrices": [0.1886721005137568, 0.8113278994862432], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.477470953304161, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "60", "market": "omen_subgraph", "title": "Title 60", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737396900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9832136567363831808, 4983657383548503040], "outcomeTokenMarginalPrices": [0.3363746418221223, 0.6636253581778777], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.614562832386401, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "61", "market": "omen_subgraph", "title": "Title 61", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737483300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16444563612950865920, 2979708136578960384], "outcomeTokenMarginalPrices": [0.15340127933759398, 0.846598720662406], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.045234192750219, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "62", "market": "omen_subgraph", "title": "Title 62", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737483300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15353343726203232256, 3191487201343165440], "outcomeTokenMarginalPrices": [0.17209578312210694, 0.8279042168778932], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.2844914242076655, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "63", "market": "omen_subgraph", "title": "Title 63", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737483300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15105365556691539968, 3243880448712043520], "outcomeTokenMarginalPrices": [0.1767854901371298, 0.8232145098628703], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.340818907280465, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "64", "market": "omen_subgraph", "title": "Title 64", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737483300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14396503071416760320, 3403604316751478272], "outcomeTokenMarginalPrices": [0.1912125720664955, 0.8087874279335044], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.505584762097602, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "65", "market": "omen_subgraph", "title": "Title 65", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737483300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16099148002944544768, 3043639327437568000], "outcomeTokenMarginalPrices": [0.15899666411729463, 0.8410033358827054], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.119421655197577, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "66", "market": "omen_subgraph", "title": "Title 66", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737483300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15913803315733039104, 3079087948231494656], "outcomeTokenMarginalPrices": [0.16211791587905783, 0.8378820841209422], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.159825254511761, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "67", "market": "omen_subgraph", "title": "Title 67", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737483300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8197517645263373312, 5977419277445874688], "outcomeTokenMarginalPrices": [0.4216893034542981, 0.5783106965457019], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.913611011770859, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "68", "market": "omen_subgraph", "title": "Title 68", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737483300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10725366646360545280, 4568608385674838016], "outcomeTokenMarginalPrices": [0.29871948764825657, 0.7012805123517434], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.4077520588810435, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "69", "market": "omen_subgraph", "title": "Title 69", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737483300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9622571724610181120, 5092193792089924608], "outcomeTokenMarginalPrices": [0.34606013845825023, 0.6539398615417498], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.659977006686086, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "70", "market": "omen_subgraph", "title": "Title 70", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737483300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10196423869543354368, 4805606419164532736], "outcomeTokenMarginalPrices": [0.3203304037308697, 0.6796695962691304], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.532449149483798, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "71", "market": "omen_subgraph", "title": "Title 71", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737569700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14230297673099175936, 3443357344001956352], "outcomeTokenMarginalPrices": [0.19482995117139854, 0.8051700488286014], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.544976401608757, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "72", "market": "omen_subgraph", "title": "Title 72", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737569700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14339510128864069632, 3417132074921281024], "outcomeTokenMarginalPrices": [0.19244246945477217, 0.8075575305452278], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.51906147994064, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "73", "market": "omen_subgraph", "title": "Title 73", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737569700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11618928879007537152, 4217256212707402752], "outcomeTokenMarginalPrices": [0.26630505947507244, 0.7336949405249276], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.188359092321478, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "74", "market": "omen_subgraph", "title": "Title 74", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737569700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14598999138884329472, 3356394471555851776], "outcomeTokenMarginalPrices": [0.1869295958850088, 0.8130704041149913], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.4579700187144775, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "75", "market": "omen_subgraph", "title": "Title 75", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737569700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9403916639263823872, 5210594891431950336], "outcomeTokenMarginalPrices": [0.3565356858139125, 0.6434643141860875], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.705663736633582, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "76", "market": "omen_subgraph", "title": "Title 76", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737569700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15991034686921756672, 3064216979034795008], "outcomeTokenMarginalPrices": [0.16080695404874754, 0.8391930459512524], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.142939160183509, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "77", "market": "omen_subgraph", "title": "Title 77", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737569700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12685106274283008000, 3862797751985692160], "outcomeTokenMarginalPrices": [0.2334312397421303, 0.7665687602578697], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.9222001677331155, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "78", "market": "omen_subgraph", "title": "Title 78", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737569700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10115849293119483904, 4843883946880112640], "outcomeTokenMarginalPrices": [0.3237948076459312, 0.6762051923540687], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.550918952081704, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "79", "market": "omen_subgraph", "title": "Title 79", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737569700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7234739436966579200, 6772876953885845504], "outcomeTokenMarginalPrices": [0.48351388022796116, 0.5164861197720388], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.996193875211932, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "80", "market": "omen_subgraph", "title": "Title 80", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737569700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12172356628365158400, 4025514655544649728], "outcomeTokenMarginalPrices": [0.24852121522557127, 0.7514787847744286], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.050177722880693, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "81", "market": "omen_subgraph", "title": "Title 81", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737656100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12772581331289022464, 3836342766513812480], "outcomeTokenMarginalPrices": [0.23098081151573904, 0.769019188484261], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.900442402103834, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "82", "market": "omen_subgraph", "title": "Title 82", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737656100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8276320206451292160, 5920505584330230784], "outcomeTokenMarginalPrices": [0.4170302341932388, 0.5829697658067612], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.902951507909233, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "83", "market": "omen_subgraph", "title": "Title 83", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737656100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14631628025628092416, 3348909630163768320], "outcomeTokenMarginalPrices": [0.1862519182837129, 0.8137480817162871], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.450337574773934, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "84", "market": "omen_subgraph", "title": "Title 84", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737656100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16562678166337484800, 2958458741267409408], "outcomeTokenMarginalPrices": [0.1515515594849845, 0.8484484405150154], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.020199410712698, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "85", "market": "omen_subgraph", "title": "Title 85", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737656100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8759431458089469952, 5593970366050156544], "outcomeTokenMarginalPrices": [0.38973132882284306, 0.6102686711771569], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.827649723787646, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "86", "market": "omen_subgraph", "title": "Title 86", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737656100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15419120738389389312, 3177872515000379392], "outcomeTokenMarginalPrices": [0.17088098445274924, 0.8291190155472508], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.269669062343562, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "87", "market": "omen_subgraph", "title": "Title 87", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737656100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15832118406519756800, 3094974326355563520], "outcomeTokenMarginalPrices": [0.16352085183054887, 0.8364791481694511], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.1777629762324455, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "88", "market": "omen_subgraph", "title": "Title 88", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737656100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9612411128821383168, 5097576387788990464], "outcomeTokenMarginalPrices": [0.3465384577677484, 0.6534615422322516], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.6621402560226075, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "89", "market": "omen_subgraph", "title": "Title 89", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737656100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16873390232729128960, 2903980724925998592], "outcomeTokenMarginalPrices": [0.14683350639190845, 0.8531664936080916], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 4.955158105181196, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "90", "market": "omen_subgraph", "title": "Title 90", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737656100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12891696413255618560, 3800896207082317824], "outcomeTokenMarginalPrices": [0.22769957271055535, 0.7723004272894446], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.870867529625007, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "91", "market": "omen_subgraph", "title": "Title 91", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737742500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10466476967394758656, 4681613512612232192], "outcomeTokenMarginalPrices": [0.30905634731923465, 0.6909436526807654], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.469462281687848, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "92", "market": "omen_subgraph", "title": "Title 92", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737742500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11859795866068922368, 4131605683044666368], "outcomeTokenMarginalPrices": [0.25836420093357504, 0.741635799066425], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.128293364344428, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "93", "market": "omen_subgraph", "title": "Title 93", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737742500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12644544459399415808, 3875189031707305984], "outcomeTokenMarginalPrices": [0.23457939159814448, 0.7654206084018557], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.932299092643207, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "94", "market": "omen_subgraph", "title": "Title 94", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737742500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15173504132599259136, 3229313385477437440], "outcomeTokenMarginalPrices": [0.17547929181525337, 0.8245207081847467], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.325271519088677, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "95", "market": "omen_subgraph", "title": "Title 95", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737742500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14470231522861453312, 3386262336064569344], "outcomeTokenMarginalPrices": [0.18963758298899536, 0.8103624170110048], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.488199462573231, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "96", "market": "omen_subgraph", "title": "Title 96", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737742500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13058861742860810240, 3752241272237066240], "outcomeTokenMarginalPrices": [0.22320018316866044, 0.7767998168313395], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.829480665961491, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "97", "market": "omen_subgraph", "title": "Title 97", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737742500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11807257176825604096, 4149990066801756160], "outcomeTokenMarginalPrices": [0.2600692966300365, 0.7399307033699635], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.1414101382139705, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "98", "market": "omen_subgraph", "title": "Title 98", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737742500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15171500643729242112, 3229739835937252352], "outcomeTokenMarginalPrices": [0.17551750598043314, 0.8244824940195669], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.325727909935785, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "99", "market": "omen_subgraph", "title": "Title 99", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737742500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16073688465767225344, 3048460227679368704], "outcomeTokenMarginalPrices": [0.15942038086567725, 0.8405796191343228], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.124947074257709, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "100", "market": "omen_subgraph", "title": "Title 100", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737742500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8243171459364809728, 5944314059406423040], "outcomeTokenMarginalPrices": [0.4189829164260007, 0.5810170835739993], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.907496037288482, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "101", "market": "omen_subgraph", "title": "Title 101", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737828900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16516875718149662720, 2966662753668120576], "outcomeTokenMarginalPrices": [0.15226509075645003, 0.84773490924355], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.029887160474129, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "102", "market": "omen_subgraph", "title": "Title 102", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737828900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14425703781235564544, 3396714693652411904], "outcomeTokenMarginalPrices": [0.19058663101410322, 0.8094133689858967], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.498692567346193, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "103", "market": "omen_subgraph", "title": "Title 103", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737828900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10862770327316846592, 4510819848301370368], "outcomeTokenMarginalPrices": [0.2934135616191536, 0.7065864383808464], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.3745682615777906, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "104", "market": "omen_subgraph", "title": "Title 104", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737828900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16760798118532548608, 2923488467164359680], "outcomeTokenMarginalPrices": [0.1485188937092919, 0.8514811062907081], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 4.97859038849847, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "105", "market": "omen_subgraph", "title": "Title 105", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737828900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11718715231986405376, 4181345738844628480], "outcomeTokenMarginalPrices": [0.26297671100226516, 0.7370232889977348], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.163498377759863, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "106", "market": "omen_subgraph", "title": "Title 106", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737828900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8740613142595386368, 5606014040503597056], "outcomeTokenMarginalPrices": [0.3907548421630243, 0.6092451578369757], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.830873817885832, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "107", "market": "omen_subgraph", "title": "Title 107", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737828900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12114245196037996544, 4044824849345595904], "outcomeTokenMarginalPrices": [0.25031297209464987, 0.7496870279053501], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.064705439407211, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "108", "market": "omen_subgraph", "title": "Title 108", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737828900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15699923080280502272, 3121034399305129472], "outcomeTokenMarginalPrices": [0.16582761013569025, 0.8341723898643096], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.206961447434161, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "109", "market": "omen_subgraph", "title": "Title 109", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737828900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14586089034871406592, 3359365206317760000], "outcomeTokenMarginalPrices": [0.18719867221901815, 0.8128013277809818], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.460993000392614, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "110", "market": "omen_subgraph", "title": "Title 110", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737828900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11745445959628857344, 4171829674958408192], "outcomeTokenMarginalPrices": [0.26209445452419494, 0.737905545475805], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.156832503864669, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "111", "market": "omen_subgraph", "title": "Title 111", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737915300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7104004906808017920, 6897517758333975552], "outcomeTokenMarginalPrices": [0.4926262609641696, 0.5073737390358303], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.9992387502238955, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "112", "market": "omen_subgraph", "title": "Title 112", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737915300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8645419410711964672, 5667741224825640960], "outcomeTokenMarginalPrices": [0.3959811092145099, 0.60401889078549], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.846845535756756, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "113", "market": "omen_subgraph", "title": "Title 113", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737915300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10202362212492615680, 4802809288617527296], "outcomeTokenMarginalPrices": [0.32007693402652515, 0.6799230659734747], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.5310816336054245, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "114", "market": "omen_subgraph", "title": "Title 114", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737915300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9761440958643187712, 5019750691276102656], "outcomeTokenMarginalPrices": [0.33960392437665954, 0.6603960756233405], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.630047314252577, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "115", "market": "omen_subgraph", "title": "Title 115", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737915300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15770729252787822592, 3107021825977906176], "outcomeTokenMarginalPrices": [0.16458643897856984, 0.8354135610214303], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.191296335623019, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "116", "market": "omen_subgraph", "title": "Title 116", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737915300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15856553156034275328, 3090205009740900352], "outcomeTokenMarginalPrices": [0.16309940638409312, 0.8369005936159069], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.172388814094017, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "117", "market": "omen_subgraph", "title": "Title 117", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737915300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16905262971506012160, 2898505635942486528], "outcomeTokenMarginalPrices": [0.14636131604023664, 0.8536386839597635], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 4.948553073031803, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "118", "market": "omen_subgraph", "title": "Title 118", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737915300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13234944940889776128, 3702319897728699392], "outcomeTokenMarginalPrices": [0.21859018755419587, 0.7814098124458041], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.786058193797103, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "119", "market": "omen_subgraph", "title": "Title 119", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737915300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9858898453915510784, 4970129292744607744], "outcomeTokenMarginalPrices": [0.335162181746137, 0.664837818253863], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.6086598308558795, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "120", "market": "omen_subgraph", "title": "Title 120", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1737915300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16517887382169937920, 2966481055736736256], "outcomeTokenMarginalPrices": [0.15224927947705363, 0.8477507205229464], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.029672904836978, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "121", "market": "omen_subgraph", "title": "Title 121", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1738001700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12133212531209666560, 4038501746669293568], "outcomeTokenMarginalPrices": [0.2497262613768472, 0.7502737386231527], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.059963607819407, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "122", "market": "omen_subgraph", "title": "Title 122", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1738001700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12197399196974301184, 4017249842257765376], "outcomeTokenMarginalPrices": [0.2477543505590439, 0.7522456494409562], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.0439174331115435, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "123", "market": "omen_subgraph", "title": "Title 123", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1738001700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13477294399218255872, 3635744575175431680], "outcomeTokenMarginalPrices": [0.21245464237039438, 0.7875453576296055], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.726627523412867, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "124", "market": "omen_subgraph", "title": "Title 124", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1738001700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13138389979151572992, 3729528509791139328], "outcomeTokenMarginalPrices": [0.22110188119748897, 0.7788981188025109], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.809845480593301, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "125", "market": "omen_subgraph", "title": "Title 125", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1738001700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11307854911350925312, 4333271021262694400], "outcomeTokenMarginalPrices": [0.27704342001539073, 0.7229565799846093], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.265533595356986, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "126", "market": "omen_subgraph", "title": "Title 126", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1738001700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12285962109257791488, 3988291642465446400], "outcomeTokenMarginalPrices": [0.24506755906046612, 0.754932440939534], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.021781489650365, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "127", "market": "omen_subgraph", "title": "Title 127", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1738001700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9881088229090754560, 4958967966275201024], "outcomeTokenMarginalPrices": [0.33416099649432046, 0.6658390035056796], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.6037485781625325, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "128", "market": "omen_subgraph", "title": "Title 128", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1738001700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12286527214538981376, 3988108205385893376], "outcomeTokenMarginalPrices": [0.24505054045654945, 0.7549494595434505], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.021640268513761, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "129", "market": "omen_subgraph", "title": "Title 129", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1738001700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14537933038676434944, 3370492893978899968], "outcomeTokenMarginalPrices": [0.1882070990858518, 0.8117929009141484], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.472284407827308, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "130", "market": "omen_subgraph", "title": "Title 130", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1738001700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7087450401950873600, 6913628628217614336], "outcomeTokenMarginalPrices": [0.49379255793933025, 0.5062074420606698], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.999460526494913, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "131", "market": "omen_subgraph", "title": "Title 131", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736878500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13008285900466096128, 3766829878657902080], "outcomeTokenMarginalPrices": [0.22454866650432187, 0.7754513334956782], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.841986504913267, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "132", "market": "omen_subgraph", "title": "Title 132", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736878500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15381686148510375936, 3185606540590178304], "outcomeTokenMarginalPrices": [0.17157086894311768, 0.8284291310568823], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.278098516620485, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "133", "market": "omen_subgraph", "title": "Title 133", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736878500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16691061650422226944, 2935703014359213568], "outcomeTokenMarginalPrices": [0.149576512711088, 0.850423487288912], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 4.993181590231867, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "134", "market": "omen_subgraph", "title": "Title 134", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736878500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14819200625850836992, 3306521130061743104], "outcomeTokenMarginalPrices": [0.18242148779444667, 0.8175785122055533], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.40668125218421, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "135", "market": "omen_subgraph", "title": "Title 135", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736878500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14593175228057757696, 3357733956746405376], "outcomeTokenMarginalPrices": [0.18705091325339668, 0.8129490867466033], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.459333507350098, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "136", "market": "omen_subgraph", "title": "Title 136", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736878500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11622537501795100672, 4215946818191118336], "outcomeTokenMarginalPrices": [0.26618372901194287, 0.7338162709880571], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.187460745617941, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "137", "market": "omen_subgraph", "title": "Title 137", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736878500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13780831210770843648, 3555663606249128448], "outcomeTokenMarginalPrices": [0.20509703049998218, 0.7949029695000178], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.652815118301148, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "138", "market": "omen_subgraph", "title": "Title 138", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736878500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15027388154496901120, 3260713005894966272], "outcomeTokenMarginalPrices": [0.17829696901267017, 0.8217030309873298], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.3586755202474015, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "139", "market": "omen_subgraph", "title": "Title 139", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736878500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12976167858040846336, 3776153371015198208], "outcomeTokenMarginalPrices": [0.22541075468787294, 0.774589245312127], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.849935579675013, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "140", "market": "omen_subgraph", "title": "Title 140", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736878500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16107854147524327424, 3041994268835056128], "outcomeTokenMarginalPrices": [0.1588521330663032, 0.8411478669336969], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.117533980910277, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "141", "market": "omen_subgraph", "title": "Title 141", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736792100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12032523120864309248, 4072296351131405312], "outcomeTokenMarginalPrices": [0.25286196832026736, 0.7471380316797327], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.085134960401751, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "142", "market": "omen_subgraph", "title": "Title 142", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736792100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9851122380846798848, 4974052509515973632], "outcomeTokenMarginalPrices": [0.3355139177986627, 0.6644860822013373], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.610377329423999, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "143", "market": "omen_subgraph", "title": "Title 143", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736792100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14945226534523643904, 3278638827374709760], "outcomeTokenMarginalPrices": [0.1799090786869805, 0.8200909213130194], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.377563873188727, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "144", "market": "omen_subgraph", "title": "Title 144", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736792100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10684931891134623744, 4585897270964890624], "outcomeTokenMarginalPrices": [0.30030440536566105, 0.699695594634339], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.417464235879542, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "145", "market": "omen_subgraph", "title": "Title 145", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736792100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12663229693201920000, 3869470994931488256], "outcomeTokenMarginalPrices": [0.23404954023687483, 0.7659504597631251], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.927646175215702, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "146", "market": "omen_subgraph", "title": "Title 146", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736792100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14370812096395372544, 3409689005139150336], "outcomeTokenMarginalPrices": [0.19176563054484902, 0.808234369455151], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.511655686213604, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "147", "market": "omen_subgraph", "title": "Title 147", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736792100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10457821517265463296, 4685488265323984896], "outcomeTokenMarginalPrices": [0.30940978772757993, 0.6905902122724201], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.47150467150005, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "148", "market": "omen_subgraph", "title": "Title 148", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736792100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13945385967157350400, 3513706979168553984], "outcomeTokenMarginalPrices": [0.20125369570862958, 0.7987463042913705], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.613120927947357, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "149", "market": "omen_subgraph", "title": "Title 149", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736792100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14397375858968385536, 3403397985854277632], "outcomeTokenMarginalPrices": [0.19119382199466306, 0.808806178005337], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.505378634339721, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "150", "market": "omen_subgraph", "title": "Title 150", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736792100, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14239625104033593344, 3441101829718817280], "outcomeTokenMarginalPrices": [0.19462445422138006, 0.8053755457786199], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.5427585283792, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "151", "market": "omen_subgraph", "title": "Title 151", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736705700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15967659292525522944, 3068702751125016064], "outcomeTokenMarginalPrices": [0.16120216373740187, 0.8387978362625982], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.148042455553492, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "152", "market": "omen_subgraph", "title": "Title 152", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736705700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15718020553524785152, 3117440891054929408], "outcomeTokenMarginalPrices": [0.1655091328782941, 0.8344908671217058], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.202951904754183, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "153", "market": "omen_subgraph", "title": "Title 153", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736705700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12589419643387486208, 3892157175468921856], "outcomeTokenMarginalPrices": [0.23615199068913986, 0.7638480093108602], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.946033020813832, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "154", "market": "omen_subgraph", "title": "Title 154", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736705700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7961385257369954304, 6154707807242474496], "outcomeTokenMarginalPrices": [0.4360064629122972, 0.5639935370877028], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.942430851895966, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "155", "market": "omen_subgraph", "title": "Title 155", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736705700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13142455728077279232, 3728374743185733632], "outcomeTokenMarginalPrices": [0.22099532975193328, 0.7790046702480667], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.808842674753246, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "156", "market": "omen_subgraph", "title": "Title 156", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736705700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14984224346210322432, 3270105870537946624], "outcomeTokenMarginalPrices": [0.1791413780571165, 0.8208586219428835], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.368589196994225, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "157", "market": "omen_subgraph", "title": "Title 157", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736705700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12986170187237163008, 3773244866924453376], "outcomeTokenMarginalPrices": [0.22514179968276993, 0.7748582003172301], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.847459453882617, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "158", "market": "omen_subgraph", "title": "Title 158", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736705700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10775157562182338560, 4547497307322512896], "outcomeTokenMarginalPrices": [0.29678259714463334, 0.7032174028553666], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.39575849189422, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "159", "market": "omen_subgraph", "title": "Title 159", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736705700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7671136858131465216, 6387579951472200704], "outcomeTokenMarginalPrices": [0.45435014005750324, 0.5456498599424967], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.970764211784613, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "160", "market": "omen_subgraph", "title": "Title 160", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736705700, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15760241558475399168, 3109089401846713856], "outcomeTokenMarginalPrices": [0.16476945623479802, 0.835230543765202], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.193612863438115, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "161", "market": "omen_subgraph", "title": "Title 161", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736619300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8967667682740025344, 5464074019414188032], "outcomeTokenMarginalPrices": [0.3786150093441993, 0.6213849906558008], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.790587166992577, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "162", "market": "omen_subgraph", "title": "Title 162", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736619300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15819086402181894144, 3097524013348933632], "outcomeTokenMarginalPrices": [0.16374624974069452, 0.8362537502593056], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.180632145362602, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "163", "market": "omen_subgraph", "title": "Title 163", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736619300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15269176675476613120, 3209079378765555200], "outcomeTokenMarginalPrices": [0.1736678704605799, 0.82633212953942], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.303530793832762, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "164", "market": "omen_subgraph", "title": "Title 164", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736619300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13503513814626349056, 3628685146152521216], "outcomeTokenMarginalPrices": [0.21180498513119958, 0.7881950148688005], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.720223085451764, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "165", "market": "omen_subgraph", "title": "Title 165", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736619300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14163356610676645888, 3459631875897464832], "outcomeTokenMarginalPrices": [0.19631357522211113, 0.803686424777889], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.56091834677531, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "166", "market": "omen_subgraph", "title": "Title 166", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736619300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7267540224288700416, 6742308743780746240], "outcomeTokenMarginalPrices": [0.4812549199600568, 0.5187450800399431], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.995078977893104, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "167", "market": "omen_subgraph", "title": "Title 167", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736619300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14715601305858682880, 3329799372893567488], "outcomeTokenMarginalPrices": [0.18452343797576498, 0.8154765620242351], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.430746689675401, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "168", "market": "omen_subgraph", "title": "Title 168", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736619300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9755240900272173056, 5022941053012118528], "outcomeTokenMarginalPrices": [0.33988897070629337, 0.6601110292937066], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.631397577170888, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "169", "market": "omen_subgraph", "title": "Title 169", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736619300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [15857701638023450624, 3089981203991646208], "outcomeTokenMarginalPrices": [0.1630796351066126, 0.8369203648933875], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.172136393516794, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "170", "market": "omen_subgraph", "title": "Title 170", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736619300, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7543730464011589632, 6495460068962072576], "outcomeTokenMarginalPrices": [0.46266628077354394, 0.537333719226456], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.980459433884645, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "171", "market": "omen_subgraph", "title": "Title 171", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736532900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10440298613135503360, 4693352347063181312], "outcomeTokenMarginalPrices": [0.31012690588719405, 0.689873094112806], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.475635010860154, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "172", "market": "omen_subgraph", "title": "Title 172", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736532900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [14324337186521468928, 3420751645395970560], "outcomeTokenMarginalPrices": [0.19277173970767564, 0.8072282602923243], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.522654799210191, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "173", "market": "omen_subgraph", "title": "Title 173", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736532900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7994560981048842240, 6129167081989218304], "outcomeTokenMarginalPrices": [0.4339624109606946, 0.5660375890393053], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.938677915816504, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "174", "market": "omen_subgraph", "title": "Title 174", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736532900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10354158059101233152, 4732398300306932736], "outcomeTokenMarginalPrices": [0.313683135340276, 0.686316864659724], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.495849527575322, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "175", "market": "omen_subgraph", "title": "Title 175", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736532900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [12656241851892482048, 3871607430816680448], "outcomeTokenMarginalPrices": [0.2342475033861191, 0.7657524966138809], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.929386112113453, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "176", "market": "omen_subgraph", "title": "Title 176", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736532900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16415510299984869376, 2984981831484407808], "outcomeTokenMarginalPrices": [0.15386113977193955, 0.8461388602280605], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.051418249387371, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "177", "market": "omen_subgraph", "title": "Title 177", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736532900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10155337524951617536, 4825048884845750272], "outcomeTokenMarginalPrices": [0.3220910831572479, 0.6779089168427521], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.541887326478223, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "178", "market": "omen_subgraph", "title": "Title 178", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736532900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10187167608983558144, 4809972887536407552], "outcomeTokenMarginalPrices": [0.3207260003100288, 0.6792739996899713], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.534579043434351, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "179", "market": "omen_subgraph", "title": "Title 179", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736532900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [11145393978585733120, 4396434984186869248], "outcomeTokenMarginalPrices": [0.2828775811854361, 0.717122418814564], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.305564180042113, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "180", "market": "omen_subgraph", "title": "Title 180", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736532900, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16856537095375976448, 2906884119956138496], "outcomeTokenMarginalPrices": [0.14708405433878163, 0.8529159456612183], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 4.9586556361999365, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "181", "market": "omen_subgraph", "title": "Title 181", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736446500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7834311217403777024, 6254538355732844544], "outcomeTokenMarginalPrices": [0.4439353492465735, 0.5560646507534265], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.955855372808989, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "182", "market": "omen_subgraph", "title": "Title 182", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736446500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [9096269571747347456, 5386823643858582528], "outcomeTokenMarginalPrices": [0.3719387539434002, 0.6280612460565999], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.76651034009795, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "183", "market": "omen_subgraph", "title": "Title 183", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736446500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16146658380116236288, 3034683638339740672], "outcomeTokenMarginalPrices": [0.1582101833865335, 0.8417898166134665], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.109131566795796, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "184", "market": "omen_subgraph", "title": "Title 184", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736446500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7895504689950172160, 6206063060461462528], "outcomeTokenMarginalPrices": [0.44009738280910665, 0.5599026171908933], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.949581900008196, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "185", "market": "omen_subgraph", "title": "Title 185", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736446500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8946495040890485760, 5477005215566832640], "outcomeTokenMarginalPrices": [0.37972788284278003, 0.6202721171572199], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.79446724148155, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "186", "market": "omen_subgraph", "title": "Title 186", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736446500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16422994237260486656, 2983621579116724736], "outcomeTokenMarginalPrices": [0.15374249726729022, 0.8462575027327097], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.049824293285487, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "187", "market": "omen_subgraph", "title": "Title 187", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736446500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [10559676885354008576, 4640293498749161472], "outcomeTokenMarginalPrices": [0.30528306184084375, 0.6947169381591562], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.447380983221713, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "188", "market": "omen_subgraph", "title": "Title 188", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736446500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [13538816177799127040, 3619223376438917632], "outcomeTokenMarginalPrices": [0.21093455140945677, 0.7890654485905433], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 5.7116082341583105, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "189", "market": "omen_subgraph", "title": "Title 189", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736446500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [16926134679132751872, 2894931473067460608], "outcomeTokenMarginalPrices": [0.1460532673085354, 0.8539467326914647], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 4.944234545583294, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "190", "market": "omen_subgraph", "title": "Title 190", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736446500, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7680568098749134848, 6379736416630455296], "outcomeTokenMarginalPrices": [0.453740984745537, 0.546259015254463], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.969977065063178, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}] \ No newline at end of file diff --git a/trader_backup/data/policy_store.json b/trader_backup/data/policy_store.json deleted file mode 100644 index 664aedf7e..000000000 --- a/trader_backup/data/policy_store.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "accuracy_store": { - "claude-prediction-offline": { - "accuracy": 57.380457380457386, - "pending": 110, - "requests": 481 - }, - "claude-prediction-online": { - "accuracy": 61.137440758293835, - "pending": 0, - "requests": 1055 - }, - "prediction-offline": { - "accuracy": 67.39834303627407, - "pending": 213, - "requests": 4466 - }, - "prediction-offline-sme": { - "accuracy": 67.203125, - "pending": 11, - "requests": 64 - }, - "prediction-online": { - "accuracy": 66.00632244467862, - "pending": 26, - "requests": 9490 - }, - "prediction-online-sme": { - "accuracy": 65.67408823931157, - "pending": 11, - "requests": 14642 - }, - "prediction-request-rag": { - "accuracy": 63.58231140839836, - "pending": 0, - "requests": 2691 - }, - "prediction-request-rag-claude": { - "accuracy": 65.64351103931072, - "pending": 0, - "requests": 7428 - }, - "prediction-request-reasoning": { - "accuracy": 67.11374625834677, - "pending": 1570, - "requests": 17372 - }, - "prediction-request-reasoning-claude": { - "accuracy": 66.72064777327935, - "pending": 0, - "requests": 2470 - }, - "prediction-url-cot-claude": { - "accuracy": 61.904761904761905, - "pending": 0, - "requests": 1596 - }, - "superforcaster": { - "accuracy": 59.104761904761905, - "pending": 0, - "requests": 596 - } - }, - "eps": 0.1, - "updated_ts": 1732095874, - "weighted_accuracy": { - "claude-prediction-offline": 0.5731026698142933, - "claude-prediction-online": 0.6103536859706571, - "prediction-offline": 0.6725913681009724, - "prediction-offline-sme": 0.6703320894919184, - "prediction-online": 0.6592139883562407, - "prediction-online-sme": 0.6563261234196577, - "prediction-request-rag": 0.6346874770676403, - "prediction-request-rag-claude": 0.6554635569636367, - "prediction-request-reasoning": 0.6706711741029258, - "prediction-request-reasoning-claude": 0.6657429380782109, - "prediction-url-cot-claude": 0.6179929719207252 - } -} \ No newline at end of file diff --git a/trader_backup/data/policy_store_multi_bet_failure_adjusting.json b/trader_backup/data/policy_store_multi_bet_failure_adjusting.json deleted file mode 100644 index 7d61291a9..000000000 --- a/trader_backup/data/policy_store_multi_bet_failure_adjusting.json +++ /dev/null @@ -1,132 +0,0 @@ -{ - "accuracy_store": { - "claude-prediction-offline": { - "accuracy": 57.0309917355372, - "pending": -3, - "requests": 484 - }, - "claude-prediction-online": { - "accuracy": 60.96691871455576, - "pending": -3, - "requests": 1058 - }, - "prediction-offline": { - "accuracy": 66.93951523237716, - "pending": -6, - "requests": 4497 - }, - "prediction-offline-sme": { - "accuracy": 63.30882352941177, - "pending": -3, - "requests": 68 - }, - "prediction-online": { - "accuracy": 65.95830262188062, - "pending": -5, - "requests": 9497 - }, - "prediction-online-sme": { - "accuracy": 65.64752867285638, - "pending": -4, - "requests": 14648 - }, - "prediction-request-rag": { - "accuracy": 63.46624629080119, - "pending": -3, - "requests": 2696 - }, - "prediction-request-rag-claude": { - "accuracy": 65.60002690703621, - "pending": -5, - "requests": 7433 - }, - "prediction-request-reasoning": { - "accuracy": 66.55790855642444, - "pending": -25, - "requests": 17519 - }, - "prediction-request-reasoning-claude": { - "accuracy": 66.6143896523848, - "pending": -4, - "requests": 2474 - }, - "prediction-url-cot-claude": { - "accuracy": 61.71392879450344, - "pending": -3, - "requests": 1601 - }, - "superforcaster": { - "accuracy": 49.09876, - "pending": -4, - "requests": 4 - } - }, - "consecutive_failures": { - "claude-prediction-offline": { - "n_failures": 3, - "timestamp": 1735921729 - }, - "claude-prediction-online": { - "n_failures": 3, - "timestamp": 1735921704 - }, - "prediction-offline": { - "n_failures": 7, - "timestamp": 1735921910 - }, - "prediction-offline-sme": { - "n_failures": 3, - "timestamp": 1735921649 - }, - "prediction-online": { - "n_failures": 0, - "timestamp": 1735925421 - }, - "prediction-online-sme": { - "n_failures": 0, - "timestamp": 1735925686 - }, - "prediction-request-rag": { - "n_failures": 0, - "timestamp": 1735925587 - }, - "prediction-request-rag-claude": { - "n_failures": 5, - "timestamp": 1735921841 - }, - "prediction-request-reasoning": { - "n_failures": 0, - "timestamp": 1735925816 - }, - "prediction-request-reasoning-claude": { - "n_failures": 4, - "timestamp": 1735921661 - }, - "prediction-url-cot-claude": { - "n_failures": 0, - "timestamp": 1735925593 - }, - "superforcaster": { - "n_failures": 4, - "timestamp": 1735921767 - } - }, - "consecutive_failures_threshold": 2, - "eps": 0.1, - "quarantine_duration": 18000, - "updated_ts": 1735920991, - "weighted_accuracy": { - "claude-prediction-offline": 0.5696527207994426, - "claude-prediction-online": 0.6086681927373647, - "prediction-offline": 0.66807803913214, - "prediction-offline-sme": 0.6317762072590968, - "prediction-online": 0.6587627902179048, - "prediction-online-sme": 0.6560976220360418, - "prediction-request-rag": 0.6335449872245215, - "prediction-request-rag-claude": 0.6550504654224211, - "prediction-request-reasoning": 0.6653425328432643, - "prediction-request-reasoning-claude": 0.66469705199124, - "prediction-url-cot-claude": 0.6161077512252101, - "superforcaster": 0.01485212484033692 - } -} \ No newline at end of file diff --git a/trader_backup/data/utilized_tools.json b/trader_backup/data/utilized_tools.json deleted file mode 100644 index 6f38a7ed4..000000000 --- a/trader_backup/data/utilized_tools.json +++ /dev/null @@ -1 +0,0 @@ -{"0x6042b69a6fc11be884faa666d5dc9355f03a8e272d55c2bb44c8ed15a81fd524": "prediction-offline", "0x8751bb5472052acb793e7d4264910b6037fe9db8e568627a81025715f27e2e49": "prediction-offline", "0x98a8b36b475a41c4b93897fb98482ea5cfad8e5d5dee6dd273bcc315e1d05118": "prediction-offline", "0xc2b6f1b6e3aeb67abcbe1b8681315717c88609ac4b8e3bc5317eda8778236d30": "prediction-offline"} \ No newline at end of file diff --git a/trader_backup/vendor/jhehemann/customs/__init__.py b/trader_backup/vendor/jhehemann/customs/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_backup/vendor/jhehemann/customs/kelly_criterion/__init__.py b/trader_backup/vendor/jhehemann/customs/kelly_criterion/__init__.py deleted file mode 100644 index f562b286a..000000000 --- a/trader_backup/vendor/jhehemann/customs/kelly_criterion/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the kelly criterion strategy.""" diff --git a/trader_backup/vendor/jhehemann/customs/kelly_criterion/component.yaml b/trader_backup/vendor/jhehemann/customs/kelly_criterion/component.yaml deleted file mode 100644 index 216c7bd70..000000000 --- a/trader_backup/vendor/jhehemann/customs/kelly_criterion/component.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: kelly_criterion -author: jhehemann -version: 0.1.0 -type: custom -description: The kelly criterion trading strategy. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeiatntqojmmkgwtqubfzp2zf4viusno2vkf7dfy4b343hmymhtf72y - kelly_criterion.py: bafybeiaeazylun25iol746juwtgc4qeuj2rlrtyqhudztpacyybbsgglcy -fingerprint_ignore_patterns: [] -entry_point: kelly_criterion.py -callable: run -dependencies: {} diff --git a/trader_backup/vendor/jhehemann/customs/kelly_criterion/kelly_criterion.py b/trader_backup/vendor/jhehemann/customs/kelly_criterion/kelly_criterion.py deleted file mode 100644 index 1c7a9b3cb..000000000 --- a/trader_backup/vendor/jhehemann/customs/kelly_criterion/kelly_criterion.py +++ /dev/null @@ -1,161 +0,0 @@ -# -*- 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 the kelly criterion strategy.""" - -from typing import Dict, Any, List, Union - -REQUIRED_FIELDS = frozenset( - { - # the fraction of the calculated kelly bet amount to use for placing the bet - "bet_kelly_fraction", - "bankroll", - "win_probability", - "confidence", - "selected_type_tokens_in_pool", - "other_tokens_in_pool", - "bet_fee", - "floor_balance", - } -) -OPTIONAL_FIELDS = frozenset({"max_bet"}) -ALL_FIELDS = REQUIRED_FIELDS.union(OPTIONAL_FIELDS) -DEFAULT_MAX_BET = 8e17 - - -def check_missing_fields(kwargs: Dict[str, Any]) -> List[str]: - """Check for missing fields and return them, if any.""" - missing = [] - for field in REQUIRED_FIELDS: - if kwargs.get(field, None) is None: - missing.append(field) - return missing - - -def remove_irrelevant_fields(kwargs: Dict[str, Any]) -> Dict[str, Any]: - """Remove the irrelevant fields from the given kwargs.""" - return {key: value for key, value in kwargs.items() if key in ALL_FIELDS} - - -def calculate_kelly_bet_amount( - x: int, y: int, p: float, c: float, b: int, f: float -) -> int: - """Calculate the Kelly bet amount.""" - if b == 0: - return 0 - numerator = ( - -4 * x**2 * y - + b * y**2 * p * c * f - + 2 * b * x * y * p * c * f - + b * x**2 * p * c * f - - 2 * b * y**2 * f - - 2 * b * x * y * f - + ( - ( - 4 * x**2 * y - - b * y**2 * p * c * f - - 2 * b * x * y * p * c * f - - b * x**2 * p * c * f - + 2 * b * y**2 * f - + 2 * b * x * y * f - ) - ** 2 - - ( - 4 - * (x**2 * f - y**2 * f) - * ( - -4 * b * x * y**2 * p * c - - 4 * b * x**2 * y * p * c - + 4 * b * x * y**2 - ) - ) - ) - ** (1 / 2) - ) - denominator = 2 * (x**2 * f - y**2 * f) - if denominator == 0: - return 0 - kelly_bet_amount = numerator / denominator - return int(kelly_bet_amount) - - -def wei_to_native(wei: int) -> float: - """Convert WEI to native token.""" - return wei / 10**18 - - -def get_bet_amount_kelly( # pylint: disable=too-many-arguments - bet_kelly_fraction: float, - bankroll: int, - win_probability: float, - confidence: float, - selected_type_tokens_in_pool: int, - other_tokens_in_pool: int, - bet_fee: int, - floor_balance: int, - max_bet: int = DEFAULT_MAX_BET, -) -> Dict[str, Union[int, List[str]]]: - """Calculate the Kelly bet amount.""" - # keep `floor_balance` xDAI in the bankroll - bankroll_adj = bankroll - floor_balance - bankroll_adj = min(bankroll_adj, max_bet) - bankroll_adj_xdai = wei_to_native(bankroll_adj) - info = [f"Adjusted bankroll: {bankroll_adj_xdai} xDAI."] - error = [] - if bankroll_adj <= 0: - error.append( - f"Bankroll ({bankroll_adj}) is less than the floor balance ({floor_balance})." - ) - error.append("Set bet amount to 0.") - error.append("Top up safe with DAI or wait for redeeming.") - return {"bet_amount": 0, "info": info, "error": error} - - fee_fraction = 1 - wei_to_native(bet_fee) - info.append(f"Fee fraction: {fee_fraction}") - kelly_bet_amount = calculate_kelly_bet_amount( - selected_type_tokens_in_pool, - other_tokens_in_pool, - win_probability, - confidence, - bankroll_adj, - fee_fraction, - ) - if kelly_bet_amount < 0: - info.append( - f"Invalid value for kelly bet amount: {kelly_bet_amount}\nSet bet amount to 0." - ) - return {"bet_amount": 0, "info": info, "error": error} - - info.append(f"Kelly bet amount: {wei_to_native(kelly_bet_amount)} xDAI") - info.append(f"Bet kelly fraction: {bet_kelly_fraction}") - adj_kelly_bet_amount = int(kelly_bet_amount * bet_kelly_fraction) - info.append( - f"Adjusted Kelly bet amount: {wei_to_native(adj_kelly_bet_amount)} xDAI" - ) - return {"bet_amount": adj_kelly_bet_amount, "info": info, "error": error} - - -def run(*_args, **kwargs) -> Dict[str, Union[int, List[str]]]: - """Run the strategy.""" - missing = check_missing_fields(kwargs) - if len(missing) > 0: - return {"error": [f"Required kwargs {missing} were not provided."]} - - kwargs = remove_irrelevant_fields(kwargs) - return get_bet_amount_kelly(**kwargs) diff --git a/trader_backup/vendor/open_aea/protocols/__init__.py b/trader_backup/vendor/open_aea/protocols/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_backup/vendor/open_aea/protocols/signing/README.md b/trader_backup/vendor/open_aea/protocols/signing/README.md deleted file mode 100644 index d010fe5b6..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Signing Protocol - -## Description - -This is a protocol for communication between a skill and a decision maker. - -## Specification - -```yaml ---- -name: signing -author: open_aea -version: 1.0.0 -description: A protocol for communication between skills and decision maker. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: open_aea/signing:1.0.0 -speech_acts: - sign_transaction: - terms: ct:Terms - raw_transaction: ct:RawTransaction - sign_message: - terms: ct:Terms - raw_message: ct:RawMessage - signed_transaction: - signed_transaction: ct:SignedTransaction - signed_message: - signed_message: ct:SignedMessage - error: - error_code: ct:ErrorCode -... ---- -ct:ErrorCode: | - enum ErrorCodeEnum { - UNSUCCESSFUL_MESSAGE_SIGNING = 0; - UNSUCCESSFUL_TRANSACTION_SIGNING = 1; - } - ErrorCodeEnum error_code = 1; -ct:RawMessage: | - bytes raw_message = 1; -ct:RawTransaction: | - bytes raw_transaction = 1; -ct:SignedMessage: | - bytes signed_message = 1; -ct:SignedTransaction: | - bytes signed_transaction = 1; -ct:Terms: | - bytes terms = 1; -... ---- -initiation: [sign_transaction, sign_message] -reply: - sign_transaction: [signed_transaction, error] - sign_message: [signed_message, error] - signed_transaction: [] - signed_message: [] - error: [] -termination: [signed_transaction, signed_message, error] -roles: {skill, decision_maker} -end_states: [successful, failed] -keep_terminal_state_dialogues: false -... -``` - -## Links diff --git a/trader_backup/vendor/open_aea/protocols/signing/__init__.py b/trader_backup/vendor/open_aea/protocols/signing/__init__.py deleted file mode 100644 index f202d9656..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 open_aea -# -# 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 the support resources for the signing protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.open_aea.protocols.signing.message import SigningMessage -from packages.open_aea.protocols.signing.serialization import SigningSerializer - - -SigningMessage.serializer = SigningSerializer diff --git a/trader_backup/vendor/open_aea/protocols/signing/custom_types.py b/trader_backup/vendor/open_aea/protocols/signing/custom_types.py deleted file mode 100644 index 121631b44..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/custom_types.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2020 open_aea -# -# 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 class representations corresponding to every custom type in the protocol specification.""" - -from enum import Enum -from typing import Any - -from aea.helpers.transaction.base import RawMessage as BaseRawMessage -from aea.helpers.transaction.base import RawTransaction as BaseRawTransaction -from aea.helpers.transaction.base import SignedMessage as BaseSignedMessage -from aea.helpers.transaction.base import SignedTransaction as BaseSignedTransaction -from aea.helpers.transaction.base import Terms as BaseTerms - - -class ErrorCode(Enum): - """This class represents an instance of ErrorCode.""" - - UNSUCCESSFUL_MESSAGE_SIGNING = 0 - UNSUCCESSFUL_TRANSACTION_SIGNING = 1 - - @staticmethod - def encode(error_code_protobuf_object: Any, error_code_object: "ErrorCode") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the error_code_protobuf_object argument is matched with the instance of this class in the 'error_code_object' argument. - - :param error_code_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param error_code_object: an instance of this class to be encoded in the protocol buffer object. - """ - error_code_protobuf_object.error_code = error_code_object.value - - @classmethod - def decode(cls, error_code_protobuf_object: Any) -> "ErrorCode": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'error_code_protobuf_object' argument. - - :param error_code_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'error_code_protobuf_object' argument. - """ - enum_value_from_pb2 = error_code_protobuf_object.error_code - return ErrorCode(enum_value_from_pb2) - - -RawMessage = BaseRawMessage -RawTransaction = BaseRawTransaction -SignedMessage = BaseSignedMessage -SignedTransaction = BaseSignedTransaction -Terms = BaseTerms diff --git a/trader_backup/vendor/open_aea/protocols/signing/dialogues.py b/trader_backup/vendor/open_aea/protocols/signing/dialogues.py deleted file mode 100644 index 49fc21248..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/dialogues.py +++ /dev/null @@ -1,136 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 open_aea -# -# 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 the classes required for signing dialogue management. - -- SigningDialogue: The dialogue class maintains state of a dialogue and manages it. -- SigningDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.open_aea.protocols.signing.message import SigningMessage - - -class SigningDialogue(Dialogue): - """The signing dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - SigningMessage.Performative.SIGN_TRANSACTION, - SigningMessage.Performative.SIGN_MESSAGE, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - SigningMessage.Performative.SIGNED_TRANSACTION, - SigningMessage.Performative.SIGNED_MESSAGE, - SigningMessage.Performative.ERROR, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - SigningMessage.Performative.ERROR: frozenset(), - SigningMessage.Performative.SIGN_MESSAGE: frozenset( - { - SigningMessage.Performative.SIGNED_MESSAGE, - SigningMessage.Performative.ERROR, - } - ), - SigningMessage.Performative.SIGN_TRANSACTION: frozenset( - { - SigningMessage.Performative.SIGNED_TRANSACTION, - SigningMessage.Performative.ERROR, - } - ), - SigningMessage.Performative.SIGNED_MESSAGE: frozenset(), - SigningMessage.Performative.SIGNED_TRANSACTION: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a signing dialogue.""" - - DECISION_MAKER = "decision_maker" - SKILL = "skill" - - class EndState(Dialogue.EndState): - """This class defines the end states of a signing dialogue.""" - - SUCCESSFUL = 0 - FAILED = 1 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[SigningMessage] = SigningMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class SigningDialogues(Dialogues, ABC): - """This class keeps track of all signing dialogues.""" - - END_STATES = frozenset( - {SigningDialogue.EndState.SUCCESSFUL, SigningDialogue.EndState.FAILED} - ) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[SigningDialogue] = SigningDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=SigningMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_backup/vendor/open_aea/protocols/signing/message.py b/trader_backup/vendor/open_aea/protocols/signing/message.py deleted file mode 100644 index c11b7ea24..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/message.py +++ /dev/null @@ -1,319 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 open_aea -# -# 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 signing's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - -from packages.open_aea.protocols.signing.custom_types import ( - ErrorCode as CustomErrorCode, -) -from packages.open_aea.protocols.signing.custom_types import ( - RawMessage as CustomRawMessage, -) -from packages.open_aea.protocols.signing.custom_types import ( - RawTransaction as CustomRawTransaction, -) -from packages.open_aea.protocols.signing.custom_types import ( - SignedMessage as CustomSignedMessage, -) -from packages.open_aea.protocols.signing.custom_types import ( - SignedTransaction as CustomSignedTransaction, -) -from packages.open_aea.protocols.signing.custom_types import Terms as CustomTerms - - -_default_logger = logging.getLogger("aea.packages.open_aea.protocols.signing.message") - -DEFAULT_BODY_SIZE = 4 - - -class SigningMessage(Message): - """A protocol for communication between skills and decision maker.""" - - protocol_id = PublicId.from_str("open_aea/signing:1.0.0") - protocol_specification_id = PublicId.from_str("open_aea/signing:1.0.0") - - ErrorCode = CustomErrorCode - - RawMessage = CustomRawMessage - - RawTransaction = CustomRawTransaction - - SignedMessage = CustomSignedMessage - - SignedTransaction = CustomSignedTransaction - - Terms = CustomTerms - - class Performative(Message.Performative): - """Performatives for the signing protocol.""" - - ERROR = "error" - SIGN_MESSAGE = "sign_message" - SIGN_TRANSACTION = "sign_transaction" - SIGNED_MESSAGE = "signed_message" - SIGNED_TRANSACTION = "signed_transaction" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = { - "error", - "sign_message", - "sign_transaction", - "signed_message", - "signed_transaction", - } - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "dialogue_reference", - "error_code", - "message_id", - "performative", - "raw_message", - "raw_transaction", - "signed_message", - "signed_transaction", - "target", - "terms", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of SigningMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=SigningMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(SigningMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def error_code(self) -> CustomErrorCode: - """Get the 'error_code' content from the message.""" - enforce(self.is_set("error_code"), "'error_code' content is not set.") - return cast(CustomErrorCode, self.get("error_code")) - - @property - def raw_message(self) -> CustomRawMessage: - """Get the 'raw_message' content from the message.""" - enforce(self.is_set("raw_message"), "'raw_message' content is not set.") - return cast(CustomRawMessage, self.get("raw_message")) - - @property - def raw_transaction(self) -> CustomRawTransaction: - """Get the 'raw_transaction' content from the message.""" - enforce(self.is_set("raw_transaction"), "'raw_transaction' content is not set.") - return cast(CustomRawTransaction, self.get("raw_transaction")) - - @property - def signed_message(self) -> CustomSignedMessage: - """Get the 'signed_message' content from the message.""" - enforce(self.is_set("signed_message"), "'signed_message' content is not set.") - return cast(CustomSignedMessage, self.get("signed_message")) - - @property - def signed_transaction(self) -> CustomSignedTransaction: - """Get the 'signed_transaction' content from the message.""" - enforce( - self.is_set("signed_transaction"), - "'signed_transaction' content is not set.", - ) - return cast(CustomSignedTransaction, self.get("signed_transaction")) - - @property - def terms(self) -> CustomTerms: - """Get the 'terms' content from the message.""" - enforce(self.is_set("terms"), "'terms' content is not set.") - return cast(CustomTerms, self.get("terms")) - - def _is_consistent(self) -> bool: - """Check that the message follows the signing protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, SigningMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == SigningMessage.Performative.SIGN_TRANSACTION: - expected_nb_of_contents = 2 - enforce( - isinstance(self.terms, CustomTerms), - "Invalid type for content 'terms'. Expected 'Terms'. Found '{}'.".format( - type(self.terms) - ), - ) - enforce( - isinstance(self.raw_transaction, CustomRawTransaction), - "Invalid type for content 'raw_transaction'. Expected 'RawTransaction'. Found '{}'.".format( - type(self.raw_transaction) - ), - ) - elif self.performative == SigningMessage.Performative.SIGN_MESSAGE: - expected_nb_of_contents = 2 - enforce( - isinstance(self.terms, CustomTerms), - "Invalid type for content 'terms'. Expected 'Terms'. Found '{}'.".format( - type(self.terms) - ), - ) - enforce( - isinstance(self.raw_message, CustomRawMessage), - "Invalid type for content 'raw_message'. Expected 'RawMessage'. Found '{}'.".format( - type(self.raw_message) - ), - ) - elif self.performative == SigningMessage.Performative.SIGNED_TRANSACTION: - expected_nb_of_contents = 1 - enforce( - isinstance(self.signed_transaction, CustomSignedTransaction), - "Invalid type for content 'signed_transaction'. Expected 'SignedTransaction'. Found '{}'.".format( - type(self.signed_transaction) - ), - ) - elif self.performative == SigningMessage.Performative.SIGNED_MESSAGE: - expected_nb_of_contents = 1 - enforce( - isinstance(self.signed_message, CustomSignedMessage), - "Invalid type for content 'signed_message'. Expected 'SignedMessage'. Found '{}'.".format( - type(self.signed_message) - ), - ) - elif self.performative == SigningMessage.Performative.ERROR: - expected_nb_of_contents = 1 - enforce( - isinstance(self.error_code, CustomErrorCode), - "Invalid type for content 'error_code'. Expected 'ErrorCode'. Found '{}'.".format( - type(self.error_code) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_backup/vendor/open_aea/protocols/signing/protocol.yaml b/trader_backup/vendor/open_aea/protocols/signing/protocol.yaml deleted file mode 100644 index 67aa31c87..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/protocol.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: signing -author: open_aea -version: 1.0.0 -protocol_specification_id: open_aea/signing:1.0.0 -type: protocol -description: A protocol for communication between skills and decision maker. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeictzqfrs3zlpmirbelejsenkupesqh7nkjncbopkmamk7dkersmrm - __init__.py: bafybeiarl4y6yah6cypjp2jqvlcpexpkt6zcgtcs67a6wsur7ncqa6u7d4 - custom_types.py: bafybeicbmroddjj6xvtoi6k6d2mt7iqr3uwxvhwt3ecpy5ze52ffc6i7bq - dialogues.py: bafybeiblb6pmkl3rluy27rn5525yvmkitcdpkb2a52byn2l7jsafsnnye4 - message.py: bafybeibwldxym64enuo55bzlhb64i34e4hnncstyj2tpnei5gcyrrww3h4 - serialization.py: bafybeialbbd7zxf6e2jekr6lev5gznux5wf3ivbiqsangwznkjyozfep2a - signing.proto: bafybeigbzr6x5wdmqzc7eanlz5xmvaoiwb4kwozgg3cugq63b7esicusra - signing_pb2.py: bafybeig5sfgd3zkclg4fwfpkq7mfh2vtv27jjgpmlzrnk2ti2po5ciysiq - tests/__init__.py: bafybeiaraxpv2z6r4e5rgmvnvdfv5rlrjdwbhqyjocxm2z2wkzpluezdey - tests/test_signing.py: bafybeifaiu6jzymbxhglisc57taub3igt5ftvs6c37s3ddonk7hxr2ni7i - tests/test_signing_dialogues.py: bafybeiewiya7lfnq4uiw3g2apa5mrxnzsy6lsu2xrbd5ljrm43rszrue7m - tests/test_signing_messages.py: bafybeiaiq6nx5v3tihclumgqpl32aqq7lr6vecqhifdefqze7inba67x6m -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_backup/vendor/open_aea/protocols/signing/serialization.py b/trader_backup/vendor/open_aea/protocols/signing/serialization.py deleted file mode 100644 index 5526c6bbf..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/serialization.py +++ /dev/null @@ -1,162 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 open_aea -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for signing protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.open_aea.protocols.signing import signing_pb2 # type: ignore -from packages.open_aea.protocols.signing.custom_types import ( # type: ignore - ErrorCode, - RawMessage, - RawTransaction, - SignedMessage, - SignedTransaction, - Terms, -) -from packages.open_aea.protocols.signing.message import SigningMessage # type: ignore - - -class SigningSerializer(Serializer): - """Serialization for the 'signing' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'Signing' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(SigningMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - signing_msg = signing_pb2.SigningMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == SigningMessage.Performative.SIGN_TRANSACTION: - performative = signing_pb2.SigningMessage.Sign_Transaction_Performative() # type: ignore - terms = msg.terms - Terms.encode(performative.terms, terms) - raw_transaction = msg.raw_transaction - RawTransaction.encode(performative.raw_transaction, raw_transaction) - signing_msg.sign_transaction.CopyFrom(performative) - elif performative_id == SigningMessage.Performative.SIGN_MESSAGE: - performative = signing_pb2.SigningMessage.Sign_Message_Performative() # type: ignore - terms = msg.terms - Terms.encode(performative.terms, terms) - raw_message = msg.raw_message - RawMessage.encode(performative.raw_message, raw_message) - signing_msg.sign_message.CopyFrom(performative) - elif performative_id == SigningMessage.Performative.SIGNED_TRANSACTION: - performative = signing_pb2.SigningMessage.Signed_Transaction_Performative() # type: ignore - signed_transaction = msg.signed_transaction - SignedTransaction.encode( - performative.signed_transaction, signed_transaction - ) - signing_msg.signed_transaction.CopyFrom(performative) - elif performative_id == SigningMessage.Performative.SIGNED_MESSAGE: - performative = signing_pb2.SigningMessage.Signed_Message_Performative() # type: ignore - signed_message = msg.signed_message - SignedMessage.encode(performative.signed_message, signed_message) - signing_msg.signed_message.CopyFrom(performative) - elif performative_id == SigningMessage.Performative.ERROR: - performative = signing_pb2.SigningMessage.Error_Performative() # type: ignore - error_code = msg.error_code - ErrorCode.encode(performative.error_code, error_code) - signing_msg.error.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = signing_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'Signing' message. - - :param obj: the bytes object. - :return: the 'Signing' message. - """ - message_pb = ProtobufMessage() - signing_pb = signing_pb2.SigningMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - signing_pb.ParseFromString(message_pb.dialogue_message.content) - performative = signing_pb.WhichOneof("performative") - performative_id = SigningMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == SigningMessage.Performative.SIGN_TRANSACTION: - pb2_terms = signing_pb.sign_transaction.terms - terms = Terms.decode(pb2_terms) - performative_content["terms"] = terms - pb2_raw_transaction = signing_pb.sign_transaction.raw_transaction - raw_transaction = RawTransaction.decode(pb2_raw_transaction) - performative_content["raw_transaction"] = raw_transaction - elif performative_id == SigningMessage.Performative.SIGN_MESSAGE: - pb2_terms = signing_pb.sign_message.terms - terms = Terms.decode(pb2_terms) - performative_content["terms"] = terms - pb2_raw_message = signing_pb.sign_message.raw_message - raw_message = RawMessage.decode(pb2_raw_message) - performative_content["raw_message"] = raw_message - elif performative_id == SigningMessage.Performative.SIGNED_TRANSACTION: - pb2_signed_transaction = signing_pb.signed_transaction.signed_transaction - signed_transaction = SignedTransaction.decode(pb2_signed_transaction) - performative_content["signed_transaction"] = signed_transaction - elif performative_id == SigningMessage.Performative.SIGNED_MESSAGE: - pb2_signed_message = signing_pb.signed_message.signed_message - signed_message = SignedMessage.decode(pb2_signed_message) - performative_content["signed_message"] = signed_message - elif performative_id == SigningMessage.Performative.ERROR: - pb2_error_code = signing_pb.error.error_code - error_code = ErrorCode.decode(pb2_error_code) - performative_content["error_code"] = error_code - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return SigningMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_backup/vendor/open_aea/protocols/signing/signing.proto b/trader_backup/vendor/open_aea/protocols/signing/signing.proto deleted file mode 100644 index 57dc09d17..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/signing.proto +++ /dev/null @@ -1,68 +0,0 @@ -syntax = "proto3"; - -package aea.open_aea.signing.v1_0_0; - -message SigningMessage{ - - // Custom Types - message ErrorCode{ - enum ErrorCodeEnum { - UNSUCCESSFUL_MESSAGE_SIGNING = 0; - UNSUCCESSFUL_TRANSACTION_SIGNING = 1; - } - ErrorCodeEnum error_code = 1; - } - - message RawMessage{ - bytes raw_message = 1; - } - - message RawTransaction{ - bytes raw_transaction = 1; - } - - message SignedMessage{ - bytes signed_message = 1; - } - - message SignedTransaction{ - bytes signed_transaction = 1; - } - - message Terms{ - bytes terms = 1; - } - - - // Performatives and contents - message Sign_Transaction_Performative{ - Terms terms = 1; - RawTransaction raw_transaction = 2; - } - - message Sign_Message_Performative{ - Terms terms = 1; - RawMessage raw_message = 2; - } - - message Signed_Transaction_Performative{ - SignedTransaction signed_transaction = 1; - } - - message Signed_Message_Performative{ - SignedMessage signed_message = 1; - } - - message Error_Performative{ - ErrorCode error_code = 1; - } - - - oneof performative{ - Error_Performative error = 5; - Sign_Message_Performative sign_message = 6; - Sign_Transaction_Performative sign_transaction = 7; - Signed_Message_Performative signed_message = 8; - Signed_Transaction_Performative signed_transaction = 9; - } -} diff --git a/trader_backup/vendor/open_aea/protocols/signing/signing_pb2.py b/trader_backup/vendor/open_aea/protocols/signing/signing_pb2.py deleted file mode 100644 index f0d03c3a9..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/signing_pb2.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: signing.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\rsigning.proto\x12\x1b\x61\x65\x61.open_aea.signing.v1_0_0"\xbc\x0c\n\x0eSigningMessage\x12O\n\x05\x65rror\x18\x05 \x01(\x0b\x32>.aea.open_aea.signing.v1_0_0.SigningMessage.Error_PerformativeH\x00\x12]\n\x0csign_message\x18\x06 \x01(\x0b\x32\x45.aea.open_aea.signing.v1_0_0.SigningMessage.Sign_Message_PerformativeH\x00\x12\x65\n\x10sign_transaction\x18\x07 \x01(\x0b\x32I.aea.open_aea.signing.v1_0_0.SigningMessage.Sign_Transaction_PerformativeH\x00\x12\x61\n\x0esigned_message\x18\x08 \x01(\x0b\x32G.aea.open_aea.signing.v1_0_0.SigningMessage.Signed_Message_PerformativeH\x00\x12i\n\x12signed_transaction\x18\t \x01(\x0b\x32K.aea.open_aea.signing.v1_0_0.SigningMessage.Signed_Transaction_PerformativeH\x00\x1a\xbd\x01\n\tErrorCode\x12W\n\nerror_code\x18\x01 \x01(\x0e\x32\x43.aea.open_aea.signing.v1_0_0.SigningMessage.ErrorCode.ErrorCodeEnum"W\n\rErrorCodeEnum\x12 \n\x1cUNSUCCESSFUL_MESSAGE_SIGNING\x10\x00\x12$\n UNSUCCESSFUL_TRANSACTION_SIGNING\x10\x01\x1a!\n\nRawMessage\x12\x13\n\x0braw_message\x18\x01 \x01(\x0c\x1a)\n\x0eRawTransaction\x12\x17\n\x0fraw_transaction\x18\x01 \x01(\x0c\x1a\'\n\rSignedMessage\x12\x16\n\x0esigned_message\x18\x01 \x01(\x0c\x1a/\n\x11SignedTransaction\x12\x1a\n\x12signed_transaction\x18\x01 \x01(\x0c\x1a\x16\n\x05Terms\x12\r\n\x05terms\x18\x01 \x01(\x0c\x1a\xb6\x01\n\x1dSign_Transaction_Performative\x12@\n\x05terms\x18\x01 \x01(\x0b\x32\x31.aea.open_aea.signing.v1_0_0.SigningMessage.Terms\x12S\n\x0fraw_transaction\x18\x02 \x01(\x0b\x32:.aea.open_aea.signing.v1_0_0.SigningMessage.RawTransaction\x1a\xaa\x01\n\x19Sign_Message_Performative\x12@\n\x05terms\x18\x01 \x01(\x0b\x32\x31.aea.open_aea.signing.v1_0_0.SigningMessage.Terms\x12K\n\x0braw_message\x18\x02 \x01(\x0b\x32\x36.aea.open_aea.signing.v1_0_0.SigningMessage.RawMessage\x1a|\n\x1fSigned_Transaction_Performative\x12Y\n\x12signed_transaction\x18\x01 \x01(\x0b\x32=.aea.open_aea.signing.v1_0_0.SigningMessage.SignedTransaction\x1ap\n\x1bSigned_Message_Performative\x12Q\n\x0esigned_message\x18\x01 \x01(\x0b\x32\x39.aea.open_aea.signing.v1_0_0.SigningMessage.SignedMessage\x1a_\n\x12\x45rror_Performative\x12I\n\nerror_code\x18\x01 \x01(\x0b\x32\x35.aea.open_aea.signing.v1_0_0.SigningMessage.ErrorCodeB\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "signing_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals["_SIGNINGMESSAGE"]._serialized_start = 47 - _globals["_SIGNINGMESSAGE"]._serialized_end = 1643 - _globals["_SIGNINGMESSAGE_ERRORCODE"]._serialized_start = 551 - _globals["_SIGNINGMESSAGE_ERRORCODE"]._serialized_end = 740 - _globals["_SIGNINGMESSAGE_ERRORCODE_ERRORCODEENUM"]._serialized_start = 653 - _globals["_SIGNINGMESSAGE_ERRORCODE_ERRORCODEENUM"]._serialized_end = 740 - _globals["_SIGNINGMESSAGE_RAWMESSAGE"]._serialized_start = 742 - _globals["_SIGNINGMESSAGE_RAWMESSAGE"]._serialized_end = 775 - _globals["_SIGNINGMESSAGE_RAWTRANSACTION"]._serialized_start = 777 - _globals["_SIGNINGMESSAGE_RAWTRANSACTION"]._serialized_end = 818 - _globals["_SIGNINGMESSAGE_SIGNEDMESSAGE"]._serialized_start = 820 - _globals["_SIGNINGMESSAGE_SIGNEDMESSAGE"]._serialized_end = 859 - _globals["_SIGNINGMESSAGE_SIGNEDTRANSACTION"]._serialized_start = 861 - _globals["_SIGNINGMESSAGE_SIGNEDTRANSACTION"]._serialized_end = 908 - _globals["_SIGNINGMESSAGE_TERMS"]._serialized_start = 910 - _globals["_SIGNINGMESSAGE_TERMS"]._serialized_end = 932 - _globals["_SIGNINGMESSAGE_SIGN_TRANSACTION_PERFORMATIVE"]._serialized_start = 935 - _globals["_SIGNINGMESSAGE_SIGN_TRANSACTION_PERFORMATIVE"]._serialized_end = 1117 - _globals["_SIGNINGMESSAGE_SIGN_MESSAGE_PERFORMATIVE"]._serialized_start = 1120 - _globals["_SIGNINGMESSAGE_SIGN_MESSAGE_PERFORMATIVE"]._serialized_end = 1290 - _globals["_SIGNINGMESSAGE_SIGNED_TRANSACTION_PERFORMATIVE"]._serialized_start = 1292 - _globals["_SIGNINGMESSAGE_SIGNED_TRANSACTION_PERFORMATIVE"]._serialized_end = 1416 - _globals["_SIGNINGMESSAGE_SIGNED_MESSAGE_PERFORMATIVE"]._serialized_start = 1418 - _globals["_SIGNINGMESSAGE_SIGNED_MESSAGE_PERFORMATIVE"]._serialized_end = 1530 - _globals["_SIGNINGMESSAGE_ERROR_PERFORMATIVE"]._serialized_start = 1532 - _globals["_SIGNINGMESSAGE_ERROR_PERFORMATIVE"]._serialized_end = 1627 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/open_aea/protocols/signing/tests/__init__.py b/trader_backup/vendor/open_aea/protocols/signing/tests/__init__.py deleted file mode 100644 index 1ca32bbc0..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 package contains the tests of the signing protocol package.""" diff --git a/trader_backup/vendor/open_aea/protocols/signing/tests/test_signing.py b/trader_backup/vendor/open_aea/protocols/signing/tests/test_signing.py deleted file mode 100644 index 5866ade42..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/tests/test_signing.py +++ /dev/null @@ -1,144 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 Valory AG -# Copyright 2018-2019 Fetch.AI Limited -# -# 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 tests for transaction.""" -# pylint: skip-file - -from typing import List, Type - -from aea_ledger_cosmos import CosmosCrypto - -from aea.helpers.transaction.base import ( - RawMessage, - RawTransaction, - SignedMessage, - SignedTransaction, - Terms, -) -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import Dialogues -from aea.test_tools.test_protocol import ( - BaseProtocolDialoguesTestCase, - BaseProtocolMessagesTestCase, -) - -from packages.open_aea.protocols.signing.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.open_aea.protocols.signing.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.open_aea.protocols.signing.message import SigningMessage - - -class TestMessages(BaseProtocolMessagesTestCase): - """Base class to test message construction for the protocol.""" - - MESSAGE_CLASS = SigningMessage - - ledger_id = CosmosCrypto.identifier - terms = Terms( - ledger_id=ledger_id, - sender_address="address1", - counterparty_address="address2", - amount_by_currency_id={"FET": -2}, - quantities_by_good_id={"good_id": 10}, - is_sender_payable_tx_fee=True, - nonce="transaction nonce", - ) - - def build_messages(self) -> List[SigningMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - SigningMessage( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - terms=self.terms, - raw_transaction=RawTransaction(self.ledger_id, {"tx": "transaction"}), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGN_MESSAGE, - terms=self.terms, - raw_message=RawMessage(self.ledger_id, b"message"), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGNED_TRANSACTION, - message_id=2, - target=1, - signed_transaction=SignedTransaction( - self.ledger_id, {"sig": "signature"} - ), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGNED_MESSAGE, - message_id=2, - target=1, - signed_message=SignedMessage(self.ledger_id, "message"), - ), - SigningMessage( - performative=SigningMessage.Performative.ERROR, - message_id=2, - target=1, - error_code=SigningMessage.ErrorCode.UNSUCCESSFUL_MESSAGE_SIGNING, - ), - ] - - def build_inconsistent(self) -> List[SigningMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - SigningMessage( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - terms=self.terms, - ), - SigningMessage( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - raw_transaction=RawTransaction(self.ledger_id, {"tx": "transaction"}), - ), - SigningMessage( - performative=SigningMessage.Performative.ERROR, - message_id=2, - target=1, - ), - ] - - -class TestDialogues(BaseProtocolDialoguesTestCase): - """Test dialogues.""" - - MESSAGE_CLASS: Type[Message] = SigningMessage - DIALOGUE_CLASS: Type[BaseDialogue] = BaseSigningDialogue - DIALOGUES_CLASS: Type[Dialogues] = BaseSigningDialogues - ROLE_FOR_THE_FIRST_MESSAGE = BaseSigningDialogue.Role.SKILL - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - terms=Terms( - ledger_id="ledger_id", - sender_address="address1", - counterparty_address="address2", - amount_by_currency_id={"FET": -2}, - quantities_by_good_id={"good_id": 10}, - is_sender_payable_tx_fee=True, - nonce="transaction nonce", - ), - raw_transaction=RawTransaction("ledger_id", {"tx": "transaction"}), - ) diff --git a/trader_backup/vendor/open_aea/protocols/signing/tests/test_signing_dialogues.py b/trader_backup/vendor/open_aea/protocols/signing/tests/test_signing_dialogues.py deleted file mode 100644 index 06b7a1fc9..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/tests/test_signing_dialogues.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 open_aea -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for signing protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.open_aea.protocols.signing.custom_types import RawTransaction, Terms -from packages.open_aea.protocols.signing.dialogues import ( - SigningDialogue, - SigningDialogues, -) -from packages.open_aea.protocols.signing.message import SigningMessage - - -class TestDialoguesSigning(BaseProtocolDialoguesTestCase): - """Test for the 'signing' protocol dialogues.""" - - MESSAGE_CLASS = SigningMessage - - DIALOGUE_CLASS = SigningDialogue - - DIALOGUES_CLASS = SigningDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = SigningDialogue.Role.DECISION_MAKER # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - terms=Terms( - ledger_id="ledger_id", - sender_address="address1", - counterparty_address="address2", - amount_by_currency_id={"FET": -2}, - quantities_by_good_id={"good_id": 10}, - is_sender_payable_tx_fee=True, - nonce="transaction nonce", - ), - raw_transaction=RawTransaction("ledger_id", {"tx": "transaction"}), - ) diff --git a/trader_backup/vendor/open_aea/protocols/signing/tests/test_signing_messages.py b/trader_backup/vendor/open_aea/protocols/signing/tests/test_signing_messages.py deleted file mode 100644 index cc352270c..000000000 --- a/trader_backup/vendor/open_aea/protocols/signing/tests/test_signing_messages.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 open_aea -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for signing protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea_ledger_cosmos import CosmosCrypto - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.open_aea.protocols.signing.custom_types import ( - ErrorCode, - RawMessage, - RawTransaction, - SignedMessage, - SignedTransaction, - Terms, -) -from packages.open_aea.protocols.signing.message import SigningMessage - - -class TestMessageSigning(BaseProtocolMessagesTestCase): - """Test for the 'signing' protocol message.""" - - MESSAGE_CLASS = SigningMessage - ledger_id = CosmosCrypto.identifier - terms = Terms( - ledger_id=ledger_id, - sender_address="address1", - counterparty_address="address2", - amount_by_currency_id={"FET": -2}, - quantities_by_good_id={"good_id": 10}, - is_sender_payable_tx_fee=True, - nonce="transaction nonce", - ) - - def build_messages(self) -> List[SigningMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - SigningMessage( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - terms=self.terms, - raw_transaction=RawTransaction(self.ledger_id, {"tx": "transaction"}), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGN_MESSAGE, - terms=self.terms, - raw_message=RawMessage(self.ledger_id, b"message"), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGNED_TRANSACTION, - signed_transaction=SignedTransaction( - self.ledger_id, {"sig": "signature"} - ), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGNED_MESSAGE, - signed_message=SignedMessage(self.ledger_id, "message"), - ), - SigningMessage( - performative=SigningMessage.Performative.ERROR, - error_code=ErrorCode.UNSUCCESSFUL_MESSAGE_SIGNING, - ), - ] - - def build_inconsistent(self) -> List[SigningMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - SigningMessage( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - # skip content: terms - raw_transaction=RawTransaction(self.ledger_id, {"tx": "transaction"}), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGN_MESSAGE, - # skip content: terms - raw_message=RawMessage(self.ledger_id, b"message"), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGNED_TRANSACTION, - # skip content: signed_transaction - ), - SigningMessage( - performative=SigningMessage.Performative.SIGNED_MESSAGE, - # skip content: signed_message - ), - SigningMessage( - performative=SigningMessage.Performative.ERROR, - # skip content: error_code - ), - ] diff --git a/trader_backup/vendor/valory/connections/__init__.py b/trader_backup/vendor/valory/connections/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_backup/vendor/valory/connections/abci/Makefile b/trader_backup/vendor/valory/connections/abci/Makefile deleted file mode 100644 index ac874c59d..000000000 --- a/trader_backup/vendor/valory/connections/abci/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# Origin -version_branch = v0.34.19 -tendermint = https://raw.githubusercontent.com/tendermint/tendermint/$(version_branch) - -# Outputs -tmabci = protos/tendermint/abci/types.proto -tmtypes = protos/tendermint/types/types.proto -tmpubkey = protos/tendermint/crypto/keys.proto -tmproof = protos/tendermint/crypto/proof.proto -tmparams = protos/tendermint/types/params.proto -tmversions = protos/tendermint/version/types.proto -tmvalidator = protos/tendermint/types/validator.proto - -# You *only* need to run this to rebuild protobufs from the tendermint source -update-proto: - curl $(tendermint)/proto/tendermint/abci/types.proto > $(tmabci) - curl $(tendermint)/proto/tendermint/crypto/keys.proto > $(tmpubkey) - curl $(tendermint)/proto/tendermint/crypto/proof.proto > $(tmproof) - curl $(tendermint)/proto/tendermint/types/params.proto > $(tmparams) - curl $(tendermint)/proto/tendermint/types/types.proto > $(tmtypes) - curl $(tendermint)/proto/tendermint/types/validator.proto > $(tmvalidator) - curl $(tendermint)/proto/tendermint/version/types.proto > $(tmversions) - curl $(tendermint)/version/version.go | grep -F -eTMVersionDefault -eABCISemVer > version.txt - python scripts/genproto.py diff --git a/trader_backup/vendor/valory/connections/abci/__init__.py b/trader_backup/vendor/valory/connections/abci/__init__.py deleted file mode 100644 index 106a84724..000000000 --- a/trader_backup/vendor/valory/connections/abci/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Abci connection.""" # pragma: nocover diff --git a/trader_backup/vendor/valory/connections/abci/check_dependencies.py b/trader_backup/vendor/valory/connections/abci/check_dependencies.py deleted file mode 100644 index d2336f3c2..000000000 --- a/trader_backup/vendor/valory/connections/abci/check_dependencies.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ -"""Check dependencies.""" -import re -import shutil -import subprocess # nosec -from itertools import islice -from typing import Iterable, List, Pattern, Tuple - - -ERROR_MESSAGE_TEMPLATE_BINARY_NOT_FOUND = ( - "'{command}' is required by the " - "abci connection, but it is not installed, " - "or it is not accessible from the system path." -) -ERROR_MESSAGE_TEMPLATE_VERSION_TOO_LOW = ( - "The installed version of '{command}' " - "is too low: expected at least {lower_bound}; " - "found {actual_version}." -) - -# for the purposes of this script, -# a version is a tuple of integers: (major, minor, patch) -VERSION = Tuple[int, int, int] -MINIMUM_TENDERMINT_VERSION: VERSION = (0, 34, 19) - - -def nth(iterable: Iterable, index: int, default: int = 0) -> int: - """Returns the item at position 'index' or a default value""" - return next(islice(iterable, index, None), default) - - -def get_version(*args: int) -> VERSION: - """ - Get the version from a list of arguments. - - Set to '0' if there are not enough arguments. - - :param args: positional arguments - :return: the version - """ - major = nth(args, 0, 0) - minor = nth(args, 1, 0) - patch = nth(args, 2, 0) - return major, minor, patch - - -def version_to_string(version: VERSION) -> str: - """ - Transform version to string. - - :param version: the version. - :return: the string representation. - """ - return ".".join(map(str, version)) - - -def print_ok_message( - binary_name: str, actual_version: VERSION, version_lower_bound: VERSION -) -> None: # pragma: nocover - """ - Print OK message. - - :param binary_name: the binary binary_name. - :param actual_version: the actual version. - :param version_lower_bound: the version lower bound. - """ - print( - f"check '{binary_name}'>={version_to_string(version_lower_bound)}, " - f"found {version_to_string(actual_version)}" - ) - - -def check_binary( - binary_name: str, - args: List[str], - version_regex: Pattern, - version_lower_bound: VERSION, - only_warning: bool = False, -) -> None: # pragma: nocover - """ - Check a binary is accessible from the terminal. - - It breaks down in: - 1) check if the binary is reachable from the system path; - 2) check that the version number is higher or equal than the minimum required version. - - :param binary_name: the name of the binary. - :param args: the arguments to provide to the binary to retrieve the version. - :param version_regex: the regex used to extract the version from the output. - :param version_lower_bound: the minimum required version. - :param only_warning: if True, don't raise error but print a warning message - """ - path = shutil.which(binary_name) - if not path: - message = ERROR_MESSAGE_TEMPLATE_BINARY_NOT_FOUND.format(command=binary_name) - if only_warning: - print("Warning: ", message) - return - raise ValueError(message) - - version_getter_command = [binary_name, *args] - stdout = subprocess.check_output(version_getter_command).decode("utf-8") # nosec - version_match = version_regex.search(stdout) - if version_match is None: - print( - f"Warning: cannot parse '{binary_name}' version " - f"from command: {version_getter_command}. stdout: {stdout}" - ) - return - actual_version: VERSION = get_version(*map(int, version_match.groups(default="0"))) - if actual_version < version_lower_bound: - message = ERROR_MESSAGE_TEMPLATE_VERSION_TOO_LOW.format( - command=binary_name, - lower_bound=version_to_string(version_lower_bound), - actual_version=version_to_string(actual_version), - ) - if only_warning: - print(f"Warning: {message}") - return - raise ValueError(message) - - print_ok_message(binary_name, actual_version, version_lower_bound) - - -def check_versions() -> None: # pragma: nocover - """Check versions.""" - check_binary( - "tendermint", - ["version"], - re.compile(r"([0-9]+)\.([0-9]+)\.([0-9]+)"), - MINIMUM_TENDERMINT_VERSION, - only_warning=True, - ) - - -def main() -> None: # pragma: nocover - """The main entrypoint of the script.""" - check_versions() - - -if __name__ == "__main__": - main() # pragma: nocover diff --git a/trader_backup/vendor/valory/connections/abci/connection.py b/trader_backup/vendor/valory/connections/abci/connection.py deleted file mode 100644 index 2eec8de9f..000000000 --- a/trader_backup/vendor/valory/connections/abci/connection.py +++ /dev/null @@ -1,1497 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ -"""Connection to interact with an ABCI server.""" -import asyncio -import json -import logging -import os -import platform -import signal -import subprocess # nosec -import sys -from asyncio import AbstractEventLoop, AbstractServer, CancelledError, Task -from io import BytesIO -from logging import Logger -from pathlib import Path -from threading import Event, Thread -from typing import Any, Dict, List, Optional, Tuple, Union, cast - -import grpc -from aea.configurations.base import PublicId -from aea.connections.base import Connection, ConnectionStates -from aea.exceptions import enforce -from aea.mail.base import Envelope -from aea.protocols.dialogue.base import DialogueLabel -from google.protobuf.message import DecodeError - -from packages.valory.connections.abci.dialogues import AbciDialogues -from packages.valory.connections.abci.tendermint.abci import ( # type: ignore - types_pb2_grpc, -) -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - Request, - RequestApplySnapshotChunk, - RequestBeginBlock, - RequestCheckTx, - RequestCommit, - RequestDeliverTx, - RequestEcho, - RequestEndBlock, - RequestFlush, - RequestInfo, - RequestInitChain, - RequestListSnapshots, - RequestLoadSnapshotChunk, - RequestOfferSnapshot, - RequestQuery, - RequestSetOption, - Response, - ResponseApplySnapshotChunk, - ResponseBeginBlock, - ResponseCheckTx, - ResponseCommit, - ResponseDeliverTx, - ResponseEcho, - ResponseEndBlock, - ResponseFlush, - ResponseInfo, - ResponseInitChain, - ResponseListSnapshots, - ResponseLoadSnapshotChunk, - ResponseOfferSnapshot, - ResponseQuery, - ResponseSetOption, -) -from packages.valory.connections.abci.tendermint_decoder import ( - _TendermintProtocolDecoder, -) -from packages.valory.connections.abci.tendermint_encoder import ( - _TendermintProtocolEncoder, -) -from packages.valory.protocols.abci import AbciMessage - - -PUBLIC_ID = PublicId.from_str("valory/abci:0.1.0") - - -_TCP = "tcp://" -ENCODING = "utf-8" -LOCALHOST = "127.0.0.1" -DEFAULT_ABCI_PORT = 26658 -DEFAULT_P2P_PORT = 26656 -DEFAULT_RPC_PORT = 26657 -DEFAULT_LISTEN_ADDRESS = "0.0.0.0" # nosec -DEFAULT_P2P_LISTEN_ADDRESS = f"{_TCP}{DEFAULT_LISTEN_ADDRESS}:{DEFAULT_P2P_PORT}" -DEFAULT_RPC_LISTEN_ADDRESS = f"{_TCP}{LOCALHOST}:{DEFAULT_RPC_PORT}" -MAX_READ_IN_BYTES = 2**20 # Max we'll consume on a read stream (1 MiB) -MAX_VARINT_BYTES = 10 # Max size of varint we support -DEFAULT_TENDERMINT_LOG_FILE = "tendermint.log" - - -class DecodeVarintError(Exception): - """This exception is raised when an error occurs while decoding a varint.""" - - -class EncodeVarintError(Exception): - """This exception is raised when an error occurs while encoding a varint.""" - - -class TooLargeVarint(Exception): - """This exception is raised when a message with varint exceeding the max size is received.""" - - def __init__(self, received_size: int, max_size: int = MAX_READ_IN_BYTES): - """ - Initialize the exception object. - - :param received_size: the received size. - :param max_size: the maximum amount the connection supports. - """ - super().__init__( - f"The max message size is {max_size}, received message with varint {received_size}." - ) - self.received_size = received_size - self.max_size = max_size - - -class ShortBufferLengthError(Exception): - """This exception is raised when the buffer length is shorter than expected.""" - - def __init__(self, expected_length: int, data: bytes): - """ - Initialize the exception object. - - :param expected_length: the expected length to be read - :param data: the data actually read - """ - super().__init__( - f"expected bytes of length {expected_length}, got bytes of length {len(data)}" - ) - self.expected_length = expected_length - self.data = data - - -class _TendermintABCISerializer: - """(stateless) utility class to encode/decode messages for the communication with Tendermint.""" - - @classmethod - def encode_varint(cls, number: int) -> bytes: - """Encode a number in varint coding.""" - - if not 0 <= number < 1 << 64: - log_msg = "Expecting uint64 from Protobuf" - raise EncodeVarintError(f"{log_msg}: {number}") - - number <<= 1 # Shift to int64 - buf = b"" - while True: - towrite = number & 0x7F - number >>= 7 - if number: - buf += bytes((towrite | 0x80,)) - else: - buf += bytes((towrite,)) - break - return buf - - @classmethod - async def decode_varint( - cls, buffer: asyncio.StreamReader, max_length: int = MAX_VARINT_BYTES - ) -> int: - """ - Decode a number from its varint coding. - - :param buffer: the buffer to read from. - :param max_length: the max number of bytes that can be read. - :return: the decoded int. - - :raise: DecodeVarintError if the varint could not be decoded. - :raise: EOFError if EOF byte is read and the process of decoding a varint has not started. - """ - enforce(max_length >= 1, "max bytes must be at least one") - nb_read_bytes = 0 - shift = 0 - result = 0 - success = False - byte = await cls._read_one(buffer) - while byte is not None and nb_read_bytes <= max_length: - nb_read_bytes += 1 - result |= (byte & 0x7F) << shift - shift += 7 - if not byte & 0x80: - success = True - break - byte = await cls._read_one(buffer) - # byte is None when EOF is reached - if byte is None and nb_read_bytes == 0: - raise EOFError() - if not success: - raise DecodeVarintError("could not decode varint") - return result >> 1 - - @classmethod - async def _read_one(cls, buffer: asyncio.StreamReader) -> Optional[int]: - """ - Read one byte to decode a varint. - - :param buffer: the buffer to read from. - :return: the next character, or None if EOF is reached. - """ - character = await buffer.read(1) - if character == b"": - return None - return ord(character) - - @classmethod - def write_message(cls, message: Response) -> bytes: - """Write a message in a buffer.""" - buffer = BytesIO(b"") - protobuf_bytes = message.SerializeToString() - encoded = cls.encode_varint(len(protobuf_bytes)) - buffer.write(encoded) - buffer.write(protobuf_bytes) - return buffer.getvalue() - - -class VarintMessageReader: # pylint: disable=too-few-public-methods - """Varint message reader.""" - - def __init__(self, reader: asyncio.StreamReader) -> None: - """Initialize the reader.""" - self._reader = reader - - async def read_next_message(self) -> bytes: - """Read next message.""" - varint = await _TendermintABCISerializer.decode_varint(self._reader) - if varint > MAX_READ_IN_BYTES: - raise TooLargeVarint(received_size=varint, max_size=MAX_READ_IN_BYTES) - message_bytes = await self.read_until(varint) - if len(message_bytes) < varint: - raise ShortBufferLengthError(varint, message_bytes) - return message_bytes - - async def read_until(self, n: int) -> bytes: - """Wait until n bytes are read from the stream.""" - result = BytesIO(b"") - read_bytes = 0 - while read_bytes < n: - data = await self._reader.read(n - read_bytes) - result.write(data) - read_bytes += len(data) - return result.getvalue() - - -class ABCIApplicationServicer(types_pb2_grpc.ABCIApplicationServicer): - """Implements the gRPC servicer (handler)""" - - # pylint: disable=invalid-overridden-method, no-member - - def __init__( - self, request_queue: asyncio.Queue, dialogues: AbciDialogues, target_skill: str - ): - """ - Initializes the abci handler. - - :param request_queue: queue holding translated abci messages. - :param dialogues: dialogues - :param target_skill: target skill of messages - """ - super().__init__() - self._request_queue = request_queue - self._dialogues = dialogues - self._target_skill = target_skill - self._response_queues: Dict[str, asyncio.Queue] = { - AbciMessage.Performative.RESPONSE_ECHO: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_FLUSH: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_INFO: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_SET_OPTION: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_DELIVER_TX: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_CHECK_TX: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_QUERY: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_COMMIT: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_INIT_CHAIN: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_BEGIN_BLOCK: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_END_BLOCK: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK: asyncio.Queue(), - } - - async def send(self, envelope: Envelope) -> Response: - """ - Returns response to the waiting request - - :param: envelope: Envelope to be returned - """ - message = cast(AbciMessage, envelope.message) - dialogue = self._dialogues.update(message) - if dialogue is None: # pragma: nocover - logging.warning(f"Could not create dialogue for message={message}") - return - - await self._response_queues[message.performative].put(envelope) - - async def Echo( - self, request: RequestEcho, context: grpc.ServicerContext - ) -> ResponseEcho: - """ - Handles "Echo" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(echo=request) - message, _ = _TendermintProtocolDecoder.request_echo( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_ECHO - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_echo(message) - context.set_code(grpc.StatusCode.OK) - - return response.echo - - async def Flush( - self, request: RequestFlush, context: grpc.ServicerContext - ) -> ResponseFlush: # pragma: no cover - """ - Handles "Flush" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(flush=request) - message, _ = _TendermintProtocolDecoder.request_flush( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_FLUSH - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_flush(message) - context.set_code(grpc.StatusCode.OK) - - return response.flush - - async def Info( - self, request: RequestInfo, context: grpc.ServicerContext - ) -> ResponseInfo: - """ - Handles "Info" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(info=request) - message, _ = _TendermintProtocolDecoder.request_info( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_INFO - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_info(message) - context.set_code(grpc.StatusCode.OK) - - return response.info - - async def SetOption( - self, request: RequestSetOption, context: grpc.ServicerContext - ) -> ResponseSetOption: # pragma: no cover - """ - Handles "SetOption" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(set_option=request) - message, _ = _TendermintProtocolDecoder.request_set_option( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_SET_OPTION - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_set_option(message) - context.set_code(grpc.StatusCode.OK) - - return response.set_option - - async def DeliverTx( - self, request: RequestDeliverTx, context: grpc.ServicerContext - ) -> ResponseDeliverTx: - """ - Handles "DeliverTx" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(deliver_tx=request) - message, _ = _TendermintProtocolDecoder.request_deliver_tx( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_DELIVER_TX - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_deliver_tx(message) - context.set_code(grpc.StatusCode.OK) - - return response.deliver_tx - - async def CheckTx( - self, request: RequestCheckTx, context: grpc.ServicerContext - ) -> ResponseCheckTx: - """ - Handles "CheckTx" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(check_tx=request) - message, _ = _TendermintProtocolDecoder.request_check_tx( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_CHECK_TX - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_check_tx(message) - context.set_code(grpc.StatusCode.OK) - - return response.check_tx - - async def Query( - self, request: RequestQuery, context: grpc.ServicerContext - ) -> ResponseQuery: - """ - Handles "Query" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(query=request) - message, _ = _TendermintProtocolDecoder.request_query( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_QUERY - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_query(message) - context.set_code(grpc.StatusCode.OK) - - return response.query - - async def Commit( - self, request: RequestCommit, context: grpc.ServicerContext - ) -> ResponseCommit: - """ - Handles "Commit" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(commit=request) - message, _ = _TendermintProtocolDecoder.request_commit( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_COMMIT - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_commit(message) - context.set_code(grpc.StatusCode.OK) - - return response.commit - - async def InitChain( - self, request: RequestInitChain, context: grpc.ServicerContext - ) -> ResponseInitChain: - """ - Handles "InitChain" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(init_chain=request) - message, _ = _TendermintProtocolDecoder.request_init_chain( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_INIT_CHAIN - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_init_chain(message) - context.set_code(grpc.StatusCode.OK) - - return response.init_chain - - async def BeginBlock( - self, request: RequestBeginBlock, context: grpc.ServicerContext - ) -> ResponseBeginBlock: - """ - Handles "BeginBlock" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(begin_block=request) - message, _ = _TendermintProtocolDecoder.request_begin_block( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_BEGIN_BLOCK - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_begin_block(message) - context.set_code(grpc.StatusCode.OK) - - return response.begin_block - - async def EndBlock( - self, request: RequestEndBlock, context: grpc.ServicerContext - ) -> ResponseEndBlock: - """ - Handles "EndBlock" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(end_block=request) - message, _ = _TendermintProtocolDecoder.request_end_block( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_END_BLOCK - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_end_block(message) - context.set_code(grpc.StatusCode.OK) - - return response.end_block - - async def ListSnapshots( - self, request: RequestListSnapshots, context: grpc.ServicerContext - ) -> ResponseListSnapshots: # pragma: no cover - """ - Handles "ListSnapshots" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(list_snapshots=request) - message, _ = _TendermintProtocolDecoder.request_list_snapshots( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_list_snapshots(message) - context.set_code(grpc.StatusCode.OK) - - return response.list_snapshots - - async def OfferSnapshot( - self, request: RequestOfferSnapshot, context: grpc.ServicerContext - ) -> ResponseOfferSnapshot: # pragma: no cover - """ - Handles "OfferSnapshot" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(offer_snapshot=request) - message, _ = _TendermintProtocolDecoder.request_offer_snapshot( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_offer_snapshot(message) - context.set_code(grpc.StatusCode.OK) - - return response.list_snapshots - - async def LoadSnapshotChunk( - self, request: RequestLoadSnapshotChunk, context: grpc.ServicerContext - ) -> ResponseLoadSnapshotChunk: # pragma: no cover - """ - Handles "LoadSnapshotChunk" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(load_snapshot_chunk=request) - message, _ = _TendermintProtocolDecoder.request_load_snapshot_chunk( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_load_snapshot_chunk(message) - context.set_code(grpc.StatusCode.OK) - - return response.load_snapshot_chunk - - async def ApplySnapshotChunk( - self, request: RequestApplySnapshotChunk, context: grpc.ServicerContext - ) -> ResponseApplySnapshotChunk: # pragma: no cover - """ - Handles "ApplySnapshotChunk" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(apply_snapshot_chunk=request) - message, _ = _TendermintProtocolDecoder.request_apply_snapshot_chunk( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_apply_snapshot_chunk(message) - context.set_code(grpc.StatusCode.OK) - - return response.apply_snapshot_chunk - - -class GrpcServerChannel: # pylint: disable=too-many-instance-attributes - """gRPC server channel to handle incoming communication from the Tendermint node.""" - - def __init__( - self, - target_skill_id: PublicId, - address: str, - port: int, - logger: Optional[Logger] = None, - ): - """ - Initialize the gRPC server. - - :param target_skill_id: the public id of the target skill. - :param address: the listen address. - :param port: the port to listen from. - :param logger: the logger. - """ - self.target_skill_id = target_skill_id - self.address = address - self.port = port - self.logger = logger - - # channel state - self._loop: Optional[AbstractEventLoop] = None - self._dialogues = AbciDialogues(connection_id=PUBLIC_ID) - self._is_stopped: bool = True - self.queue: Optional[asyncio.Queue] = None - self._server: Optional[grpc.Server] = None - self._server_task: Optional[Task] = None - self._servicer: Optional[ABCIApplicationServicer] = None - - @property - def is_stopped(self) -> bool: - """Check that the channel is stopped.""" - return self._is_stopped - - async def _start_server(self) -> None: - """Start the gRPC server.""" - self.logger = cast(Logger, self.logger) - self.queue = cast(asyncio.Queue, self.queue) - self.logger.info("Starting gRPC server") - server = grpc.aio.server() - self._servicer = ABCIApplicationServicer( - self.queue, self._dialogues, str(self.target_skill_id) - ) - types_pb2_grpc.add_ABCIApplicationServicer_to_server(self._servicer, server) - server.add_insecure_port(f"[::]:{self.port}") - self._server = server - await self._server.start() - await self._server.wait_for_termination() - - async def connect(self, loop: AbstractEventLoop) -> None: - """ - Connect. - - :param loop: asyncio event loop - """ - if not self._is_stopped: # pragma: nocover - return - self._loop = loop - self._is_stopped = False - self.queue = asyncio.Queue() - - asyncio.create_task(self._start_server()) - - async def disconnect(self) -> None: - """Disconnect the channel""" - if self.is_stopped: # pragma: nocover - return - self._is_stopped = True - self._server = cast(grpc.Server, self._server) - await self._server.stop(0) - - self.queue = None - self._server = None - - async def get_message(self) -> Envelope: - """Get a message from the queue.""" - return await cast(asyncio.Queue, self.queue).get() - - async def send(self, envelope: Envelope) -> None: - """Send a message.""" - self._servicer = cast(ABCIApplicationServicer, self._servicer) - await self._servicer.send(envelope) - - -class TcpServerChannel: # pylint: disable=too-many-instance-attributes - """TCP server channel to handle incoming communication from the Tendermint node.""" - - def __init__( - self, - target_skill_id: PublicId, - address: str, - port: int, - logger: Optional[Logger] = None, - ): - """ - Initialize the TCP server. - - :param target_skill_id: the public id of the target skill. - :param address: the listen address. - :param port: the port to listen from. - :param logger: the logger. - """ - self.target_skill_id = target_skill_id - self.address = address - self.port = port - self.logger = logger or logging.getLogger() - - # channel state - self._loop: Optional[AbstractEventLoop] = None - self._dialogues = AbciDialogues(connection_id=PUBLIC_ID) - self._is_stopped: bool = True - self.queue: Optional[asyncio.Queue] = None - self._server: Optional[AbstractServer] = None - self._server_task: Optional[Task] = None - # a single Tendermint opens four concurrent connections: - # https://docs.tendermint.com/master/spec/abci/apps.html - # this dictionary keeps track of the reader-writer stream pair - # by socket name (ip address and port) - self._streams_by_socket: Dict[ - str, Tuple[asyncio.StreamReader, asyncio.StreamWriter] - ] = {} - # this dictionary associates requests to socket name - # such that responses are sent to the right receiver - self._request_id_to_socket: Dict[DialogueLabel, str] = {} - - @property - def is_stopped(self) -> bool: - """Check that the channel is stopped.""" - return self._is_stopped - - async def connect(self, loop: AbstractEventLoop) -> None: - """ - Connect. - - Upon TCP Channel connection, start the TCP Server asynchronously. - - :param loop: asyncio event loop - """ - if not self._is_stopped: # pragma: nocover - return - self._loop = loop - self._is_stopped = False - self.queue = asyncio.Queue() - self._server = await asyncio.start_server( - self.receive_messages, host=self.address, port=self.port - ) - - async def disconnect(self) -> None: - """Disconnect the channel""" - if self.is_stopped: # pragma: nocover - return - self._is_stopped = True - self._server = cast(AbstractServer, self._server) - self._server.close() - await self._server.wait_closed() - - self.queue = None - self._server = None - self._streams_by_socket = {} - self._request_id_to_socket = {} - - async def receive_messages( - self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter - ) -> None: - """Receive incoming messages.""" - self.logger = cast(Logger, self.logger) - self.queue = cast(asyncio.Queue, self.queue) - ip_address, socket, *_ = writer.get_extra_info("peername") - peer_name = f"{ip_address}:{socket}" - self._streams_by_socket[peer_name] = (reader, writer) - self.logger.debug(f"Connection with Tendermint @ {peer_name}") - - varint_message_reader = VarintMessageReader(reader) - while not self.is_stopped: - try: - message_bytes = await varint_message_reader.read_next_message() - if len(message_bytes) == 0: - self.logger.error( - f"Tendermint node {peer_name} closed connection." - ) # pragma: nocover - # break to the _stop if the connection stops - break # pragma: nocover - self.logger.debug( - f"Received {len(message_bytes)} bytes from connection {peer_name}" - ) - message = Request() - message.ParseFromString(message_bytes) - except ( - DecodeVarintError, - DecodeError, - ) as e: # pragma: nocover - self.logger.error( - f"an error occurred while reading a message: " - f"{type(e).__name__}: {e}. " - f"The message will be ignored." - ) - if reader.at_eof(): - self.logger.info("connection at EOF, stop receiving loop.") - return - continue - except TooLargeVarint as e: # pragma: nocover - self.logger.error( - f"A message exceeding the configured max size was received. " - f"{type(e).__name__}: {e} " - f"Closing the connection to the node." - ) - await self.disconnect() - return - except EOFError: - self.logger.info("connection at EOF, stop receiving loop.") - return - except CancelledError: # pragma: nocover - self.logger.debug(f"Read task for peer {peer_name} cancelled.") - return - await self._handle_message(message, peer_name) - - async def _handle_message(self, message: Request, peer_name: str) -> None: - """Handle a single message from a peer.""" - try: - req_type = message.WhichOneof("value") - result = _TendermintProtocolDecoder.process( - message, self._dialogues, str(self.target_skill_id) - ) - if result is not None: - request, dialogue = result - # associate request to peer, so we remember who to reply to - self._request_id_to_socket[ - dialogue.incomplete_dialogue_label - ] = peer_name - envelope = Envelope( - to=request.to, sender=request.sender, message=request - ) - await cast(asyncio.Queue, self.queue).put(envelope) - else: # pragma: nocover - self.logger.warning(f"Decoded request {req_type} was not a match.") - except Exception as e: # pylint: disable=broad-except # pragma: no cover - self.logger.error(f"Unhandled exception {type(e).__name__}: {e}") - - async def get_message(self) -> Envelope: - """Get a message from the queue.""" - return await cast(asyncio.Queue, self.queue).get() - - async def send(self, envelope: Envelope) -> None: - """Send a message.""" - self.logger = cast(Logger, self.logger) - message = cast(AbciMessage, envelope.message) - dialogue = self._dialogues.update(message) - if dialogue is None: # pragma: nocover - self.logger.warning(f"Could not create dialogue for message={message}") - return - - # we only deal with atomic request-response cycles, so it is safe to remove the reference - peer_name = self._request_id_to_socket.pop(dialogue.incomplete_dialogue_label) - _reader, writer = self._streams_by_socket[peer_name] - protobuf_message = _TendermintProtocolEncoder.process(message) - data = _TendermintABCISerializer.write_message(protobuf_message) - self.logger.debug(f"Writing {len(data)} bytes") - writer.write(data) - - -class StoppableThread( - Thread, -): - """Thread class with a stop() method.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialise the thread.""" - super().__init__(*args, **kwargs) - self._stop_event = Event() - - def stop(self) -> None: - """Set the stop event.""" - self._stop_event.set() - - def stopped(self) -> bool: - """Check if the thread is stopped.""" - return self._stop_event.is_set() - - -class TendermintParams: # pylint: disable=too-few-public-methods - """Tendermint node parameters.""" - - def __init__( # pylint: disable=too-many-arguments - self, - proxy_app: str, - rpc_laddr: str = DEFAULT_RPC_LISTEN_ADDRESS, - p2p_laddr: str = DEFAULT_P2P_LISTEN_ADDRESS, - p2p_seeds: Optional[List[str]] = None, - consensus_create_empty_blocks: bool = True, - home: Optional[str] = None, - use_grpc: bool = False, - ): - """ - Initialize the parameters to the Tendermint node. - - :param proxy_app: ABCI address. - :param rpc_laddr: RPC address. - :param p2p_laddr: P2P address. - :param p2p_seeds: P2P seeds. - :param consensus_create_empty_blocks: if true, Tendermint node creates empty blocks. - :param home: Tendermint's home directory. - :param use_grpc: Whether to use a gRPC server, or TCP - """ - - self.proxy_app = proxy_app - self.rpc_laddr = rpc_laddr - self.p2p_laddr = p2p_laddr - self.p2p_seeds = p2p_seeds - self.consensus_create_empty_blocks = consensus_create_empty_blocks - self.home = home - self.use_grpc = use_grpc - - def __str__(self) -> str: - """Get the string representation.""" - return ( - f"{self.__class__.__name__}(" - f" proxy_app={self.proxy_app},\n" - f" rpc_laddr={self.rpc_laddr},\n" - f" p2p_laddr={self.p2p_laddr},\n" - f" p2p_seeds={self.p2p_seeds},\n" - f" consensus_create_empty_blocks={self.consensus_create_empty_blocks},\n" - f" home={self.home},\n" - ")" - ) - - def build_node_command(self, debug: bool = False) -> List[str]: - """Build the 'node' command.""" - p2p_seeds = ",".join(self.p2p_seeds) if self.p2p_seeds else "" - cmd = [ - "tendermint", - "node", - f"--proxy_app={self.proxy_app}", - f"--rpc.laddr={self.rpc_laddr}", - f"--p2p.laddr={self.p2p_laddr}", - f"--p2p.seeds={p2p_seeds}", - f"--consensus.create_empty_blocks={str(self.consensus_create_empty_blocks).lower()}", - f"--abci={'grpc' if self.use_grpc else 'socket'}", - ] - if debug: - cmd.append("--log_level=debug") - if self.home is not None: # pragma: nocover - cmd += ["--home", self.home] - return cmd - - @staticmethod - def get_node_command_kwargs() -> Dict: - """Get the node command kwargs""" - kwargs = { - "bufsize": 1, - "universal_newlines": True, - "stdout": subprocess.PIPE, - "stderr": subprocess.STDOUT, - } - if platform.system() == "Windows": # pragma: nocover - kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP # type: ignore - else: - kwargs["preexec_fn"] = os.setsid # type: ignore - return kwargs - - -class TendermintNode: - """A class to manage a Tendermint node.""" - - def __init__( - self, - params: TendermintParams, - logger: Optional[Logger] = None, - write_to_log: bool = False, - ): - """ - Initialize a Tendermint node. - - :param params: the parameters. - :param logger: the logger. - :param write_to_log: Write to log file. - """ - self.params = params - self._process: Optional[subprocess.Popen] = None - self._monitoring: Optional[StoppableThread] = None - self._stopping = False - self.logger = logger or logging.getLogger() - self.log_file = os.environ.get("LOG_FILE", DEFAULT_TENDERMINT_LOG_FILE) - self.write_to_log = write_to_log - - def _build_init_command(self) -> List[str]: - """Build the 'init' command.""" - cmd = [ - "tendermint", - "init", - ] - if self.params.home is not None: # pragma: nocover - cmd += ["--home", self.params.home] - return cmd - - def init(self) -> None: - """Initialize Tendermint node.""" - cmd = self._build_init_command() - subprocess.call(cmd) # nosec - - def _monitor_tendermint_process( - self, - ) -> None: - """Check server status.""" - if self._monitoring is None: - raise ValueError("Monitoring is not running") - self.log("Monitoring thread started\n") - while not self._monitoring.stopped(): - try: - if self._process is not None and self._process.stdout is not None: - line = self._process.stdout.readline() - self.log(line) - for trigger in [ - # this occurs when we lose connection from the tm side - "RPC HTTP server stopped", - # whenever the node is stopped because of a closed connection - # from on any of the tendermint modules (abci, p2p, rpc, etc) - # we restart the node - "Stopping abci.socketClient for error: read message: EOF", - ]: - if self._monitoring.stopped(): - break - if line.find(trigger) >= 0: - self._stop_tm_process() - # we can only reach this step if monitoring was activated - # so we make sure that after reset the monitoring continues - self._start_tm_process() - self.log( - f"Restarted the HTTP RPC server, as a connection was dropped with message:\n\t\t {line}\n" - ) - except Exception as e: # pylint: disable=broad-except - self.log(f"Error!: {str(e)}") - self.log("Monitoring thread terminated\n") - - def _start_tm_process(self, debug: bool = False) -> None: - """Start a Tendermint node process.""" - if self._process is not None or self._stopping: # pragma: nocover - return - cmd = self.params.build_node_command(debug) - kwargs = self.params.get_node_command_kwargs() - self.log(f"Starting Tendermint: {cmd}\n") - self._process = ( - subprocess.Popen( # nosec # pylint: disable=consider-using-with,W1509 - cmd, **kwargs - ) - ) - self.log("Tendermint process started\n") - - def _start_monitoring_thread(self) -> None: - """Start a monitoring thread.""" - self._monitoring = StoppableThread(target=self._monitor_tendermint_process) - self._monitoring.start() - - def start(self, debug: bool = False) -> None: - """Start a Tendermint node process.""" - self._start_tm_process(debug) - self._start_monitoring_thread() - - def _stop_tm_process(self) -> None: - """Stop a Tendermint node process.""" - if self._process is None or self._stopping: - return - - self._stopping = True - if platform.system() == "Windows": - self._win_stop_tm() - else: - # this will raise an exception if the process - # is not terminated within the specified timeout - self._unix_stop_tm() - - self._stopping = False - self._process = None - self.log("Tendermint process stopped\n") - - def _win_stop_tm(self) -> None: - """Stop a Tendermint node process on Windows.""" - os.kill(self._process.pid, signal.CTRL_C_EVENT) # type: ignore # pylint: disable=no-member - try: - self._process.wait(timeout=5) # type: ignore - except subprocess.TimeoutExpired: # nosec - os.kill(self._process.pid, signal.CTRL_BREAK_EVENT) # type: ignore # pylint: disable=no-member - - def _unix_stop_tm(self) -> None: - """Stop a Tendermint node process on Unix.""" - self._process.send_signal(signal.SIGTERM) # type: ignore - try: - self._process.wait(timeout=5) # type: ignore - except subprocess.TimeoutExpired: # nosec - self.log("Tendermint process did not stop gracefully\n") - - # if the process is still running poll will return None - poll = self._process.poll() # type: ignore - if poll is not None: - return - - self._process.terminate() # type: ignore - self._process.wait(3) # type: ignore - - def _stop_monitoring_thread(self) -> None: - """Stop a monitoring process.""" - if self._monitoring is not None: - self._monitoring.stop() # set stop event - self._monitoring.join() - - def stop(self) -> None: - """Stop a Tendermint node process.""" - self._stop_tm_process() - self._stop_monitoring_thread() - - @staticmethod - def _write_to_console(line: str) -> None: - """Write line to console.""" - sys.stdout.write(str(line)) - sys.stdout.flush() - - def _write_to_file(self, line: str) -> None: - """Write line to console.""" - with open(self.log_file, "a", encoding=ENCODING) as file: - file.write(line) - - def log(self, line: str) -> None: - """Open and write a line to the log file.""" - self._write_to_console(line=line) - if self.write_to_log: - self._write_to_file(line=line) - - def prune_blocks(self) -> int: - """Prune blocks from the Tendermint state""" - return subprocess.call( # nosec: - ["tendermint", "--home", str(self.params.home), "unsafe-reset-all"] - ) - - def reset_genesis_file( - self, genesis_time: str, initial_height: str, period_count: str - ) -> None: - """Reset genesis file.""" - - genesis_file = Path(str(self.params.home), "config", "genesis.json") - genesis_config = json.loads(genesis_file.read_text(encoding=ENCODING)) - genesis_config["genesis_time"] = genesis_time - genesis_config["initial_height"] = initial_height - # chain id should be max 50 chars. - # this means that the app would theoretically break when a 40-digit period is reached - genesis_config["chain_id"] = f"autonolas-{period_count}" - genesis_file.write_text(json.dumps(genesis_config, indent=2), encoding=ENCODING) - - -class ABCIServerConnection(Connection): # pylint: disable=too-many-instance-attributes - """ABCI server.""" - - connection_id = PUBLIC_ID - params: Optional[TendermintParams] = None - node: Optional[TendermintNode] = None - channel: Optional[Union[TcpServerChannel, GrpcServerChannel]] = None - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize the connection. - - :param kwargs: keyword arguments passed to component base - """ - super().__init__(**kwargs) # pragma: no cover - - self._process_connection_params() - self._process_tendermint_params() - - if self.use_grpc: - self.channel = GrpcServerChannel( - self.target_skill_id, - address=self.host, - port=self.port, - logger=self.logger, - ) - else: - self.channel = TcpServerChannel( - self.target_skill_id, - address=self.host, - port=self.port, - logger=self.logger, - ) - - def _process_connection_params(self) -> None: - """ - Process the connection parameters. - - The parameters to process are: - - host - - port - - target_skill_id - """ - self.host = cast(str, self.configuration.config.get("host")) - self.port = cast(int, self.configuration.config.get("port")) - target_skill_id_string = cast( - Optional[str], self.configuration.config.get("target_skill_id") - ) - - if ( - self.host is None or self.port is None or target_skill_id_string is None - ): # pragma: no cover - raise ValueError("host and port and target_skill_id must be set!") - target_skill_id = PublicId.try_from_str(target_skill_id_string) - if target_skill_id is None: # pragma: no cover - raise ValueError("Provided target_skill_id is not a valid public id.") - self.target_skill_id = target_skill_id - - def _process_tendermint_params(self) -> None: - """ - Process the Tendermint parameters. - - In particular, if use_tendermint is False, do nothing. - Else, process the following parameters: - - rpc_laddr: the listening address for RPC communication - - p2p_laddr: the listening address for P2P communication - - p2p_seeds: a comma-separated list of IP addresses and ports - """ - self.use_tendermint = cast( - bool, self.configuration.config.get("use_tendermint") - ) - self.use_grpc = cast(bool, self.configuration.config.get("use_grpc", False)) - - if not self.use_tendermint: - return - tendermint_config = self.configuration.config.get("tendermint_config", {}) - rpc_laddr = cast( - str, tendermint_config.get("rpc_laddr", DEFAULT_RPC_LISTEN_ADDRESS) - ) - p2p_laddr = cast( - str, tendermint_config.get("p2p_laddr", DEFAULT_P2P_LISTEN_ADDRESS) - ) - p2p_seeds = cast(List[str], tendermint_config.get("p2p_seeds", [])) - home = cast(Optional[str], tendermint_config.get("home", None)) - consensus_create_empty_blocks = cast( - bool, tendermint_config.get("consensus_create_empty_blocks", True) - ) - proxy_app = f"{_TCP}{self.host}:{self.port}" - self.params = TendermintParams( - proxy_app, - rpc_laddr, - p2p_laddr, - p2p_seeds, - consensus_create_empty_blocks, - home, - self.use_grpc, - ) - self.logger.debug(f"Tendermint parameters: {self.params}") - self.node = TendermintNode(self.params, self.logger) - - def _ensure_connected(self) -> None: - """Ensure that the connection and the channel are ready.""" - super()._ensure_connected() - - self.channel = cast(Union[TcpServerChannel, GrpcServerChannel], self.channel) - if self.channel.is_stopped: - raise ConnectionError("The channel is stopped.") - - async def connect(self) -> None: - """ - Set up the connection. - - In the implementation, remember to update 'connection_status' accordingly. - """ - if self.is_connected: # pragma: no cover - return - - self.state = ConnectionStates.connecting - self.channel = cast(Union[TcpServerChannel, GrpcServerChannel], self.channel) - if self.use_tendermint: - self.node = cast(TendermintNode, self.node) - self.node.init() - self.node.start() - self.channel.logger = self.logger - await self.channel.connect(loop=self.loop) - if self.channel.is_stopped: # pragma: no cover - self.state = ConnectionStates.disconnected - return - self.state = ConnectionStates.connected - - async def disconnect(self) -> None: - """ - Tear down the connection. - - In the implementation, remember to update 'connection_status' accordingly. - """ - if self.is_disconnected: # pragma: no cover - return - - self.state = ConnectionStates.disconnecting - self.channel = cast(Union[TcpServerChannel, GrpcServerChannel], self.channel) - await self.channel.disconnect() - if self.use_tendermint: - self.node = cast(TendermintNode, self.node) - self.node.stop() - self.state = ConnectionStates.disconnected - - async def send(self, envelope: Envelope) -> None: - """ - Send an envelope. - - :param envelope: the envelope to send. - """ - self._ensure_connected() - self.channel = cast(Union[TcpServerChannel, GrpcServerChannel], self.channel) - await self.channel.send(envelope) - - async def receive(self, *args: Any, **kwargs: Any) -> Optional[Envelope]: - """ - Receive an envelope. Blocking. - - :param args: arguments to receive - :param kwargs: keyword arguments to receive - :return: the envelope received, if present. # noqa: DAR202 - """ - self._ensure_connected() - self.channel = cast(Union[TcpServerChannel, GrpcServerChannel], self.channel) - try: - message = await self.channel.get_message() - return message - except CancelledError: # pragma: no cover - return None diff --git a/trader_backup/vendor/valory/connections/abci/connection.yaml b/trader_backup/vendor/valory/connections/abci/connection.yaml deleted file mode 100644 index 81e50c09f..000000000 --- a/trader_backup/vendor/valory/connections/abci/connection.yaml +++ /dev/null @@ -1,84 +0,0 @@ -name: abci -author: valory -version: 0.1.0 -type: connection -description: connection to wrap communication with an ABCI server. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - Makefile: bafybeibdgarch56r46dfy7x7fouj52nbjpjs4fgtrd3prgtwelowyjan5i - __init__.py: bafybeic2m6f6j42cbfxz3jcwhju2dcbbdcw6xyc7mslq7uk2hwe6ctcugi - check_dependencies.py: bafybeihmhemryyl2iacwwrqebr7us7wx4otvwbdbtckwkl5kxqopidyzwm - connection.py: bafybeidirftkcxgvof3p3zecpxcvn4mska4hyxczgu2sa2imetn6r7xrla - dialogues.py: bafybeibpdsphu5vqjpieczrb3ulhqfcq4l73qnx6j3zhbz4dpunwegboxq - gogoproto/__init__.py: bafybeifmpcbkrpygdt7uvhpq6gaxgskofpczxktoalp2cwyouay46drcke - gogoproto/gogo_pb2.py: bafybeifdutphcruyva7lcngujrcmfsaycyodyfjbgwcrxthiouotl4fxpu - protos/gogoproto/gogo.proto: bafybeieg7yu62cx25ssjgvjnsc2alececsgush6l5adpxuscaf6ksh6dou - protos/tendermint/abci/types.proto: bafybeigimbf3rrfavl2o2jakr5c6dfm652lzxsddcmho7w5ytxo33sgrm4 - protos/tendermint/crypto/keys.proto: bafybeiar5g76sw7wgiyvaczpfgmw2bqkuillti7lnibmmmenz5zdofm6xe - protos/tendermint/crypto/proof.proto: bafybeibunrccs4vfxakjh4vulifko3dd7gl2mmwey42hsqlwsod4xxml6i - protos/tendermint/types/params.proto: bafybeihmrq4mbifdsai3i3yefuqyucsxeuqavhl5ljyofnwueip43w7lqu - protos/tendermint/types/types.proto: bafybeify5f2ja6semnrvtrberwn2pwhr3bvso6dtteif757bdrhnc3djsu - protos/tendermint/types/validator.proto: bafybeihejcuz3m5gm37sscly4azzdc72gng4kcnd7pwlxkjuhabw6yh7jm - protos/tendermint/version/types.proto: bafybeidqxroep4axnt6y6dhdu7et5abmktsswtwajvm32uot5q4wziefnq - readme.md: bafybeierlmc7t4dwpgc3sgmn5m5l3r4fwnwzbf6agna3igndsogk3iqlv4 - scripts/genproto.py: bafybeicfgwktvlrzqwfbvbld6bor3qd2rcfcgmk5rzfcfl6oj3jrr2mequ - tendermint/__init__.py: bafybeifayxyjcebekkn62sucyupfcuwzlj57kuiwafynpw4nrbocqxe6ya - tendermint/abci/types_pb2.py: bafybeidvvklivlllwprj2rh6un45apg773muyjrsq5momcihi2abxioqsi - tendermint/abci/types_pb2_grpc.py: bafybeihmecy4uas7itftoaslrqvrjb3m2jewojuzxvie7pjzsrw5exnu6u - tendermint/crypto/keys_pb2.py: bafybeiamkizmrn7txfboyrqqdara7n6ix5pbfh4evc3xedeva65snmlfhe - tendermint/crypto/proof_pb2.py: bafybeie7zueijrsuzldcol7dkcd2udupbof6nm73zm6zzkkin6teauan2m - tendermint/types/params_pb2.py: bafybeifblynzqqhyuvwjzgz33izwi5fl6fqabyiuwspasdlkw32xhltxq4 - tendermint/types/types_pb2.py: bafybeiad3gl7a3o4aewrcxfg5qpmjgtpeobcvb5knjxofwo7jjiimeb4m4 - tendermint/types/validator_pb2.py: bafybeibdhuvir43t4he337ajwe6sk7suhzxgdxyk2i6neoonoxfjqtqd6q - tendermint/version/types_pb2.py: bafybeib7ucwdh2oqbprdjskfofjkidf3odpj34zwicckkze6esx2zlsdaq - tendermint_decoder.py: bafybeig3teywhof2vztwaiqj36nx5bv6fysxzmu7i5ewqxa2w7rdf3wa7i - tendermint_encoder.py: bafybeibpnofkac6jizpbezlo7rdsbijloovsuz5rjysshjrims7x44wxv4 - tests/__init__.py: bafybeiaca7l7u423yejqpbbkyvrkrhog2zqpmtbvrga6bjou3yogj4bina - tests/helper.py: bafybeidahgf7lfoachhqliysh6uxc3prjl3yweicay4tkjsqwkxt67lphu - tests/test_abci.py: bafybeia4pw67do72gzc66kz23yzllnspbzqrtd5c5muqxhol27ipjjscxa - tests/test_abci_fuzz.py: bafybeiddeye3fbgefihbgdhqwwuv3dlseo6d5kt3jpixpq45bewm5dep2u - tests/test_abci_spec.py: bafybeifacnizp2mryyb2j64iugnxn5rhtx7xr4emwbw5xcke6le6utpwhu - tests/test_fuzz/__init__.py: bafybeiggaobawdxpx2j637ldmacq7r7tnyeygukmjuayodj3vytdyqsjze - tests/test_fuzz/base.py: bafybeifcv7r4dk7dfw726r3dy42s6mozb5yk4mmhml5i3hpu653odax7bq - tests/test_fuzz/mock_node/__init__.py: bafybeibt3bm4l3wethryy564mzcbhqmnztsbko4c5bt5ila5ghq2e7vz7u - tests/test_fuzz/mock_node/channels/__init__.py: bafybeifjjnlxtqd4pz76aq6w642n5d6pa635ehkhjxgzyjidakza27adja - tests/test_fuzz/mock_node/channels/base.py: bafybeicsirvtetuxnophhibjlzeos4bwtchhxr76v4k4ajsht6vrsqb5ni - tests/test_fuzz/mock_node/channels/grpc_channel.py: bafybeidita6lkds4urwrt3jwpou22js7ngruoof7kynuhkultdytx5taua - tests/test_fuzz/mock_node/channels/tcp_channel.py: bafybeiehlihhp7itiypkilugorwa2rytz2fm3awkm7vhti5p2v7fcvvajq - tests/test_fuzz/mock_node/node.py: bafybeiakzuvng5elaws6mv246o2nrjitdvjr7j5ltrhxscpezybbsyzh3i - tests/test_fuzz/test_fuzz.py: bafybeihfsayqmhajvhthvirxicd4swpe32u2gohe7sq5ixjuygico6wzge - tests/test_tendermint_decoder.py: bafybeihogt3aopyln5newihm3rbiqimoc4aw6za2cngplnjnwatv6nakea - tests/test_tendermint_encoder.py: bafybeigpun2ybwr5tu7b52his3b5apyrlmdytlgofcszbctsmmabo3sjg4 - version.txt: bafybeifjb44fd7qve2ku62ythui6z4mvd4k7qkjomlcdnl3ymb3bnq6xee -fingerprint_ignore_patterns: [] -build_entrypoint: check_dependencies.py -connections: [] -protocols: -- valory/abci:0.1.0:bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u -class_name: ABCIServerConnection -config: - host: 127.0.0.1 - port: 26658 - target_skill_id: null - tendermint_config: - p2p_laddr: tcp://0.0.0.0:26656 - p2p_seeds: [] - rpc_laddr: tcp://127.0.0.1:26657 - home: null - consensus_create_empty_blocks: true - use_grpc: false - use_tendermint: true -excluded_protocols: [] -restricted_to_protocols: [] -dependencies: - grpcio: - version: ==1.53.0 - hypothesis: - version: ==6.21.6 - open-aea-test-autonomy: - version: ==0.14.14.post1 - protobuf: - version: <4.25.0,>=4.21.6 -is_abstract: false -cert_requests: [] diff --git a/trader_backup/vendor/valory/connections/abci/dialogues.py b/trader_backup/vendor/valory/connections/abci/dialogues.py deleted file mode 100644 index 9fc60a3ac..000000000 --- a/trader_backup/vendor/valory/connections/abci/dialogues.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ -"""Dialogues classes for the ABCI connection.""" - -from typing import Any - -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue - -from packages.valory.protocols.abci.dialogues import AbciDialogue as BaseAbciDialogue -from packages.valory.protocols.abci.dialogues import AbciDialogues as BaseAbciDialogues - - -AbciDialogue = BaseAbciDialogue - - -class AbciDialogues(BaseAbciDialogues): - """The dialogues class keeps track of all ABCI dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.CLIENT - - BaseAbciDialogues.__init__( - self, - self_address=str(kwargs.pop("connection_id")), - role_from_first_message=role_from_first_message, - dialogue_class=AbciDialogue, - ) diff --git a/trader_backup/vendor/valory/connections/abci/gogoproto/__init__.py b/trader_backup/vendor/valory/connections/abci/gogoproto/__init__.py deleted file mode 100644 index a2b9f1c4a..000000000 --- a/trader_backup/vendor/valory/connections/abci/gogoproto/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the Protobuf Python modules for Gogoproto.""" # pragma: nocover diff --git a/trader_backup/vendor/valory/connections/abci/gogoproto/gogo_pb2.py b/trader_backup/vendor/valory/connections/abci/gogoproto/gogo_pb2.py deleted file mode 100644 index e02509ae4..000000000 --- a/trader_backup/vendor/valory/connections/abci/gogoproto/gogo_pb2.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: gogoproto/gogo.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x14gogoproto/gogo.proto\x12\tgogoproto\x1a google/protobuf/descriptor.proto:;\n\x13goproto_enum_prefix\x12\x1c.google.protobuf.EnumOptions\x18\xb1\xe4\x03 \x01(\x08:=\n\x15goproto_enum_stringer\x12\x1c.google.protobuf.EnumOptions\x18\xc5\xe4\x03 \x01(\x08:5\n\renum_stringer\x12\x1c.google.protobuf.EnumOptions\x18\xc6\xe4\x03 \x01(\x08:7\n\x0f\x65num_customname\x12\x1c.google.protobuf.EnumOptions\x18\xc7\xe4\x03 \x01(\t:0\n\x08\x65numdecl\x12\x1c.google.protobuf.EnumOptions\x18\xc8\xe4\x03 \x01(\x08:A\n\x14\x65numvalue_customname\x12!.google.protobuf.EnumValueOptions\x18\xd1\x83\x04 \x01(\t:;\n\x13goproto_getters_all\x12\x1c.google.protobuf.FileOptions\x18\x99\xec\x03 \x01(\x08:?\n\x17goproto_enum_prefix_all\x12\x1c.google.protobuf.FileOptions\x18\x9a\xec\x03 \x01(\x08:<\n\x14goproto_stringer_all\x12\x1c.google.protobuf.FileOptions\x18\x9b\xec\x03 \x01(\x08:9\n\x11verbose_equal_all\x12\x1c.google.protobuf.FileOptions\x18\x9c\xec\x03 \x01(\x08:0\n\x08\x66\x61\x63\x65_all\x12\x1c.google.protobuf.FileOptions\x18\x9d\xec\x03 \x01(\x08:4\n\x0cgostring_all\x12\x1c.google.protobuf.FileOptions\x18\x9e\xec\x03 \x01(\x08:4\n\x0cpopulate_all\x12\x1c.google.protobuf.FileOptions\x18\x9f\xec\x03 \x01(\x08:4\n\x0cstringer_all\x12\x1c.google.protobuf.FileOptions\x18\xa0\xec\x03 \x01(\x08:3\n\x0bonlyone_all\x12\x1c.google.protobuf.FileOptions\x18\xa1\xec\x03 \x01(\x08:1\n\tequal_all\x12\x1c.google.protobuf.FileOptions\x18\xa5\xec\x03 \x01(\x08:7\n\x0f\x64\x65scription_all\x12\x1c.google.protobuf.FileOptions\x18\xa6\xec\x03 \x01(\x08:3\n\x0btestgen_all\x12\x1c.google.protobuf.FileOptions\x18\xa7\xec\x03 \x01(\x08:4\n\x0c\x62\x65nchgen_all\x12\x1c.google.protobuf.FileOptions\x18\xa8\xec\x03 \x01(\x08:5\n\rmarshaler_all\x12\x1c.google.protobuf.FileOptions\x18\xa9\xec\x03 \x01(\x08:7\n\x0funmarshaler_all\x12\x1c.google.protobuf.FileOptions\x18\xaa\xec\x03 \x01(\x08:<\n\x14stable_marshaler_all\x12\x1c.google.protobuf.FileOptions\x18\xab\xec\x03 \x01(\x08:1\n\tsizer_all\x12\x1c.google.protobuf.FileOptions\x18\xac\xec\x03 \x01(\x08:A\n\x19goproto_enum_stringer_all\x12\x1c.google.protobuf.FileOptions\x18\xad\xec\x03 \x01(\x08:9\n\x11\x65num_stringer_all\x12\x1c.google.protobuf.FileOptions\x18\xae\xec\x03 \x01(\x08:<\n\x14unsafe_marshaler_all\x12\x1c.google.protobuf.FileOptions\x18\xaf\xec\x03 \x01(\x08:>\n\x16unsafe_unmarshaler_all\x12\x1c.google.protobuf.FileOptions\x18\xb0\xec\x03 \x01(\x08:B\n\x1agoproto_extensions_map_all\x12\x1c.google.protobuf.FileOptions\x18\xb1\xec\x03 \x01(\x08:@\n\x18goproto_unrecognized_all\x12\x1c.google.protobuf.FileOptions\x18\xb2\xec\x03 \x01(\x08:8\n\x10gogoproto_import\x12\x1c.google.protobuf.FileOptions\x18\xb3\xec\x03 \x01(\x08:6\n\x0eprotosizer_all\x12\x1c.google.protobuf.FileOptions\x18\xb4\xec\x03 \x01(\x08:3\n\x0b\x63ompare_all\x12\x1c.google.protobuf.FileOptions\x18\xb5\xec\x03 \x01(\x08:4\n\x0ctypedecl_all\x12\x1c.google.protobuf.FileOptions\x18\xb6\xec\x03 \x01(\x08:4\n\x0c\x65numdecl_all\x12\x1c.google.protobuf.FileOptions\x18\xb7\xec\x03 \x01(\x08:<\n\x14goproto_registration\x12\x1c.google.protobuf.FileOptions\x18\xb8\xec\x03 \x01(\x08:7\n\x0fmessagename_all\x12\x1c.google.protobuf.FileOptions\x18\xb9\xec\x03 \x01(\x08:=\n\x15goproto_sizecache_all\x12\x1c.google.protobuf.FileOptions\x18\xba\xec\x03 \x01(\x08:;\n\x13goproto_unkeyed_all\x12\x1c.google.protobuf.FileOptions\x18\xbb\xec\x03 \x01(\x08::\n\x0fgoproto_getters\x12\x1f.google.protobuf.MessageOptions\x18\x81\xf4\x03 \x01(\x08:;\n\x10goproto_stringer\x12\x1f.google.protobuf.MessageOptions\x18\x83\xf4\x03 \x01(\x08:8\n\rverbose_equal\x12\x1f.google.protobuf.MessageOptions\x18\x84\xf4\x03 \x01(\x08:/\n\x04\x66\x61\x63\x65\x12\x1f.google.protobuf.MessageOptions\x18\x85\xf4\x03 \x01(\x08:3\n\x08gostring\x12\x1f.google.protobuf.MessageOptions\x18\x86\xf4\x03 \x01(\x08:3\n\x08populate\x12\x1f.google.protobuf.MessageOptions\x18\x87\xf4\x03 \x01(\x08:3\n\x08stringer\x12\x1f.google.protobuf.MessageOptions\x18\xc0\x8b\x04 \x01(\x08:2\n\x07onlyone\x12\x1f.google.protobuf.MessageOptions\x18\x89\xf4\x03 \x01(\x08:0\n\x05\x65qual\x12\x1f.google.protobuf.MessageOptions\x18\x8d\xf4\x03 \x01(\x08:6\n\x0b\x64\x65scription\x12\x1f.google.protobuf.MessageOptions\x18\x8e\xf4\x03 \x01(\x08:2\n\x07testgen\x12\x1f.google.protobuf.MessageOptions\x18\x8f\xf4\x03 \x01(\x08:3\n\x08\x62\x65nchgen\x12\x1f.google.protobuf.MessageOptions\x18\x90\xf4\x03 \x01(\x08:4\n\tmarshaler\x12\x1f.google.protobuf.MessageOptions\x18\x91\xf4\x03 \x01(\x08:6\n\x0bunmarshaler\x12\x1f.google.protobuf.MessageOptions\x18\x92\xf4\x03 \x01(\x08:;\n\x10stable_marshaler\x12\x1f.google.protobuf.MessageOptions\x18\x93\xf4\x03 \x01(\x08:0\n\x05sizer\x12\x1f.google.protobuf.MessageOptions\x18\x94\xf4\x03 \x01(\x08:;\n\x10unsafe_marshaler\x12\x1f.google.protobuf.MessageOptions\x18\x97\xf4\x03 \x01(\x08:=\n\x12unsafe_unmarshaler\x12\x1f.google.protobuf.MessageOptions\x18\x98\xf4\x03 \x01(\x08:A\n\x16goproto_extensions_map\x12\x1f.google.protobuf.MessageOptions\x18\x99\xf4\x03 \x01(\x08:?\n\x14goproto_unrecognized\x12\x1f.google.protobuf.MessageOptions\x18\x9a\xf4\x03 \x01(\x08:5\n\nprotosizer\x12\x1f.google.protobuf.MessageOptions\x18\x9c\xf4\x03 \x01(\x08:2\n\x07\x63ompare\x12\x1f.google.protobuf.MessageOptions\x18\x9d\xf4\x03 \x01(\x08:3\n\x08typedecl\x12\x1f.google.protobuf.MessageOptions\x18\x9e\xf4\x03 \x01(\x08:6\n\x0bmessagename\x12\x1f.google.protobuf.MessageOptions\x18\xa1\xf4\x03 \x01(\x08:<\n\x11goproto_sizecache\x12\x1f.google.protobuf.MessageOptions\x18\xa2\xf4\x03 \x01(\x08::\n\x0fgoproto_unkeyed\x12\x1f.google.protobuf.MessageOptions\x18\xa3\xf4\x03 \x01(\x08:1\n\x08nullable\x12\x1d.google.protobuf.FieldOptions\x18\xe9\xfb\x03 \x01(\x08:.\n\x05\x65mbed\x12\x1d.google.protobuf.FieldOptions\x18\xea\xfb\x03 \x01(\x08:3\n\ncustomtype\x12\x1d.google.protobuf.FieldOptions\x18\xeb\xfb\x03 \x01(\t:3\n\ncustomname\x12\x1d.google.protobuf.FieldOptions\x18\xec\xfb\x03 \x01(\t:0\n\x07jsontag\x12\x1d.google.protobuf.FieldOptions\x18\xed\xfb\x03 \x01(\t:1\n\x08moretags\x12\x1d.google.protobuf.FieldOptions\x18\xee\xfb\x03 \x01(\t:1\n\x08\x63\x61sttype\x12\x1d.google.protobuf.FieldOptions\x18\xef\xfb\x03 \x01(\t:0\n\x07\x63\x61stkey\x12\x1d.google.protobuf.FieldOptions\x18\xf0\xfb\x03 \x01(\t:2\n\tcastvalue\x12\x1d.google.protobuf.FieldOptions\x18\xf1\xfb\x03 \x01(\t:0\n\x07stdtime\x12\x1d.google.protobuf.FieldOptions\x18\xf2\xfb\x03 \x01(\x08:4\n\x0bstdduration\x12\x1d.google.protobuf.FieldOptions\x18\xf3\xfb\x03 \x01(\x08:3\n\nwktpointer\x12\x1d.google.protobuf.FieldOptions\x18\xf4\xfb\x03 \x01(\x08\x42\x45\n\x13\x63om.google.protobufB\nGoGoProtosZ"github.com/gogo/protobuf/gogoproto' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "gogoproto.gogo_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b'\n\023com.google.protobufB\nGoGoProtosZ"github.com/gogo/protobuf/gogoproto' - ) -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/connections/abci/protos/gogoproto/gogo.proto b/trader_backup/vendor/valory/connections/abci/protos/gogoproto/gogo.proto deleted file mode 100644 index b80c85653..000000000 --- a/trader_backup/vendor/valory/connections/abci/protos/gogoproto/gogo.proto +++ /dev/null @@ -1,144 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto2"; -package gogoproto; - -import "google/protobuf/descriptor.proto"; - -option java_package = "com.google.protobuf"; -option java_outer_classname = "GoGoProtos"; -option go_package = "github.com/gogo/protobuf/gogoproto"; - -extend google.protobuf.EnumOptions { - optional bool goproto_enum_prefix = 62001; - optional bool goproto_enum_stringer = 62021; - optional bool enum_stringer = 62022; - optional string enum_customname = 62023; - optional bool enumdecl = 62024; -} - -extend google.protobuf.EnumValueOptions { - optional string enumvalue_customname = 66001; -} - -extend google.protobuf.FileOptions { - optional bool goproto_getters_all = 63001; - optional bool goproto_enum_prefix_all = 63002; - optional bool goproto_stringer_all = 63003; - optional bool verbose_equal_all = 63004; - optional bool face_all = 63005; - optional bool gostring_all = 63006; - optional bool populate_all = 63007; - optional bool stringer_all = 63008; - optional bool onlyone_all = 63009; - - optional bool equal_all = 63013; - optional bool description_all = 63014; - optional bool testgen_all = 63015; - optional bool benchgen_all = 63016; - optional bool marshaler_all = 63017; - optional bool unmarshaler_all = 63018; - optional bool stable_marshaler_all = 63019; - - optional bool sizer_all = 63020; - - optional bool goproto_enum_stringer_all = 63021; - optional bool enum_stringer_all = 63022; - - optional bool unsafe_marshaler_all = 63023; - optional bool unsafe_unmarshaler_all = 63024; - - optional bool goproto_extensions_map_all = 63025; - optional bool goproto_unrecognized_all = 63026; - optional bool gogoproto_import = 63027; - optional bool protosizer_all = 63028; - optional bool compare_all = 63029; - optional bool typedecl_all = 63030; - optional bool enumdecl_all = 63031; - - optional bool goproto_registration = 63032; - optional bool messagename_all = 63033; - - optional bool goproto_sizecache_all = 63034; - optional bool goproto_unkeyed_all = 63035; -} - -extend google.protobuf.MessageOptions { - optional bool goproto_getters = 64001; - optional bool goproto_stringer = 64003; - optional bool verbose_equal = 64004; - optional bool face = 64005; - optional bool gostring = 64006; - optional bool populate = 64007; - optional bool stringer = 67008; - optional bool onlyone = 64009; - - optional bool equal = 64013; - optional bool description = 64014; - optional bool testgen = 64015; - optional bool benchgen = 64016; - optional bool marshaler = 64017; - optional bool unmarshaler = 64018; - optional bool stable_marshaler = 64019; - - optional bool sizer = 64020; - - optional bool unsafe_marshaler = 64023; - optional bool unsafe_unmarshaler = 64024; - - optional bool goproto_extensions_map = 64025; - optional bool goproto_unrecognized = 64026; - - optional bool protosizer = 64028; - optional bool compare = 64029; - - optional bool typedecl = 64030; - - optional bool messagename = 64033; - - optional bool goproto_sizecache = 64034; - optional bool goproto_unkeyed = 64035; -} - -extend google.protobuf.FieldOptions { - optional bool nullable = 65001; - optional bool embed = 65002; - optional string customtype = 65003; - optional string customname = 65004; - optional string jsontag = 65005; - optional string moretags = 65006; - optional string casttype = 65007; - optional string castkey = 65008; - optional string castvalue = 65009; - - optional bool stdtime = 65010; - optional bool stdduration = 65011; - optional bool wktpointer = 65012; - -} diff --git a/trader_backup/vendor/valory/connections/abci/protos/tendermint/abci/types.proto b/trader_backup/vendor/valory/connections/abci/protos/tendermint/abci/types.proto deleted file mode 100644 index 8e3a90936..000000000 --- a/trader_backup/vendor/valory/connections/abci/protos/tendermint/abci/types.proto +++ /dev/null @@ -1,407 +0,0 @@ -syntax = "proto3"; -package tendermint.abci; - -option go_package = "github.com/tendermint/tendermint/abci/types"; - -// For more information on gogo.proto, see: -// https://github.com/gogo/protobuf/blob/master/extensions.md -import "tendermint/crypto/proof.proto"; -import "tendermint/types/types.proto"; -import "tendermint/crypto/keys.proto"; -import "tendermint/types/params.proto"; -import "google/protobuf/timestamp.proto"; -import "gogoproto/gogo.proto"; - -// This file is copied from http://github.com/tendermint/abci -// NOTE: When using custom types, mind the warnings. -// https://github.com/gogo/protobuf/blob/master/custom_types.md#warnings-and-issues - -//---------------------------------------- -// Request types - -message Request { - oneof value { - RequestEcho echo = 1; - RequestFlush flush = 2; - RequestInfo info = 3; - RequestSetOption set_option = 4; - RequestInitChain init_chain = 5; - RequestQuery query = 6; - RequestBeginBlock begin_block = 7; - RequestCheckTx check_tx = 8; - RequestDeliverTx deliver_tx = 9; - RequestEndBlock end_block = 10; - RequestCommit commit = 11; - RequestListSnapshots list_snapshots = 12; - RequestOfferSnapshot offer_snapshot = 13; - RequestLoadSnapshotChunk load_snapshot_chunk = 14; - RequestApplySnapshotChunk apply_snapshot_chunk = 15; - } -} - -message RequestEcho { - string message = 1; -} - -message RequestFlush {} - -message RequestInfo { - string version = 1; - uint64 block_version = 2; - uint64 p2p_version = 3; -} - -// nondeterministic -message RequestSetOption { - string key = 1; - string value = 2; -} - -message RequestInitChain { - google.protobuf.Timestamp time = 1 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - string chain_id = 2; - ConsensusParams consensus_params = 3; - repeated ValidatorUpdate validators = 4 [(gogoproto.nullable) = false]; - bytes app_state_bytes = 5; - int64 initial_height = 6; -} - -message RequestQuery { - bytes data = 1; - string path = 2; - int64 height = 3; - bool prove = 4; -} - -message RequestBeginBlock { - bytes hash = 1; - tendermint.types.Header header = 2 [(gogoproto.nullable) = false]; - LastCommitInfo last_commit_info = 3 [(gogoproto.nullable) = false]; - repeated Evidence byzantine_validators = 4 [(gogoproto.nullable) = false]; -} - -enum CheckTxType { - NEW = 0 [(gogoproto.enumvalue_customname) = "New"]; - RECHECK = 1 [(gogoproto.enumvalue_customname) = "Recheck"]; -} - -message RequestCheckTx { - bytes tx = 1; - CheckTxType type = 2; -} - -message RequestDeliverTx { - bytes tx = 1; -} - -message RequestEndBlock { - int64 height = 1; -} - -message RequestCommit {} - -// lists available snapshots -message RequestListSnapshots { -} - -// offers a snapshot to the application -message RequestOfferSnapshot { - Snapshot snapshot = 1; // snapshot offered by peers - bytes app_hash = 2; // light client-verified app hash for snapshot height -} - -// loads a snapshot chunk -message RequestLoadSnapshotChunk { - uint64 height = 1; - uint32 format = 2; - uint32 chunk = 3; -} - -// Applies a snapshot chunk -message RequestApplySnapshotChunk { - uint32 index = 1; - bytes chunk = 2; - string sender = 3; -} - -//---------------------------------------- -// Response types - -message Response { - oneof value { - ResponseException exception = 1; - ResponseEcho echo = 2; - ResponseFlush flush = 3; - ResponseInfo info = 4; - ResponseSetOption set_option = 5; - ResponseInitChain init_chain = 6; - ResponseQuery query = 7; - ResponseBeginBlock begin_block = 8; - ResponseCheckTx check_tx = 9; - ResponseDeliverTx deliver_tx = 10; - ResponseEndBlock end_block = 11; - ResponseCommit commit = 12; - ResponseListSnapshots list_snapshots = 13; - ResponseOfferSnapshot offer_snapshot = 14; - ResponseLoadSnapshotChunk load_snapshot_chunk = 15; - ResponseApplySnapshotChunk apply_snapshot_chunk = 16; - } -} - -// nondeterministic -message ResponseException { - string error = 1; -} - -message ResponseEcho { - string message = 1; -} - -message ResponseFlush {} - -message ResponseInfo { - string data = 1; - - string version = 2; - uint64 app_version = 3; - - int64 last_block_height = 4; - bytes last_block_app_hash = 5; -} - -// nondeterministic -message ResponseSetOption { - uint32 code = 1; - // bytes data = 2; - string log = 3; - string info = 4; -} - -message ResponseInitChain { - ConsensusParams consensus_params = 1; - repeated ValidatorUpdate validators = 2 [(gogoproto.nullable) = false]; - bytes app_hash = 3; -} - -message ResponseQuery { - uint32 code = 1; - // bytes data = 2; // use "value" instead. - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 index = 5; - bytes key = 6; - bytes value = 7; - tendermint.crypto.ProofOps proof_ops = 8; - int64 height = 9; - string codespace = 10; -} - -message ResponseBeginBlock { - repeated Event events = 1 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; -} - -message ResponseCheckTx { - uint32 code = 1; - bytes data = 2; - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 gas_wanted = 5 [json_name = "gas_wanted"]; - int64 gas_used = 6 [json_name = "gas_used"]; - repeated Event events = 7 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; - string codespace = 8; -} - -message ResponseDeliverTx { - uint32 code = 1; - bytes data = 2; - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 gas_wanted = 5 [json_name = "gas_wanted"]; - int64 gas_used = 6 [json_name = "gas_used"]; - repeated Event events = 7 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; // nondeterministic - string codespace = 8; -} - -message ResponseEndBlock { - repeated ValidatorUpdate validator_updates = 1 - [(gogoproto.nullable) = false]; - ConsensusParams consensus_param_updates = 2; - repeated Event events = 3 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; -} - -message ResponseCommit { - // reserve 1 - bytes data = 2; - int64 retain_height = 3; -} - -message ResponseListSnapshots { - repeated Snapshot snapshots = 1; -} - -message ResponseOfferSnapshot { - Result result = 1; - - enum Result { - UNKNOWN = 0; // Unknown result, abort all snapshot restoration - ACCEPT = 1; // Snapshot accepted, apply chunks - ABORT = 2; // Abort all snapshot restoration - REJECT = 3; // Reject this specific snapshot, try others - REJECT_FORMAT = 4; // Reject all snapshots of this format, try others - REJECT_SENDER = 5; // Reject all snapshots from the sender(s), try others - } -} - -message ResponseLoadSnapshotChunk { - bytes chunk = 1; -} - -message ResponseApplySnapshotChunk { - Result result = 1; - repeated uint32 refetch_chunks = 2; // Chunks to refetch and reapply - repeated string reject_senders = 3; // Chunk senders to reject and ban - - enum Result { - UNKNOWN = 0; // Unknown result, abort all snapshot restoration - ACCEPT = 1; // Chunk successfully accepted - ABORT = 2; // Abort all snapshot restoration - RETRY = 3; // Retry chunk (combine with refetch and reject) - RETRY_SNAPSHOT = 4; // Retry snapshot (combine with refetch and reject) - REJECT_SNAPSHOT = 5; // Reject this snapshot, try others - } -} - -//---------------------------------------- -// Misc. - -// ConsensusParams contains all consensus-relevant parameters -// that can be adjusted by the abci app -message ConsensusParams { - BlockParams block = 1; - tendermint.types.EvidenceParams evidence = 2; - tendermint.types.ValidatorParams validator = 3; - tendermint.types.VersionParams version = 4; -} - -// BlockParams contains limits on the block size. -message BlockParams { - // Note: must be greater than 0 - int64 max_bytes = 1; - // Note: must be greater or equal to -1 - int64 max_gas = 2; -} - -message LastCommitInfo { - int32 round = 1; - repeated VoteInfo votes = 2 [(gogoproto.nullable) = false]; -} - -// Event allows application developers to attach additional information to -// ResponseBeginBlock, ResponseEndBlock, ResponseCheckTx and ResponseDeliverTx. -// Later, transactions may be queried using these events. -message Event { - string type = 1; - repeated EventAttribute attributes = 2 [ - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "attributes,omitempty" - ]; -} - -// EventAttribute is a single key-value pair, associated with an event. -message EventAttribute { - bytes key = 1; - bytes value = 2; - bool index = 3; // nondeterministic -} - -// TxResult contains results of executing the transaction. -// -// One usage is indexing transaction results. -message TxResult { - int64 height = 1; - uint32 index = 2; - bytes tx = 3; - ResponseDeliverTx result = 4 [(gogoproto.nullable) = false]; -} - -//---------------------------------------- -// Blockchain Types - -// Validator -message Validator { - bytes address = 1; // The first 20 bytes of SHA256(public key) - // PubKey pub_key = 2 [(gogoproto.nullable)=false]; - int64 power = 3; // The voting power -} - -// ValidatorUpdate -message ValidatorUpdate { - tendermint.crypto.PublicKey pub_key = 1 [(gogoproto.nullable) = false]; - int64 power = 2; -} - -// VoteInfo -message VoteInfo { - Validator validator = 1 [(gogoproto.nullable) = false]; - bool signed_last_block = 2; -} - -enum EvidenceType { - UNKNOWN = 0; - DUPLICATE_VOTE = 1; - LIGHT_CLIENT_ATTACK = 2; -} - -message Evidence { - EvidenceType type = 1; - // The offending validator - Validator validator = 2 [(gogoproto.nullable) = false]; - // The height when the offense occurred - int64 height = 3; - // The corresponding time where the offense occurred - google.protobuf.Timestamp time = 4 [ - (gogoproto.nullable) = false, - (gogoproto.stdtime) = true - ]; - // Total voting power of the validator set in case the ABCI application does - // not store historical validators. - // https://github.com/tendermint/tendermint/issues/4581 - int64 total_voting_power = 5; -} - -//---------------------------------------- -// State Sync Types - -message Snapshot { - uint64 height = 1; // The height at which the snapshot was taken - uint32 format = 2; // The application-specific snapshot format - uint32 chunks = 3; // Number of chunks in the snapshot - bytes hash = 4; // Arbitrary snapshot hash, equal only if identical - bytes metadata = 5; // Arbitrary application metadata -} - -//---------------------------------------- -// Service Definition - -service ABCIApplication { - rpc Echo(RequestEcho) returns (ResponseEcho); - rpc Flush(RequestFlush) returns (ResponseFlush); - rpc Info(RequestInfo) returns (ResponseInfo); - rpc SetOption(RequestSetOption) returns (ResponseSetOption); - rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx); - rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); - rpc Query(RequestQuery) returns (ResponseQuery); - rpc Commit(RequestCommit) returns (ResponseCommit); - rpc InitChain(RequestInitChain) returns (ResponseInitChain); - rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock); - rpc EndBlock(RequestEndBlock) returns (ResponseEndBlock); - rpc ListSnapshots(RequestListSnapshots) returns (ResponseListSnapshots); - rpc OfferSnapshot(RequestOfferSnapshot) returns (ResponseOfferSnapshot); - rpc LoadSnapshotChunk(RequestLoadSnapshotChunk) returns (ResponseLoadSnapshotChunk); - rpc ApplySnapshotChunk(RequestApplySnapshotChunk) returns (ResponseApplySnapshotChunk); -} diff --git a/trader_backup/vendor/valory/connections/abci/protos/tendermint/crypto/keys.proto b/trader_backup/vendor/valory/connections/abci/protos/tendermint/crypto/keys.proto deleted file mode 100644 index 16fd7adf3..000000000 --- a/trader_backup/vendor/valory/connections/abci/protos/tendermint/crypto/keys.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; -package tendermint.crypto; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; - -import "gogoproto/gogo.proto"; - -// PublicKey defines the keys available for use with Tendermint Validators -message PublicKey { - option (gogoproto.compare) = true; - option (gogoproto.equal) = true; - - oneof sum { - bytes ed25519 = 1; - bytes secp256k1 = 2; - } -} diff --git a/trader_backup/vendor/valory/connections/abci/protos/tendermint/crypto/proof.proto b/trader_backup/vendor/valory/connections/abci/protos/tendermint/crypto/proof.proto deleted file mode 100644 index 975df7685..000000000 --- a/trader_backup/vendor/valory/connections/abci/protos/tendermint/crypto/proof.proto +++ /dev/null @@ -1,41 +0,0 @@ -syntax = "proto3"; -package tendermint.crypto; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; - -import "gogoproto/gogo.proto"; - -message Proof { - int64 total = 1; - int64 index = 2; - bytes leaf_hash = 3; - repeated bytes aunts = 4; -} - -message ValueOp { - // Encoded in ProofOp.Key. - bytes key = 1; - - // To encode in ProofOp.Data - Proof proof = 2; -} - -message DominoOp { - string key = 1; - string input = 2; - string output = 3; -} - -// ProofOp defines an operation used for calculating Merkle root -// The data could be arbitrary format, providing nessecary data -// for example neighbouring node hash -message ProofOp { - string type = 1; - bytes key = 2; - bytes data = 3; -} - -// ProofOps is Merkle proof defined by the list of ProofOps -message ProofOps { - repeated ProofOp ops = 1 [(gogoproto.nullable) = false]; -} diff --git a/trader_backup/vendor/valory/connections/abci/protos/tendermint/types/params.proto b/trader_backup/vendor/valory/connections/abci/protos/tendermint/types/params.proto deleted file mode 100644 index 0de7d846f..000000000 --- a/trader_backup/vendor/valory/connections/abci/protos/tendermint/types/params.proto +++ /dev/null @@ -1,80 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/duration.proto"; - -option (gogoproto.equal_all) = true; - -// ConsensusParams contains consensus critical parameters that determine the -// validity of blocks. -message ConsensusParams { - BlockParams block = 1 [(gogoproto.nullable) = false]; - EvidenceParams evidence = 2 [(gogoproto.nullable) = false]; - ValidatorParams validator = 3 [(gogoproto.nullable) = false]; - VersionParams version = 4 [(gogoproto.nullable) = false]; -} - -// BlockParams contains limits on the block size. -message BlockParams { - // Max block size, in bytes. - // Note: must be greater than 0 - int64 max_bytes = 1; - // Max gas per block. - // Note: must be greater or equal to -1 - int64 max_gas = 2; - // Minimum time increment between consecutive blocks (in milliseconds) If the - // block header timestamp is ahead of the system clock, decrease this value. - // - // Not exposed to the application. - int64 time_iota_ms = 3; -} - -// EvidenceParams determine how we handle evidence of malfeasance. -message EvidenceParams { - // Max age of evidence, in blocks. - // - // The basic formula for calculating this is: MaxAgeDuration / {average block - // time}. - int64 max_age_num_blocks = 1; - - // Max age of evidence, in time. - // - // It should correspond with an app's "unbonding period" or other similar - // mechanism for handling [Nothing-At-Stake - // attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed). - google.protobuf.Duration max_age_duration = 2 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - - // This sets the maximum size of total evidence in bytes that can be committed in a single block. - // and should fall comfortably under the max block bytes. - // Default is 1048576 or 1MB - int64 max_bytes = 3; -} - -// ValidatorParams restrict the public key types validators can use. -// NOTE: uses ABCI pubkey naming, not Amino names. -message ValidatorParams { - option (gogoproto.populate) = true; - option (gogoproto.equal) = true; - - repeated string pub_key_types = 1; -} - -// VersionParams contains the ABCI application version. -message VersionParams { - option (gogoproto.populate) = true; - option (gogoproto.equal) = true; - - uint64 app_version = 1; -} - -// HashedParams is a subset of ConsensusParams. -// -// It is hashed into the Header.ConsensusHash. -message HashedParams { - int64 block_max_bytes = 1; - int64 block_max_gas = 2; -} diff --git a/trader_backup/vendor/valory/connections/abci/protos/tendermint/types/types.proto b/trader_backup/vendor/valory/connections/abci/protos/tendermint/types/types.proto deleted file mode 100644 index 7f7ea74ca..000000000 --- a/trader_backup/vendor/valory/connections/abci/protos/tendermint/types/types.proto +++ /dev/null @@ -1,157 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; -import "tendermint/crypto/proof.proto"; -import "tendermint/version/types.proto"; -import "tendermint/types/validator.proto"; - -// BlockIdFlag indicates which BlcokID the signature is for -enum BlockIDFlag { - option (gogoproto.goproto_enum_stringer) = true; - option (gogoproto.goproto_enum_prefix) = false; - - BLOCK_ID_FLAG_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "BlockIDFlagUnknown"]; - BLOCK_ID_FLAG_ABSENT = 1 [(gogoproto.enumvalue_customname) = "BlockIDFlagAbsent"]; - BLOCK_ID_FLAG_COMMIT = 2 [(gogoproto.enumvalue_customname) = "BlockIDFlagCommit"]; - BLOCK_ID_FLAG_NIL = 3 [(gogoproto.enumvalue_customname) = "BlockIDFlagNil"]; -} - -// SignedMsgType is a type of signed message in the consensus. -enum SignedMsgType { - option (gogoproto.goproto_enum_stringer) = true; - option (gogoproto.goproto_enum_prefix) = false; - - SIGNED_MSG_TYPE_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "UnknownType"]; - // Votes - SIGNED_MSG_TYPE_PREVOTE = 1 [(gogoproto.enumvalue_customname) = "PrevoteType"]; - SIGNED_MSG_TYPE_PRECOMMIT = 2 [(gogoproto.enumvalue_customname) = "PrecommitType"]; - - // Proposals - SIGNED_MSG_TYPE_PROPOSAL = 32 [(gogoproto.enumvalue_customname) = "ProposalType"]; -} - -// PartsetHeader -message PartSetHeader { - uint32 total = 1; - bytes hash = 2; -} - -message Part { - uint32 index = 1; - bytes bytes = 2; - tendermint.crypto.Proof proof = 3 [(gogoproto.nullable) = false]; -} - -// BlockID -message BlockID { - bytes hash = 1; - PartSetHeader part_set_header = 2 [(gogoproto.nullable) = false]; -} - -// -------------------------------- - -// Header defines the structure of a Tendermint block header. -message Header { - // basic block info - tendermint.version.Consensus version = 1 [(gogoproto.nullable) = false]; - string chain_id = 2 [(gogoproto.customname) = "ChainID"]; - int64 height = 3; - google.protobuf.Timestamp time = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - - // prev block info - BlockID last_block_id = 5 [(gogoproto.nullable) = false]; - - // hashes of block data - bytes last_commit_hash = 6; // commit from validators from the last block - bytes data_hash = 7; // transactions - - // hashes from the app output from the prev block - bytes validators_hash = 8; // validators for the current block - bytes next_validators_hash = 9; // validators for the next block - bytes consensus_hash = 10; // consensus params for current block - bytes app_hash = 11; // state after txs from the previous block - bytes last_results_hash = 12; // root hash of all results from the txs from the previous block - - // consensus info - bytes evidence_hash = 13; // evidence included in the block - bytes proposer_address = 14; // original proposer of the block -} - -// Data contains the set of transactions included in the block -message Data { - // Txs that will be applied by state @ block.Height+1. - // NOTE: not all txs here are valid. We're just agreeing on the order first. - // This means that block.AppHash does not include these txs. - repeated bytes txs = 1; -} - -// Vote represents a prevote, precommit, or commit vote from validators for -// consensus. -message Vote { - SignedMsgType type = 1; - int64 height = 2; - int32 round = 3; - BlockID block_id = 4 - [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; // zero if vote is nil. - google.protobuf.Timestamp timestamp = 5 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes validator_address = 6; - int32 validator_index = 7; - bytes signature = 8; -} - -// Commit contains the evidence that a block was committed by a set of validators. -message Commit { - int64 height = 1; - int32 round = 2; - BlockID block_id = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; - repeated CommitSig signatures = 4 [(gogoproto.nullable) = false]; -} - -// CommitSig is a part of the Vote included in a Commit. -message CommitSig { - BlockIDFlag block_id_flag = 1; - bytes validator_address = 2; - google.protobuf.Timestamp timestamp = 3 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes signature = 4; -} - -message Proposal { - SignedMsgType type = 1; - int64 height = 2; - int32 round = 3; - int32 pol_round = 4; - BlockID block_id = 5 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; - google.protobuf.Timestamp timestamp = 6 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes signature = 7; -} - -message SignedHeader { - Header header = 1; - Commit commit = 2; -} - -message LightBlock { - SignedHeader signed_header = 1; - tendermint.types.ValidatorSet validator_set = 2; -} - -message BlockMeta { - BlockID block_id = 1 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; - int64 block_size = 2; - Header header = 3 [(gogoproto.nullable) = false]; - int64 num_txs = 4; -} - -// TxProof represents a Merkle proof of the presence of a transaction in the Merkle tree. -message TxProof { - bytes root_hash = 1; - bytes data = 2; - tendermint.crypto.Proof proof = 3; -} diff --git a/trader_backup/vendor/valory/connections/abci/protos/tendermint/types/validator.proto b/trader_backup/vendor/valory/connections/abci/protos/tendermint/types/validator.proto deleted file mode 100644 index 49860b96d..000000000 --- a/trader_backup/vendor/valory/connections/abci/protos/tendermint/types/validator.proto +++ /dev/null @@ -1,25 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "tendermint/crypto/keys.proto"; - -message ValidatorSet { - repeated Validator validators = 1; - Validator proposer = 2; - int64 total_voting_power = 3; -} - -message Validator { - bytes address = 1; - tendermint.crypto.PublicKey pub_key = 2 [(gogoproto.nullable) = false]; - int64 voting_power = 3; - int64 proposer_priority = 4; -} - -message SimpleValidator { - tendermint.crypto.PublicKey pub_key = 1; - int64 voting_power = 2; -} diff --git a/trader_backup/vendor/valory/connections/abci/protos/tendermint/version/types.proto b/trader_backup/vendor/valory/connections/abci/protos/tendermint/version/types.proto deleted file mode 100644 index 6061868bd..000000000 --- a/trader_backup/vendor/valory/connections/abci/protos/tendermint/version/types.proto +++ /dev/null @@ -1,24 +0,0 @@ -syntax = "proto3"; -package tendermint.version; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/version"; - -import "gogoproto/gogo.proto"; - -// App includes the protocol and software version for the application. -// This information is included in ResponseInfo. The App.Protocol can be -// updated in ResponseEndBlock. -message App { - uint64 protocol = 1; - string software = 2; -} - -// Consensus captures the consensus rules for processing a block in the blockchain, -// including all blockchain data structures and the rules of the application's -// state transition machine. -message Consensus { - option (gogoproto.equal) = true; - - uint64 block = 1; - uint64 app = 2; -} diff --git a/trader_backup/vendor/valory/connections/abci/readme.md b/trader_backup/vendor/valory/connections/abci/readme.md deleted file mode 100644 index c8f120b2f..000000000 --- a/trader_backup/vendor/valory/connections/abci/readme.md +++ /dev/null @@ -1,8 +0,0 @@ -# ABCI connection - -This package implements an AEA connection that wraps -the HTTP requests that can be done to an ABCI server. - -## Usage - -Configure the fields `host` and `port` to the ABCI server you want to interact with. diff --git a/trader_backup/vendor/valory/connections/abci/scripts/genproto.py b/trader_backup/vendor/valory/connections/abci/scripts/genproto.py deleted file mode 100644 index d85dba5fc..000000000 --- a/trader_backup/vendor/valory/connections/abci/scripts/genproto.py +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -""" -Update Python modules from Tendermint Protobuf files. - -NOTE: This code is adapted from the google protobuf Python library. Specifically from the setup.py file. -""" - -import os -import re -import subprocess # nosec -import sys -from distutils.spawn import find_executable -from pathlib import Path -from typing import cast - - -PACKAGE_IMPORT_PATH_PREFIX = "packages.valory.connections.abci" - - -def _find_protoc() -> str: - """Find protoc binary.""" - if "PROTOC" in os.environ and os.path.exists(os.environ["PROTOC"]): - protoc_bin = os.environ["PROTOC"] - elif os.path.exists("../src/protoc"): - protoc_bin = "../src/protoc" - elif os.path.exists("../src/protoc.exe"): - protoc_bin = "../src/protoc.exe" - elif os.path.exists("../vsprojects/Debug/protoc.exe"): - protoc_bin = "../vsprojects/Debug/protoc.exe" - elif os.path.exists("../vsprojects/Release/protoc.exe"): - protoc_bin = "../vsprojects/Release/protoc.exe" - else: - which_protoc = find_executable("protoc") - if which_protoc is None: - raise ValueError("cannot find 'protoc' binary on the system.") - protoc_bin = which_protoc - return cast(str, protoc_bin) - - -protoc = _find_protoc() - - -def generate_proto(source: str) -> None: - """ - Generate a protobuf file. - - Invokes the Protocol Compiler to generate a _pb2.py from the given - .proto file. Does nothing if the output already exists and is newer than - the input. - - :param source: path to the source. - """ - - if not os.path.exists(source): - return - - output = source.replace(".proto", "_pb2.py").replace("./protos/", "./") - - if not os.path.exists(output) or ( - os.path.exists(source) and os.path.getmtime(source) > os.path.getmtime(output) - ): - print("Generating %s..." % output) - - if not os.path.exists(source): - sys.stderr.write("Can't find required file: %s\n" % source) - sys.exit(-1) - - if protoc is None: - sys.stderr.write("protoc is not installed!\n") - sys.exit(-1) - - protoc_cross_platform = protoc.replace("/", os.path.sep) - protoc_command = [ - protoc_cross_platform, - "-I./protos", - "-I.", - "--python_out=.", - source, - ] - if subprocess.call(protoc_command) != 0: # nosec - sys.exit(-1) - - # prepend to all imports statement the AEA package import prefix path - output_path = Path(output) - output_content = output_path.read_text() - output_content = re.sub( - "from tendermint", - f"from {PACKAGE_IMPORT_PATH_PREFIX}.tendermint", - output_content, - ) - output_content = re.sub( - "from gogoproto", - f"from {PACKAGE_IMPORT_PATH_PREFIX}.gogoproto", - output_content, - ) - output_path.write_text(output_content) - - -if __name__ == "__main__": - # Build all the protobuf files and put into their directory - generate_proto("./protos/gogoproto/gogo.proto") - generate_proto("./protos/tendermint/crypto/keys.proto") - generate_proto("./protos/tendermint/crypto/proof.proto") - generate_proto("./protos/tendermint/types/params.proto") - generate_proto("./protos/tendermint/types/types.proto") - generate_proto("./protos/tendermint/types/validator.proto") - generate_proto("./protos/tendermint/version/types.proto") - generate_proto("./protos/tendermint/abci/types.proto") diff --git a/trader_backup/vendor/valory/connections/abci/tendermint/__init__.py b/trader_backup/vendor/valory/connections/abci/tendermint/__init__.py deleted file mode 100644 index 3c34ec6d0..000000000 --- a/trader_backup/vendor/valory/connections/abci/tendermint/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the Protobuf Python modules for the Tendermint-ABCI messages.""" # pragma: nocover diff --git a/trader_backup/vendor/valory/connections/abci/tendermint/abci/types_pb2.py b/trader_backup/vendor/valory/connections/abci/tendermint/abci/types_pb2.py deleted file mode 100644 index 6f94ff4ba..000000000 --- a/trader_backup/vendor/valory/connections/abci/tendermint/abci/types_pb2.py +++ /dev/null @@ -1,211 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/abci/types.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) -from packages.valory.connections.abci.tendermint.crypto import ( - keys_pb2 as tendermint_dot_crypto_dot_keys__pb2, -) -from packages.valory.connections.abci.tendermint.crypto import ( - proof_pb2 as tendermint_dot_crypto_dot_proof__pb2, -) -from packages.valory.connections.abci.tendermint.types import ( - params_pb2 as tendermint_dot_types_dot_params__pb2, -) -from packages.valory.connections.abci.tendermint.types import ( - types_pb2 as tendermint_dot_types_dot_types__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1btendermint/abci/types.proto\x12\x0ftendermint.abci\x1a\x1dtendermint/crypto/proof.proto\x1a\x1ctendermint/types/types.proto\x1a\x1ctendermint/crypto/keys.proto\x1a\x1dtendermint/types/params.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x14gogoproto/gogo.proto"\xea\x06\n\x07Request\x12,\n\x04\x65\x63ho\x18\x01 \x01(\x0b\x32\x1c.tendermint.abci.RequestEchoH\x00\x12.\n\x05\x66lush\x18\x02 \x01(\x0b\x32\x1d.tendermint.abci.RequestFlushH\x00\x12,\n\x04info\x18\x03 \x01(\x0b\x32\x1c.tendermint.abci.RequestInfoH\x00\x12\x37\n\nset_option\x18\x04 \x01(\x0b\x32!.tendermint.abci.RequestSetOptionH\x00\x12\x37\n\ninit_chain\x18\x05 \x01(\x0b\x32!.tendermint.abci.RequestInitChainH\x00\x12.\n\x05query\x18\x06 \x01(\x0b\x32\x1d.tendermint.abci.RequestQueryH\x00\x12\x39\n\x0b\x62\x65gin_block\x18\x07 \x01(\x0b\x32".tendermint.abci.RequestBeginBlockH\x00\x12\x33\n\x08\x63heck_tx\x18\x08 \x01(\x0b\x32\x1f.tendermint.abci.RequestCheckTxH\x00\x12\x37\n\ndeliver_tx\x18\t \x01(\x0b\x32!.tendermint.abci.RequestDeliverTxH\x00\x12\x35\n\tend_block\x18\n \x01(\x0b\x32 .tendermint.abci.RequestEndBlockH\x00\x12\x30\n\x06\x63ommit\x18\x0b \x01(\x0b\x32\x1e.tendermint.abci.RequestCommitH\x00\x12?\n\x0elist_snapshots\x18\x0c \x01(\x0b\x32%.tendermint.abci.RequestListSnapshotsH\x00\x12?\n\x0eoffer_snapshot\x18\r \x01(\x0b\x32%.tendermint.abci.RequestOfferSnapshotH\x00\x12H\n\x13load_snapshot_chunk\x18\x0e \x01(\x0b\x32).tendermint.abci.RequestLoadSnapshotChunkH\x00\x12J\n\x14\x61pply_snapshot_chunk\x18\x0f \x01(\x0b\x32*.tendermint.abci.RequestApplySnapshotChunkH\x00\x42\x07\n\x05value"\x1e\n\x0bRequestEcho\x12\x0f\n\x07message\x18\x01 \x01(\t"\x0e\n\x0cRequestFlush"J\n\x0bRequestInfo\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x15\n\rblock_version\x18\x02 \x01(\x04\x12\x13\n\x0bp2p_version\x18\x03 \x01(\x04".\n\x10RequestSetOption\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t"\x81\x02\n\x10RequestInitChain\x12\x32\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x08\xc8\xde\x1f\x00\x90\xdf\x1f\x01\x12\x10\n\x08\x63hain_id\x18\x02 \x01(\t\x12:\n\x10\x63onsensus_params\x18\x03 \x01(\x0b\x32 .tendermint.abci.ConsensusParams\x12:\n\nvalidators\x18\x04 \x03(\x0b\x32 .tendermint.abci.ValidatorUpdateB\x04\xc8\xde\x1f\x00\x12\x17\n\x0f\x61pp_state_bytes\x18\x05 \x01(\x0c\x12\x16\n\x0einitial_height\x18\x06 \x01(\x03"I\n\x0cRequestQuery\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x12\x0c\n\x04path\x18\x02 \x01(\t\x12\x0e\n\x06height\x18\x03 \x01(\x03\x12\r\n\x05prove\x18\x04 \x01(\x08"\xd1\x01\n\x11RequestBeginBlock\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12.\n\x06header\x18\x02 \x01(\x0b\x32\x18.tendermint.types.HeaderB\x04\xc8\xde\x1f\x00\x12?\n\x10last_commit_info\x18\x03 \x01(\x0b\x32\x1f.tendermint.abci.LastCommitInfoB\x04\xc8\xde\x1f\x00\x12=\n\x14\x62yzantine_validators\x18\x04 \x03(\x0b\x32\x19.tendermint.abci.EvidenceB\x04\xc8\xde\x1f\x00"H\n\x0eRequestCheckTx\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12*\n\x04type\x18\x02 \x01(\x0e\x32\x1c.tendermint.abci.CheckTxType"\x1e\n\x10RequestDeliverTx\x12\n\n\x02tx\x18\x01 \x01(\x0c"!\n\x0fRequestEndBlock\x12\x0e\n\x06height\x18\x01 \x01(\x03"\x0f\n\rRequestCommit"\x16\n\x14RequestListSnapshots"U\n\x14RequestOfferSnapshot\x12+\n\x08snapshot\x18\x01 \x01(\x0b\x32\x19.tendermint.abci.Snapshot\x12\x10\n\x08\x61pp_hash\x18\x02 \x01(\x0c"I\n\x18RequestLoadSnapshotChunk\x12\x0e\n\x06height\x18\x01 \x01(\x04\x12\x0e\n\x06\x66ormat\x18\x02 \x01(\r\x12\r\n\x05\x63hunk\x18\x03 \x01(\r"I\n\x19RequestApplySnapshotChunk\x12\r\n\x05index\x18\x01 \x01(\r\x12\r\n\x05\x63hunk\x18\x02 \x01(\x0c\x12\x0e\n\x06sender\x18\x03 \x01(\t"\xb3\x07\n\x08Response\x12\x37\n\texception\x18\x01 \x01(\x0b\x32".tendermint.abci.ResponseExceptionH\x00\x12-\n\x04\x65\x63ho\x18\x02 \x01(\x0b\x32\x1d.tendermint.abci.ResponseEchoH\x00\x12/\n\x05\x66lush\x18\x03 \x01(\x0b\x32\x1e.tendermint.abci.ResponseFlushH\x00\x12-\n\x04info\x18\x04 \x01(\x0b\x32\x1d.tendermint.abci.ResponseInfoH\x00\x12\x38\n\nset_option\x18\x05 \x01(\x0b\x32".tendermint.abci.ResponseSetOptionH\x00\x12\x38\n\ninit_chain\x18\x06 \x01(\x0b\x32".tendermint.abci.ResponseInitChainH\x00\x12/\n\x05query\x18\x07 \x01(\x0b\x32\x1e.tendermint.abci.ResponseQueryH\x00\x12:\n\x0b\x62\x65gin_block\x18\x08 \x01(\x0b\x32#.tendermint.abci.ResponseBeginBlockH\x00\x12\x34\n\x08\x63heck_tx\x18\t \x01(\x0b\x32 .tendermint.abci.ResponseCheckTxH\x00\x12\x38\n\ndeliver_tx\x18\n \x01(\x0b\x32".tendermint.abci.ResponseDeliverTxH\x00\x12\x36\n\tend_block\x18\x0b \x01(\x0b\x32!.tendermint.abci.ResponseEndBlockH\x00\x12\x31\n\x06\x63ommit\x18\x0c \x01(\x0b\x32\x1f.tendermint.abci.ResponseCommitH\x00\x12@\n\x0elist_snapshots\x18\r \x01(\x0b\x32&.tendermint.abci.ResponseListSnapshotsH\x00\x12@\n\x0eoffer_snapshot\x18\x0e \x01(\x0b\x32&.tendermint.abci.ResponseOfferSnapshotH\x00\x12I\n\x13load_snapshot_chunk\x18\x0f \x01(\x0b\x32*.tendermint.abci.ResponseLoadSnapshotChunkH\x00\x12K\n\x14\x61pply_snapshot_chunk\x18\x10 \x01(\x0b\x32+.tendermint.abci.ResponseApplySnapshotChunkH\x00\x42\x07\n\x05value""\n\x11ResponseException\x12\r\n\x05\x65rror\x18\x01 \x01(\t"\x1f\n\x0cResponseEcho\x12\x0f\n\x07message\x18\x01 \x01(\t"\x0f\n\rResponseFlush"z\n\x0cResponseInfo\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12\x13\n\x0b\x61pp_version\x18\x03 \x01(\x04\x12\x19\n\x11last_block_height\x18\x04 \x01(\x03\x12\x1b\n\x13last_block_app_hash\x18\x05 \x01(\x0c"<\n\x11ResponseSetOption\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0b\n\x03log\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t"\x9d\x01\n\x11ResponseInitChain\x12:\n\x10\x63onsensus_params\x18\x01 \x01(\x0b\x32 .tendermint.abci.ConsensusParams\x12:\n\nvalidators\x18\x02 \x03(\x0b\x32 .tendermint.abci.ValidatorUpdateB\x04\xc8\xde\x1f\x00\x12\x10\n\x08\x61pp_hash\x18\x03 \x01(\x0c"\xb6\x01\n\rResponseQuery\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0b\n\x03log\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t\x12\r\n\x05index\x18\x05 \x01(\x03\x12\x0b\n\x03key\x18\x06 \x01(\x0c\x12\r\n\x05value\x18\x07 \x01(\x0c\x12.\n\tproof_ops\x18\x08 \x01(\x0b\x32\x1b.tendermint.crypto.ProofOps\x12\x0e\n\x06height\x18\t \x01(\x03\x12\x11\n\tcodespace\x18\n \x01(\t"V\n\x12ResponseBeginBlock\x12@\n\x06\x65vents\x18\x01 \x03(\x0b\x32\x16.tendermint.abci.EventB\x18\xc8\xde\x1f\x00\xea\xde\x1f\x10\x65vents,omitempty"\xd9\x01\n\x0fResponseCheckTx\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x0b\n\x03log\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t\x12\x1e\n\ngas_wanted\x18\x05 \x01(\x03R\ngas_wanted\x12\x1a\n\x08gas_used\x18\x06 \x01(\x03R\x08gas_used\x12@\n\x06\x65vents\x18\x07 \x03(\x0b\x32\x16.tendermint.abci.EventB\x18\xc8\xde\x1f\x00\xea\xde\x1f\x10\x65vents,omitempty\x12\x11\n\tcodespace\x18\x08 \x01(\t"\xdb\x01\n\x11ResponseDeliverTx\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x0b\n\x03log\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t\x12\x1e\n\ngas_wanted\x18\x05 \x01(\x03R\ngas_wanted\x12\x1a\n\x08gas_used\x18\x06 \x01(\x03R\x08gas_used\x12@\n\x06\x65vents\x18\x07 \x03(\x0b\x32\x16.tendermint.abci.EventB\x18\xc8\xde\x1f\x00\xea\xde\x1f\x10\x65vents,omitempty\x12\x11\n\tcodespace\x18\x08 \x01(\t"\xda\x01\n\x10ResponseEndBlock\x12\x41\n\x11validator_updates\x18\x01 \x03(\x0b\x32 .tendermint.abci.ValidatorUpdateB\x04\xc8\xde\x1f\x00\x12\x41\n\x17\x63onsensus_param_updates\x18\x02 \x01(\x0b\x32 .tendermint.abci.ConsensusParams\x12@\n\x06\x65vents\x18\x03 \x03(\x0b\x32\x16.tendermint.abci.EventB\x18\xc8\xde\x1f\x00\xea\xde\x1f\x10\x65vents,omitempty"5\n\x0eResponseCommit\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x15\n\rretain_height\x18\x03 \x01(\x03"E\n\x15ResponseListSnapshots\x12,\n\tsnapshots\x18\x01 \x03(\x0b\x32\x19.tendermint.abci.Snapshot"\xb6\x01\n\x15ResponseOfferSnapshot\x12=\n\x06result\x18\x01 \x01(\x0e\x32-.tendermint.abci.ResponseOfferSnapshot.Result"^\n\x06Result\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x41\x43\x43\x45PT\x10\x01\x12\t\n\x05\x41\x42ORT\x10\x02\x12\n\n\x06REJECT\x10\x03\x12\x11\n\rREJECT_FORMAT\x10\x04\x12\x11\n\rREJECT_SENDER\x10\x05"*\n\x19ResponseLoadSnapshotChunk\x12\r\n\x05\x63hunk\x18\x01 \x01(\x0c"\xf2\x01\n\x1aResponseApplySnapshotChunk\x12\x42\n\x06result\x18\x01 \x01(\x0e\x32\x32.tendermint.abci.ResponseApplySnapshotChunk.Result\x12\x16\n\x0erefetch_chunks\x18\x02 \x03(\r\x12\x16\n\x0ereject_senders\x18\x03 \x03(\t"`\n\x06Result\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x41\x43\x43\x45PT\x10\x01\x12\t\n\x05\x41\x42ORT\x10\x02\x12\t\n\x05RETRY\x10\x03\x12\x12\n\x0eRETRY_SNAPSHOT\x10\x04\x12\x13\n\x0fREJECT_SNAPSHOT\x10\x05"\xda\x01\n\x0f\x43onsensusParams\x12+\n\x05\x62lock\x18\x01 \x01(\x0b\x32\x1c.tendermint.abci.BlockParams\x12\x32\n\x08\x65vidence\x18\x02 \x01(\x0b\x32 .tendermint.types.EvidenceParams\x12\x34\n\tvalidator\x18\x03 \x01(\x0b\x32!.tendermint.types.ValidatorParams\x12\x30\n\x07version\x18\x04 \x01(\x0b\x32\x1f.tendermint.types.VersionParams"1\n\x0b\x42lockParams\x12\x11\n\tmax_bytes\x18\x01 \x01(\x03\x12\x0f\n\x07max_gas\x18\x02 \x01(\x03"O\n\x0eLastCommitInfo\x12\r\n\x05round\x18\x01 \x01(\x05\x12.\n\x05votes\x18\x02 \x03(\x0b\x32\x19.tendermint.abci.VoteInfoB\x04\xc8\xde\x1f\x00"h\n\x05\x45vent\x12\x0c\n\x04type\x18\x01 \x01(\t\x12Q\n\nattributes\x18\x02 \x03(\x0b\x32\x1f.tendermint.abci.EventAttributeB\x1c\xc8\xde\x1f\x00\xea\xde\x1f\x14\x61ttributes,omitempty";\n\x0e\x45ventAttribute\x12\x0b\n\x03key\x18\x01 \x01(\x0c\x12\r\n\x05value\x18\x02 \x01(\x0c\x12\r\n\x05index\x18\x03 \x01(\x08"o\n\x08TxResult\x12\x0e\n\x06height\x18\x01 \x01(\x03\x12\r\n\x05index\x18\x02 \x01(\r\x12\n\n\x02tx\x18\x03 \x01(\x0c\x12\x38\n\x06result\x18\x04 \x01(\x0b\x32".tendermint.abci.ResponseDeliverTxB\x04\xc8\xde\x1f\x00"+\n\tValidator\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0c\x12\r\n\x05power\x18\x03 \x01(\x03"U\n\x0fValidatorUpdate\x12\x33\n\x07pub_key\x18\x01 \x01(\x0b\x32\x1c.tendermint.crypto.PublicKeyB\x04\xc8\xde\x1f\x00\x12\r\n\x05power\x18\x02 \x01(\x03"Z\n\x08VoteInfo\x12\x33\n\tvalidator\x18\x01 \x01(\x0b\x32\x1a.tendermint.abci.ValidatorB\x04\xc8\xde\x1f\x00\x12\x19\n\x11signed_last_block\x18\x02 \x01(\x08"\xcc\x01\n\x08\x45vidence\x12+\n\x04type\x18\x01 \x01(\x0e\x32\x1d.tendermint.abci.EvidenceType\x12\x33\n\tvalidator\x18\x02 \x01(\x0b\x32\x1a.tendermint.abci.ValidatorB\x04\xc8\xde\x1f\x00\x12\x0e\n\x06height\x18\x03 \x01(\x03\x12\x32\n\x04time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x08\xc8\xde\x1f\x00\x90\xdf\x1f\x01\x12\x1a\n\x12total_voting_power\x18\x05 \x01(\x03"Z\n\x08Snapshot\x12\x0e\n\x06height\x18\x01 \x01(\x04\x12\x0e\n\x06\x66ormat\x18\x02 \x01(\r\x12\x0e\n\x06\x63hunks\x18\x03 \x01(\r\x12\x0c\n\x04hash\x18\x04 \x01(\x0c\x12\x10\n\x08metadata\x18\x05 \x01(\x0c*9\n\x0b\x43heckTxType\x12\x10\n\x03NEW\x10\x00\x1a\x07\x8a\x9d \x03New\x12\x18\n\x07RECHECK\x10\x01\x1a\x0b\x8a\x9d \x07Recheck*H\n\x0c\x45videnceType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x12\n\x0e\x44UPLICATE_VOTE\x10\x01\x12\x17\n\x13LIGHT_CLIENT_ATTACK\x10\x02\x32\x83\n\n\x0f\x41\x42\x43IApplication\x12\x43\n\x04\x45\x63ho\x12\x1c.tendermint.abci.RequestEcho\x1a\x1d.tendermint.abci.ResponseEcho\x12\x46\n\x05\x46lush\x12\x1d.tendermint.abci.RequestFlush\x1a\x1e.tendermint.abci.ResponseFlush\x12\x43\n\x04Info\x12\x1c.tendermint.abci.RequestInfo\x1a\x1d.tendermint.abci.ResponseInfo\x12R\n\tSetOption\x12!.tendermint.abci.RequestSetOption\x1a".tendermint.abci.ResponseSetOption\x12R\n\tDeliverTx\x12!.tendermint.abci.RequestDeliverTx\x1a".tendermint.abci.ResponseDeliverTx\x12L\n\x07\x43heckTx\x12\x1f.tendermint.abci.RequestCheckTx\x1a .tendermint.abci.ResponseCheckTx\x12\x46\n\x05Query\x12\x1d.tendermint.abci.RequestQuery\x1a\x1e.tendermint.abci.ResponseQuery\x12I\n\x06\x43ommit\x12\x1e.tendermint.abci.RequestCommit\x1a\x1f.tendermint.abci.ResponseCommit\x12R\n\tInitChain\x12!.tendermint.abci.RequestInitChain\x1a".tendermint.abci.ResponseInitChain\x12U\n\nBeginBlock\x12".tendermint.abci.RequestBeginBlock\x1a#.tendermint.abci.ResponseBeginBlock\x12O\n\x08\x45ndBlock\x12 .tendermint.abci.RequestEndBlock\x1a!.tendermint.abci.ResponseEndBlock\x12^\n\rListSnapshots\x12%.tendermint.abci.RequestListSnapshots\x1a&.tendermint.abci.ResponseListSnapshots\x12^\n\rOfferSnapshot\x12%.tendermint.abci.RequestOfferSnapshot\x1a&.tendermint.abci.ResponseOfferSnapshot\x12j\n\x11LoadSnapshotChunk\x12).tendermint.abci.RequestLoadSnapshotChunk\x1a*.tendermint.abci.ResponseLoadSnapshotChunk\x12m\n\x12\x41pplySnapshotChunk\x12*.tendermint.abci.RequestApplySnapshotChunk\x1a+.tendermint.abci.ResponseApplySnapshotChunkB-Z+github.com/tendermint/tendermint/abci/typesb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.abci.types_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b"Z+github.com/tendermint/tendermint/abci/types" - _CHECKTXTYPE.values_by_name["NEW"]._options = None - _CHECKTXTYPE.values_by_name["NEW"]._serialized_options = b"\212\235 \003New" - _CHECKTXTYPE.values_by_name["RECHECK"]._options = None - _CHECKTXTYPE.values_by_name["RECHECK"]._serialized_options = b"\212\235 \007Recheck" - _REQUESTINITCHAIN.fields_by_name["time"]._options = None - _REQUESTINITCHAIN.fields_by_name[ - "time" - ]._serialized_options = b"\310\336\037\000\220\337\037\001" - _REQUESTINITCHAIN.fields_by_name["validators"]._options = None - _REQUESTINITCHAIN.fields_by_name[ - "validators" - ]._serialized_options = b"\310\336\037\000" - _REQUESTBEGINBLOCK.fields_by_name["header"]._options = None - _REQUESTBEGINBLOCK.fields_by_name[ - "header" - ]._serialized_options = b"\310\336\037\000" - _REQUESTBEGINBLOCK.fields_by_name["last_commit_info"]._options = None - _REQUESTBEGINBLOCK.fields_by_name[ - "last_commit_info" - ]._serialized_options = b"\310\336\037\000" - _REQUESTBEGINBLOCK.fields_by_name["byzantine_validators"]._options = None - _REQUESTBEGINBLOCK.fields_by_name[ - "byzantine_validators" - ]._serialized_options = b"\310\336\037\000" - _RESPONSEINITCHAIN.fields_by_name["validators"]._options = None - _RESPONSEINITCHAIN.fields_by_name[ - "validators" - ]._serialized_options = b"\310\336\037\000" - _RESPONSEBEGINBLOCK.fields_by_name["events"]._options = None - _RESPONSEBEGINBLOCK.fields_by_name[ - "events" - ]._serialized_options = b"\310\336\037\000\352\336\037\020events,omitempty" - _RESPONSECHECKTX.fields_by_name["events"]._options = None - _RESPONSECHECKTX.fields_by_name[ - "events" - ]._serialized_options = b"\310\336\037\000\352\336\037\020events,omitempty" - _RESPONSEDELIVERTX.fields_by_name["events"]._options = None - _RESPONSEDELIVERTX.fields_by_name[ - "events" - ]._serialized_options = b"\310\336\037\000\352\336\037\020events,omitempty" - _RESPONSEENDBLOCK.fields_by_name["validator_updates"]._options = None - _RESPONSEENDBLOCK.fields_by_name[ - "validator_updates" - ]._serialized_options = b"\310\336\037\000" - _RESPONSEENDBLOCK.fields_by_name["events"]._options = None - _RESPONSEENDBLOCK.fields_by_name[ - "events" - ]._serialized_options = b"\310\336\037\000\352\336\037\020events,omitempty" - _LASTCOMMITINFO.fields_by_name["votes"]._options = None - _LASTCOMMITINFO.fields_by_name["votes"]._serialized_options = b"\310\336\037\000" - _EVENT.fields_by_name["attributes"]._options = None - _EVENT.fields_by_name[ - "attributes" - ]._serialized_options = b"\310\336\037\000\352\336\037\024attributes,omitempty" - _TXRESULT.fields_by_name["result"]._options = None - _TXRESULT.fields_by_name["result"]._serialized_options = b"\310\336\037\000" - _VALIDATORUPDATE.fields_by_name["pub_key"]._options = None - _VALIDATORUPDATE.fields_by_name["pub_key"]._serialized_options = b"\310\336\037\000" - _VOTEINFO.fields_by_name["validator"]._options = None - _VOTEINFO.fields_by_name["validator"]._serialized_options = b"\310\336\037\000" - _EVIDENCE.fields_by_name["validator"]._options = None - _EVIDENCE.fields_by_name["validator"]._serialized_options = b"\310\336\037\000" - _EVIDENCE.fields_by_name["time"]._options = None - _EVIDENCE.fields_by_name[ - "time" - ]._serialized_options = b"\310\336\037\000\220\337\037\001" - _globals["_CHECKTXTYPE"]._serialized_start = 6314 - _globals["_CHECKTXTYPE"]._serialized_end = 6371 - _globals["_EVIDENCETYPE"]._serialized_start = 6373 - _globals["_EVIDENCETYPE"]._serialized_end = 6445 - _globals["_REQUEST"]._serialized_start = 226 - _globals["_REQUEST"]._serialized_end = 1100 - _globals["_REQUESTECHO"]._serialized_start = 1102 - _globals["_REQUESTECHO"]._serialized_end = 1132 - _globals["_REQUESTFLUSH"]._serialized_start = 1134 - _globals["_REQUESTFLUSH"]._serialized_end = 1148 - _globals["_REQUESTINFO"]._serialized_start = 1150 - _globals["_REQUESTINFO"]._serialized_end = 1224 - _globals["_REQUESTSETOPTION"]._serialized_start = 1226 - _globals["_REQUESTSETOPTION"]._serialized_end = 1272 - _globals["_REQUESTINITCHAIN"]._serialized_start = 1275 - _globals["_REQUESTINITCHAIN"]._serialized_end = 1532 - _globals["_REQUESTQUERY"]._serialized_start = 1534 - _globals["_REQUESTQUERY"]._serialized_end = 1607 - _globals["_REQUESTBEGINBLOCK"]._serialized_start = 1610 - _globals["_REQUESTBEGINBLOCK"]._serialized_end = 1819 - _globals["_REQUESTCHECKTX"]._serialized_start = 1821 - _globals["_REQUESTCHECKTX"]._serialized_end = 1893 - _globals["_REQUESTDELIVERTX"]._serialized_start = 1895 - _globals["_REQUESTDELIVERTX"]._serialized_end = 1925 - _globals["_REQUESTENDBLOCK"]._serialized_start = 1927 - _globals["_REQUESTENDBLOCK"]._serialized_end = 1960 - _globals["_REQUESTCOMMIT"]._serialized_start = 1962 - _globals["_REQUESTCOMMIT"]._serialized_end = 1977 - _globals["_REQUESTLISTSNAPSHOTS"]._serialized_start = 1979 - _globals["_REQUESTLISTSNAPSHOTS"]._serialized_end = 2001 - _globals["_REQUESTOFFERSNAPSHOT"]._serialized_start = 2003 - _globals["_REQUESTOFFERSNAPSHOT"]._serialized_end = 2088 - _globals["_REQUESTLOADSNAPSHOTCHUNK"]._serialized_start = 2090 - _globals["_REQUESTLOADSNAPSHOTCHUNK"]._serialized_end = 2163 - _globals["_REQUESTAPPLYSNAPSHOTCHUNK"]._serialized_start = 2165 - _globals["_REQUESTAPPLYSNAPSHOTCHUNK"]._serialized_end = 2238 - _globals["_RESPONSE"]._serialized_start = 2241 - _globals["_RESPONSE"]._serialized_end = 3188 - _globals["_RESPONSEEXCEPTION"]._serialized_start = 3190 - _globals["_RESPONSEEXCEPTION"]._serialized_end = 3224 - _globals["_RESPONSEECHO"]._serialized_start = 3226 - _globals["_RESPONSEECHO"]._serialized_end = 3257 - _globals["_RESPONSEFLUSH"]._serialized_start = 3259 - _globals["_RESPONSEFLUSH"]._serialized_end = 3274 - _globals["_RESPONSEINFO"]._serialized_start = 3276 - _globals["_RESPONSEINFO"]._serialized_end = 3398 - _globals["_RESPONSESETOPTION"]._serialized_start = 3400 - _globals["_RESPONSESETOPTION"]._serialized_end = 3460 - _globals["_RESPONSEINITCHAIN"]._serialized_start = 3463 - _globals["_RESPONSEINITCHAIN"]._serialized_end = 3620 - _globals["_RESPONSEQUERY"]._serialized_start = 3623 - _globals["_RESPONSEQUERY"]._serialized_end = 3805 - _globals["_RESPONSEBEGINBLOCK"]._serialized_start = 3807 - _globals["_RESPONSEBEGINBLOCK"]._serialized_end = 3893 - _globals["_RESPONSECHECKTX"]._serialized_start = 3896 - _globals["_RESPONSECHECKTX"]._serialized_end = 4113 - _globals["_RESPONSEDELIVERTX"]._serialized_start = 4116 - _globals["_RESPONSEDELIVERTX"]._serialized_end = 4335 - _globals["_RESPONSEENDBLOCK"]._serialized_start = 4338 - _globals["_RESPONSEENDBLOCK"]._serialized_end = 4556 - _globals["_RESPONSECOMMIT"]._serialized_start = 4558 - _globals["_RESPONSECOMMIT"]._serialized_end = 4611 - _globals["_RESPONSELISTSNAPSHOTS"]._serialized_start = 4613 - _globals["_RESPONSELISTSNAPSHOTS"]._serialized_end = 4682 - _globals["_RESPONSEOFFERSNAPSHOT"]._serialized_start = 4685 - _globals["_RESPONSEOFFERSNAPSHOT"]._serialized_end = 4867 - _globals["_RESPONSEOFFERSNAPSHOT_RESULT"]._serialized_start = 4773 - _globals["_RESPONSEOFFERSNAPSHOT_RESULT"]._serialized_end = 4867 - _globals["_RESPONSELOADSNAPSHOTCHUNK"]._serialized_start = 4869 - _globals["_RESPONSELOADSNAPSHOTCHUNK"]._serialized_end = 4911 - _globals["_RESPONSEAPPLYSNAPSHOTCHUNK"]._serialized_start = 4914 - _globals["_RESPONSEAPPLYSNAPSHOTCHUNK"]._serialized_end = 5156 - _globals["_RESPONSEAPPLYSNAPSHOTCHUNK_RESULT"]._serialized_start = 5060 - _globals["_RESPONSEAPPLYSNAPSHOTCHUNK_RESULT"]._serialized_end = 5156 - _globals["_CONSENSUSPARAMS"]._serialized_start = 5159 - _globals["_CONSENSUSPARAMS"]._serialized_end = 5377 - _globals["_BLOCKPARAMS"]._serialized_start = 5379 - _globals["_BLOCKPARAMS"]._serialized_end = 5428 - _globals["_LASTCOMMITINFO"]._serialized_start = 5430 - _globals["_LASTCOMMITINFO"]._serialized_end = 5509 - _globals["_EVENT"]._serialized_start = 5511 - _globals["_EVENT"]._serialized_end = 5615 - _globals["_EVENTATTRIBUTE"]._serialized_start = 5617 - _globals["_EVENTATTRIBUTE"]._serialized_end = 5676 - _globals["_TXRESULT"]._serialized_start = 5678 - _globals["_TXRESULT"]._serialized_end = 5789 - _globals["_VALIDATOR"]._serialized_start = 5791 - _globals["_VALIDATOR"]._serialized_end = 5834 - _globals["_VALIDATORUPDATE"]._serialized_start = 5836 - _globals["_VALIDATORUPDATE"]._serialized_end = 5921 - _globals["_VOTEINFO"]._serialized_start = 5923 - _globals["_VOTEINFO"]._serialized_end = 6013 - _globals["_EVIDENCE"]._serialized_start = 6016 - _globals["_EVIDENCE"]._serialized_end = 6220 - _globals["_SNAPSHOT"]._serialized_start = 6222 - _globals["_SNAPSHOT"]._serialized_end = 6312 - _globals["_ABCIAPPLICATION"]._serialized_start = 6448 - _globals["_ABCIAPPLICATION"]._serialized_end = 7731 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/connections/abci/tendermint/abci/types_pb2_grpc.py b/trader_backup/vendor/valory/connections/abci/tendermint/abci/types_pb2_grpc.py deleted file mode 100644 index aec5cfb23..000000000 --- a/trader_backup/vendor/valory/connections/abci/tendermint/abci/types_pb2_grpc.py +++ /dev/null @@ -1,719 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from packages.valory.connections.abci.tendermint.abci import ( - types_pb2 as tendermint_dot_abci_dot_types__pb2, -) - - -class ABCIApplicationStub(object): - """---------------------------------------- - Service Definition - - """ - - def __init__(self, channel): - """Constructor. - - :param channel: A grpc.Channel. - """ - self.Echo = channel.unary_unary( - "/tendermint.abci.ABCIApplication/Echo", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestEcho.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseEcho.FromString, - ) - self.Flush = channel.unary_unary( - "/tendermint.abci.ABCIApplication/Flush", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestFlush.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseFlush.FromString, - ) - self.Info = channel.unary_unary( - "/tendermint.abci.ABCIApplication/Info", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestInfo.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseInfo.FromString, - ) - self.SetOption = channel.unary_unary( - "/tendermint.abci.ABCIApplication/SetOption", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestSetOption.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseSetOption.FromString, - ) - self.DeliverTx = channel.unary_unary( - "/tendermint.abci.ABCIApplication/DeliverTx", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestDeliverTx.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseDeliverTx.FromString, - ) - self.CheckTx = channel.unary_unary( - "/tendermint.abci.ABCIApplication/CheckTx", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestCheckTx.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseCheckTx.FromString, - ) - self.Query = channel.unary_unary( - "/tendermint.abci.ABCIApplication/Query", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestQuery.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseQuery.FromString, - ) - self.Commit = channel.unary_unary( - "/tendermint.abci.ABCIApplication/Commit", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestCommit.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseCommit.FromString, - ) - self.InitChain = channel.unary_unary( - "/tendermint.abci.ABCIApplication/InitChain", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestInitChain.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseInitChain.FromString, - ) - self.BeginBlock = channel.unary_unary( - "/tendermint.abci.ABCIApplication/BeginBlock", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestBeginBlock.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseBeginBlock.FromString, - ) - self.EndBlock = channel.unary_unary( - "/tendermint.abci.ABCIApplication/EndBlock", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestEndBlock.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseEndBlock.FromString, - ) - self.ListSnapshots = channel.unary_unary( - "/tendermint.abci.ABCIApplication/ListSnapshots", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestListSnapshots.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseListSnapshots.FromString, - ) - self.OfferSnapshot = channel.unary_unary( - "/tendermint.abci.ABCIApplication/OfferSnapshot", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestOfferSnapshot.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseOfferSnapshot.FromString, - ) - self.LoadSnapshotChunk = channel.unary_unary( - "/tendermint.abci.ABCIApplication/LoadSnapshotChunk", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestLoadSnapshotChunk.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseLoadSnapshotChunk.FromString, - ) - self.ApplySnapshotChunk = channel.unary_unary( - "/tendermint.abci.ABCIApplication/ApplySnapshotChunk", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestApplySnapshotChunk.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseApplySnapshotChunk.FromString, - ) - - -class ABCIApplicationServicer(object): - """---------------------------------------- - Service Definition - - """ - - def Echo(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def Flush(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def Info(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def SetOption(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def DeliverTx(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def CheckTx(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def Query(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def Commit(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def InitChain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def BeginBlock(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def EndBlock(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def ListSnapshots(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def OfferSnapshot(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def LoadSnapshotChunk(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def ApplySnapshotChunk(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - -def add_ABCIApplicationServicer_to_server(servicer, server): - rpc_method_handlers = { - "Echo": grpc.unary_unary_rpc_method_handler( - servicer.Echo, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestEcho.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseEcho.SerializeToString, - ), - "Flush": grpc.unary_unary_rpc_method_handler( - servicer.Flush, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestFlush.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseFlush.SerializeToString, - ), - "Info": grpc.unary_unary_rpc_method_handler( - servicer.Info, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestInfo.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseInfo.SerializeToString, - ), - "SetOption": grpc.unary_unary_rpc_method_handler( - servicer.SetOption, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestSetOption.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseSetOption.SerializeToString, - ), - "DeliverTx": grpc.unary_unary_rpc_method_handler( - servicer.DeliverTx, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestDeliverTx.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseDeliverTx.SerializeToString, - ), - "CheckTx": grpc.unary_unary_rpc_method_handler( - servicer.CheckTx, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestCheckTx.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseCheckTx.SerializeToString, - ), - "Query": grpc.unary_unary_rpc_method_handler( - servicer.Query, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestQuery.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseQuery.SerializeToString, - ), - "Commit": grpc.unary_unary_rpc_method_handler( - servicer.Commit, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestCommit.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseCommit.SerializeToString, - ), - "InitChain": grpc.unary_unary_rpc_method_handler( - servicer.InitChain, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestInitChain.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseInitChain.SerializeToString, - ), - "BeginBlock": grpc.unary_unary_rpc_method_handler( - servicer.BeginBlock, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestBeginBlock.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseBeginBlock.SerializeToString, - ), - "EndBlock": grpc.unary_unary_rpc_method_handler( - servicer.EndBlock, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestEndBlock.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseEndBlock.SerializeToString, - ), - "ListSnapshots": grpc.unary_unary_rpc_method_handler( - servicer.ListSnapshots, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestListSnapshots.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseListSnapshots.SerializeToString, - ), - "OfferSnapshot": grpc.unary_unary_rpc_method_handler( - servicer.OfferSnapshot, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestOfferSnapshot.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseOfferSnapshot.SerializeToString, - ), - "LoadSnapshotChunk": grpc.unary_unary_rpc_method_handler( - servicer.LoadSnapshotChunk, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestLoadSnapshotChunk.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseLoadSnapshotChunk.SerializeToString, - ), - "ApplySnapshotChunk": grpc.unary_unary_rpc_method_handler( - servicer.ApplySnapshotChunk, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestApplySnapshotChunk.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseApplySnapshotChunk.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - "tendermint.abci.ABCIApplication", rpc_method_handlers - ) - server.add_generic_rpc_handlers((generic_handler,)) - - -# This class is part of an EXPERIMENTAL API. -class ABCIApplication(object): - """---------------------------------------- - Service Definition - - """ - - @staticmethod - def Echo( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/Echo", - tendermint_dot_abci_dot_types__pb2.RequestEcho.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseEcho.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def Flush( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/Flush", - tendermint_dot_abci_dot_types__pb2.RequestFlush.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseFlush.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def Info( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/Info", - tendermint_dot_abci_dot_types__pb2.RequestInfo.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseInfo.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def SetOption( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/SetOption", - tendermint_dot_abci_dot_types__pb2.RequestSetOption.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseSetOption.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def DeliverTx( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/DeliverTx", - tendermint_dot_abci_dot_types__pb2.RequestDeliverTx.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseDeliverTx.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def CheckTx( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/CheckTx", - tendermint_dot_abci_dot_types__pb2.RequestCheckTx.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseCheckTx.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def Query( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/Query", - tendermint_dot_abci_dot_types__pb2.RequestQuery.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseQuery.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def Commit( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/Commit", - tendermint_dot_abci_dot_types__pb2.RequestCommit.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseCommit.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def InitChain( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/InitChain", - tendermint_dot_abci_dot_types__pb2.RequestInitChain.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseInitChain.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def BeginBlock( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/BeginBlock", - tendermint_dot_abci_dot_types__pb2.RequestBeginBlock.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseBeginBlock.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def EndBlock( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/EndBlock", - tendermint_dot_abci_dot_types__pb2.RequestEndBlock.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseEndBlock.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def ListSnapshots( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/ListSnapshots", - tendermint_dot_abci_dot_types__pb2.RequestListSnapshots.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseListSnapshots.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def OfferSnapshot( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/OfferSnapshot", - tendermint_dot_abci_dot_types__pb2.RequestOfferSnapshot.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseOfferSnapshot.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def LoadSnapshotChunk( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/LoadSnapshotChunk", - tendermint_dot_abci_dot_types__pb2.RequestLoadSnapshotChunk.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseLoadSnapshotChunk.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def ApplySnapshotChunk( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/ApplySnapshotChunk", - tendermint_dot_abci_dot_types__pb2.RequestApplySnapshotChunk.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseApplySnapshotChunk.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) diff --git a/trader_backup/vendor/valory/connections/abci/tendermint/crypto/keys_pb2.py b/trader_backup/vendor/valory/connections/abci/tendermint/crypto/keys_pb2.py deleted file mode 100644 index dc00b9008..000000000 --- a/trader_backup/vendor/valory/connections/abci/tendermint/crypto/keys_pb2.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/crypto/keys.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1ctendermint/crypto/keys.proto\x12\x11tendermint.crypto\x1a\x14gogoproto/gogo.proto"D\n\tPublicKey\x12\x11\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x01 \x01(\x0cH\x00\x12\x13\n\tsecp256k1\x18\x02 \x01(\x0cH\x00:\x08\xe8\xa0\x1f\x01\xe8\xa1\x1f\x01\x42\x05\n\x03sumB:Z8github.com/tendermint/tendermint/proto/tendermint/cryptob\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.crypto.keys_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b"Z8github.com/tendermint/tendermint/proto/tendermint/crypto" - ) - _PUBLICKEY._options = None - _PUBLICKEY._serialized_options = b"\350\240\037\001\350\241\037\001" - _globals["_PUBLICKEY"]._serialized_start = 73 - _globals["_PUBLICKEY"]._serialized_end = 141 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/connections/abci/tendermint/crypto/proof_pb2.py b/trader_backup/vendor/valory/connections/abci/tendermint/crypto/proof_pb2.py deleted file mode 100644 index adf30b16e..000000000 --- a/trader_backup/vendor/valory/connections/abci/tendermint/crypto/proof_pb2.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/crypto/proof.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1dtendermint/crypto/proof.proto\x12\x11tendermint.crypto\x1a\x14gogoproto/gogo.proto"G\n\x05Proof\x12\r\n\x05total\x18\x01 \x01(\x03\x12\r\n\x05index\x18\x02 \x01(\x03\x12\x11\n\tleaf_hash\x18\x03 \x01(\x0c\x12\r\n\x05\x61unts\x18\x04 \x03(\x0c"?\n\x07ValueOp\x12\x0b\n\x03key\x18\x01 \x01(\x0c\x12\'\n\x05proof\x18\x02 \x01(\x0b\x32\x18.tendermint.crypto.Proof"6\n\x08\x44ominoOp\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05input\x18\x02 \x01(\t\x12\x0e\n\x06output\x18\x03 \x01(\t"2\n\x07ProofOp\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c"9\n\x08ProofOps\x12-\n\x03ops\x18\x01 \x03(\x0b\x32\x1a.tendermint.crypto.ProofOpB\x04\xc8\xde\x1f\x00\x42:Z8github.com/tendermint/tendermint/proto/tendermint/cryptob\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.crypto.proof_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b"Z8github.com/tendermint/tendermint/proto/tendermint/crypto" - ) - _PROOFOPS.fields_by_name["ops"]._options = None - _PROOFOPS.fields_by_name["ops"]._serialized_options = b"\310\336\037\000" - _globals["_PROOF"]._serialized_start = 74 - _globals["_PROOF"]._serialized_end = 145 - _globals["_VALUEOP"]._serialized_start = 147 - _globals["_VALUEOP"]._serialized_end = 210 - _globals["_DOMINOOP"]._serialized_start = 212 - _globals["_DOMINOOP"]._serialized_end = 266 - _globals["_PROOFOP"]._serialized_start = 268 - _globals["_PROOFOP"]._serialized_end = 318 - _globals["_PROOFOPS"]._serialized_start = 320 - _globals["_PROOFOPS"]._serialized_end = 377 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/connections/abci/tendermint/types/params_pb2.py b/trader_backup/vendor/valory/connections/abci/tendermint/types/params_pb2.py deleted file mode 100644 index c94e41144..000000000 --- a/trader_backup/vendor/valory/connections/abci/tendermint/types/params_pb2.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/types/params.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1dtendermint/types/params.proto\x12\x10tendermint.types\x1a\x14gogoproto/gogo.proto\x1a\x1egoogle/protobuf/duration.proto"\xf3\x01\n\x0f\x43onsensusParams\x12\x32\n\x05\x62lock\x18\x01 \x01(\x0b\x32\x1d.tendermint.types.BlockParamsB\x04\xc8\xde\x1f\x00\x12\x38\n\x08\x65vidence\x18\x02 \x01(\x0b\x32 .tendermint.types.EvidenceParamsB\x04\xc8\xde\x1f\x00\x12:\n\tvalidator\x18\x03 \x01(\x0b\x32!.tendermint.types.ValidatorParamsB\x04\xc8\xde\x1f\x00\x12\x36\n\x07version\x18\x04 \x01(\x0b\x32\x1f.tendermint.types.VersionParamsB\x04\xc8\xde\x1f\x00"G\n\x0b\x42lockParams\x12\x11\n\tmax_bytes\x18\x01 \x01(\x03\x12\x0f\n\x07max_gas\x18\x02 \x01(\x03\x12\x14\n\x0ctime_iota_ms\x18\x03 \x01(\x03"~\n\x0e\x45videnceParams\x12\x1a\n\x12max_age_num_blocks\x18\x01 \x01(\x03\x12=\n\x10max_age_duration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationB\x08\xc8\xde\x1f\x00\x98\xdf\x1f\x01\x12\x11\n\tmax_bytes\x18\x03 \x01(\x03"2\n\x0fValidatorParams\x12\x15\n\rpub_key_types\x18\x01 \x03(\t:\x08\xb8\xa0\x1f\x01\xe8\xa0\x1f\x01".\n\rVersionParams\x12\x13\n\x0b\x61pp_version\x18\x01 \x01(\x04:\x08\xb8\xa0\x1f\x01\xe8\xa0\x1f\x01">\n\x0cHashedParams\x12\x17\n\x0f\x62lock_max_bytes\x18\x01 \x01(\x03\x12\x15\n\rblock_max_gas\x18\x02 \x01(\x03\x42=Z7github.com/tendermint/tendermint/proto/tendermint/types\xa8\xe2\x1e\x01\x62\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.types.params_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b"Z7github.com/tendermint/tendermint/proto/tendermint/types\250\342\036\001" - ) - _CONSENSUSPARAMS.fields_by_name["block"]._options = None - _CONSENSUSPARAMS.fields_by_name["block"]._serialized_options = b"\310\336\037\000" - _CONSENSUSPARAMS.fields_by_name["evidence"]._options = None - _CONSENSUSPARAMS.fields_by_name[ - "evidence" - ]._serialized_options = b"\310\336\037\000" - _CONSENSUSPARAMS.fields_by_name["validator"]._options = None - _CONSENSUSPARAMS.fields_by_name[ - "validator" - ]._serialized_options = b"\310\336\037\000" - _CONSENSUSPARAMS.fields_by_name["version"]._options = None - _CONSENSUSPARAMS.fields_by_name["version"]._serialized_options = b"\310\336\037\000" - _EVIDENCEPARAMS.fields_by_name["max_age_duration"]._options = None - _EVIDENCEPARAMS.fields_by_name[ - "max_age_duration" - ]._serialized_options = b"\310\336\037\000\230\337\037\001" - _VALIDATORPARAMS._options = None - _VALIDATORPARAMS._serialized_options = b"\270\240\037\001\350\240\037\001" - _VERSIONPARAMS._options = None - _VERSIONPARAMS._serialized_options = b"\270\240\037\001\350\240\037\001" - _globals["_CONSENSUSPARAMS"]._serialized_start = 106 - _globals["_CONSENSUSPARAMS"]._serialized_end = 349 - _globals["_BLOCKPARAMS"]._serialized_start = 351 - _globals["_BLOCKPARAMS"]._serialized_end = 422 - _globals["_EVIDENCEPARAMS"]._serialized_start = 424 - _globals["_EVIDENCEPARAMS"]._serialized_end = 550 - _globals["_VALIDATORPARAMS"]._serialized_start = 552 - _globals["_VALIDATORPARAMS"]._serialized_end = 602 - _globals["_VERSIONPARAMS"]._serialized_start = 604 - _globals["_VERSIONPARAMS"]._serialized_end = 650 - _globals["_HASHEDPARAMS"]._serialized_start = 652 - _globals["_HASHEDPARAMS"]._serialized_end = 714 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/connections/abci/tendermint/types/types_pb2.py b/trader_backup/vendor/valory/connections/abci/tendermint/types/types_pb2.py deleted file mode 100644 index 1818466ed..000000000 --- a/trader_backup/vendor/valory/connections/abci/tendermint/types/types_pb2.py +++ /dev/null @@ -1,158 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/types/types.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) -from packages.valory.connections.abci.tendermint.crypto import ( - proof_pb2 as tendermint_dot_crypto_dot_proof__pb2, -) -from packages.valory.connections.abci.tendermint.types import ( - validator_pb2 as tendermint_dot_types_dot_validator__pb2, -) -from packages.valory.connections.abci.tendermint.version import ( - types_pb2 as tendermint_dot_version_dot_types__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1ctendermint/types/types.proto\x12\x10tendermint.types\x1a\x14gogoproto/gogo.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1dtendermint/crypto/proof.proto\x1a\x1etendermint/version/types.proto\x1a tendermint/types/validator.proto",\n\rPartSetHeader\x12\r\n\x05total\x18\x01 \x01(\r\x12\x0c\n\x04hash\x18\x02 \x01(\x0c"S\n\x04Part\x12\r\n\x05index\x18\x01 \x01(\r\x12\r\n\x05\x62ytes\x18\x02 \x01(\x0c\x12-\n\x05proof\x18\x03 \x01(\x0b\x32\x18.tendermint.crypto.ProofB\x04\xc8\xde\x1f\x00"W\n\x07\x42lockID\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12>\n\x0fpart_set_header\x18\x02 \x01(\x0b\x32\x1f.tendermint.types.PartSetHeaderB\x04\xc8\xde\x1f\x00"\xb3\x03\n\x06Header\x12\x34\n\x07version\x18\x01 \x01(\x0b\x32\x1d.tendermint.version.ConsensusB\x04\xc8\xde\x1f\x00\x12\x1d\n\x08\x63hain_id\x18\x02 \x01(\tB\x0b\xe2\xde\x1f\x07\x43hainID\x12\x0e\n\x06height\x18\x03 \x01(\x03\x12\x32\n\x04time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x08\xc8\xde\x1f\x00\x90\xdf\x1f\x01\x12\x36\n\rlast_block_id\x18\x05 \x01(\x0b\x32\x19.tendermint.types.BlockIDB\x04\xc8\xde\x1f\x00\x12\x18\n\x10last_commit_hash\x18\x06 \x01(\x0c\x12\x11\n\tdata_hash\x18\x07 \x01(\x0c\x12\x17\n\x0fvalidators_hash\x18\x08 \x01(\x0c\x12\x1c\n\x14next_validators_hash\x18\t \x01(\x0c\x12\x16\n\x0e\x63onsensus_hash\x18\n \x01(\x0c\x12\x10\n\x08\x61pp_hash\x18\x0b \x01(\x0c\x12\x19\n\x11last_results_hash\x18\x0c \x01(\x0c\x12\x15\n\revidence_hash\x18\r \x01(\x0c\x12\x18\n\x10proposer_address\x18\x0e \x01(\x0c"\x13\n\x04\x44\x61ta\x12\x0b\n\x03txs\x18\x01 \x03(\x0c"\x92\x02\n\x04Vote\x12-\n\x04type\x18\x01 \x01(\x0e\x32\x1f.tendermint.types.SignedMsgType\x12\x0e\n\x06height\x18\x02 \x01(\x03\x12\r\n\x05round\x18\x03 \x01(\x05\x12<\n\x08\x62lock_id\x18\x04 \x01(\x0b\x32\x19.tendermint.types.BlockIDB\x0f\xc8\xde\x1f\x00\xe2\xde\x1f\x07\x42lockID\x12\x37\n\ttimestamp\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x08\xc8\xde\x1f\x00\x90\xdf\x1f\x01\x12\x19\n\x11validator_address\x18\x06 \x01(\x0c\x12\x17\n\x0fvalidator_index\x18\x07 \x01(\x05\x12\x11\n\tsignature\x18\x08 \x01(\x0c"\x9c\x01\n\x06\x43ommit\x12\x0e\n\x06height\x18\x01 \x01(\x03\x12\r\n\x05round\x18\x02 \x01(\x05\x12<\n\x08\x62lock_id\x18\x03 \x01(\x0b\x32\x19.tendermint.types.BlockIDB\x0f\xc8\xde\x1f\x00\xe2\xde\x1f\x07\x42lockID\x12\x35\n\nsignatures\x18\x04 \x03(\x0b\x32\x1b.tendermint.types.CommitSigB\x04\xc8\xde\x1f\x00"\xa8\x01\n\tCommitSig\x12\x34\n\rblock_id_flag\x18\x01 \x01(\x0e\x32\x1d.tendermint.types.BlockIDFlag\x12\x19\n\x11validator_address\x18\x02 \x01(\x0c\x12\x37\n\ttimestamp\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x08\xc8\xde\x1f\x00\x90\xdf\x1f\x01\x12\x11\n\tsignature\x18\x04 \x01(\x0c"\xf5\x01\n\x08Proposal\x12-\n\x04type\x18\x01 \x01(\x0e\x32\x1f.tendermint.types.SignedMsgType\x12\x0e\n\x06height\x18\x02 \x01(\x03\x12\r\n\x05round\x18\x03 \x01(\x05\x12\x11\n\tpol_round\x18\x04 \x01(\x05\x12<\n\x08\x62lock_id\x18\x05 \x01(\x0b\x32\x19.tendermint.types.BlockIDB\x0f\xc8\xde\x1f\x00\xe2\xde\x1f\x07\x42lockID\x12\x37\n\ttimestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x08\xc8\xde\x1f\x00\x90\xdf\x1f\x01\x12\x11\n\tsignature\x18\x07 \x01(\x0c"b\n\x0cSignedHeader\x12(\n\x06header\x18\x01 \x01(\x0b\x32\x18.tendermint.types.Header\x12(\n\x06\x63ommit\x18\x02 \x01(\x0b\x32\x18.tendermint.types.Commit"z\n\nLightBlock\x12\x35\n\rsigned_header\x18\x01 \x01(\x0b\x32\x1e.tendermint.types.SignedHeader\x12\x35\n\rvalidator_set\x18\x02 \x01(\x0b\x32\x1e.tendermint.types.ValidatorSet"\x9e\x01\n\tBlockMeta\x12<\n\x08\x62lock_id\x18\x01 \x01(\x0b\x32\x19.tendermint.types.BlockIDB\x0f\xc8\xde\x1f\x00\xe2\xde\x1f\x07\x42lockID\x12\x12\n\nblock_size\x18\x02 \x01(\x03\x12.\n\x06header\x18\x03 \x01(\x0b\x32\x18.tendermint.types.HeaderB\x04\xc8\xde\x1f\x00\x12\x0f\n\x07num_txs\x18\x04 \x01(\x03"S\n\x07TxProof\x12\x11\n\troot_hash\x18\x01 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\'\n\x05proof\x18\x03 \x01(\x0b\x32\x18.tendermint.crypto.Proof*\xd7\x01\n\x0b\x42lockIDFlag\x12\x31\n\x15\x42LOCK_ID_FLAG_UNKNOWN\x10\x00\x1a\x16\x8a\x9d \x12\x42lockIDFlagUnknown\x12/\n\x14\x42LOCK_ID_FLAG_ABSENT\x10\x01\x1a\x15\x8a\x9d \x11\x42lockIDFlagAbsent\x12/\n\x14\x42LOCK_ID_FLAG_COMMIT\x10\x02\x1a\x15\x8a\x9d \x11\x42lockIDFlagCommit\x12)\n\x11\x42LOCK_ID_FLAG_NIL\x10\x03\x1a\x12\x8a\x9d \x0e\x42lockIDFlagNil\x1a\x08\x88\xa3\x1e\x00\xa8\xa4\x1e\x01*\xd7\x01\n\rSignedMsgType\x12,\n\x17SIGNED_MSG_TYPE_UNKNOWN\x10\x00\x1a\x0f\x8a\x9d \x0bUnknownType\x12,\n\x17SIGNED_MSG_TYPE_PREVOTE\x10\x01\x1a\x0f\x8a\x9d \x0bPrevoteType\x12\x30\n\x19SIGNED_MSG_TYPE_PRECOMMIT\x10\x02\x1a\x11\x8a\x9d \rPrecommitType\x12.\n\x18SIGNED_MSG_TYPE_PROPOSAL\x10 \x1a\x10\x8a\x9d \x0cProposalType\x1a\x08\x88\xa3\x1e\x00\xa8\xa4\x1e\x01\x42\x39Z7github.com/tendermint/tendermint/proto/tendermint/typesb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.types.types_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b"Z7github.com/tendermint/tendermint/proto/tendermint/types" - ) - _BLOCKIDFLAG._options = None - _BLOCKIDFLAG._serialized_options = b"\210\243\036\000\250\244\036\001" - _BLOCKIDFLAG.values_by_name["BLOCK_ID_FLAG_UNKNOWN"]._options = None - _BLOCKIDFLAG.values_by_name[ - "BLOCK_ID_FLAG_UNKNOWN" - ]._serialized_options = b"\212\235 \022BlockIDFlagUnknown" - _BLOCKIDFLAG.values_by_name["BLOCK_ID_FLAG_ABSENT"]._options = None - _BLOCKIDFLAG.values_by_name[ - "BLOCK_ID_FLAG_ABSENT" - ]._serialized_options = b"\212\235 \021BlockIDFlagAbsent" - _BLOCKIDFLAG.values_by_name["BLOCK_ID_FLAG_COMMIT"]._options = None - _BLOCKIDFLAG.values_by_name[ - "BLOCK_ID_FLAG_COMMIT" - ]._serialized_options = b"\212\235 \021BlockIDFlagCommit" - _BLOCKIDFLAG.values_by_name["BLOCK_ID_FLAG_NIL"]._options = None - _BLOCKIDFLAG.values_by_name[ - "BLOCK_ID_FLAG_NIL" - ]._serialized_options = b"\212\235 \016BlockIDFlagNil" - _SIGNEDMSGTYPE._options = None - _SIGNEDMSGTYPE._serialized_options = b"\210\243\036\000\250\244\036\001" - _SIGNEDMSGTYPE.values_by_name["SIGNED_MSG_TYPE_UNKNOWN"]._options = None - _SIGNEDMSGTYPE.values_by_name[ - "SIGNED_MSG_TYPE_UNKNOWN" - ]._serialized_options = b"\212\235 \013UnknownType" - _SIGNEDMSGTYPE.values_by_name["SIGNED_MSG_TYPE_PREVOTE"]._options = None - _SIGNEDMSGTYPE.values_by_name[ - "SIGNED_MSG_TYPE_PREVOTE" - ]._serialized_options = b"\212\235 \013PrevoteType" - _SIGNEDMSGTYPE.values_by_name["SIGNED_MSG_TYPE_PRECOMMIT"]._options = None - _SIGNEDMSGTYPE.values_by_name[ - "SIGNED_MSG_TYPE_PRECOMMIT" - ]._serialized_options = b"\212\235 \rPrecommitType" - _SIGNEDMSGTYPE.values_by_name["SIGNED_MSG_TYPE_PROPOSAL"]._options = None - _SIGNEDMSGTYPE.values_by_name[ - "SIGNED_MSG_TYPE_PROPOSAL" - ]._serialized_options = b"\212\235 \014ProposalType" - _PART.fields_by_name["proof"]._options = None - _PART.fields_by_name["proof"]._serialized_options = b"\310\336\037\000" - _BLOCKID.fields_by_name["part_set_header"]._options = None - _BLOCKID.fields_by_name["part_set_header"]._serialized_options = b"\310\336\037\000" - _HEADER.fields_by_name["version"]._options = None - _HEADER.fields_by_name["version"]._serialized_options = b"\310\336\037\000" - _HEADER.fields_by_name["chain_id"]._options = None - _HEADER.fields_by_name["chain_id"]._serialized_options = b"\342\336\037\007ChainID" - _HEADER.fields_by_name["time"]._options = None - _HEADER.fields_by_name[ - "time" - ]._serialized_options = b"\310\336\037\000\220\337\037\001" - _HEADER.fields_by_name["last_block_id"]._options = None - _HEADER.fields_by_name["last_block_id"]._serialized_options = b"\310\336\037\000" - _VOTE.fields_by_name["block_id"]._options = None - _VOTE.fields_by_name[ - "block_id" - ]._serialized_options = b"\310\336\037\000\342\336\037\007BlockID" - _VOTE.fields_by_name["timestamp"]._options = None - _VOTE.fields_by_name[ - "timestamp" - ]._serialized_options = b"\310\336\037\000\220\337\037\001" - _COMMIT.fields_by_name["block_id"]._options = None - _COMMIT.fields_by_name[ - "block_id" - ]._serialized_options = b"\310\336\037\000\342\336\037\007BlockID" - _COMMIT.fields_by_name["signatures"]._options = None - _COMMIT.fields_by_name["signatures"]._serialized_options = b"\310\336\037\000" - _COMMITSIG.fields_by_name["timestamp"]._options = None - _COMMITSIG.fields_by_name[ - "timestamp" - ]._serialized_options = b"\310\336\037\000\220\337\037\001" - _PROPOSAL.fields_by_name["block_id"]._options = None - _PROPOSAL.fields_by_name[ - "block_id" - ]._serialized_options = b"\310\336\037\000\342\336\037\007BlockID" - _PROPOSAL.fields_by_name["timestamp"]._options = None - _PROPOSAL.fields_by_name[ - "timestamp" - ]._serialized_options = b"\310\336\037\000\220\337\037\001" - _BLOCKMETA.fields_by_name["block_id"]._options = None - _BLOCKMETA.fields_by_name[ - "block_id" - ]._serialized_options = b"\310\336\037\000\342\336\037\007BlockID" - _BLOCKMETA.fields_by_name["header"]._options = None - _BLOCKMETA.fields_by_name["header"]._serialized_options = b"\310\336\037\000" - _globals["_BLOCKIDFLAG"]._serialized_start = 2207 - _globals["_BLOCKIDFLAG"]._serialized_end = 2422 - _globals["_SIGNEDMSGTYPE"]._serialized_start = 2425 - _globals["_SIGNEDMSGTYPE"]._serialized_end = 2640 - _globals["_PARTSETHEADER"]._serialized_start = 202 - _globals["_PARTSETHEADER"]._serialized_end = 246 - _globals["_PART"]._serialized_start = 248 - _globals["_PART"]._serialized_end = 331 - _globals["_BLOCKID"]._serialized_start = 333 - _globals["_BLOCKID"]._serialized_end = 420 - _globals["_HEADER"]._serialized_start = 423 - _globals["_HEADER"]._serialized_end = 858 - _globals["_DATA"]._serialized_start = 860 - _globals["_DATA"]._serialized_end = 879 - _globals["_VOTE"]._serialized_start = 882 - _globals["_VOTE"]._serialized_end = 1156 - _globals["_COMMIT"]._serialized_start = 1159 - _globals["_COMMIT"]._serialized_end = 1315 - _globals["_COMMITSIG"]._serialized_start = 1318 - _globals["_COMMITSIG"]._serialized_end = 1486 - _globals["_PROPOSAL"]._serialized_start = 1489 - _globals["_PROPOSAL"]._serialized_end = 1734 - _globals["_SIGNEDHEADER"]._serialized_start = 1736 - _globals["_SIGNEDHEADER"]._serialized_end = 1834 - _globals["_LIGHTBLOCK"]._serialized_start = 1836 - _globals["_LIGHTBLOCK"]._serialized_end = 1958 - _globals["_BLOCKMETA"]._serialized_start = 1961 - _globals["_BLOCKMETA"]._serialized_end = 2119 - _globals["_TXPROOF"]._serialized_start = 2121 - _globals["_TXPROOF"]._serialized_end = 2204 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/connections/abci/tendermint/types/validator_pb2.py b/trader_backup/vendor/valory/connections/abci/tendermint/types/validator_pb2.py deleted file mode 100644 index 990e243ee..000000000 --- a/trader_backup/vendor/valory/connections/abci/tendermint/types/validator_pb2.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/types/validator.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) -from packages.valory.connections.abci.tendermint.crypto import ( - keys_pb2 as tendermint_dot_crypto_dot_keys__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n tendermint/types/validator.proto\x12\x10tendermint.types\x1a\x14gogoproto/gogo.proto\x1a\x1ctendermint/crypto/keys.proto"\x8a\x01\n\x0cValidatorSet\x12/\n\nvalidators\x18\x01 \x03(\x0b\x32\x1b.tendermint.types.Validator\x12-\n\x08proposer\x18\x02 \x01(\x0b\x32\x1b.tendermint.types.Validator\x12\x1a\n\x12total_voting_power\x18\x03 \x01(\x03"\x82\x01\n\tValidator\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0c\x12\x33\n\x07pub_key\x18\x02 \x01(\x0b\x32\x1c.tendermint.crypto.PublicKeyB\x04\xc8\xde\x1f\x00\x12\x14\n\x0cvoting_power\x18\x03 \x01(\x03\x12\x19\n\x11proposer_priority\x18\x04 \x01(\x03"V\n\x0fSimpleValidator\x12-\n\x07pub_key\x18\x01 \x01(\x0b\x32\x1c.tendermint.crypto.PublicKey\x12\x14\n\x0cvoting_power\x18\x02 \x01(\x03\x42\x39Z7github.com/tendermint/tendermint/proto/tendermint/typesb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.types.validator_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b"Z7github.com/tendermint/tendermint/proto/tendermint/types" - ) - _VALIDATOR.fields_by_name["pub_key"]._options = None - _VALIDATOR.fields_by_name["pub_key"]._serialized_options = b"\310\336\037\000" - _globals["_VALIDATORSET"]._serialized_start = 107 - _globals["_VALIDATORSET"]._serialized_end = 245 - _globals["_VALIDATOR"]._serialized_start = 248 - _globals["_VALIDATOR"]._serialized_end = 378 - _globals["_SIMPLEVALIDATOR"]._serialized_start = 380 - _globals["_SIMPLEVALIDATOR"]._serialized_end = 466 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/connections/abci/tendermint/version/types_pb2.py b/trader_backup/vendor/valory/connections/abci/tendermint/version/types_pb2.py deleted file mode 100644 index 46fcbdf52..000000000 --- a/trader_backup/vendor/valory/connections/abci/tendermint/version/types_pb2.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/version/types.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1etendermint/version/types.proto\x12\x12tendermint.version\x1a\x14gogoproto/gogo.proto")\n\x03\x41pp\x12\x10\n\x08protocol\x18\x01 \x01(\x04\x12\x10\n\x08software\x18\x02 \x01(\t"-\n\tConsensus\x12\r\n\x05\x62lock\x18\x01 \x01(\x04\x12\x0b\n\x03\x61pp\x18\x02 \x01(\x04:\x04\xe8\xa0\x1f\x01\x42;Z9github.com/tendermint/tendermint/proto/tendermint/versionb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.version.types_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b"Z9github.com/tendermint/tendermint/proto/tendermint/version" - ) - _CONSENSUS._options = None - _CONSENSUS._serialized_options = b"\350\240\037\001" - _globals["_APP"]._serialized_start = 76 - _globals["_APP"]._serialized_end = 117 - _globals["_CONSENSUS"]._serialized_start = 119 - _globals["_CONSENSUS"]._serialized_end = 164 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/connections/abci/tendermint_decoder.py b/trader_backup/vendor/valory/connections/abci/tendermint_decoder.py deleted file mode 100644 index a50a501fa..000000000 --- a/trader_backup/vendor/valory/connections/abci/tendermint_decoder.py +++ /dev/null @@ -1,472 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ -"""Decode AEA messages from Tendermint protobuf messages.""" - -# isort: skip_file # noqa - -from typing import Callable, Optional, Tuple, cast - -from aea.exceptions import enforce -from google.protobuf.timestamp_pb2 import ( # pylint: disable=no-name-in-module - Timestamp as TimestampPb, -) - -from packages.valory.connections.abci.dialogues import AbciDialogue, AbciDialogues -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - Evidence as EvidencePb, -) -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - LastCommitInfo as LastCommitInfoPb, -) -from packages.valory.connections.abci.tendermint.abci.types_pb2 import Request # type: ignore -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - Validator as ValidatorPb, -) -from packages.valory.connections.abci.tendermint.types.types_pb2 import ( # type: ignore - Header as HeaderPb, -) -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import ( - BlockID, - CheckTxType, - CheckTxTypeEnum, - ConsensusParams, - Evidence, - Evidences, - Header, - LastCommitInfo, - PartSetHeader, - Snapshot, - Timestamp, - Validator, - ValidatorUpdates, - ValidatorUpdate, -) - - -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore # isort:skip - ConsensusParams as ConsensusParamsPb, -) -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore # isort:skip - ValidatorUpdate as ValidatorUpdatePb, -) - - -from packages.valory.connections.abci.tendermint.types.types_pb2 import ( # type: ignore - BlockID as BlockIDPb, -) - - -class _TendermintProtocolDecoder: - """ - Decoder called by the server to process requests from the TCP connection with Tendermint. - - It translates from Tendermint's ABCI Protobuf messages into the AEA's ABCI protocol messages. - """ - - @classmethod - def process( - cls, message: Request, dialogues: AbciDialogues, counterparty: str - ) -> Optional[Tuple[AbciMessage, AbciDialogue]]: - """Process an ABCI request or response.""" - is_request = isinstance(message, Request) - enforce(is_request, "only Request messages are allowed") - message_type = f"request_{message.WhichOneof('value')}" - handler: Callable[ - [Request, AbciDialogues, str], Optional[Tuple[AbciMessage, AbciDialogue]] - ] = getattr(cls, message_type, cls.no_match) - result = handler(message, dialogues, counterparty) - return result - - @classmethod - def request_echo( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode an echo request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - echo = request.echo - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_ECHO, - counterparty=counterparty, - message=echo.message, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_flush( - cls, _request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a flush request. - - :param _request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_FLUSH, - counterparty=counterparty, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_info( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a info request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - info = request.info - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_INFO, - counterparty=counterparty, - version=info.version, - block_version=info.block_version, - p2p_version=info.p2p_version, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_set_option( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a set_option request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - set_option = request.set_option - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_SET_OPTION, - counterparty=counterparty, - option_key=set_option.key, - option_value=set_option.value, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_init_chain( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a init_chain request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - init_chain = request.init_chain - timestamp = cls._decode_timestamp(init_chain.time) - chain_id = init_chain.chain_id - consensus_params = ( - cls._decode_consensus_params(init_chain.consensus_params) - if init_chain.consensus_params is not None - else None - ) - validators = ValidatorUpdates( - [ - cls._decode_validator_update(validator_update_pb) - for validator_update_pb in list(init_chain.validators) - ] - ) - app_state_bytes = init_chain.app_state_bytes - initial_height = init_chain.initial_height - - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_INIT_CHAIN, - counterparty=counterparty, - time=timestamp, - chain_id=chain_id, - validators=validators, - app_state_bytes=app_state_bytes, - initial_height=initial_height, - ) - if consensus_params is not None: - abci_message.set("consensus_params", consensus_params) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_begin_block( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a begin_block request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - begin_block = request.begin_block - hash_ = begin_block.hash - header = cls._decode_header(begin_block.header) - last_commit_info = cls._decode_last_commit_info(begin_block.last_commit_info) - evidences = [ - cls._decode_evidence(byzantine_validator) - for byzantine_validator in list(begin_block.byzantine_validators) - ] - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_BEGIN_BLOCK, - counterparty=counterparty, - hash=hash_, - header=header, - last_commit_info=last_commit_info, - byzantine_validators=Evidences(evidences), - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_check_tx( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a check_tx request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - check_tx = request.check_tx - transaction = check_tx.tx - check_tx_type = CheckTxType(CheckTxTypeEnum(check_tx.type)) - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_CHECK_TX, - counterparty=counterparty, - tx=transaction, - type=check_tx_type, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_deliver_tx( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a deliver_tx request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - counterparty=counterparty, - tx=request.deliver_tx.tx, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_query( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a query request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_QUERY, - counterparty=counterparty, - query_data=request.query.data, - path=request.query.path, - height=request.query.height, - prove=request.query.prove, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_commit( - cls, _request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a commit request. - - :param _request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_COMMIT, - counterparty=counterparty, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_end_block( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode an end_block request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_END_BLOCK, - counterparty=counterparty, - height=request.end_block.height, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_list_snapshots( - cls, _request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """Decode a list_snapshots request.""" - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS, - counterparty=counterparty, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_offer_snapshot( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """Decode a offer_snapshot request.""" - offer_snapshot = request.offer_snapshot - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT, - counterparty=counterparty, - snapshot=Snapshot( - offer_snapshot.snapshot.height, - offer_snapshot.snapshot.format, - offer_snapshot.snapshot.chunks, - offer_snapshot.snapshot.hash, - offer_snapshot.snapshot.metadata, - ), - app_hash=offer_snapshot.app_hash, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_load_snapshot_chunk( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """Decode a load_snapshot_chunk request.""" - load_snapshot_chunk = request.load_snapshot_chunk - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK, - counterparty=counterparty, - height=load_snapshot_chunk.height, - format=load_snapshot_chunk.format, - chunk_index=load_snapshot_chunk.chunk, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_apply_snapshot_chunk( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """Decode a apply_snapshot_chunk request.""" - apply_snapshot_chunk = request.apply_snapshot_chunk - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK, - counterparty=counterparty, - index=apply_snapshot_chunk.index, - chunk=apply_snapshot_chunk.chunk, - chunk_sender=apply_snapshot_chunk.sender, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def no_match( - cls, _request: Request, _dialogues: AbciDialogues, _counterparty: str - ) -> None: # pragma: nocover - """Handle the case in which the request is not supported.""" - return None - - @classmethod - def _decode_timestamp(cls, timestamp_tendermint_pb: TimestampPb) -> Timestamp: - """Decode a timestamp object.""" - return Timestamp( - timestamp_tendermint_pb.seconds, - timestamp_tendermint_pb.nanos, - ) - - @classmethod - def _decode_consensus_params( - cls, consensus_params_tendermint_pb: ConsensusParamsPb - ) -> ConsensusParams: - """Decode a ConsensusParams object.""" - return ConsensusParams.decode(consensus_params_tendermint_pb) - - @classmethod - def _decode_validator_update( - cls, validator_update_pb: ValidatorUpdatePb - ) -> ValidatorUpdate: - """Decode a ValidatorUpdate object.""" - return ValidatorUpdate.decode(validator_update_pb) - - @classmethod - def _decode_header(cls, header_tendermint_pb: HeaderPb) -> Header: - """Decode a Header object.""" - return Header.decode(header_tendermint_pb) - - @classmethod - def _decode_block_id(cls, block_id_pb: BlockIDPb) -> BlockID: # pragma: nocover - """Decode a Block ID object.""" - part_set_header_pb = block_id_pb.part_set_header - part_set_header = PartSetHeader( - part_set_header_pb.index, part_set_header_pb.bytes - ) - return BlockID(block_id_pb.hash, part_set_header) - - @classmethod - def _decode_last_commit_info( - cls, last_commit_info_tendermint_pb: LastCommitInfoPb - ) -> LastCommitInfo: - """Decode a LastCommitInfo object.""" - return LastCommitInfo.decode(last_commit_info_tendermint_pb) - - @classmethod - def _decode_validator( - cls, validator_pb: ValidatorPb - ) -> Validator: # pragma: nocover - """Decode a Validator object.""" - return Validator(validator_pb.address, validator_pb.power) - - @classmethod - def _decode_evidence(cls, evidence_pb: EvidencePb) -> Evidence: # pragma: nocover - """Decode an Evidence object.""" - return Evidence.decode(evidence_pb) diff --git a/trader_backup/vendor/valory/connections/abci/tendermint_encoder.py b/trader_backup/vendor/valory/connections/abci/tendermint_encoder.py deleted file mode 100644 index 47b9d1041..000000000 --- a/trader_backup/vendor/valory/connections/abci/tendermint_encoder.py +++ /dev/null @@ -1,418 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ -"""Encode AEA messages into Tendermint protobuf messages.""" -# pylint: disable=no-member -from typing import Callable, Optional, Union, cast - -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - ConsensusParams, - Event, - EventAttribute, - Request, - Response, - ResponseApplySnapshotChunk, - ResponseBeginBlock, - ResponseCheckTx, - ResponseCommit, - ResponseDeliverTx, - ResponseEcho, - ResponseEndBlock, - ResponseException, - ResponseFlush, - ResponseInfo, - ResponseInitChain, - ResponseListSnapshots, - ResponseLoadSnapshotChunk, - ResponseOfferSnapshot, - ResponseQuery, - ResponseSetOption, - Snapshot, - ValidatorUpdate, -) -from packages.valory.connections.abci.tendermint.crypto.proof_pb2 import ( # type: ignore - ProofOp, - ProofOps, -) -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import ( - ConsensusParams as CustomConsensusParams, -) -from packages.valory.protocols.abci.custom_types import Event as CustomEvent -from packages.valory.protocols.abci.custom_types import ( - EventAttribute as CustomEventAttribute, -) -from packages.valory.protocols.abci.custom_types import ProofOp as CustomProofOp -from packages.valory.protocols.abci.custom_types import ProofOps as CustomProofOps -from packages.valory.protocols.abci.custom_types import Snapshot as CustomSnapshot -from packages.valory.protocols.abci.custom_types import ( - ValidatorUpdate as CustomValidatorUpdate, -) - - -class _TendermintProtocolEncoder: - """ - Decoder called by the server to process requests *towards* the TCP connection with Tendermint. - - It translates from the AEA's ABCI protocol messages into Tendermint's ABCI Protobuf messages. - """ - - @classmethod - def process(cls, message: AbciMessage) -> Optional[Union[Request, Response]]: - """Encode an AbciMessage object into either Request or Response protobuf objects.""" - # from "(request|response)_type", get 'type' - handler: Callable[[AbciMessage], Union[Request, Response]] = getattr( - cls, message.performative.value, cls.no_match - ) - return handler(message) - - @classmethod - def response_exception(cls, message: AbciMessage) -> Response: - """ - Process the response exception. - - :param message: the response. - :return: the ABCI protobuf object. - """ - exception = ResponseException() - exception.error = message.error - response = Response(exception=exception) - return response - - @classmethod - def response_echo(cls, message: AbciMessage) -> Response: - """ - Process the response echo. - - :param message: the response. - :return: the ABCI protobuf object. - """ - echo = ResponseEcho() - echo.message = message.message - response = Response(echo=echo) - return response - - @classmethod - def response_set_option(cls, message: AbciMessage) -> Response: - """ - Process the response set_option. - - :param message: the response. - :return: the ABCI protobuf object. - """ - set_option = ResponseSetOption() - set_option.code = message.code - set_option.log = message.log - set_option.info = message.info - response = Response(set_option=set_option) - return response - - @classmethod - def response_info(cls, message: AbciMessage) -> Response: - """ - Process the response info. - - :param message: the response. - :return: the ABCI protobuf object. - """ - info = ResponseInfo() - info.data = message.info_data - info.version = message.version - info.app_version = message.app_version - info.last_block_height = message.last_block_height - info.last_block_app_hash = message.last_block_app_hash - response = Response(info=info) - return response - - @classmethod - def response_flush(cls, _message: AbciMessage) -> Response: - """ - Process the response flush. - - :param _message: the response. - :return: the ABCI protobuf object. - """ - response = Response(flush=ResponseFlush()) - return response - - @classmethod - def response_init_chain(cls, message: AbciMessage) -> Response: - """ - Process the response init_chain. - - :param message: the response. - :return: the ABCI protobuf object. - """ - init_chain = ResponseInitChain() - - if message.consensus_params is not None: - consensus_params_pb = cls._encode_consensus_params(message.consensus_params) - init_chain.consensus_params.CopyFrom(consensus_params_pb) - - validators_pb = [ - cls._encode_validator_update(vu) - for vu in list(message.validators.validator_updates) - ] - init_chain.validators.extend(validators_pb) - - init_chain.app_hash = message.app_hash - - response = Response(init_chain=init_chain) - return response - - @classmethod - def response_query(cls, message: AbciMessage) -> Response: - """ - Process the response query. - - :param message: the response. - :return: the ABCI protobuf object. - """ - query = ResponseQuery() - - query.code = message.code - query.log = message.log - query.info = message.info - query.index = message.index - query.key = message.key - query.value = message.value - - proof_ops_pb = cls._encode_proof_ops(message.proof_ops) - query.proof_ops.CopyFrom(proof_ops_pb) - - query.height = message.height - query.codespace = message.codespace - - response = Response(query=query) - return response - - @classmethod - def response_check_tx(cls, message: AbciMessage) -> Response: - """ - Process the response check_tx. - - :param message: the response. - :return: the ABCI protobuf object. - """ - check_tx = ResponseCheckTx() - - check_tx.code = message.code - check_tx.data = message.data - check_tx.log = message.log - check_tx.info = message.info - check_tx.gas_wanted = message.gas_wanted - check_tx.gas_used = message.gas_used - - events_pb = [cls._encode_event(e) for e in message.events.events] - check_tx.events.extend(events_pb) - - check_tx.codespace = message.codespace - - response = Response(check_tx=check_tx) - return response - - @classmethod - def response_deliver_tx(cls, message: AbciMessage) -> Response: - """ - Process the response deliver_tx. - - :param message: the response. - :return: the ABCI protobuf object. - """ - deliver_tx = ResponseDeliverTx() - - deliver_tx.code = message.code - deliver_tx.data = message.data - deliver_tx.log = message.log - deliver_tx.info = message.info - deliver_tx.gas_wanted = message.gas_wanted - deliver_tx.gas_used = message.gas_used - - events_pb = [cls._encode_event(e) for e in message.events.events] - deliver_tx.events.extend(events_pb) - - deliver_tx.codespace = message.codespace - - response = Response(deliver_tx=deliver_tx) - return response - - @classmethod - def response_begin_block(cls, message: AbciMessage) -> Response: - """ - Process the response begin_block. - - :param message: the response. - :return: the ABCI protobuf object. - """ - begin_block = ResponseBeginBlock() - - events_pb = [cls._encode_event(e) for e in message.events.events] - begin_block.events.extend(events_pb) - - response = Response(begin_block=begin_block) - return response - - @classmethod - def response_end_block(cls, message: AbciMessage) -> Response: - """ - Process the response end_block. - - :param message: the response. - :return: the ABCI protobuf object. - """ - end_block = ResponseEndBlock() - - if ( - message.is_set("consensus_param_updates") - and message.consensus_param_updates is not None - ): - consensus_params_updates = cast( - ConsensusParams, message.consensus_param_updates - ) - consensus_params_pb = cls._encode_consensus_params(consensus_params_updates) - end_block.consensus_param_updates.CopyFrom(consensus_params_pb) - - validator_updates_pb = [ - cls._encode_validator_update(vu) - for vu in message.validator_updates.validator_updates - ] - end_block.validator_updates.extend(validator_updates_pb) - - events_pb = [cls._encode_event(e) for e in message.events.events] - end_block.events.extend(events_pb) - - response = Response(end_block=end_block) - return response - - @classmethod - def response_commit(cls, message: AbciMessage) -> Response: - """ - Process the response commit. - - :param message: the response. - :return: the ABCI protobuf object. - """ - commit = ResponseCommit() - commit.data = message.data - commit.retain_height = message.retain_height - return Response(commit=commit) - - @classmethod - def response_list_snapshots(cls, message: AbciMessage) -> Response: - """ - Process the response list_snapshots. - - :param message: the response. - :return: the ABCI protobuf object. - """ - list_snapshots = ResponseListSnapshots() - snapshots_pb = [ - cls._encode_snapshot(snapshot) for snapshot in message.snapshots.snapshots - ] - list_snapshots.snapshots.extend(snapshots_pb) - return Response(list_snapshots=list_snapshots) - - @classmethod - def response_offer_snapshot(cls, message: AbciMessage) -> Response: - """ - Process the response offer_snapshot. - - :param message: the response. - :return: the ABCI protobuf object. - """ - offer_snapshot = ResponseOfferSnapshot() - offer_snapshot.result = message.result.result_type.value - return Response(offer_snapshot=offer_snapshot) - - @classmethod - def response_load_snapshot_chunk(cls, message: AbciMessage) -> Response: - """ - Process the response load_snapshot_chunk. - - :param message: the response. - :return: the ABCI protobuf object. - """ - load_snapshot_chunk = ResponseLoadSnapshotChunk() - load_snapshot_chunk.chunk = message.chunk - return Response(load_snapshot_chunk=load_snapshot_chunk) - - @classmethod - def response_apply_snapshot_chunk(cls, message: AbciMessage) -> Response: - """ - Process the response apply_snapshot_chunk. - - :param message: the response. - :return: the ABCI protobuf object. - """ - apply_snapshot_chunk = ResponseApplySnapshotChunk() - apply_snapshot_chunk.result = message.result.result_type.value - apply_snapshot_chunk.refetch_chunks.extend(message.refetch_chunks) - apply_snapshot_chunk.reject_senders.extend(message.reject_senders) - return Response(apply_snapshot_chunk=apply_snapshot_chunk) - - @classmethod - def no_match(cls, _request: Request) -> None: # pragma: nocover - """No match.""" - return None - - @classmethod - def _encode_consensus_params( - cls, consensus_params: CustomConsensusParams - ) -> ConsensusParams: - consensus_params_pb = ConsensusParams() - CustomConsensusParams.encode(consensus_params_pb, consensus_params) - return consensus_params_pb - - @classmethod - def _encode_validator_update( - cls, validator_update: CustomValidatorUpdate - ) -> ValidatorUpdate: - validator_update_pb = ValidatorUpdate() - CustomValidatorUpdate.encode(validator_update_pb, validator_update) - return validator_update_pb - - @classmethod - def _encode_event(cls, event: CustomEvent) -> Event: - attributes_pb = [] - for attribute in event.attributes: - attribute_pb = EventAttribute() - CustomEventAttribute.encode(attribute_pb, attribute) - attributes_pb.append(attribute_pb) - - event_pb = Event() - event_pb.type = event.type_ - event_pb.attributes.extend(attributes_pb) - return event_pb - - @classmethod - def _encode_proof_ops(cls, proof_ops: CustomProofOps) -> ProofOps: - ops_pb = [] - for proof_op in proof_ops.proof_ops: - proof_op_pb = ProofOp() - CustomProofOp.encode(proof_op_pb, proof_op) - ops_pb.append(proof_op_pb) - - proof_ops_pb = ProofOps() - proof_ops_pb.ops.extend(ops_pb) - return proof_ops_pb - - @classmethod - def _encode_snapshot(cls, snapshot: CustomSnapshot) -> Event: - snapshot_pb = Snapshot() - CustomSnapshot.encode(snapshot_pb, snapshot) - return snapshot_pb diff --git a/trader_backup/vendor/valory/connections/abci/tests/__init__.py b/trader_backup/vendor/valory/connections/abci/tests/__init__.py deleted file mode 100644 index 0a13f4963..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/abci connection.""" - -from hypothesis import settings - - -CI = "CI" # pragma: nocover - -settings.register_profile(CI, deadline=5000) # pragma: nocover diff --git a/trader_backup/vendor/valory/connections/abci/tests/helper.py b/trader_backup/vendor/valory/connections/abci/tests/helper.py deleted file mode 100644 index da6e982df..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/helper.py +++ /dev/null @@ -1,533 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Helper functions for checking compliance to ABCI spec""" - -# pylint: skip-file - -import builtins -import functools -import inspect -from enum import Enum -from pathlib import Path -from types import ModuleType -from typing import Any, Dict, List, Tuple, Type, Union - -import yaml -from aea.protocols.generator.common import ( - SPECIFICATION_COMPOSITIONAL_TYPES, - _camel_case_to_snake_case, - _get_sub_types_of_compositional_types, - _to_camel_case, -) -from google.protobuf.descriptor import FieldDescriptor - -from packages.valory.connections.abci.connection import PUBLIC_ID -from packages.valory.connections.abci.connection import ( - _TendermintProtocolDecoder as Decoder, -) -from packages.valory.connections.abci.connection import ( - _TendermintProtocolEncoder as Encoder, -) -from packages.valory.connections.abci.dialogues import AbciDialogues -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - DESCRIPTOR, - Request, - Response, -) -from packages.valory.protocols import abci as valory_abci_protocol -from packages.valory.protocols.abci import AbciMessage, custom_types - - -Node = Dict[str, Any] - -camel_to_snake = _camel_case_to_snake_case -snake_to_camel = _to_camel_case - - -type_mapping = { - v: k[5:].lower() for k, v in vars(FieldDescriptor).items() if k.startswith("TYPE_") -} - -type_to_python = dict.fromkeys(type_mapping.values()) -type_to_python.update( - dict( - double=float, - float=float, - int64=int, - uint64=int, - int32=int, - bool=bool, - string=str, - bytes=bytes, - uint32=int, - ) -) - -TENDERMINT_PRIMITIVES = tuple(type_mapping.values()) -PYTHON_PRIMITIVES = (int, float, bool, str, bytes) - -# simple value strategy -AEA_PRIMITIVES = {str: "sss", bytes: b"bbb", int: 123, float: 3.14, bool: True} -TENDER_PRIMITIVES = dict( - int32=-32, - uint32=32, - int64=-64, - uint64=64, - bool=True, - string="sss", - bytes=b"bbb", - nanos=999, -) -REPEATED_FIELD_SIZE = 3 -USE_NON_ZERO_ENUM: bool = True - - -def is_enum(d_type: Any) -> bool: - """Check if a type is an Enum (not instance!).""" - return isinstance(d_type, type) and issubclass(d_type, Enum) - - -def my_repr(self: Any) -> str: - """Custom __repr__ for Tendermint protobuf objects, which lack it.""" - return f"<{self.__module__}.{type(self).__name__} object at {hex(id(self))}>" - - -def is_typing_list(d_type: Any) -> bool: - """Check if field is repeated.""" - return d_type.__class__.__module__ == "typing" and d_type.__origin__ is list - - -def replace_keys(node: Node, trans: Node) -> None: - """Replace keys in-place""" - for k, v in trans.items(): - if isinstance(v, dict): - replace_keys(node[k], v) - else: - node[v] = node.pop(k) - - -def set_repr(cls: Type) -> Type: - """Set custom __repr__""" - cls.__repr__ = my_repr # type: ignore - return cls - - -def get_aea_classes(module: ModuleType) -> Dict[str, Type]: - """Get AEA custom classes.""" - - def is_locally_defined_class(item: Any) -> bool: - return isinstance(item, type) and item.__module__ == module.__name__ - - return {k: v for k, v in vars(module).items() if is_locally_defined_class(v)} - - -AEA_CUSTOM = get_aea_classes(custom_types) - - -@functools.lru_cache() -def get_protocol_readme_spec() -> Tuple[Any, Any, Any]: - """Test specification used to generate protocol matches ABCI spec""" - - protocol_readme = Path(valory_abci_protocol.__file__).parent / "README.md" - raw_chunks = open(protocol_readme).read().split("```") - assert len(raw_chunks) == 3, "Expecting a single YAML code block" - - yaml_chunks = raw_chunks[1].strip("yaml").split("\n---") - yaml_content = [] - for raw_doc in filter(None, yaml_chunks): - try: - yaml_content.append(yaml.safe_load(raw_doc)) - except yaml.YAMLError as e: - raise e - - protocol, custom, dialogues = yaml_content - assert protocol["name"] == "abci" # sanity check - return protocol, custom, dialogues - - -# 1. Create type tree for the AEA-native ABCI protocol -def _create_aea_custom_type_tree(custom_type: Type) -> Tuple[Type, Node]: - """Create custom type tree for AEA-native ABCI spec""" - - kwarg_types = {} - parameters = inspect.signature(custom_type).parameters - for name, parameter in parameters.items(): - d_type = parameter.annotation - if d_type in PYTHON_PRIMITIVES: - kwarg_types[name] = d_type - elif is_enum(d_type): - kwarg_types[name] = d_type - elif is_typing_list(d_type): # "repeated" - assert len(d_type.__args__) == 1 # check assumption - container, content = d_type.__origin__, d_type.__args__[0] - if content in AEA_CUSTOM.values(): - content = _create_aea_custom_type_tree(content) - kwarg_types[name] = container, content - else: - nested_type = AEA_CUSTOM.get(d_type, d_type) - kwarg_types[name] = _create_aea_custom_type_tree(nested_type) - - return custom_type, kwarg_types - - -def _create_aea_type_tree(field: str) -> Any: - """Create type tree for AEA-native ABCI spec""" - - if any(map(field.startswith, SPECIFICATION_COMPOSITIONAL_TYPES)): - subfields = _get_sub_types_of_compositional_types(field) - if field.startswith("pt:optional"): - return _create_aea_type_tree(*subfields) - elif field.startswith("pt:list"): # repeated - return list, _create_aea_type_tree(*subfields) - raise NotImplementedError(f"field: {field}") - - if field.startswith("ct:"): - custom_type = AEA_CUSTOM[field[3:]] - return _create_aea_custom_type_tree(custom_type) - - primitive = getattr(builtins, field[3:]) - return primitive - - -def create_aea_abci_type_tree( - speech_acts: Dict[str, Dict[str, str]] -) -> Dict[str, Node]: - """Create AEA-native ABCI type tree from the defined speech acts""" - - def _get_message_types(fields: Dict[str, str]) -> Node: - """Get message types for AEA-native ABCI spec""" - return {k: _create_aea_type_tree(v) for k, v in fields.items()} - - return {k: _get_message_types(v) for k, v in speech_acts.items()} - - -# 2. Initialize AEA-native ABCI primitives -def _init_subtree(node: Node) -> Node: - """Initialize subtree of type_tree non-custom objects""" - - def init_repeated(repeated_type: Any) -> Tuple[Any, ...]: - """Repeated fields must be tuples for Tendermint protobuf""" - - if repeated_type in PYTHON_PRIMITIVES: - data = AEA_PRIMITIVES[repeated_type] - return tuple(data for _ in range(REPEATED_FIELD_SIZE)) - elif isinstance(repeated_type, tuple): - cls, kws = repeated_type - return tuple(_init_subtree(kws) for _ in range(REPEATED_FIELD_SIZE)) - raise NotImplementedError(f"Repeated in {name}: {repeated_type}") - - kwargs: Node = {} - for name, d_type in node.items(): - if isinstance(d_type, tuple): - container, content = d_type - if container is list: - kwargs[name] = init_repeated(content) - else: - kwargs[name] = _init_subtree(content) - elif d_type in PYTHON_PRIMITIVES: - kwargs[name] = AEA_PRIMITIVES[d_type] - elif is_enum(d_type): - kwargs[name] = list(d_type)[USE_NON_ZERO_ENUM] - else: - raise NotImplementedError(f"{name}: {d_type}") - - return kwargs - - -def init_type_tree_primitives(type_tree: Node) -> Node: - """ - Initialize the primitive types and size of repeated fields. - - These are the only initialization parameters that can vary; - after this the initialization of custom types is what remains - - This structure allows: - - Comparison of structure and these values with Tendermint translation - - Visual inspection of fields to be sets, also on custom objects - - Randomized testing strategies using e.g. hypothesis - - :param type_tree: mapping from message / field name to type. - :return: mapping from message / field name to initialized primitive. - """ - return {k: _init_subtree(node) for k, node in type_tree.items()} - - -# 3. Initialize AEA-native ABCI protocol messages -def _complete_init(type_node: Node, init_node: Node) -> Node: - """Initialize custom classes and containers""" - - def init_repeated(repeated_type: Any) -> Tuple[Any, ...]: - if not isinstance(content, tuple): - return init_node[key] # already initialized primitives - custom_type, kwargs = repeated_type - return tuple(custom_type(**_complete_init(kwargs, c)) for c in init_node[key]) - - node: Node = {} - for key, d_type in type_node.items(): - if d_type in PYTHON_PRIMITIVES: - node[key] = init_node[key] - elif isinstance(d_type, tuple): - container, content = d_type - if container is list: - node[key] = init_repeated(content) - else: - node[key] = container(**_complete_init(content, init_node[key])) - elif is_enum(d_type): - node[key] = init_node[key] - else: - raise NotImplementedError(f"{key}: {d_type}") - - return node - - -def init_aea_abci_messages(type_tree: Node, init_tree: Node) -> Node: - """ - Create ABCI messages for AEA-native ABCI spec - - We iterate the type_tree and init_tree to finalize the - initialization of custom objects contained in it, and - create an instance of all ABCI messages. - - :param type_tree: mapping from message / field name to type. - :param init_tree: mapping from message / field name to initialized primitive. - :return: mapping from message name to ABCI Message instance - """ - - messages = dict.fromkeys(type_tree) - for key in type_tree: - performative = getattr(AbciMessage.Performative, key.upper()) - kwargs = _complete_init(type_tree[key], init_tree[key]) - messages[key] = AbciMessage(performative, **kwargs) - - return messages - - -class EncodingError(Exception): - """EncodingError AEA- to Tendermint-native ABCI message""" - - -class DecodingError(Exception): - """DecodingError Tendermint- to AEA-native ABCI message""" - - -# 4. Translate AEA-native to Tendermint-native -def encode(message: AbciMessage) -> Response: - """Encode AEA-native ABCI protocol messages to Tendermint-native""" - - try: - return Encoder.process(message) - except Exception as e: - raise EncodingError(f"ABCI message {message}: {e}") - - -def decode(request: Request) -> AbciMessage: - """Decode Tendermint-native ABCI protocol messages to AEA-native""" - - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - try: - message, dialogue = Decoder().process(request, dialogues, "dummy") # type: ignore - return message - except Exception as e: - raise DecodingError(f"Request {request}: {e}") - - -# 5. Build content tree from Tendermint-native ABCI messages -def _get_message_content(message: Any) -> Node: - """Verify Tendermint-native ABCI message""" - - # NOTE: PublicKey objects are an Enum in AEA-native protocol - # but are retrieved as mapping from Tendermint side - - assert message.IsInitialized() - assert not message.FindInitializationErrors() - - # NOTE: ListFields does not retrieve what is empty! - fields = dict(message.DESCRIPTOR.fields_by_name) - enum_types = dict(message.DESCRIPTOR.enum_types_by_name) - oneofs = dict(message.DESCRIPTOR.oneofs_by_name) - - kwargs: Node = {} - for name, descr in fields.items(): - attr = getattr(message, name) - - if descr.enum_type: - enum_type = enum_types.pop(snake_to_camel(name)) - kwargs[name] = (enum_type.values[attr].name, attr) - elif isinstance(attr, PYTHON_PRIMITIVES): - kwargs[name] = attr - elif descr.label == descr.LABEL_REPEATED: - assert isinstance(descr.default_value, list) # attr - assert len(set(map(type, attr))) <= 1, "Expecting single type" - if not attr or isinstance(attr[0], PYTHON_PRIMITIVES): - kwargs[name] = list(attr) - else: - kwargs[name] = [_get_message_content(c) for c in attr] - elif descr.message_type: - kwargs[name] = _get_message_content(attr) - else: - raise NotImplementedError(f"name: {name} {attr}") - - # in the case of oneofs, we assert they were retrieved from fields (PublicKey) - expected = {f.name for oneof in oneofs.values() for f in oneof.fields} - assert all(k in kwargs for k in expected), f"oneofs in {message}" - assert not enum_types, f"assumed max 1 enum per message: {message}" - - return kwargs - - -def get_tendermint_content(envelope: Union[Request, Response]) -> Node: - """ - Get Tendermint-native ABCI message content. - - For all Request / Response instances obtained after encoding, - we retrieve the information present in the message they contain. - - :param envelope: a Tendermint Request / Response object. - :return: mapping structure from message / field name to leaf values - """ - - assert isinstance(envelope, (Request, Response)) - assert envelope.IsInitialized() - assert not envelope.FindInitializationErrors() - assert len(envelope.ListFields()) == 1 - descr, message = envelope.ListFields()[0] - return _get_message_content(message) - - -# compare AEA- and Tendermint-native ABCI protocol input and output -def compare_trees(init_node: Node, tender_node: Node) -> None: - """Compare Initialization and Tendermint tree nodes""" - - # NOTE: PublicKey objects are an Enum in AEA-native protocol - # but are retrieved as mapping from Tendermint side - - if init_node == tender_node: - return - - for k, init_child in init_node.items(): - # translate key to tendermint key - tk = {"type_": "type", "format_": "format", "hash_": "hash"}.get(k, k) - tender_child = tender_node[tk] - - if k == "pub_key": - init_child = {init_child["key_type"].name: init_child["data"]} - - if init_child == tender_child: - continue - elif isinstance(init_child, dict) and isinstance(tender_child, dict): - compare_trees(init_child, tender_child) - - elif isinstance(tender_child, list): - # we use a nested mapping to represent a custom class, - # tendermint doesn't use this for storing repeated fields - if isinstance(init_child, dict): - repeated = list(init_child.values()) - assert len(repeated) == 1 - init_child = repeated[0] - - assert len(init_child) == len(tender_child) - for a, b in zip(init_child, tender_child): - compare_trees(a, b) - - else: - assert len(init_child) == 1, "expecting enum" - enum = set(init_child.values()).pop() - assert (enum.name, enum.value) == tender_node[tk] - - -def _process_message_descriptor(m_descriptor: Any) -> Node: - """Process fields of the message descriptor""" - - node: Node = {} - for name, field in m_descriptor.fields_by_name.items(): - if field.message_type: - cls = set_repr(field.message_type._concrete_class) - node[name] = cls, _process_message_descriptor(cls.DESCRIPTOR) - elif field.enum_type: - names = field.enum_type.values_by_name - numbers = field.enum_type.values_by_number - node[name] = Enum(name, zip(names, numbers)) - else: - node[name] = type_mapping[field.type] - - if field.label == field.LABEL_REPEATED: - node[name] = list, node[name] - - return node - - -def get_tender_type_tree() -> Node: - """Tendermint type tree""" - - descriptor = DESCRIPTOR - tender_type_tree = {} - for msg, msg_descr in descriptor.message_types_by_name.items(): - cls = set_repr(msg_descr._concrete_class) - tender_type_tree[msg] = cls, _process_message_descriptor(msg_descr) - return tender_type_tree - - -def _init_tender_tree(tender_node: Node) -> Node: - """Initialize Tendermint classes""" - - def init_repeated(repeated_type: Any) -> List[Any]: - if isinstance(repeated_type, str): - return [ - TENDER_PRIMITIVES[repeated_type] for _ in range(REPEATED_FIELD_SIZE) - ] - cls, kwargs = repeated_type - return [cls(**_init_tender_tree(kwargs)) for _ in range(REPEATED_FIELD_SIZE)] - - node = {} - for field, d_type in tender_node.items(): - if isinstance(d_type, str): - if field == "nanos": # special - node[field] = TENDER_PRIMITIVES[field] - else: - node[field] = TENDER_PRIMITIVES[d_type] - elif is_enum(d_type): - node[field] = list(d_type)[USE_NON_ZERO_ENUM].value - elif isinstance(d_type, tuple): - container, content = d_type - if container is list: - node[field] = init_repeated(content) - else: - node[field] = container(**_init_tender_tree(content)) - else: - raise NotImplementedError(f"field {field}: {d_type}") - - return node - - -def _build_tendermint_messages(cls: Type, tree: Node) -> List[Union[Request, Response]]: - """Build tendermint messages""" - - return [cls(**{k: v}) for k, v in _init_tender_tree(tree).items()] - - -def init_tendermint_messages(tender_type_tree: Node) -> List[Union[Request, Response]]: - """Initialize tendermint ABCI messages""" - - request_cls, request_tree = tender_type_tree["Request"] - - # construct Tendermint-native messages - messages = _build_tendermint_messages(request_cls, request_tree) - - return messages diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_abci.py b/trader_backup/vendor/valory/connections/abci/tests/test_abci.py deleted file mode 100644 index e88e917b3..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_abci.py +++ /dev/null @@ -1,661 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/abci connection.""" - -# pylint: skip-file - -import asyncio -import logging -import os -import shutil -import time -from abc import ABC, abstractmethod -from cmath import inf -from contextlib import suppress -from pathlib import Path -from tempfile import TemporaryDirectory -from typing import Any, Callable, Generator, List, NoReturn, cast -from unittest import mock -from unittest.mock import MagicMock - -import docker -import pytest -import requests -from _pytest.fixtures import SubRequest # type: ignore -from aea.configurations.base import ConnectionConfig -from aea.connections.base import ConnectionStates -from aea.identity.base import Identity -from aea.mail.base import Envelope -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea_test_autonomy.configurations import ANY_ADDRESS, HTTP_LOCALHOST -from aea_test_autonomy.docker.base import skip_docker_tests -from aea_test_autonomy.docker.tendermint import TendermintDockerImage -from aea_test_autonomy.fixture_helpers import ( # noqa: F401 - DEFAULT_TENDERMINT_PORT, - abci_host, - abci_port, - tendermint_port, -) -from aea_test_autonomy.helpers.async_utils import ( - AnotherThreadTask, - BaseThreadedAsyncLoop, - wait_for_condition, -) -from docker.models.containers import Container -from hypothesis import database, given, settings -from hypothesis.strategies import integers - -from packages.valory.connections.abci import check_dependencies as dep_utils -from packages.valory.connections.abci.connection import ( - ABCIServerConnection, - DEFAULT_ABCI_PORT, - DEFAULT_LISTEN_ADDRESS, - DecodeVarintError, - EncodeVarintError, - ShortBufferLengthError, - TooLargeVarint, - VarintMessageReader, - _TendermintABCISerializer, -) -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import ( - BlockParams, - ConsensusParams, - Duration, - Event, - EventAttribute, - Events, - EvidenceParams, - ProofOps, - ValidatorParams, - ValidatorUpdates, - VersionParams, -) -from packages.valory.protocols.abci.dialogues import AbciDialogue -from packages.valory.protocols.abci.dialogues import AbciDialogues as BaseAbciDialogues - - -PACKAGE_DIR = Path(__file__).parent.parent - - -@pytest.fixture(scope="session", autouse=True) -def hypothesis_cleanup() -> Generator: - """Fixture to remove hypothesis directory after tests.""" - yield - hypothesis_dir = PACKAGE_DIR / ".hypothesis" - if hypothesis_dir.exists(): - with suppress(OSError, PermissionError): - shutil.rmtree(hypothesis_dir) - - -class AsyncBytesIO: - """Utility class to emulate asyncio.StreamReader.""" - - def __init__(self, data: bytes) -> None: - """Initialize the buffer.""" - self.data = data - - self._pointer: int = 0 - - async def read(self, n: int) -> bytes: - """Read n bytes.""" - new_pointer = self._pointer + n - result = self.data[self._pointer : new_pointer] - self._pointer = new_pointer - return result - - -class ABCIAppTest: - """A dummy ABCI application for testing purposes.""" - - class AbciDialogues(BaseAbciDialogues): - """The dialogues class keeps track of all ABCI dialogues.""" - - def __init__(self, address: str) -> None: - """Initialize dialogues.""" - self.address = address - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.SERVER - - BaseAbciDialogues.__init__( - self, - self_address=self.address, - role_from_first_message=role_from_first_message, - dialogue_class=AbciDialogue, - ) - - def __init__(self, address: str): - """Initialize.""" - self._dialogues = ABCIAppTest.AbciDialogues(address) - - def handle(self, request: AbciMessage) -> AbciMessage: - """Process a request.""" - # check that it is not a response - assert "request" in request.performative.value, "performative is not a Request" - # performative of requests is of the form "request_{request_name}" - request_type = request.performative.value.replace("request_", "") - handler: Callable[[AbciMessage], AbciMessage] = getattr( - self, request_type, self.no_match - ) - return handler(request) - - def _update_dialogues(self, request: AbciMessage) -> AbciDialogue: - """Update dialogues.""" - abci_dialogue = self._dialogues.update(request) - assert abci_dialogue is not None, "cannot update dialogue" - return cast(AbciDialogue, abci_dialogue) - - def echo(self, request: AbciMessage) -> AbciMessage: - """Process echo request""" - - abci_dialogue = self._update_dialogues(request) - reply = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_ECHO, - target_message=request, - message=request.message, - ) - return cast(AbciMessage, reply) - - def info(self, request: AbciMessage) -> AbciMessage: - """Process an info request.""" - abci_dialogue = self._update_dialogues(request) - assert request.performative == AbciMessage.Performative.REQUEST_INFO - info_data = "" - version = request.version - app_version = 0 - last_block_height = 0 - last_block_app_hash = b"" - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_INFO, - info_data=info_data, - version=version, - app_version=app_version, - last_block_height=last_block_height, - last_block_app_hash=last_block_app_hash, - ) - return cast(AbciMessage, response) - - def flush(self, request: AbciMessage) -> AbciMessage: - """Process a flush request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_FLUSH - ) - return cast(AbciMessage, response) - - def init_chain(self, request: AbciMessage) -> AbciMessage: - """Process an init_chain request.""" - abci_dialogue = self._update_dialogues(request) - app_hash = b"" - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_INIT_CHAIN, - validators=request.validators, - app_hash=app_hash, - consensus_params=self._get_test_consensus_params(), - ) - return cast(AbciMessage, response) - - def query(self, request: AbciMessage) -> AbciMessage: - """Process a query request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_QUERY, - code=0, - log="", - info="", - index=0, - key=b"", - value=b"", - proof_ops=ProofOps([]), - height=0, - codespace="", - ) - return cast(AbciMessage, response) - - def check_tx(self, request: AbciMessage) -> AbciMessage: - """Process a check_tx request.""" - abci_dialogue = self._update_dialogues(request) - attributes: List[EventAttribute] = [] - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, - code=0, # OK - data=b"", - log="", - info="", - gas_wanted=0, - gas_used=0, - events=Events([Event(type_="", attributes=attributes)]), - codespace="", - ) - return cast(AbciMessage, response) - - def deliver_tx(self, request: AbciMessage) -> AbciMessage: - """Process a deliver_tx request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, - code=0, # OK - data=b"", - log="", - info="", - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, response) - - def begin_block(self, request: AbciMessage) -> AbciMessage: - """Process a begin_block request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, - events=Events([]), - ) - return cast(AbciMessage, response) - - def end_block(self, request: AbciMessage) -> AbciMessage: - """Process an end_block request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_END_BLOCK, - validator_updates=ValidatorUpdates([]), - events=Events([]), - consensus_param_updates=self._get_test_consensus_params(), - ) - return cast(AbciMessage, response) - - def commit(self, request: AbciMessage) -> AbciMessage: - """Process a commit request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_COMMIT, - data=b"", - retain_height=0, - ) - return cast(AbciMessage, response) - - def set_option(self, request: AbciMessage) -> AbciMessage: - """Process a commit request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_SET_OPTION, - code=0, - log="", - info="", - ) - return cast(AbciMessage, response) - - def no_match(self, request: AbciMessage) -> NoReturn: - """No match.""" - raise Exception( - f"Received request with performative {request.performative.value}, but no handler available" - ) - - def _get_test_consensus_params(self) -> ConsensusParams: - """Get an instance of ConsensusParams for testing purposes.""" - return ConsensusParams( - BlockParams(max_bytes=22020096, max_gas=-1), - EvidenceParams( - max_age_num_blocks=100000, - max_age_duration=Duration(seconds=17280, nanos=0), - max_bytes=50, - ), - ValidatorParams(pub_key_types=["ed25519"]), - VersionParams(app_version=0), - ) - - -class BaseABCITest: - """Base class for ABCI test (mixin).""" - - TARGET_SKILL_ID: str - - def make_app(self) -> ABCIAppTest: - """Make an ABCI app.""" - return ABCIAppTest(self.TARGET_SKILL_ID) - - -def start_tendermint_docker_image(use_grpc: bool) -> Container: - """Start TendermintDockerImage""" - - TendermintDockerImage.use_grpc = use_grpc - client = docker.from_env() - image = TendermintDockerImage(client) - container = image.create() - container.start() - logging.info(f"Setting up image {image.image}...") - success = image.wait() - logging.info(f"TendermintDockerImage running: {success}...") - return container - - -@pytest.mark.integration -class BaseTestABCITendermintIntegration(BaseThreadedAsyncLoop, ABC): - """ - Integration test between ABCI connection and Tendermint node. - - To use this class: - - - inherit from this class, and write test methods; - - overwrite the method "make_app". The app must implement a 'handle(message)' method. - """ - - TARGET_SKILL_ID = "dummy_author/dummy:0.1.0" - ADDRESS = "agent_address" - PUBLIC_KEY = "agent_public_key" - tendermint_port = DEFAULT_TENDERMINT_PORT # noqa: F811 - - @pytest.fixture(autouse=True, params=[False, True]) - def setup_and_teardown(self, request: SubRequest) -> Generator: - """Set up the test.""" - - use_grpc = request.param - logging.info(f"Tendermint abci connection using: {('TCP', 'gRPC')[use_grpc]}") - - self.agent_identity = Identity( - "name", address=self.ADDRESS, public_key=self.PUBLIC_KEY - ) - - self.configuration = ConnectionConfig( - connection_id=ABCIServerConnection.connection_id, - host=DEFAULT_LISTEN_ADDRESS, - port=DEFAULT_ABCI_PORT, - target_skill_id=self.TARGET_SKILL_ID, - use_tendermint=False, # using docker image instead - use_grpc=use_grpc, - ) - - self.connection = ABCIServerConnection( - identity=self.agent_identity, configuration=self.configuration, data_dir="" - ) - self.app = self.make_app() - - self.execute(self.connection.connect()) - - self.stopped = False - self.receiving_task: AnotherThreadTask = self.loop.call( - self.process_incoming_messages() - ) - - # connection must be established, - # unlike TCP, only a single ECHO request is send with gRPC - time.sleep(5) - container = start_tendermint_docker_image(use_grpc=use_grpc) - - # wait until tendermint node synchronized with abci - wait_for_condition(self.health_check, period=5, timeout=1000000) - - yield # execute test - - # teardown - self.stopped = True - self.receiving_task.cancel() - self.execute(self.connection.disconnect()) - container.stop() - container.remove() - - @abstractmethod - def make_app(self) -> Any: - """Make an ABCI app.""" - raise NotImplementedError - - def health_check(self) -> bool: - """Do a health-check.""" - end_point = self.tendermint_url() + "/health" - try: - result = requests.get(end_point).status_code == 200 - except requests.exceptions.ConnectionError: - result = False - logging.debug(f"Health-check result {end_point}: {result}") - return result - - def tendermint_url(self) -> str: - """Get the current Tendermint URL.""" - return f"{HTTP_LOCALHOST}:{self.tendermint_port}" - - async def process_incoming_messages(self) -> None: - """Receive requests and send responses from/to the Tendermint node""" - while not self.stopped: - try: - request_envelope = await self.connection.receive() - except asyncio.CancelledError: - break - assert request_envelope is not None - request_type = cast(Message, request_envelope.message).performative.value - logging.debug(f"Received request {request_type}") - response = self.app.handle(cast(AbciMessage, request_envelope.message)) - if response is not None: - response_envelope = Envelope( - to=request_envelope.sender, - sender=request_envelope.to, - message=response, - ) - await self.connection.send(response_envelope) - else: - logging.warning(f"Response to {request_type} was None.") - - -@skip_docker_tests -class TestNoop(BaseABCITest, BaseTestABCITendermintIntegration): - """Test integration between ABCI connection and Tendermint, without txs.""" - - SECONDS = 5 - - def test_run(self) -> None: - """ - Run the test. - - Sleep for N seconds, check Tendermint is still running, and then stop the test. - """ - time.sleep(self.SECONDS) - assert self.health_check() - - -@skip_docker_tests -class TestQuery(BaseABCITest, BaseTestABCITendermintIntegration): - """Test integration ABCI-Tendermint with a query.""" - - def test_run(self) -> None: - """ - Run the test. - - Send a query request to the Tendermint node, which will trigger - a query request to the ABCI connection. - """ - logging.debug("Send request") - response = requests.get(self.tendermint_url() + "/abci_query") - assert response.status_code == 200 - - -@skip_docker_tests -class TestTransaction(BaseABCITest, BaseTestABCITendermintIntegration): - """Test integration ABCI-Tendermint by sending a transaction.""" - - def test_run(self) -> None: - """ - Run the test. - - Send a query request to the Tendermint node, which will trigger - a query request to the ABCI connection. - """ - logging.debug("Send request") - response = requests.get( - self.tendermint_url() + "/broadcast_tx_commit", params=dict(tx="0x01") - ) - assert response.status_code == 200 - - -@pytest.mark.asyncio -async def test_connection_standalone_tendermint_setup() -> None: - """Test the setup of the connection configured with Tendermint.""" - try: - temp_dir = TemporaryDirectory() - os.environ["LOG_FILE"] = str(Path(temp_dir.name, "log.txt")) - agent_identity = Identity( - "name", address="agent_address", public_key="agent_public_key" - ) - configuration = ConnectionConfig( - connection_id=ABCIServerConnection.connection_id, - host=DEFAULT_LISTEN_ADDRESS, - port=DEFAULT_ABCI_PORT, - target_skill_id="dummy_author/dummy:0.1.0", - use_tendermint=True, - tendermint_config=dict( - rpc_laddr=f"{ANY_ADDRESS}:26657", - p2p_laddr=f"{ANY_ADDRESS}:26656", - p2p_seeds=[], - ), - ) - connection = ABCIServerConnection( - identity=agent_identity, configuration=configuration, data_dir="" - ) - await connection.connect() - await asyncio.sleep(2.0) - await connection.disconnect() - - del os.environ["LOG_FILE"] - finally: - temp_dir.cleanup() - - -def test_ensure_connected_raises_connection_error() -> None: - """Test '_ensure_connected' raises ConnectionError if the channel is not connected.""" - configuration_mock = ConnectionConfig( - connection_id=ABCIServerConnection.connection_id, - target_skill_id="dummy_author/dummy:0.1.0", - host=DEFAULT_LISTEN_ADDRESS, - port=DEFAULT_ABCI_PORT, - use_tendermint=False, - use_grpc=False, - ) - connection = ABCIServerConnection( - identity=MagicMock(), configuration=configuration_mock, data_dir="" - ) - - # simulate connection, but without channel connection - connection.state = ConnectionStates.connected - with pytest.raises(ConnectionError, match="The channel is stopped."): - connection._ensure_connected() - - -def test_encode_varint_method() -> None: - """Test encode_varint (uint64 Protobuf) method""" - hard_zero_encoded = b"\x00" - max_uint32_encoded = b"\xfe\xff\xff\xff\x1f" - max_uint64_encoded = b"\xfe\xff\xff\xff\xff\xff\xff\xff\xff\x03" - assert _TendermintABCISerializer.encode_varint(0) == hard_zero_encoded - assert _TendermintABCISerializer.encode_varint((1 << 32) - 1) == max_uint32_encoded - assert _TendermintABCISerializer.encode_varint((1 << 64) - 1) == max_uint64_encoded - - -@settings(database=database.InMemoryExampleDatabase()) -@given(integers(min_value=0, max_value=(1 << 64) - 1)) -@pytest.mark.asyncio -async def test_encode_decode_varint(value: int) -> None: - """Test that encoding and decoding works.""" - encoder = _TendermintABCISerializer.encode_varint - encoded_value = encoder(value) - reader = asyncio.StreamReader() - reader.feed_data(encoded_value) - decoder = _TendermintABCISerializer.decode_varint - decoded_value = await decoder(reader) - assert decoded_value == value - - -@pytest.mark.parametrize("value", [-1, 1 << 64]) -@pytest.mark.asyncio -async def test_encoding_raises(value: int) -> None: - """Test encoding raises""" - encoder = _TendermintABCISerializer.encode_varint - with pytest.raises(EncodeVarintError): - encoder(value) - - -@pytest.mark.asyncio -async def test_decode_varint_raises_exception_when_failing() -> None: - """Test that decode_varint raises exception when the decoding fails.""" - with pytest.raises(DecodeVarintError, match="could not decode varint"): - # set CONTINUE_BIT so to trigger an exception - b = b"\x80" - reader = AsyncBytesIO(b) - await _TendermintABCISerializer.decode_varint(reader) # type: ignore - - -@pytest.mark.asyncio -async def test_decode_varint_raises_eof_error() -> None: - """Test that decode_varint raises exception when the EOF of the stream is reached.""" - with pytest.raises(EOFError, match=""): - reader = AsyncBytesIO(b"") - await _TendermintABCISerializer.decode_varint(reader) # type: ignore - - -def test_dep_util() -> None: - """Test dependency utils.""" - assert dep_utils.nth([0, 1, 2, 3], 1, -1) == 1 - assert dep_utils.nth([0, 1, 2, 3], 5, -1) == -1 - assert dep_utils.get_version(1, 0, 0) == (1, 0, 0) - assert dep_utils.version_to_string((1, 0, 0)) == "1.0.0" - - -@pytest.mark.asyncio -async def test_varint_message_reader() -> None: - """Test VarintMessageReader""" - - async def read(nb: int) -> bytes: - return b"hello" - - def patch_async_methods(value: Any) -> Callable: - async def decode_varint(*args: Any, **kwargs: Any) -> Any: - return value - - return decode_varint - - stream_reader = MagicMock(read=read) - vmr = VarintMessageReader(stream_reader) - - with mock.patch.object( - _TendermintABCISerializer, "decode_varint", new=patch_async_methods(inf) - ): - with pytest.raises(TooLargeVarint): - await vmr.read_next_message() - - with mock.patch.object( - _TendermintABCISerializer, "decode_varint", new=patch_async_methods(10) - ): - with mock.patch.object(vmr, "read_until", new=patch_async_methods(b"")): - with pytest.raises(ShortBufferLengthError): - await vmr.read_next_message() - - with mock.patch.object( - _TendermintABCISerializer, "decode_varint", new=patch_async_methods(5) - ): - res = await vmr.read_next_message() - assert res == b"hello" diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_abci_fuzz.py b/trader_backup/vendor/valory/connections/abci/tests/test_abci_fuzz.py deleted file mode 100644 index 9a978b080..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_abci_fuzz.py +++ /dev/null @@ -1,339 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Test random initializations of ABCI Message content""" - -# pylint: skip-file - -from typing import Any, Callable, Dict - -from hypothesis import HealthCheck, given, settings -from hypothesis import strategies as st -from hypothesis.strategies._internal.lazy import SearchStrategy - -from packages.valory.connections.abci.tests.helper import ( - AbciMessage, - PYTHON_PRIMITIVES, - Request, - camel_to_snake, - create_aea_abci_type_tree, - decode, - encode, - get_protocol_readme_spec, - get_tender_type_tree, - get_tendermint_content, - is_enum, - replace_keys, -) - - -KEY_MAPPING = dict( # AEA to Tendermint, one-to-one - request_set_option={"key": "option_key", "value": "option_value"}, - request_query={"data": "query_data"}, - request_load_snapshot_chunk={"chunk": "chunk_index"}, - request_apply_snapshot_chunk={"sender": "chunk_sender"}, - response_info={"data": "info_data"}, -) - - -key_translation = { - "type_": "type", - "format_": "format", - "hash_": "hash", - "round_": "round", - "evidence_params": "evidence", - "validator_params": "validator", - "version_params": "version", - "evidence_type": "type", -} - - -Node = Dict[str, Any] - - -BIT32 = 1 << 31 -BIT64 = 1 << 63 - -STRATEGY_MAP = dict( # TODO: strategy to assert failure - int32=st.integers(min_value=-BIT32, max_value=BIT32 - 1), - uint32=st.integers(min_value=0, max_value=(BIT32 << 1) - 1), - int64=st.integers(min_value=-BIT64, max_value=BIT64 - 1), - uint64=st.integers(min_value=0, max_value=(BIT64 << 1) - 1), - bool=st.booleans(), - string=st.text(), - bytes=st.binary(), - nanos=st.integers(min_value=0, max_value=10**9 - 1), # special case -) - - -# Step 1: retrieve tendermint protobuf type for primitives -def _translate(aea_type_node: Node, tender_type_node: Node) -> Node: - """ - Translate type_node primitive to abci_node specification. - - Create a one-to-one mapping from Tendermint to AEA type tree. - This is necessary because different types of integers are - distinguished in protobuf: int32, uint32, int64, uint64. - As long as the structure is maintained this can be used to - initialize the AEA ABCIMessage instances. - - :param aea_type_node: mapping from message / field name to AEA type. - :param tender_type_node: mapping from message / field name to Tendermint type. - :return: mapping from message / field name to initialized primitive. - """ - - for key, type_child in aea_type_node.items(): - if is_enum(type_child): - continue - if key == "pub_key": - type_child[-1]["data"] = "bytes" - continue - if key == "proof_ops" and "ops" in tender_type_node: - _translate(type_child[-1][-1], tender_type_node["ops"][-1][-1]) - continue - - tender_key = key_translation.get(key, key) - abci_child = tender_type_node[tender_key] - - if isinstance(type_child, str) or type_child in PYTHON_PRIMITIVES: - aea_type_node[key] = abci_child - elif is_enum(abci_child): - continue - elif isinstance(type_child, dict) and isinstance(abci_child, dict): - _translate(type_child, abci_child) - - elif isinstance(type_child, tuple) and isinstance(abci_child, tuple): - cls, d_type = type_child - name, nested = abci_child - if d_type in PYTHON_PRIMITIVES: - aea_type_node[key] = cls, nested - elif isinstance(d_type, dict) and isinstance(nested, dict): - _translate(d_type, nested) - elif isinstance(d_type, tuple): - _translate(d_type[-1], nested[-1]) - else: # extra nested mapping - repeated = list(d_type.values()) - assert len(repeated) == 1 - _translate(repeated[0][-1][-1], nested[-1]) - else: - raise NotImplementedError(f"{key}:\n{type_child}\n{abci_child}") - - return aea_type_node - - -def create_tender_type_tree(aea_type_tree: Node, tender_type_tree: Node) -> Node: - """Create type tree with Tendermint primitives (as string)""" - - aea_with_tender_type_tree = {} - for k, aea_type_node in aea_type_tree.items(): - tender_type_node = tender_type_tree[k][-1] - default_value: Dict[str, str] = {} - replace_keys(tender_type_node, KEY_MAPPING.get(k, default_value)) - aea_with_tender_type_tree[k] = _translate(aea_type_node, tender_type_node) - - return aea_with_tender_type_tree - - -# 3. Create hypothesis strategies -def _init_subtree(node: Any) -> Any: - """Initialize subtree with hypothesis strategies""" - - def init_repeated(repeated_type: Any) -> SearchStrategy: - """Repeated fields must be tuples for Tendermint protobuf""" - if isinstance(repeated_type, str) or repeated_type in PYTHON_PRIMITIVES: - strategy = STRATEGY_MAP[repeated_type] - return st.lists(strategy, min_size=0, max_size=100) - elif isinstance(repeated_type, tuple): - cls, kws = repeated_type - strategy = st.builds(cls, **_init_subtree(kws)) - return st.lists(strategy, min_size=0, max_size=100) - else: - raise NotImplementedError(f"Repeated in {name}: {repeated_type}") - - if isinstance(node, str): - return node - - kwargs: Node = {} - for name, d_type in node.items(): - if isinstance(d_type, str) or d_type in PYTHON_PRIMITIVES: - if name == "nanos": # special case - kwargs[name] = STRATEGY_MAP[name] - else: - kwargs[name] = STRATEGY_MAP[d_type] - elif is_enum(d_type): - kwargs[name] = st.sampled_from(list(d_type)) - elif isinstance(d_type, tuple): - container, content = d_type - if container is list: - kwargs[name] = init_repeated(content) - else: - kwargs[name] = st.builds(container, **_init_subtree(content)) - else: - raise NotImplementedError(f"{name}: {d_type}") - - return kwargs - - -def init_type_tree_hypotheses(type_tree: Node) -> Node: - """ - Initialize the hypothesis strategies - - :param type_tree: mapping from message / field name to type. - :return: mapping from message / field name to initialized primitive. - """ - return {k: _init_subtree(node) for k, node in type_tree.items()} - - -def create_aea_hypotheses() -> Any: - """Create hypotheses for ABCI Messages""" - - aea_protocol, *_ = get_protocol_readme_spec() - speech_acts = aea_protocol["speech_acts"] - - # 1. create type tree from speech acts - aea_type_tree = create_aea_abci_type_tree(speech_acts) - aea_type_tree.pop("dummy") # TODO: known oddity on our side - - # 2. create abci tree from Tendermint type definitions - tender_type_tree = {camel_to_snake(k): v for k, v in get_tender_type_tree().items()} - - # 3. map the primitive types from ABCI spec onto the type tree - aea_with_tender_type_tree = create_tender_type_tree(aea_type_tree, tender_type_tree) - - # 4. initialize with hypothesis - hypo_tree = init_type_tree_hypotheses(aea_with_tender_type_tree) - - # 5. collapse hypo_tree - def collapse(node: Node) -> Node: - for k, v in node.items(): - if isinstance(v, dict): - node[k] = st.fixed_dictionaries(collapse(v)) - return node - - return collapse(hypo_tree) - - -def init_abci_messages(type_tree: Node, init_tree: Node) -> Node: - """Create ABCI messages for AEA-native ABCI spec""" - - messages = dict.fromkeys(type_tree) - for key in type_tree: - performative = getattr(AbciMessage.Performative, key.upper()) - messages[key] = AbciMessage(performative, **init_tree[key]) - - return messages - - -def list_to_tuple(node: Node) -> Node: - """Expecting tuples instead of lists""" - for key, value in node.items(): - if isinstance(value, dict): - list_to_tuple(value) - elif isinstance(value, list): - node[key] = tuple(value) - return node - - -def make_aea_test_method(message_key: str, strategy: Node) -> Callable: - """Dynamically create AEA test""" - - @settings(deadline=5000, suppress_health_check=[HealthCheck.too_slow]) - @given(st.fixed_dictionaries({message_key: strategy})) - def test_method(self: Any, conjecture: Node) -> None: - key = list(conjecture)[0] - performative = getattr(AbciMessage.Performative, key.upper()) - message = AbciMessage(performative, **list_to_tuple(conjecture)[key]) - encoded = encode(message) - if key.startswith("request"): - assert encoded is None - else: - assert get_tendermint_content(encoded) is not None - - return test_method - - -class TestAeaHypotheses: - """Test AEA hypotheses""" - - -aea_hypotheses = create_aea_hypotheses() -for k, v in aea_hypotheses.items(): - setattr(TestAeaHypotheses, f"test_{k}", make_aea_test_method(k, v)) - - -# tendermint fuzzing -def _init_tender_hypo_tree(tender_node: Node) -> Node: - """Initialize Tendermint classes""" - - def init_repeated(repeated_type: Any) -> SearchStrategy: - if isinstance(repeated_type, str): - strategy = STRATEGY_MAP[repeated_type] - return st.lists(strategy, min_size=0, max_size=100) - cls, kwargs = repeated_type - strategy = st.builds(cls, **_init_tender_hypo_tree(kwargs)) - return st.lists(strategy, min_size=0, max_size=100) - - node = {} - for field, d_type in tender_node.items(): - if isinstance(d_type, str): - if field == "nanos": # special - node[field] = STRATEGY_MAP[field] - else: - node[field] = STRATEGY_MAP[d_type] - elif is_enum(d_type): - node[field] = st.sampled_from([f.value for f in d_type]) - elif isinstance(d_type, tuple): - container, content = d_type - if container is list: - node[field] = init_repeated(content) - else: - node[field] = st.builds(container, **_init_tender_hypo_tree(content)) - else: - raise NotImplementedError(f"field {field}: {d_type}") - - return node - - -def create_tendermint_hypotheses() -> Node: - """Create Tendermint hypotheses""" - tender_type_tree = get_tender_type_tree() - _, request_tree = tender_type_tree["Request"] - tender_hypo_tree = _init_tender_hypo_tree(request_tree) - return tender_hypo_tree - - -def make_tendermint_test_method(message_key: str, strategy: Node) -> Callable: - """Dynamically create Tendermint test""" - - @settings(deadline=5000, suppress_health_check=[HealthCheck.too_slow]) - @given(st.fixed_dictionaries({message_key: strategy})) - def test_method(self: Any, conjecture: Node) -> None: - request = Request(**conjecture) - assert decode(request) - - return test_method - - -class TestTendermintHypotheses: - """Test Tendermint hypotheses""" - - -tendermint_hypotheses = create_tendermint_hypotheses() -for k, v in tendermint_hypotheses.items(): - setattr(TestTendermintHypotheses, f"test_{k}", make_tendermint_test_method(k, v)) diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_abci_spec.py b/trader_backup/vendor/valory/connections/abci/tests/test_abci_spec.py deleted file mode 100644 index d27de0d89..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_abci_spec.py +++ /dev/null @@ -1,220 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests to ensure implementation is on par with ABCI spec""" - -# pylint: skip-file - -import logging -import time -from pathlib import Path -from typing import Any, Dict, Set - -import requests -from aea.protocols.generator.common import ( - SPECIFICATION_COMPOSITIONAL_TYPES, - _get_sub_types_of_compositional_types, -) - -from packages.valory.connections import abci as tendermint_abci -from packages.valory.connections.abci.tests.helper import ( - camel_to_snake, - compare_trees, - create_aea_abci_type_tree, - decode, - encode, - get_protocol_readme_spec, - get_tender_type_tree, - get_tendermint_content, - init_aea_abci_messages, - init_tendermint_messages, - init_type_tree_primitives, - replace_keys, -) - - -Node = Dict[str, Any] - -# constants & utility functions -ENCODING = "utf-8" -VERSION = "v0.34.19" -REPO_PATH = Path(*tendermint_abci.__package__.split(".")).absolute() -PROTO_FILES = list((REPO_PATH / "protos" / "tendermint").glob("**/*.proto")) -URL_PREFIX = f"https://raw.githubusercontent.com/tendermint/tendermint/{VERSION}/proto/tendermint/" - -# to ensure primitives are not initialized to empty default values -NON_DEFAULT_PRIMITIVES = {str: "sss", bytes: b"bbb", int: 123, float: 3.14, bool: True} -REPEATED_FIELD_SIZE = 3 -USE_NON_ZERO_ENUM: bool = True - - -# tests -def test_local_types_file_matches_github(request_attempts: int = 3) -> None: - """Test local file containing ABCI spec matches Tendermint GitHub""" - - different = [] - for file in PROTO_FILES: - url = URL_PREFIX + "/".join(file.parts[-2:]) - response, i = requests.get(url), 0 - while response.status_code != 200 and i < request_attempts: - time.sleep(0.1) - response, i = requests.get(url), i + 1 - if response.status_code != 200: - log_msg = "Failed to retrieve Tendermint proto types from Github" - status_code, reason = response.status_code, response.reason - raise requests.HTTPError(f"{log_msg}: {status_code} ({reason})") - github_data = response.text - local_data = file.read_text(encoding=ENCODING) - if not github_data == local_data: - different.append([file, url]) - - if different: - logging.error("\n".join(" =/= ".join(map(str, x)) for x in different)) - assert not bool(different) - - -def test_all_custom_types_used() -> None: - """ - Test if all custom types are used in speech acts. - - By asserting their usage in the speech acts we can delegate - the verification of their implementation and translation to - another test that addresses this (test_aea_to_tendermint). - """ - - aea_protocol, custom_types, _ = get_protocol_readme_spec() - speech_acts = aea_protocol["speech_acts"] - defined_types = {v for vals in speech_acts.values() for v in vals.values()} - - custom_in_speech: Set[str] = set() - for d_type in defined_types: - if any(map(d_type.startswith, SPECIFICATION_COMPOSITIONAL_TYPES)): - subfields = _get_sub_types_of_compositional_types(d_type) - custom_in_speech.update(s[3:] for s in subfields if s.startswith("ct:")) - elif d_type.startswith("ct:"): - custom_in_speech.add(d_type[3:]) - - assert custom_in_speech == {s[3:] for s in custom_types} - - -def test_defined_dialogues_match_abci_spec() -> None: - """ - Test defined dialogues match ABCI spec. - - It verifies solely that request response pairs match: - - AEA requests match Tendermint requests - - AEA responses match Tendermint responses - - That all requests have a matching response - - That all request, response and the exception are covered - """ - - *_, dialogues = get_protocol_readme_spec() - tender_type_tree = get_tender_type_tree() - - # expected - request_oneof = tender_type_tree["Request"][-1] - request_keys = {camel_to_snake(cls.__name__) for cls, _ in request_oneof.values()} - response_oneof = tender_type_tree["Response"][-1] - response_keys = {camel_to_snake(cls.__name__) for cls, _ in response_oneof.values()} - - # defined - initiation = dialogues["initiation"] - reply = dialogues["reply"] - termination = dialogues["termination"] - - # initiation - assert not request_keys.difference(initiation) - assert set(initiation).difference(request_keys) == {"dummy"} - - # reply - missing_response, alt = set(), "response_exception" - for key in request_keys: - if not set(reply[key]) == {key.replace("request", "response"), alt}: - missing_response.add(key) - assert not missing_response - assert not any(reply[key] for key in response_keys) - - # termination - assert not response_keys.difference(termination) - assert set(termination).difference(response_keys) == {"dummy"} - - -def test_aea_to_tendermint() -> None: - """ - Test translation from AEA-native to Tendermint-native ABCI protocol. - - "repeated" fields are returned as list in python, - but must be passed as tuples to Tendermint protobuf. - """ - - aea_protocol, *_ = get_protocol_readme_spec() - speech_acts = aea_protocol["speech_acts"] - - # 1. create type tree from speech acts - type_tree = create_aea_abci_type_tree(speech_acts) - type_tree.pop("dummy") # TODO: known oddity on our side - - # 2. initialize primitives - init_tree = init_type_tree_primitives(type_tree) - - # 3. create AEA-native ABCI protocol messages - abci_messages = init_aea_abci_messages(type_tree, init_tree) - - # 4. encode to Tendermint-native ABCI protocol - # NOTE: request not implemented in encoder - encoded = {k: encode(v) for k, v in abci_messages.items()} - translated = {k: v for k, v in encoded.items() if v} - untranslated = set(encoded).difference(translated) - assert all(k.startswith("request") for k in untranslated) - - # 5. create Tendermint message content tree - tender_tree = {k: get_tendermint_content(v) for k, v in translated.items()} - - # 6. translate expected differences in attribute / field naming - # these are known difference introduced by translating between protocols - param_keys_trans = {k: f"{k}_params" for k in ["evidence", "validator", "version"]} - tendermint_to_aea = dict( - response_info={"data": "info_data"}, - response_query={"proof_ops": {"ops": "proof_ops"}}, - response_init_chain={"consensus_params": param_keys_trans}, - response_end_block={"consensus_param_updates": param_keys_trans}, - ) - replace_keys(tender_tree, tendermint_to_aea) - - # 7. compare AEA-native message initialization with the information - # retrieved from the Tendermint Response after translation - shared = set(type_tree).intersection(tender_tree) - assert len(shared) == 16 # expected number of matches - for k in shared: - init_node, tender_node = init_tree[k], tender_tree[k] - compare_trees(init_node, tender_node) - - -def test_tendermint_decoding() -> None: - """Test Tendermint ABCI message decoding""" - - # 1. create tendermint type tree - tender_type_tree = get_tender_type_tree() - - # 2. initialize messages - messages = init_tendermint_messages(tender_type_tree) - - # 3. translate to AEA-native ABCI Messages - decoded = list(map(decode, messages)) - assert len(decoded) == 15 # expected number of matches diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/__init__.py b/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/__init__.py deleted file mode 100644 index 49e069946..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 fuzzy tests for the ABCI Connection""" diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/base.py b/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/base.py deleted file mode 100644 index d054f0694..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/base.py +++ /dev/null @@ -1,373 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ -"""Defines the base of the fuzzy tests""" - -# pylint: skip-file - -import logging -import os -from pathlib import Path -from typing import Any, Dict, List, Tuple, Type - -from aea.exceptions import enforce -from aea.test_tools.test_cases import AEATestCaseMany -from hypothesis import given, settings -from hypothesis.strategies import binary, booleans, integers, lists, text, tuples - -from packages.valory.connections.abci.tests import CI -from packages.valory.connections.abci.tests.test_fuzz.mock_node.channels.base import ( - BaseChannel, -) -from packages.valory.connections.abci.tests.test_fuzz.mock_node.node import MockNode - - -running_on_ci = os.getenv(CI) -if running_on_ci: - settings.load_profile(CI) - - -class BaseFuzzyTests(AEATestCaseMany): - """ - Base class for the Fuzzy Tests - """ - - package_registry_src_rel = Path(__file__).parents[5] - - UINT_64_MAX_VALUE = 18446744073709551615 - UINT_64_MIN_VALUE = 0 - INT_64_MAX_VALUE = 9223372036854775807 - INT_64_MIN_VALUE = -9223372036854775808 - - UINT_32_MAX_VALUE = 4294967295 - UINT_32_MIN_VALUE = 0 - INT_32_MAX_VALUE = 2147483647 - INT_32_MIN_VALUE = -2147483648 - - CHANNEL_TYPE: Type[BaseChannel] = BaseChannel - CHANNEL_ARGS: Dict[str, Any] = dict() - IS_LOCAL = True - USE_GRPC = False - - channel: BaseChannel - mock_node: MockNode - agent_package = "valory/test_abci:0.1.0" - agent_name = "test_abci" - agent_process = None - cli_log_options = ["-v", "INFO"] - - AGENT_TIMEOUT_SECONDS = 10 - - @classmethod - def setup_class(cls) -> None: - """Sets up the environment for the tests.""" - - super().setup_class() - cls.fetch_agent(cls.agent_package, cls.agent_name, is_local=cls.IS_LOCAL) - cls.set_agent_context(cls.agent_name) - cls.generate_private_key("ethereum", "ethereum_private_key.txt") - cls.add_private_key("ethereum", "ethereum_private_key.txt") - # issue certificates for libp2p proof of representation - cls.generate_private_key("cosmos", "cosmos_private_key.txt") - cls.add_private_key("cosmos", "cosmos_private_key.txt") - cls.run_cli_command("issue-certificates", cwd=cls._get_cwd()) - - # we are mocking a tendermint node - cls.set_config("vendor.valory.connections.abci.config.use_tendermint", False) - - cls.set_config("vendor.valory.connections.abci.config.use_grpc", cls.USE_GRPC) - - cls.run_install() - cls.agent_process = cls.run_agent() - - enforce( - cls.is_running(cls.agent_process, cls.AGENT_TIMEOUT_SECONDS), - f"The agent was not started in the defined timeout ({cls.AGENT_TIMEOUT_SECONDS}s)", - ) - - enforce(cls.CHANNEL_TYPE is not None, "A channel type must be provided") - - cls.channel = cls.CHANNEL_TYPE(**cls.CHANNEL_ARGS) - cls.mock_node = MockNode(cls.channel) - cls.mock_node.connect() - logging.disable(logging.INFO) - - @classmethod - def teardown_class(cls) -> None: - """Tear down the testing environment.""" - logging.disable(logging.NOTSET) - cls.mock_node.disconnect() - super().teardown_class() - - # flake8: noqa:D102 - @given(message=text()) - def test_echo(self, message: str) -> None: - assert self.mock_node.echo(message) - - @given( - version=text().filter(lambda x: x != ""), - block_version=integers(0, UINT_64_MAX_VALUE), - p2p_version=integers(0, UINT_64_MAX_VALUE), - ) - def test_info(self, version: str, block_version: int, p2p_version: int) -> None: - assert self.mock_node.info(version, block_version, p2p_version) - - def test_flush(self) -> None: - assert self.mock_node.flush() - - @given(key=text(), value=text()) - def test_set_option(self, key: str, value: str) -> None: - assert self.mock_node.set_option(key, value) - - @given(tx=binary()) - def test_deliver_tx(self, tx: bytes) -> None: - assert self.mock_node.deliver_tx(tx) - - @given(tx=binary(), is_new_check=booleans()) - def test_check_tx(self, tx: bytes, is_new_check: bool) -> None: - assert self.mock_node.check_tx(tx, is_new_check) - - @given( - data=binary(), - path=text(), - height=integers(-INT_64_MAX_VALUE, INT_64_MAX_VALUE), - prove=booleans(), - ) - def test_query(self, data: bytes, path: str, height: int, prove: bool) -> None: - assert self.mock_node.query(data, path, height, prove) - - def test_commit(self) -> None: - assert self.mock_node.commit() - - @given( - time_seconds=integers(0, INT_64_MAX_VALUE), - time_nanos=integers(0, 10**9), - chain_id=text(), - block_max_bytes=integers(1, INT_64_MAX_VALUE), - block_max_gas=integers(-1, INT_32_MAX_VALUE), - evidence_max_age_num_blocks=integers(INT_64_MIN_VALUE, INT_64_MAX_VALUE), - evidence_max_age_seconds=integers(0, INT_64_MAX_VALUE), - evidence_max_age_nanos=integers(0, 10**9), - evidence_max_bytes=integers(1, INT_64_MAX_VALUE), - pub_key_types=lists(booleans()), - app_version=integers(0, INT_32_MAX_VALUE), - validator_pub_keys=lists(tuples(binary(), booleans())), - validator_power=lists(integers(0, INT_32_MAX_VALUE)), - app_state_bytes=binary(), - initial_height=integers(0, INT_32_MAX_VALUE), - ) - def test_init_chain( - self, - time_seconds: int, - time_nanos: int, - chain_id: str, - block_max_bytes: int, - block_max_gas: int, - evidence_max_age_num_blocks: int, - evidence_max_age_seconds: int, - evidence_max_age_nanos: int, - evidence_max_bytes: int, - pub_key_types: List[str], - app_version: int, - validator_pub_keys: List[Tuple[bytes, bool]], - validator_power: List[int], - app_state_bytes: bytes, - initial_height: int, - ) -> None: - min_validator_length = min( - validator_power.__len__(), - validator_pub_keys.__len__(), - pub_key_types.__len__(), - ) - - assert self.mock_node.init_chain( - time_seconds, - time_nanos, - chain_id, - block_max_bytes, - block_max_gas, - evidence_max_age_num_blocks, - evidence_max_age_seconds, - evidence_max_age_nanos, - evidence_max_bytes, - ["ed25519" if pk else "secp256k1" for pk in pub_key_types][ - :min_validator_length - ], - app_version, - [ - (pk, "ed25519") if tp else (pk, "secp256k1") - for pk, tp in validator_pub_keys - ][:min_validator_length], - validator_power[:min_validator_length], - app_state_bytes, - initial_height, - ) - - @given( - hash_=binary(), - consen_ver_block=integers(0, UINT_64_MAX_VALUE), - consen_ver_app=integers(0, UINT_64_MAX_VALUE), - chain_id=text(), - height=integers(-INT_64_MAX_VALUE, INT_64_MAX_VALUE), - time_seconds=integers(1, INT_64_MAX_VALUE), - time_nanos=integers(0, 10**9), - last_block_id_hash=binary(), - last_commit_hash=binary(), - data_hash=binary(), - validators_hash=binary(), - next_validators_hash=binary(), - next_validators_part_header_total=integers(0, UINT_32_MAX_VALUE), - next_validators_part_header_hash=binary(), - header_consensus_hash=binary(), - header_app_hash=binary(), - header_last_results_hash=binary(), - header_evidence_hash=binary(), - header_proposer_address=binary(), - last_commit_round=integers(INT_32_MIN_VALUE, INT_32_MAX_VALUE), - last_commit_info_votes=lists( - tuples(binary(), integers(INT_64_MIN_VALUE, INT_64_MAX_VALUE)) - ), - last_commit_info_signed_last_block=lists(booleans()), - evidence_type=lists(integers()), - evidence_validator_address=lists(binary()), - evidence_validator_power=lists(integers(INT_64_MIN_VALUE, INT_64_MAX_VALUE)), - evidence_height=lists(integers(INT_64_MIN_VALUE, INT_64_MAX_VALUE)), - evidence_time_seconds=lists(integers(1, INT_64_MAX_VALUE)), - evidence_time_nanos=lists(integers(0, 10**9)), - evidence_total_voting_power=lists(integers(0, INT_64_MAX_VALUE)), - ) - def test_begin_block( - self, - hash_: bytes, - consen_ver_block: int, - consen_ver_app: int, - chain_id: str, - height: int, - time_seconds: int, - time_nanos: int, - last_block_id_hash: bytes, - last_commit_hash: bytes, - data_hash: bytes, - validators_hash: bytes, - next_validators_hash: bytes, - next_validators_part_header_total: int, - next_validators_part_header_hash: bytes, - header_consensus_hash: bytes, - header_app_hash: bytes, - header_last_results_hash: bytes, - header_evidence_hash: bytes, - header_proposer_address: bytes, - last_commit_round: int, - last_commit_info_votes: List[Tuple[bytes, int]], - last_commit_info_signed_last_block: List[bool], - evidence_type: List[int], - evidence_validator_address: List[bytes], - evidence_validator_power: List[int], - evidence_height: List[int], - evidence_time_seconds: List[int], - evidence_time_nanos: List[int], - evidence_total_voting_power: List[int], - ) -> None: - last_commit_len = min( - last_commit_info_votes.__len__(), - last_commit_info_signed_last_block.__len__(), - ) - evidence_len = min( - evidence_type.__len__(), - evidence_validator_address.__len__(), - evidence_validator_power.__len__(), - evidence_height.__len__(), - evidence_time_seconds.__len__(), - evidence_time_nanos.__len__(), - evidence_total_voting_power.__len__(), - ) - self.mock_node.begin_block( - hash_, - consen_ver_block, - consen_ver_app, - chain_id, - height, - time_seconds, - time_nanos, - last_block_id_hash, - last_commit_hash, - data_hash, - validators_hash, - next_validators_hash, - next_validators_part_header_total, - next_validators_part_header_hash, - header_consensus_hash, - header_app_hash, - header_last_results_hash, - header_evidence_hash, - header_proposer_address, - last_commit_round, - last_commit_info_votes[:last_commit_len], - last_commit_info_signed_last_block[:last_commit_len], - evidence_type[:evidence_len], - evidence_validator_address[:evidence_len], - evidence_validator_power[:evidence_len], - evidence_height[:evidence_len], - evidence_time_seconds[:evidence_len], - evidence_time_nanos[:evidence_len], - evidence_total_voting_power[:evidence_len], - ) - - @given(height=integers(INT_64_MIN_VALUE, INT_64_MAX_VALUE)) - def test_end_block(self, height: int) -> None: - assert self.mock_node.end_block(height) - - def test_list_snapshots(self) -> None: - assert self.mock_node.list_snapshots() - - @given( - height=integers(UINT_64_MIN_VALUE, UINT_64_MAX_VALUE), - format_=integers(UINT_32_MIN_VALUE, UINT_32_MAX_VALUE), - chunks=integers(UINT_32_MIN_VALUE, UINT_32_MAX_VALUE), - hash_=binary(), - metadata=binary(), - app_hash=binary(), - ) - def test_offer_snapshot( - self, - height: int, - format_: int, - chunks: int, - hash_: bytes, - metadata: bytes, - app_hash: bytes, - ) -> None: - assert self.mock_node.offer_snapshot( - height, format_, chunks, hash_, metadata, app_hash - ) - - @given( - height=integers(UINT_64_MIN_VALUE, UINT_64_MAX_VALUE), - format_=integers(UINT_32_MIN_VALUE, UINT_32_MAX_VALUE), - chunk=integers(UINT_32_MIN_VALUE, UINT_32_MAX_VALUE), - ) - def test_load_snapshot_chunk(self, height: int, format_: int, chunk: int) -> None: - assert self.mock_node.load_snapshot_chunk(height, format_, chunk) - - @given( - index=integers(UINT_32_MIN_VALUE, UINT_32_MAX_VALUE), - chunk=binary(), - sender=text(), - ) - def test_apply_snapshot_chunk(self, index: int, chunk: bytes, sender: str) -> None: - assert self.mock_node.apply_snapshot_chunk(index, chunk, sender) diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/__init__.py b/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/__init__.py deleted file mode 100644 index 226b566c9..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 mocks a Tendermint Node""" diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/__init__.py b/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/__init__.py deleted file mode 100644 index d1e04f729..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 imlpements the channels for the ABCI <-> Tendermint (Mock) Node communication""" diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/base.py b/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/base.py deleted file mode 100644 index 5f790294d..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/base.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -# pylint: disable=no-member - -"""BaseChannel for MockNode""" - -from typing import Dict - -import packages.valory.connections.abci.tendermint.abci.types_pb2 as abci_types # type: ignore - - -class BaseChannel: - """Defines the interface for other channels to use""" - - def __init__(self, **kwargs: Dict) -> None: - """Initializes a channel""" - - def connect(self) -> None: - """ - Set up the channel. - - By default, it is a no-op. - """ - - def disconnect(self) -> None: - """ - Tear down the channel. - - By default, it is a no-op. - """ - - def send_info(self, request: abci_types.RequestInfo) -> abci_types.ResponseInfo: # type: ignore - """ - Sends an info request. - - :param: request: RequestInfo pb object - """ - raise NotImplementedError - - def send_echo(self, request: abci_types.RequestEcho) -> abci_types.ResponseEcho: # type: ignore - """ - Sends an echo request. - - :param: request: RequestEcho pb object - """ - raise NotImplementedError - - def send_flush(self, request: abci_types.RequestFlush) -> abci_types.ResponseFlush: # type: ignore - """ - Sends an flush request. - - :param: request: RequestFlush pb object - """ - raise NotImplementedError - - def send_set_option( - self, request: abci_types.RequestSetOption # type: ignore - ) -> abci_types.ResponseSetOption: # type: ignore - """ - Sends an setOption request. - - :param: request: RequestSetOption pb object - """ - raise NotImplementedError - - def send_deliver_tx( - self, request: abci_types.RequestDeliverTx # type: ignore - ) -> abci_types.ResponseDeliverTx: # type: ignore - """ - Sends an deliverTx request. - - :param: request: RequestDeliverTx pb object - """ - raise NotImplementedError - - def send_check_tx( - self, request: abci_types.RequestCheckTx # type: ignore - ) -> abci_types.ResponseCheckTx: # type: ignore - """ - Sends an checkTx request. - - :param: request: RequestCheckTx pb object - """ - raise NotImplementedError - - def send_query(self, request: abci_types.RequestQuery) -> abci_types.ResponseQuery: # type: ignore - """ - Sends an query request. - - :param: request: RequestQuery pb object - """ - raise NotImplementedError - - def send_commit( - self, request: abci_types.RequestCommit # type: ignore - ) -> abci_types.ResponseCommit: # type: ignore - """ - Sends an commit request. - - :param: request: RequestCommit pb object - """ - raise NotImplementedError - - def send_init_chain( - self, request: abci_types.RequestInitChain # type: ignore - ) -> abci_types.ResponseInitChain: # type: ignore - """ - Sends an initChain request. - - :param: request: RequestInitChain pb object - """ - raise NotImplementedError - - def send_begin_block( - self, request: abci_types.RequestBeginBlock # type: ignore - ) -> abci_types.ResponseBeginBlock: # type: ignore - """ - Sends an beginBlock request. - - :param: request: RequestBeginBlock pb object - """ - raise NotImplementedError - - def send_end_block( - self, request: abci_types.RequestEndBlock # type: ignore - ) -> abci_types.ResponseEndBlock: # type: ignore - """ - Sends an endBlock request. - - :param: request: RequestEndBlock pb object - """ - raise NotImplementedError - - def send_list_snapshots( - self, request: abci_types.RequestListSnapshots # type: ignore - ) -> abci_types.ResponseListSnapshots: # type: ignore - """ - Sends an listSnapshots request. - - :param: request: RequestListSnapshots pb object - """ - raise NotImplementedError - - def send_offer_snapshot( - self, request: abci_types.RequestOfferSnapshot # type: ignore - ) -> abci_types.ResponseOfferSnapshot: # type: ignore - """ - Sends an offerSnapshot request. - - :param: request: RequestOfferSnapshot pb object - """ - raise NotImplementedError - - def send_load_snapshot_chunk( - self, request: abci_types.RequestLoadSnapshotChunk # type: ignore - ) -> abci_types.ResponseLoadSnapshotChunk: # type: ignore - """ - Sends an loadSnapshotChunk request. - - :param: request: RequestLoadSnapshotChunk pb object - """ - raise NotImplementedError - - def send_apply_snapshot_chunk( - self, request: abci_types.RequestApplySnapshotChunk # type: ignore - ) -> abci_types.ResponseApplySnapshotChunk: # type: ignore - """ - Sends an applySnapshotChunk request. - - :param: request: RequestApplySnapshotChunk pb object - """ - raise NotImplementedError diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/grpc_channel.py b/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/grpc_channel.py deleted file mode 100644 index f247815cd..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/grpc_channel.py +++ /dev/null @@ -1,213 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ -"""GrpcChannel for MockNode""" -# pylint: skip-file - -import logging -from typing import Dict - -import grpc - -import packages.valory.connections.abci.tendermint.abci.types_pb2 as abci_types # type: ignore -import packages.valory.connections.abci.tendermint.abci.types_pb2_grpc as tendermint_grpc # type: ignore - -from .base import BaseChannel - - -_default_logger = logging.getLogger(__name__) - -logging.basicConfig() - - -class GrpcChannel(BaseChannel): - """Implements BaseChannel to use gRPC""" - - def __init__(self, **kwargs: Dict) -> None: - """ - Initializes a GrpcChannel - - :param: kwargs: - - host: the host of the ABCI app (localhost by default) - - port: the port of the ABCI app (26658 by default) - """ - super().__init__() - - host = kwargs.get("host", "localhost") - port = kwargs.get("port", 26658) - self.logger = _default_logger - - grpc_channel = grpc.insecure_channel(f"{host}:{port}") - self.grpc_client = tendermint_grpc.ABCIApplicationStub(grpc_channel) - - def send_info(self, request: abci_types.RequestInfo) -> abci_types.ResponseInfo: # type: ignore - """ - Sends an info request. - - :param: request: RequestInfo pb object - :return: ResponseInfo pb object - """ - return self.grpc_client.Info(request) - - def send_echo(self, request: abci_types.RequestEcho) -> abci_types.ResponseEcho: # type: ignore - """ - Sends an echo request. - - :param: request: RequestEcho pb object - :return: ResponseEcho pb object - """ - return self.grpc_client.Echo(request) - - def send_flush(self, request: abci_types.RequestFlush) -> abci_types.ResponseFlush: # type: ignore - """ - Sends an flush request. - - :param: request: RequestFlush pb object - :return: ResponseFlush pb object - """ - return self.grpc_client.Flush(request) - - def send_set_option( - self, request: abci_types.RequestSetOption # type: ignore - ) -> abci_types.ResponseSetOption: # type: ignore - """ - Sends an setOption request. - - :param: request: RequestSetOption pb object - :return: ResponseSetOption pb object - """ - return self.grpc_client.SetOption(request) - - def send_deliver_tx( - self, request: abci_types.RequestDeliverTx # type: ignore - ) -> abci_types.ResponseDeliverTx: # type: ignore - """ - Sends an deliverTx request. - - :param: request: RequestDeliverTx pb object - :return: ResponseDeliverTx pb object - """ - return self.grpc_client.DeliverTx(request) - - def send_check_tx( - self, request: abci_types.RequestCheckTx # type: ignore - ) -> abci_types.ResponseCheckTx: # type: ignore - """ - Sends an checkTx request. - - :param: request: RequestCheckTx pb object - :return: ResponseCheckTx pb object - """ - return self.grpc_client.CheckTx(request) - - def send_query(self, request: abci_types.RequestQuery) -> abci_types.ResponseQuery: # type: ignore - """ - Sends an query request. - - :param: request: RequestQuery pb object - :return: ResponseQuery pb object - """ - return self.grpc_client.Query(request) - - def send_commit( - self, request: abci_types.RequestCommit # type: ignore - ) -> abci_types.ResponseCommit: # type: ignore - """ - Sends an commit request. - - :param: request: RequestCommit pb object - :return: ResponseCommit pb object - """ - return self.grpc_client.Commit(request) - - def send_init_chain( - self, request: abci_types.RequestInitChain # type: ignore - ) -> abci_types.ResponseInitChain: # type: ignore - """ - Sends an initChain request. - - :param: request: RequestInitChain pb object - :return: ResponseInitChain pb object - """ - return self.grpc_client.InitChain(request) - - def send_begin_block( - self, request: abci_types.RequestBeginBlock # type: ignore - ) -> abci_types.ResponseBeginBlock: # type: ignore - """ - Sends an beginBlock request. - - :param: request: RequestBeginBlock pb object - :return: ResponseBeginBlock pb object - """ - return self.grpc_client.BeginBlock(request) - - def send_end_block( - self, request: abci_types.RequestEndBlock # type: ignore - ) -> abci_types.ResponseEndBlock: # type: ignore - """ - Sends an endBlock request. - - :param: request: RequestEndBlock pb object - :return: ResponseEndBlock pb object - """ - return self.grpc_client.EndBlock(request) - - def send_list_snapshots( - self, request: abci_types.RequestListSnapshots # type: ignore - ) -> abci_types.ResponseListSnapshots: # type: ignore - """ - Sends an listSnapshots request. - - :param: request: RequestListSnapshots pb object - :return: ResponseListSnapshots pb object - """ - return self.grpc_client.ListSnapshots(request) - - def send_offer_snapshot( - self, request: abci_types.RequestOfferSnapshot # type: ignore - ) -> abci_types.ResponseOfferSnapshot: # type: ignore - """ - Sends an offerSnapshot request. - - :param: request: RequestOfferSnapshot pb object - :return: ResponseOfferSnapshot pb object - """ - return self.grpc_client.OfferSnapshot(request) - - def send_load_snapshot_chunk( - self, request: abci_types.RequestLoadSnapshotChunk # type: ignore - ) -> abci_types.ResponseLoadSnapshotChunk: # type: ignore - """ - Sends an loadSnapshotChunk request. - - :param: request: RequestLoadSnapshotChunk pb object - :return: ResponseLoadSnapshotChunk pb object - """ - return self.grpc_client.LoadSnapshotChunk(request) - - def send_apply_snapshot_chunk( - self, request: abci_types.RequestApplySnapshotChunk # type: ignore - ) -> abci_types.ResponseApplySnapshotChunk: # type: ignore - """ - Sends an applySnapshotChunk request. - - :param: request: RequestApplySnapshotChunk pb object - :return: ResponseApplySnapshotChunk pb object - """ - return self.grpc_client.ApplySnapshotChunk(request) diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/tcp_channel.py b/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/tcp_channel.py deleted file mode 100644 index a28cb7ea1..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/tcp_channel.py +++ /dev/null @@ -1,535 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ -"""TcpChannel for MockNode""" -# pylint: skip-file - -import asyncio -import logging -import platform -import socket -from asyncio import AbstractEventLoop -from threading import Thread -from typing import Dict, Optional, cast - -from aea.exceptions import enforce - -import packages.valory.connections.abci.tendermint.abci.types_pb2 as abci_types # type: ignore -from packages.valory.connections.abci.connection import ( - VarintMessageReader, - _TendermintABCISerializer, -) -from packages.valory.connections.abci.tests.test_fuzz.mock_node.channels.base import ( - BaseChannel, -) - - -_default_logger = logging.getLogger(__name__) - -logging.basicConfig() - - -class TcpChannel(BaseChannel): - """Implements BaseChannel to use TCP sockets""" - - MAX_READ_IN_BYTES = 64 * 1024 # Max we'll consume on a read stream - - def __init__(self, **kwargs: Dict) -> None: - """ - Initializes a TcpChannel - - :param: kwargs: - - host: the host of the ABCI app (localhost by default) - - port: the port of the ABCI app (26658 by default) - """ - super().__init__(**kwargs) - - self.host: str = cast(str, kwargs.get("host", "localhost")) - self.port: int = cast(int, kwargs.get("port", 26658)) - self.logger = _default_logger - - # attributes for the channel state - self.loop: Optional[AbstractEventLoop] = None - self.loop_thread: Optional[Thread] = None - self.message_reader: Optional[VarintMessageReader] = None - self.reader: Optional[asyncio.StreamReader] = None - self.writer: Optional[asyncio.StreamWriter] = None - - @property - def is_connected(self) -> bool: - """Check whether the channel is connected.""" - return self.loop_thread is not None - - def connect(self) -> None: - """Set up the channel.""" - if self.is_connected: - return - - if platform.system() == "Windows": - self.loop = cast( - asyncio.AbstractEventLoop, - asyncio.WindowsSelectorEventLoopPolicy().new_event_loop(), # type: ignore # windows only - ) - else: - self.loop = cast(asyncio.AbstractEventLoop, asyncio.new_event_loop()) - self.loop_thread = Thread(target=self._run_loop_in_thread, args=(self.loop,)) - self.loop_thread.start() - - # set up asyncio connection - future = asyncio.run_coroutine_threadsafe( - asyncio.open_connection(self.host, self.port, family=socket.AF_INET), - self.loop, - ) - self.reader, self.writer = future.result() - self.message_reader = VarintMessageReader(self.reader) - - def disconnect(self) -> None: - """Tear down the channel.""" - if not self.is_connected: - return - - cast(asyncio.StreamWriter, self.writer).close() - - loop = cast(AbstractEventLoop, self.loop) - loop.call_soon_threadsafe(loop.stop) - cast(Thread, self.loop_thread).join(5) - - # restore channel state - self.loop = None - self.loop_thread = None - self.message_reader = None - self.reader = None - self.writer = None - - @staticmethod - def _run_loop_in_thread(loop: AbstractEventLoop) -> None: - """Run an asyncio loop in the thread of the caller.""" - asyncio.set_event_loop(loop) - loop.run_forever() - - def _get_response(self) -> abci_types.Response: # type: ignore - """ - Gets the response for a request. - - :return: a pb response object - - It assumes that: - - For every request there's a response. - - Responses are sent in the same order as the reqs. - - """ - future = asyncio.run_coroutine_threadsafe( - cast(VarintMessageReader, self.message_reader).read_next_message(), - cast(AbstractEventLoop, self.loop), - ) - message_bytes = future.result() - message = abci_types.Response() # type: ignore - message.ParseFromString(message_bytes) - return message - - def _send_data(self, data: bytes) -> None: - """Send data over the TCP connection.""" - cast(asyncio.StreamWriter, self.writer).write(data) - future = asyncio.run_coroutine_threadsafe( - cast(asyncio.StreamWriter, self.writer).drain(), - cast(AbstractEventLoop, self.loop), - ) - future.result() - - def send_info(self, request: abci_types.RequestInfo) -> abci_types.ResponseInfo: # type: ignore - """ - Sends an info request. - - :param: request: RequestInfo pb object - :return: ResponseInfo pb object - """ - - message = abci_types.Request() # type: ignore - message.info.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "info", - f"expected response of type info, {response_type} was received", - ) - - return response.info - - def send_echo(self, request: abci_types.RequestEcho) -> abci_types.ResponseEcho: # type: ignore - """ - Sends an echo request. - - :param: request: RequestEcho pb object - :return: ResponseEcho pb object - """ - message = abci_types.Request() # type: ignore - message.echo.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "echo", - f"expected response of type echo, {response_type} was received", - ) - - return response.echo - - def send_flush(self, request: abci_types.RequestFlush) -> abci_types.ResponseFlush: # type: ignore - """ - Sends an flush request. - - :param: request: RequestFlush pb object - :return: ResponseFlush pb object - """ - message = abci_types.Request() # type: ignore - message.flush.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "flush", - f"expected response of type flush, {response_type} was received", - ) - - return response.flush - - def send_set_option( - self, request: abci_types.RequestSetOption # type: ignore - ) -> abci_types.ResponseSetOption: # type: ignore - """ - Sends an setOption request. - - :param: request: RequestSetOption pb object - :return: ResponseSetOption pb object - """ - message = abci_types.Request() # type: ignore - message.set_option.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "set_option", - f"expected response of type set_option, {response_type} was received", - ) - - return response.set_option - - def send_deliver_tx( - self, request: abci_types.RequestDeliverTx # type: ignore - ) -> abci_types.ResponseDeliverTx: # type: ignore - """ - Sends an deliverTx request. - - :param: request: RequestDeliverTx pb object - :return: ResponseDeliverTx pb object - """ - message = abci_types.Request() # type: ignore - message.deliver_tx.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "deliver_tx", - f"expected response of type deliver_tx, {response_type} was received", - ) - - return response.deliver_tx - - def send_check_tx( - self, request: abci_types.RequestCheckTx # type: ignore - ) -> abci_types.ResponseCheckTx: # type: ignore - """ - Sends an checkTx request. - - :param: request: RequestCheckTx pb object - :return: ResponseCheckTx pb object - """ - message = abci_types.Request() # type: ignore - message.check_tx.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "check_tx", - f"expected response of type check_tx, {response_type} was received", - ) - - return response.check_tx - - def send_query(self, request: abci_types.RequestQuery) -> abci_types.ResponseQuery: # type: ignore - """ - Sends an query request. - - :param: request: RequestQuery pb object - :return: ResponseQuery pb object - """ - message = abci_types.Request() # type: ignore - message.query.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "query", - f"expected response of type query, {response_type} was received", - ) - - return response.query - - def send_commit( - self, request: abci_types.RequestCommit # type: ignore - ) -> abci_types.ResponseCommit: # type: ignore - """ - Sends an commit request. - - :param: request: RequestCommit pb object - :return: ResponseCommit pb object - """ - message = abci_types.Request() # type: ignore - message.commit.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "commit", - f"expected response of type commit, {response_type} was received", - ) - - return response.commit - - def send_init_chain( - self, request: abci_types.RequestInitChain # type: ignore - ) -> abci_types.ResponseInitChain: # type: ignore - """ - Sends an initChain request. - - :param: request: RequestInitChain pb object - :return: ResponseInitChain pb object - """ - message = abci_types.Request() # type: ignore - message.init_chain.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "init_chain", - f"expected response of type init_chain, {response_type} was received", - ) - - return response.init_chain - - def send_begin_block( - self, request: abci_types.RequestBeginBlock # type: ignore - ) -> abci_types.ResponseBeginBlock: # type: ignore - """ - Sends an beginBlock request. - - :param: request: RequestBeginBlock pb object - :return: ResponseBeginBlock pb object - """ - message = abci_types.Request() # type: ignore - message.begin_block.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "begin_block", - f"expected response of type begin_block, {response_type} was received", - ) - - return response.begin_block - - def send_end_block( - self, request: abci_types.RequestEndBlock # type: ignore - ) -> abci_types.ResponseEndBlock: # type: ignore - """ - Sends an endBlock request. - - :param: request: RequestEndBlock pb object - :return: ResponseEndBlock pb object - """ - message = abci_types.Request() # type: ignore - message.end_block.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "end_block", - f"expected response of type end_block, {response_type} was received", - ) - - return response.end_block - - def send_list_snapshots( - self, request: abci_types.RequestListSnapshots # type: ignore - ) -> abci_types.ResponseListSnapshots: # type: ignore - """ - Sends an listSnapshots request. - - :param: request: RequestListSnapshots pb object - :return: ResponseListSnapshots pb object - """ - message = abci_types.Request() # type: ignore - message.list_snapshots.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "list_snapshots", - f"expected response of type list_snapshots, {response_type} was received", - ) - - return response.list_snapshots - - def send_offer_snapshot( - self, request: abci_types.RequestOfferSnapshot # type: ignore - ) -> abci_types.ResponseOfferSnapshot: # type: ignore - """ - Sends an offerSnapshot request. - - :param: request: RequestOfferSnapshot pb object - :return: ResponseOfferSnapshot pb object - """ - message = abci_types.Request() # type: ignore - message.offer_snapshot.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "offer_snapshot", - f"expected response of type offer_snapshot, {response_type} was received", - ) - - return response.offer_snapshot - - def send_load_snapshot_chunk( - self, request: abci_types.RequestLoadSnapshotChunk # type: ignore - ) -> abci_types.ResponseLoadSnapshotChunk: # type: ignore - """ - Sends an loadSnapshotChunk request. - - :param: request: RequestLoadSnapshotChunk pb object - :return: ResponseLoadSnapshotChunk pb object - """ - message = abci_types.Request() # type: ignore - message.load_snapshot_chunk.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "load_snapshot_chunk", - f"expected response of type load_snapshot_chunk, {response_type} was received", - ) - - return response.load_snapshot_chunk - - def send_apply_snapshot_chunk( - self, request: abci_types.RequestApplySnapshotChunk # type: ignore - ) -> abci_types.ResponseApplySnapshotChunk: # type: ignore - """ - Sends an applySnapshotChunk request. - - :param: request: RequestApplySnapshotChunk pb object - :return: ResponseApplySnapshotChunk pb object - """ - message = abci_types.Request() # type: ignore - message.apply_snapshot_chunk.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "apply_snapshot_chunk", - f"expected response of type apply_snapshot_chunk, {response_type} was received", - ) - - return response.apply_snapshot_chunk diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/node.py b/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/node.py deleted file mode 100644 index 3c5bb3f87..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/mock_node/node.py +++ /dev/null @@ -1,520 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ -"""Used for mocking a tendermint node""" -# flake8: noqa:D102 -# pylint: skip-file - -import logging -from typing import List, Tuple - -from aea.exceptions import enforce -from google.protobuf import timestamp_pb2 - -import packages.valory.connections.abci.tendermint.abci.types_pb2 as abci_types # type: ignore -import packages.valory.connections.abci.tendermint.crypto.keys_pb2 as keys_types # type: ignore -import packages.valory.connections.abci.tendermint.types.types_pb2 as tendermint_types # type: ignore -import packages.valory.connections.abci.tendermint.version.types_pb2 as version_type # type: ignore -from packages.valory.protocols.abci.custom_types import ( - BlockParams, - ConsensusParams, - Duration, - EvidenceParams, - PublicKey, - Snapshot, - Timestamp, - ValidatorParams, - ValidatorUpdate, - VersionParams, -) - -from .channels.base import BaseChannel - - -_default_logger = logging.getLogger(__name__) - -logging.basicConfig() - - -class MockNode: - """Mocks a Tendermint Node""" - - def __init__(self, channel: BaseChannel) -> None: - self.logger = _default_logger - self.logger.setLevel(logging.DEBUG) - - enforce(channel is not None, "channel is None") - - self.channel = channel - - def connect(self) -> None: - """Connect the node.""" - self.channel.connect() - - def disconnect(self) -> None: - """Disconnect the node.""" - self.channel.disconnect() - - def info(self, version: str, block_version: int, p2p_version: int) -> bool: - request = abci_types.RequestInfo() # type: ignore - request.version = version - request.block_version = block_version - request.p2p_version = p2p_version - - self.logger.info( - f"Calling info with version={version}, block_version={block_version}, p2p_version={p2p_version}" - ) - - response = self.channel.send_info(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def echo(self, message: str) -> bool: - request = abci_types.RequestEcho() # type: ignore - request.message = message - - self.logger.info(f"Calling echo with message={message}") - - response = self.channel.send_echo(request) - - self.logger.info(f"Received response {str(response)}") - return True - - def flush(self) -> bool: - request = abci_types.RequestFlush() # type: ignore - - self.logger.info("Sending flush req") - - response = self.channel.send_flush(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def set_option(self, key: str, value: str) -> bool: - request = abci_types.RequestSetOption() # type: ignore - request.key = key - request.value = value - - self.logger.info(f"Calling set_options with key={key} value={value}") - - response = self.channel.send_set_option(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def deliver_tx(self, tx: bytes) -> bool: - request = abci_types.RequestDeliverTx() # type: ignore - request.tx = tx - - self.logger.info(f"Calling deliver_tx with tx={tx!r}") - - response = self.channel.send_deliver_tx(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def check_tx(self, tx: bytes, is_new_check: bool) -> bool: - request = abci_types.RequestCheckTx() # type: ignore - request.tx = tx - request.type = 1 if is_new_check else 0 - - self.logger.info(f"Calling check_tx with tx={tx!r} and is_new={is_new_check}") - - response = self.channel.send_check_tx(request) - - self.logger.info(f"Received response {str(response)}") - - return response - - def query(self, data: bytes, path: str, height: int, prove: bool) -> bool: - request = abci_types.RequestQuery() # type: ignore - request.data = data - request.path = path - request.height = height - request.prove = prove - - self.logger.info( - f"Calling query with data={data!r} and path={path} height={height} prove={prove}" - ) - - response = self.channel.send_query(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def commit(self) -> bool: - request = abci_types.RequestCommit() # type: ignore - - self.logger.info("Calling commit") - - response = self.channel.send_commit(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def init_chain( - self, - time_seconds: int, - time_nanos: int, - chain_id: str, - block_max_bytes: int, - block_max_gas: int, - evidence_max_age_num_blocks: int, - evidence_max_age_seconds: int, - evidence_max_age_nanos: int, - evidence_max_bytes: int, - pub_key_types: List[str], - app_version: int, - validator_pub_keys: List[Tuple[bytes, str]], - validator_power: List[int], - app_state_bytes: bytes, - initial_height: int, - ) -> bool: - request = abci_types.RequestInitChain() # type: ignore - - timestamp = timestamp_pb2.Timestamp() - Timestamp.encode(timestamp, Timestamp(time_seconds, time_nanos)) - request.time.CopyFrom(timestamp) - - request.chain_id = chain_id - - block_params = BlockParams(block_max_bytes, block_max_gas) - duration = Duration(evidence_max_age_seconds, evidence_max_age_nanos) - evidence_params = EvidenceParams( - evidence_max_age_num_blocks, duration, evidence_max_bytes - ) - validator_params = ValidatorParams(pub_key_types) - version_params = VersionParams(app_version) - consensus_params = abci_types.ConsensusParams() # type: ignore - ConsensusParams.encode( - consensus_params, - ConsensusParams( - block_params, evidence_params, validator_params, version_params - ), - ) - request.consensus_params.CopyFrom(consensus_params) - - enforce( - validator_pub_keys.__len__() == validator_power.__len__(), - "pubkeys should have same length as power", - ) - - pub_keys = [ - PublicKey(bs, PublicKey.PublicKeyType(tp)) for bs, tp in validator_pub_keys - ] - validator_updates = [ - ValidatorUpdate(pk, vp) for pk, vp in zip(pub_keys, validator_power) - ] - validator_updates_pb = [] - - for validator_update_object in validator_updates: - validator_update_protobuf_object = abci_types.ValidatorUpdate() # type: ignore - pub_key = keys_types.PublicKey() # type: ignore - - PublicKey.encode(pub_key, validator_update_object.pub_key) - validator_update_protobuf_object.power = validator_update_object.power - validator_update_protobuf_object.pub_key.CopyFrom(pub_key) - - validator_updates_pb.append(validator_update_protobuf_object) - - request.validators.extend(validator_updates_pb) - - request.app_state_bytes = app_state_bytes - request.initial_height = initial_height - - self.logger.info( - f"""Calling init_chain - time_seconds={time_seconds} - time_nanos={time_nanos} - chain_id={chain_id} - block_max_bytes={block_max_bytes} - block_max_gas={block_max_gas} - evidence_max_age_num_blocks={evidence_max_age_num_blocks} - evidence_max_age_seconds={evidence_max_age_seconds} - evidence_max_age_nanos={evidence_max_age_nanos} - evidence_max_bytes={evidence_max_bytes} - pub_key_types={pub_key_types} - app_version={app_version} - validator_pub_keys={validator_pub_keys} - validator_power={validator_power} - app_state_bytes={app_state_bytes!r} - initial_height={initial_height} - """ - ) - - response = self.channel.send_init_chain(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def begin_block( - self, - hash_: bytes, - consen_ver_block: int, - consen_ver_app: int, - chain_id: str, - height: int, - time_seconds: int, - time_nanos: int, - last_block_id_hash: bytes, - last_commit_hash: bytes, - data_hash: bytes, - validators_hash: bytes, - next_validators_hash: bytes, - next_validators_part_header_total: int, - next_validators_part_header_hash: bytes, - header_consensus_hash: bytes, - header_app_hash: bytes, - header_last_results_hash: bytes, - header_evidence_hash: bytes, - header_proposer_address: bytes, - last_commit_round: int, - last_commit_info_votes: List[Tuple[bytes, int]], - last_commit_info_signed_last_block: List[bool], - evidence_type: List[int], - evidence_validator_address: List[bytes], - evidence_validator_power: List[int], - evidence_height: List[int], - evidence_time_seconds: List[int], - evidence_time_nanos: List[int], - evidence_total_voting_power: List[int], - ) -> bool: - consensus_version = version_type.Consensus() # type: ignore - consensus_version.block = consen_ver_block - consensus_version.app = consen_ver_app - - part_set_header = tendermint_types.PartSetHeader() # type: ignore - part_set_header.total = next_validators_part_header_total - part_set_header.hash = next_validators_part_header_hash - - block_id = tendermint_types.BlockID() # type: ignore - block_id.hash = last_block_id_hash - block_id.part_set_header.CopyFrom(part_set_header) - - time = timestamp_pb2.Timestamp() - time.seconds = time_seconds - time.nanos = time_nanos - - header = tendermint_types.Header() # type: ignore - header.version.CopyFrom(consensus_version) - header.chain_id = chain_id - header.height = height - header.time.CopyFrom(time) - header.last_block_id.CopyFrom(block_id) - header.last_commit_hash = last_commit_hash - header.data_hash = data_hash - header.validators_hash = validators_hash - header.next_validators_hash = next_validators_hash - header.consensus_hash = header_consensus_hash - header.app_hash = header_app_hash - header.last_results_hash = header_last_results_hash - header.evidence_hash = header_evidence_hash - header.proposer_address = header_proposer_address - - enforce( - last_commit_info_signed_last_block.__len__() - == last_commit_info_signed_last_block.__len__(), - "last_commit_info_signed_last_block should have same length last_commit_info_signed_last_block", - ) - - vote_infos = [] - for i in range(last_commit_info_votes.__len__()): - validator = abci_types.Validator() # type: ignore - validator.address = last_commit_info_votes[i][0] - validator.power = last_commit_info_votes[i][1] - - vote_info = abci_types.VoteInfo() # type: ignore - vote_info.validator.CopyFrom(validator) - vote_info.signed_last_block = last_commit_info_signed_last_block[i] - - vote_infos.append(vote_info) - - last_commit_info = abci_types.LastCommitInfo() # type: ignore - last_commit_info.round = last_commit_round - last_commit_info.votes.extend(vote_infos) - - enforce( - { - evidence_validator_address.__len__(), - evidence_validator_power.__len__(), - evidence_height.__len__(), - evidence_time_seconds.__len__(), - evidence_time_nanos.__len__(), - evidence_total_voting_power.__len__(), - evidence_type.__len__(), - }.__len__() - == 1, - "evidence_* lists should have same length", - ) - - evidences = [] - - for i in range(evidence_type.__len__()): - validator = abci_types.Validator() # type: ignore - validator.address = evidence_validator_address[i] - validator.power = evidence_validator_power[i] - - time = timestamp_pb2.Timestamp() - time.seconds = evidence_time_seconds[i] - time.nanos = evidence_time_nanos[i] - - evidence = abci_types.Evidence() # type: ignore - evidence.type = evidence_type[i] % 3 - evidence.height = evidence_height[i] - evidence.total_voting_power = evidence_total_voting_power[i] - evidence.time.CopyFrom(time) - evidence.validator.CopyFrom(validator) - - evidences.append(evidence) - - request = abci_types.RequestBeginBlock() # type: ignore - request.hash = hash_ - request.header.CopyFrom(header) - request.last_commit_info.CopyFrom(last_commit_info) - request.byzantine_validators.extend(evidences) - - self.logger.info( - f""" - Calling begin_block - hash_: {hash_!r} - consen_ver_block={consen_ver_block} - consen_ver_app={consen_ver_app} - chain_id={chain_id} - height={height} - time_seconds={time_seconds}" - time_nanos={time_nanos} - last_block_id_hash={last_block_id_hash!r} - last_commit_hash={last_commit_hash!r} - data_hash={data_hash!r} - validators_hash={validators_hash!r}" - next_validators_hash={next_validators_hash!r} - next_validators_part_header_total={next_validators_part_header_total} - next_validators_part_header_hash={next_validators_part_header_hash!r} - header_consensus_hash={header_consensus_hash!r} - header_app_hash={header_app_hash!r} - header_last_results_hash={header_last_results_hash!r} - header_evidence_hash={header_evidence_hash!r} - header_proposer_address={header_proposer_address!r} - last_commit_round={last_commit_round} - last_commit_info_votes={last_commit_info_votes} - last_commit_info_signed_last_block={last_commit_info_signed_last_block} - evidence_type={evidence_type} - evidence_validator_address={evidence_validator_address} - evidence_validator_power={evidence_validator_power} - evidence_height={evidence_height} - evidence_time_seconds={evidence_time_seconds} - evidence_time_nanos={evidence_time_nanos} - evidence_total_voting_power={evidence_total_voting_power} - """ - ) - - response = self.channel.send_begin_block(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def end_block(self, height: int) -> bool: - request = abci_types.RequestEndBlock() # type: ignore - request.height = height - - self.logger.info(f"Calling end_block height={height}") - - response = self.channel.send_end_block(request) - - self.logger.info(f"Received response {str(response)}") - - return response - - def list_snapshots(self) -> bool: - request = abci_types.RequestListSnapshots() # type: ignore - - self.logger.info("Calling list snapshots") - - response = self.channel.send_list_snapshots(request) - - self.logger.info(f"Received response {str(response)}") - - return response - - def offer_snapshot( - self, - height: int, - format_: int, - chunks: int, - hash_: bytes, - metadata: bytes, - app_hash: bytes, - ) -> bool: - snapshot = abci_types.Snapshot() # type: ignore - Snapshot.encode(snapshot, Snapshot(height, format_, chunks, hash_, metadata)) - - request = abci_types.RequestOfferSnapshot() # type: ignore - request.snapshot.CopyFrom(snapshot) - request.app_hash = app_hash - - self.logger.info( - f"Calling offer snapshot height={height},format_={format_}," - f"chunks={chunks},hash_={hash_!r},metadata={metadata!r},app_hash={app_hash!r}" - ) - - response = self.channel.send_offer_snapshot(request) - - self.logger.info(f"Received response {str(response)}") - - return response - - def load_snapshot_chunk(self, height: int, format_: int, chunk: int) -> bool: - request = abci_types.RequestLoadSnapshotChunk() # type: ignore - request.height = height - request.format = format_ - request.chunk = chunk - - self.logger.info( - f"Calling load snapshot chunk height={height} format={format_} chunk={chunk}" - ) - - response = self.channel.send_load_snapshot_chunk(request) - - self.logger.info(f"Received response {str(response)}") - - return response - - def apply_snapshot_chunk(self, index: int, chunk: bytes, sender: str) -> bool: - request = abci_types.RequestApplySnapshotChunk() # type: ignore - request.index = index - request.chunk = chunk - request.sender = sender - - self.logger.info( - f"Calling load snapshot chunk index={index} chunk={chunk!r} sender={sender}" - ) - - response = self.channel.send_apply_snapshot_chunk(request) - - self.logger.info(f"Received response {str(response)}") - - return response diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/test_fuzz.py b/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/test_fuzz.py deleted file mode 100644 index 02333a39c..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_fuzz/test_fuzz.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Fuzzy tests for valory/abci connection""" -import os - -from hypothesis import settings - -from packages.valory.connections.abci.tests import CI -from packages.valory.connections.abci.tests.test_fuzz.base import BaseFuzzyTests -from packages.valory.connections.abci.tests.test_fuzz.mock_node.channels.grpc_channel import ( - GrpcChannel, -) -from packages.valory.connections.abci.tests.test_fuzz.mock_node.channels.tcp_channel import ( - TcpChannel, -) - - -running_on_ci = os.getenv(CI) -if running_on_ci: - settings.load_profile(CI) - - -class TestFuzzyGrpc(BaseFuzzyTests): - """Test the connection when gRPC is used""" - - CHANNEL_TYPE = GrpcChannel - USE_GRPC = True - AGENT_TIMEOUT_SECONDS = 30 - - -class TestFuzzyTcp(BaseFuzzyTests): - """Test the connection when TCP is used""" - - CHANNEL_TYPE = TcpChannel - USE_GRPC = False - AGENT_TIMEOUT_SECONDS = 30 diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_tendermint_decoder.py b/trader_backup/vendor/valory/connections/abci/tests/test_tendermint_decoder.py deleted file mode 100644 index 15285a9d4..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_tendermint_decoder.py +++ /dev/null @@ -1,121 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/abci connection, tendermint_decoder module.""" - -# pylint: skip-file - -from packages.valory.connections.abci.connection import PUBLIC_ID -from packages.valory.connections.abci.dialogues import AbciDialogue, AbciDialogues -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - Request, - RequestApplySnapshotChunk, - RequestEcho, - RequestListSnapshots, - RequestLoadSnapshotChunk, - RequestOfferSnapshot, - RequestSetOption, - Snapshot, -) -from packages.valory.connections.abci.tendermint_decoder import ( - _TendermintProtocolDecoder, -) -from packages.valory.protocols.abci import AbciMessage - - -class TestTendermintProtocolDecoder: - """Test for the Tendermint protocol decoder.""" - - def test_request_echo(self) -> None: - """Test decoding of a request echo.""" - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - request = Request() - echo = RequestEcho() - echo.message = "" - request.echo.CopyFrom(echo) - message, dialogue = _TendermintProtocolDecoder.request_echo( - request, dialogues, "counterparty" - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) - - def test_request_set_option(self) -> None: - """Test decoding of a request set-option.""" - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - request = Request() - set_option = RequestSetOption() - set_option.key = "" - set_option.value = "" - request.set_option.CopyFrom(set_option) - message, dialogue = _TendermintProtocolDecoder.request_set_option( - request, dialogues, "counterparty" - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) - - def test_request_list_snapshots(self) -> None: - """Test decoding of a request list-snapshots.""" - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - request = Request() - list_snapshots = RequestListSnapshots() - request.list_snapshots.CopyFrom(list_snapshots) - message, dialogue = _TendermintProtocolDecoder.request_list_snapshots( - request, dialogues, "counterparty" - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) - - def test_request_offer_snapshot(self) -> None: - """Test decoding of a request offer-snapshot.""" - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - request = Request() - offer_snapshot = RequestOfferSnapshot() - snapshot = Snapshot() - offer_snapshot.snapshot.CopyFrom(snapshot) - offer_snapshot.app_hash = b"" - request.offer_snapshot.CopyFrom(offer_snapshot) - message, dialogue = _TendermintProtocolDecoder.request_offer_snapshot( - request, dialogues, "counterparty" - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) - - def test_request_load_snapshot_chunk(self) -> None: - """Test decoding of a request load-snapshot-chunk.""" - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - request = Request() - load_snapshot_chunk = RequestLoadSnapshotChunk() - request.load_snapshot_chunk.CopyFrom(load_snapshot_chunk) - message, dialogue = _TendermintProtocolDecoder.request_load_snapshot_chunk( - request, dialogues, "counterparty" - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) - - def test_request_apply_snapshot_chunk(self) -> None: - """Test decoding of a request load-snapshot-chunk.""" - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - request = Request() - apply_snapshot_chunk = RequestApplySnapshotChunk() - request.apply_snapshot_chunk.CopyFrom(apply_snapshot_chunk) - message, dialogue = _TendermintProtocolDecoder.request_apply_snapshot_chunk( - request, dialogues, "counterparty" - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) diff --git a/trader_backup/vendor/valory/connections/abci/tests/test_tendermint_encoder.py b/trader_backup/vendor/valory/connections/abci/tests/test_tendermint_encoder.py deleted file mode 100644 index 51df9d778..000000000 --- a/trader_backup/vendor/valory/connections/abci/tests/test_tendermint_encoder.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/abci connection, tendermint_encoder module.""" - -# pylint: skip-file - -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - ResponseListSnapshots, -) -from packages.valory.connections.abci.tendermint_encoder import ( - _TendermintProtocolEncoder, -) -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import Result, ResultType, SnapShots -from packages.valory.protocols.abci.custom_types import Snapshot as CustomSnapshot - - -class TestTendermintProtocolEncoder: - """Test for the Tendermint protocol encoder.""" - - def test_response_exception(self) -> None: - """Test decoding of a response exception.""" - expected_error = "error" - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_EXCEPTION, # type: ignore - error=expected_error, - ) - message = _TendermintProtocolEncoder.response_exception(abci_message) - assert message.exception.error == expected_error - - def test_response_echo(self) -> None: - """Test decoding of a response echo.""" - expected_message = "message" - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_ECHO, # type: ignore - message=expected_message, - ) - message = _TendermintProtocolEncoder.response_echo(abci_message) - assert message.echo.message == expected_message - - def test_response_set_option(self) -> None: - """Test decoding of a response set-option.""" - expected_code = 0 - expected_log = "log" - expected_info = "info" - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_SET_OPTION, # type: ignore - code=expected_code, - log=expected_log, - info=expected_info, - ) - message = _TendermintProtocolEncoder.response_set_option(abci_message) - assert message.set_option.code == expected_code - assert message.set_option.log == expected_log - assert message.set_option.info == expected_info - - def test_response_list_snapshots(self) -> None: - """Test decoding of a response list-snapshots.""" - snapshot = CustomSnapshot(0, 0, 0, b"", b"") - snapshots = SnapShots([snapshot]) - - # expected snapshots object - list_snapshots = ResponseListSnapshots() - snapshots_pb = [ - _TendermintProtocolEncoder._encode_snapshot(snapshot) - for snapshot in snapshots.snapshots - ] - list_snapshots.snapshots.extend(snapshots_pb) - - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, # type: ignore - snapshots=snapshots, - ) - message = _TendermintProtocolEncoder.response_list_snapshots(abci_message) - assert message.list_snapshots == list_snapshots - - def test_response_offer_snapshot(self) -> None: - """Test decoding of a response offer-snapshot.""" - expected_result = Result(ResultType.ACCEPT) - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, # type: ignore - result=expected_result, - ) - message = _TendermintProtocolEncoder.response_offer_snapshot(abci_message) - assert message.offer_snapshot.result == expected_result.result_type.value - - def test_response_load_snapshot_chunk(self) -> None: - """Test decoding of a response load-snapshot-chunk.""" - expected_chunk = b"chunk" - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, # type: ignore - chunk=expected_chunk, - ) - message = _TendermintProtocolEncoder.response_load_snapshot_chunk(abci_message) - assert message.load_snapshot_chunk.chunk == expected_chunk - - def test_response_apply_snapshot_chunk(self) -> None: - """Test decoding of a response apply-snapshot-chunk.""" - result = Result(ResultType.ACCEPT) - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, # type: ignore - result=result, - refetch_chunks=tuple(), - reject_senders=tuple(), - ) - message = _TendermintProtocolEncoder.response_apply_snapshot_chunk(abci_message) - assert message.apply_snapshot_chunk.result == result.result_type.value diff --git a/trader_backup/vendor/valory/connections/abci/version.txt b/trader_backup/vendor/valory/connections/abci/version.txt deleted file mode 100644 index a1ed4c348..000000000 --- a/trader_backup/vendor/valory/connections/abci/version.txt +++ /dev/null @@ -1,6 +0,0 @@ - TMCoreSemVer = TMVersionDefault - // TMVersionDefault is the used as the fallback version of Tendermint Core - TMVersionDefault = "0.34.19" - // ABCISemVer is the semantic version of the ABCI library - ABCISemVer = "0.17.0" - ABCIVersion = ABCISemVer diff --git a/trader_backup/vendor/valory/connections/http_client/README.md b/trader_backup/vendor/valory/connections/http_client/README.md deleted file mode 100644 index 376f78401..000000000 --- a/trader_backup/vendor/valory/connections/http_client/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# HTTP client connection - -This connection wraps an HTTP client. It consumes messages from the AEA, translates them into HTTP requests, then sends the HTTP response as a message back to the AEA. - -## Usage - -First, add the connection to your AEA project (`aea add connection valory/http_client:0.23.0`). Then, update the `config` in `connection.yaml` by providing a `host` and `port` of the server. diff --git a/trader_backup/vendor/valory/connections/http_client/__init__.py b/trader_backup/vendor/valory/connections/http_client/__init__.py deleted file mode 100644 index 6c4b07655..000000000 --- a/trader_backup/vendor/valory/connections/http_client/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 Valory AG -# Copyright 2018-2020 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Implementation of the HTTP_client connection and channel.""" diff --git a/trader_backup/vendor/valory/connections/http_client/connection.py b/trader_backup/vendor/valory/connections/http_client/connection.py deleted file mode 100644 index 248f57268..000000000 --- a/trader_backup/vendor/valory/connections/http_client/connection.py +++ /dev/null @@ -1,446 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""HTTP client connection and channel.""" - -import asyncio -import email -import logging -import ssl -from asyncio import CancelledError -from asyncio.events import AbstractEventLoop -from asyncio.tasks import Task -from traceback import format_exc -from typing import Any, Optional, Set, Tuple, Union, cast - -import aiohttp -import certifi # pylint: disable=wrong-import-order -from aiohttp import ClientTimeout -from aiohttp.client_reqrep import ClientResponse # pylint: disable=wrong-import-order -from multidict import ( # pylint: disable=wrong-import-order - CIMultiDict, - CIMultiDictProxy, -) - -from aea.common import Address -from aea.configurations.base import PublicId -from aea.connections.base import Connection, ConnectionStates -from aea.exceptions import enforce -from aea.mail.base import Envelope, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue - -from packages.valory.protocols.http.dialogues import HttpDialogue as BaseHttpDialogue -from packages.valory.protocols.http.dialogues import HttpDialogues as BaseHttpDialogues -from packages.valory.protocols.http.message import HttpMessage - - -SUCCESS = 200 -NOT_FOUND = 404 -REQUEST_TIMEOUT = 408 -SERVER_ERROR = 500 -PUBLIC_ID = PublicId.from_str("valory/http_client:0.23.0") - -_default_logger = logging.getLogger("aea.packages.valory.connections.http_client") - -RequestId = str - -ssl_context = ssl.create_default_context(cafile=certifi.where()) - - -def headers_to_string(headers: CIMultiDictProxy) -> str: - """ - Convert headers to string. - - :param headers: dict - - :return: str - """ - msg = email.message.Message() - for name, value in headers.items(): - msg.add_header(name, value) - return msg.as_string() - - -HttpDialogue = BaseHttpDialogue - - -class HttpDialogues(BaseHttpDialogues): - """The dialogues class keeps track of all http dialogues.""" - - def __init__(self) -> None: - """Initialize dialogues.""" - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - # The client connection maintains the dialogue on behalf of the server - return HttpDialogue.Role.SERVER - - BaseHttpDialogues.__init__( - self, - self_address=str(HTTPClientConnection.connection_id), - role_from_first_message=role_from_first_message, - dialogue_class=HttpDialogue, - ) - - -class HTTPClientAsyncChannel: # pylint: disable=too-many-instance-attributes - """A wrapper for a HTTPClient.""" - - DEFAULT_EXCEPTION_CODE = ( - 600 # custom code to indicate there was exception during request - ) - - def __init__( - self, - agent_address: Address, - address: str, - port: int, - timeout: int, - connection_id: PublicId, - ): - """ - Initialize an http client channel. - - :param agent_address: the address of the agent. - :param address: server hostname / IP address. - :param port: server port number. - :param timeout: the time to wait for a response. - :param connection_id: the id of the connection. - """ - self.agent_address = agent_address - self.address = address - self.port = port - self.timeout = timeout - self.connection_id = connection_id - self._dialogues = HttpDialogues() - - self._in_queue = None # type: Optional[asyncio.Queue] # pragma: no cover - self._loop = ( - None - ) # type: Optional[asyncio.AbstractEventLoop] # pragma: no cover - self.is_stopped = True - self._tasks: Set[Task] = set() - - self.logger = _default_logger - self.logger.debug("Initialised the HTTP client channel") - - async def connect(self, loop: AbstractEventLoop) -> None: - """ - Connect channel using loop. - - :param loop: asyncio event loop to use - """ - self._loop = loop - self._in_queue = asyncio.Queue() - self.is_stopped = False - - def _get_message_and_dialogue( - self, envelope: Envelope - ) -> Tuple[HttpMessage, Optional[HttpDialogue]]: - """ - Get a message copy and dialogue related to this message. - - :param envelope: incoming envelope - - :return: Tuple[Message, Optional[Dialogue]] - """ - message = cast(HttpMessage, envelope.message) - dialogue = cast(Optional[HttpDialogue], self._dialogues.update(message)) - return message, dialogue - - async def _http_request_task(self, request_envelope: Envelope) -> None: - """ - Perform http request and send back response. - - :param request_envelope: request envelope - """ - if not self._loop: # pragma: nocover - raise ValueError("Channel is not connected") - - request_http_message, dialogue = self._get_message_and_dialogue( - request_envelope - ) - - if not dialogue: - self.logger.warning( - f"Could not create dialogue for message={request_http_message}" - ) - return - - try: - resp = await asyncio.wait_for( - self._perform_http_request(request_http_message), - timeout=self.timeout, - ) - envelope = self.to_envelope( - request_http_message, - status_code=resp.status, - headers=resp.headers, - status_text=resp.reason, - body=resp._body # pylint: disable=protected-access - if resp._body is not None # pylint: disable=protected-access - else b"", - dialogue=dialogue, - ) - except Exception: # pylint: disable=broad-except - envelope = self.to_envelope( - request_http_message, - status_code=self.DEFAULT_EXCEPTION_CODE, - headers=CIMultiDictProxy(CIMultiDict()), - status_text="HTTPConnection request error.", - body=format_exc().encode("utf-8"), - dialogue=dialogue, - ) - - if self._in_queue is not None: - await self._in_queue.put(envelope) - - async def _perform_http_request( - self, request_http_message: HttpMessage - ) -> ClientResponse: - """ - Perform http request and return response. - - :param request_http_message: HttpMessage with http request constructed. - - :return: aiohttp.ClientResponse - """ - try: - if request_http_message.is_set("headers") and request_http_message.headers: - headers: Optional[dict] = dict( - email.message_from_string(request_http_message.headers).items() - ) - else: - headers = None - session_timeout = ClientTimeout(self.timeout) - async with aiohttp.ClientSession(timeout=session_timeout) as session: - async with session.request( - method=request_http_message.method, - url=request_http_message.url, - headers=headers, - data=request_http_message.body, - ssl=ssl_context, - ) as resp: - await resp.read() - return resp - except Exception as e: # pragma: nocover # pylint: disable=broad-except - self.logger.debug( - f"Exception raised during http call: {request_http_message.method} {request_http_message.url}, {e}" - ) - raise - - def send(self, request_envelope: Envelope) -> None: - """ - Send an envelope with http request data to request. - - Convert an http envelope into an http request. - Send the http request - Wait for and receive its response - Translate the response into a response envelop. - Send the response envelope to the in-queue. - - :param request_envelope: the envelope containing an http request - """ - if self._loop is None or self.is_stopped: - raise ValueError("Can not send a message! Channel is not started!") - - if request_envelope is None: - return - - enforce( - isinstance(request_envelope.message, HttpMessage), - "Message not of type HttpMessage", - ) - - request_http_message = cast(HttpMessage, request_envelope.message) - - if ( - request_http_message.performative != HttpMessage.Performative.REQUEST - ): # pragma: nocover - self.logger.warning( - "The HTTPMessage performative must be a REQUEST. Envelop dropped." - ) - return - - task = self._loop.create_task(self._http_request_task(request_envelope)) - task.add_done_callback(self._task_done_callback) - self._tasks.add(task) - - def _task_done_callback(self, task: Task) -> None: - """ - Handle http request task completed. - - Removes tasks from _tasks. - - :param task: Task completed. - """ - self._tasks.remove(task) - self.logger.debug(f"Task completed: {task}") - - async def get_message(self) -> Optional["Envelope"]: - """ - Get http response from in-queue. - - :return: None or envelope with http response. - """ - if self._in_queue is None: - raise ValueError("Looks like channel is not connected!") - - try: - return await self._in_queue.get() - except CancelledError: # pragma: nocover - return None - - @staticmethod - def to_envelope( - http_request_message: HttpMessage, - status_code: int, - headers: CIMultiDictProxy, - status_text: Optional[Any], - body: bytes, - dialogue: HttpDialogue, - ) -> Envelope: - """ - Convert an HTTP response object (from the 'requests' library) into an Envelope containing an HttpMessage (from the 'http' Protocol). - - :param http_request_message: the message of the http request envelop - :param status_code: the http status code, int - :param headers: dict of http response headers - :param status_text: the http status_text, str - :param body: bytes of http response content - :param dialogue: the http dialogue - - :return: Envelope with http response data. - """ - http_message = dialogue.reply( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_request_message, - status_code=status_code, - headers=headers_to_string(headers), - status_text=status_text, - body=body, - version="", - ) - envelope = Envelope( - to=http_message.to, - sender=http_message.sender, - message=http_message, - ) - return envelope - - async def _cancel_tasks(self) -> None: - """Cancel all requests tasks pending.""" - for task in list(self._tasks): - if task.done(): # pragma: nocover - continue - task.cancel() - - for task in list(self._tasks): - try: - await task - except KeyboardInterrupt: # pragma: nocover - raise - except BaseException: # pragma: nocover # pylint: disable=broad-except - pass # nosec - - async def disconnect(self) -> None: - """Disconnect.""" - if not self.is_stopped: - self.logger.info(f"HTTP Client has shutdown on port: {self.port}.") - self.is_stopped = True - - await self._cancel_tasks() - - -class HTTPClientConnection(Connection): - """Proxy to the functionality of the web client.""" - - DEFAULT_TIMEOUT = 300 # default timeout in seconds - connection_id = PUBLIC_ID - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize a HTTP client connection. - - :param kwargs: keyword arguments - """ - super().__init__(**kwargs) - host = cast(str, self.configuration.config.get("host")) - port = cast(int, self.configuration.config.get("port")) - timeout = int(self.configuration.config.get("timeout", self.DEFAULT_TIMEOUT)) - if host is None or port is None: # pragma: nocover - raise ValueError("host and port must be set!") - self.channel = HTTPClientAsyncChannel( - self.address, - host, - port, - timeout, - connection_id=self.connection_id, - ) - - async def connect(self) -> None: - """Connect to a HTTP server.""" - if self.is_connected: # pragma: nocover - return - - with self._connect_context(): - self.channel.logger = self.logger - await self.channel.connect(self.loop) - - async def disconnect(self) -> None: - """Disconnect from a HTTP server.""" - if self.is_disconnected: - return # pragma: nocover - self.state = ConnectionStates.disconnecting - await self.channel.disconnect() - self.state = ConnectionStates.disconnected - - async def send(self, envelope: "Envelope") -> None: - """ - Send an envelope. - - :param envelope: the envelop - """ - self._ensure_connected() - self.channel.send(envelope) - - async def receive( - self, *args: Any, **kwargs: Any - ) -> Optional[Union["Envelope", None]]: - """ - Receive an envelope. - - :param args: arguments - :param kwargs: keyword arguments - :return: the envelope received, or None. - """ - self._ensure_connected() - try: - return await self.channel.get_message() - except Exception: # pragma: nocover # pylint: disable=broad-except - self.logger.debug("Exception on receive") - return None diff --git a/trader_backup/vendor/valory/connections/http_client/connection.yaml b/trader_backup/vendor/valory/connections/http_client/connection.yaml deleted file mode 100644 index a4694f248..000000000 --- a/trader_backup/vendor/valory/connections/http_client/connection.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: http_client -author: valory -version: 0.23.0 -type: connection -description: The HTTP_client connection that wraps a web-based client connecting to - a RESTful API specification. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeigqhgnqpgi22gfxqvsgbmrjdkrklpgu2m4px6zwb7bhvy3gkkyetu - __init__.py: bafybeieh7rjtg22qukaznxzhadreuxhyfeamj3lcluxtcbfiexktue2nim - connection.py: bafybeiephqitgfzzautuegh2fpp5yezglkri4gj646glu3erokbfgsupzu - tests/__init__.py: bafybeiak7fbussk7n5zl2o4trefz7whvc3ae3k2vrryhb6cettb2qskjau - tests/test_http_client.py: bafybeic4k7g6k4y5axh3pgpz25j7drghqxl5gblczux2sxtms54ududepe -fingerprint_ignore_patterns: [] -connections: [] -protocols: -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -class_name: HTTPClientConnection -config: - host: 127.0.0.1 - port: 8000 - timeout: 300 -excluded_protocols: [] -restricted_to_protocols: -- valory/http:1.0.0 -dependencies: - aiohttp: - version: <4.0.0,>=3.8.5 - certifi: {} - multidict: {} -is_abstract: false diff --git a/trader_backup/vendor/valory/connections/http_client/tests/__init__.py b/trader_backup/vendor/valory/connections/http_client/tests/__init__.py deleted file mode 100644 index f7c0817d8..000000000 --- a/trader_backup/vendor/valory/connections/http_client/tests/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 Valory AG -# Copyright 2018-2020 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/http_client connection.""" diff --git a/trader_backup/vendor/valory/connections/http_client/tests/test_http_client.py b/trader_backup/vendor/valory/connections/http_client/tests/test_http_client.py deleted file mode 100644 index 85f92b505..000000000 --- a/trader_backup/vendor/valory/connections/http_client/tests/test_http_client.py +++ /dev/null @@ -1,362 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ -"""Tests for valory/http_client connection. Adapted from original AEA code.""" -# pylint: skip-file - -import asyncio -import logging -from asyncio import CancelledError -from typing import Any, cast -from unittest.mock import MagicMock, Mock, patch - -import aiohttp -import pytest - -from aea.common import Address -from aea.configurations.base import ConnectionConfig -from aea.identity.base import Identity -from aea.mail.base import Envelope, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.test_tools.constants import UNKNOWN_PROTOCOL_PUBLIC_ID -from aea.test_tools.mocks import AnyStringWith -from aea.test_tools.network import get_host, get_unused_tcp_port - -from packages.valory.connections.http_client.connection import HTTPClientConnection -from packages.valory.protocols.http.dialogues import HttpDialogue -from packages.valory.protocols.http.dialogues import HttpDialogues as BaseHttpDialogues -from packages.valory.protocols.http.message import HttpMessage - - -logger = logging.getLogger(__name__) - - -class _MockRequest: - """Fake request for aiohttp client session.""" - - def __init__(self, response: Mock) -> None: - """Init with mock response.""" - self.response = response - - async def __aenter__(self) -> Mock: - """Enter async context.""" - return self.response - - async def __aexit__(self, *args: Any, **kwargs: Any) -> None: - """Exit async context.""" - return None - - -class HttpDialogues(BaseHttpDialogues): - """The dialogues class keeps track of all http dialogues.""" - - def __init__(self, self_address: Address, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param self_address: the address - :param kwargs: keyword arguments - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return HttpDialogue.Role.CLIENT - - BaseHttpDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - ) - - -@pytest.mark.asyncio -class TestHTTPClientConnect: - """Tests the http client connection's 'connect' functionality.""" - - def setup(self) -> None: - """Initialise the class.""" - self.address = get_host() - self.port = get_unused_tcp_port() - self.agent_identity = Identity( - "name", address="some string", public_key="some public_key" - ) - self.client_skill_id = "some/skill:0.1.0" - configuration = ConnectionConfig( - host=self.address, - port=self.port, - connection_id=HTTPClientConnection.connection_id, - ) - self.http_client_connection = HTTPClientConnection( - configuration=configuration, - data_dir=MagicMock(), - identity=self.agent_identity, - ) - self.connection_address = str(HTTPClientConnection.connection_id) - self.http_dialogs = HttpDialogues(self.client_skill_id) - - @pytest.mark.asyncio - async def test_initialization(self) -> None: - """Test the initialisation of the class.""" - assert self.http_client_connection.address == self.agent_identity.address - - @pytest.mark.asyncio - async def test_connection(self) -> None: - """Test the connect functionality of the http client connection.""" - await self.http_client_connection.connect() - assert self.http_client_connection.is_connected is True - - @pytest.mark.asyncio - async def test_disconnect(self) -> None: - """Test the disconnect functionality of the http client connection.""" - await self.http_client_connection.connect() - assert self.http_client_connection.is_connected is True - - await self.http_client_connection.disconnect() - assert self.http_client_connection.is_connected is False - - @pytest.mark.asyncio - async def test_http_send_error(self) -> None: - """Test request fails and send back result with code 600.""" - await self.http_client_connection.connect() - request_http_message, _ = self.http_dialogs.create( - counterparty=self.connection_address, - performative=HttpMessage.Performative.REQUEST, - method="get", - url="bad url", - headers="", - version="", - body=b"", - ) - request_envelope = Envelope( - to=self.connection_address, - sender=self.client_skill_id, - protocol_specification_id=UNKNOWN_PROTOCOL_PUBLIC_ID, - message=request_http_message, - ) - - connection_response_mock = Mock() - connection_response_mock.status_code = 200 - - await self.http_client_connection.send(envelope=request_envelope) - # TODO: Consider returning the response from the server in order to be able to assert that the message send! - envelope = await asyncio.wait_for( - self.http_client_connection.receive(), timeout=10 - ) - assert envelope - assert isinstance(envelope.message, HttpMessage) - assert envelope.message.status_code == 600 - - await self.http_client_connection.disconnect() - - @pytest.mark.asyncio - async def test_http_client_send_not_connected_error(self) -> None: - """Test connection.send error if not conencted.""" - with pytest.raises(ConnectionError): - await self.http_client_connection.send(Mock()) - - @pytest.mark.asyncio - async def test_http_channel_send_not_connected_error(self) -> None: - """Test channel.send error if not conencted.""" - with pytest.raises(ValueError): - self.http_client_connection.channel.send(Mock()) - - @pytest.mark.asyncio - async def test_send_empty_envelope_skip(self) -> None: - """Test skip on empty envelope request sent.""" - await self.http_client_connection.connect() - with patch.object( - self.http_client_connection.channel, "_http_request_task" - ) as mock: - await self.http_client_connection.send(None) # type: ignore - mock.assert_not_called() - - @pytest.mark.asyncio - async def test_channel_get_message_not_connected(self) -> None: - """Test errro on message get if not connected.""" - with pytest.raises(ValueError): - await self.http_client_connection.channel.get_message() - - @pytest.mark.asyncio - async def test_channel_cancel_tasks_on_disconnect(self) -> None: - """Test requests tasks cancelled on disconnect.""" - await self.http_client_connection.connect() - request_http_message, _ = self.http_dialogs.create( - counterparty=self.connection_address, - performative=HttpMessage.Performative.REQUEST, - method="get", - url="https://not-a-google.com", - headers="Host: https://not-a-google.com", - version="", - body=b"", - ) - request_envelope = Envelope( - to=self.connection_address, - sender=self.client_skill_id, - protocol_specification_id=UNKNOWN_PROTOCOL_PUBLIC_ID, - message=request_http_message, - ) - - connection_response_mock = Mock() - connection_response_mock.status_code = 200 - - response_mock = Mock() - response_mock.status = 200 - response_mock.headers = {"headers": "some header"} - response_mock.reason = "OK" - response_mock._body = b"Some content" - response_mock.read.return_value = asyncio.Future() - - with patch.object( - aiohttp.ClientSession, - "request", - return_value=_MockRequest(response_mock), - ): - await self.http_client_connection.send(envelope=request_envelope) - - assert self.http_client_connection.channel._tasks - task = list(self.http_client_connection.channel._tasks)[0] - assert not task.done() - await self.http_client_connection.disconnect() - - assert not self.http_client_connection.channel._tasks - assert task.done() - with pytest.raises(CancelledError): - await task - - @pytest.mark.asyncio - async def test_http_send_ok(self) -> None: - """Test request is ok cause mocked.""" - await self.http_client_connection.connect() - request_http_message, sending_dialogue = self.http_dialogs.create( - counterparty=self.connection_address, - performative=HttpMessage.Performative.REQUEST, - method="get", - url="https://not-a-google.com", - headers="", - version="", - body=b"", - ) - request_envelope = Envelope( - to=self.connection_address, - sender=self.client_skill_id, - message=request_http_message, - ) - - connection_response_mock = Mock() - connection_response_mock.status_code = 200 - - response_mock = Mock() - response_mock.status = 200 - response_mock.headers = {"headers": "some header"} - response_mock.reason = "OK" - response_mock._body = b"Some content" - response_mock.read.return_value = asyncio.Future() - response_mock.read.return_value.set_result("") - - with patch.object( - aiohttp.ClientSession, - "request", - return_value=_MockRequest(response_mock), - ): - await self.http_client_connection.send(envelope=request_envelope) - # TODO: Consider returning the response from the server in order to be able to assert that the message send! - envelope = await asyncio.wait_for( - self.http_client_connection.receive(), timeout=10 - ) - - assert envelope is not None and envelope.message is not None - message = envelope.message - assert isinstance(message, HttpMessage) - response_dialogue = self.http_dialogs.update(message) - assert message.status_code == response_mock.status, message.body.decode("utf-8") - assert sending_dialogue == response_dialogue - await self.http_client_connection.disconnect() - - @pytest.mark.asyncio - async def test_http_dialogue_construct_fail(self) -> None: - """Test dialogue not properly constructed.""" - await self.http_client_connection.connect() - - incorrect_http_message = HttpMessage( - dialogue_reference=self.http_dialogs.new_self_initiated_dialogue_reference(), - performative=HttpMessage.Performative.RESPONSE, # type: ignore - status_code=500, - headers="", - status_text="", - body=b"", - version="", - ) - incorrect_http_message.to = self.connection_address - incorrect_http_message.sender = self.client_skill_id - - # the incorrect message cannot be sent into a dialogue, so this is omitted. - - envelope = Envelope( - to=incorrect_http_message.to, - sender=incorrect_http_message.sender, - message=incorrect_http_message, - ) - with patch.object( - self.http_client_connection.channel.logger, "warning" - ) as mock_logger: - await self.http_client_connection.channel._http_request_task(envelope) - mock_logger.assert_any_call( - AnyStringWith("Could not create dialogue for message=") - ) - - @pytest.mark.asyncio - async def test_http_send_exception(self) -> None: - """Test request is ok cause mocked.""" - await self.http_client_connection.connect() - request_http_message, sending_dialogue = self.http_dialogs.create( - counterparty=self.connection_address, - performative=HttpMessage.Performative.REQUEST, # type: ignore - method="get", - url="https://not-a-google.com", - headers="Host: https://not-a-google.com", - version="", - body=b"", - ) - request_envelope = Envelope( - to=self.connection_address, - sender=self.client_skill_id, - message=request_http_message, - ) - - with patch.object( - aiohttp.ClientSession, - "request", - side_effect=asyncio.TimeoutError("expected exception"), - ): - await self.http_client_connection.send(envelope=request_envelope) - envelope = await asyncio.wait_for( - self.http_client_connection.receive(), timeout=10 - ) - - assert envelope - message = cast(HttpMessage, envelope.message) - assert message.performative == HttpMessage.Performative.RESPONSE - assert b"expected exception" in message.body diff --git a/trader_backup/vendor/valory/connections/http_server/README.md b/trader_backup/vendor/valory/connections/http_server/README.md deleted file mode 100644 index a2947c138..000000000 --- a/trader_backup/vendor/valory/connections/http_server/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# HTTP server connection - -This connection wraps an HTTP server. It consumes requests from clients, translates them into messages for the AEA, waits for a response message from the AEA, then serves the response to the client. - -## Usage - -First, add the connection to your AEA project (`aea add connection valory/http_server:0.22.0`). Then, update the `config` in `connection.yaml` by providing a `host` and `port` of the server. Optionally, provide a path to an [OpenAPI specification](https://swagger.io/docs/specification/about/) for request validation. \ No newline at end of file diff --git a/trader_backup/vendor/valory/connections/http_server/__init__.py b/trader_backup/vendor/valory/connections/http_server/__init__.py deleted file mode 100644 index 031e3523f..000000000 --- a/trader_backup/vendor/valory/connections/http_server/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2023 Valory AG -# Copyright 2018-2020 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Implementation of the HTTP connection and channel.""" diff --git a/trader_backup/vendor/valory/connections/http_server/connection.py b/trader_backup/vendor/valory/connections/http_server/connection.py deleted file mode 100644 index 55b38e7bb..000000000 --- a/trader_backup/vendor/valory/connections/http_server/connection.py +++ /dev/null @@ -1,645 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2023 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ -"""HTTP server connection, channel, server, and handler.""" -import asyncio -import email -import logging -import ssl -from abc import ABC, abstractmethod -from asyncio import CancelledError -from asyncio.events import AbstractEventLoop -from asyncio.futures import Future -from concurrent.futures._base import CancelledError as FuturesCancelledError -from traceback import format_exc -from typing import Any, Dict, Optional, cast -from urllib.parse import parse_qs, urlparse - -from aiohttp import web -from aiohttp.web_request import BaseRequest -from openapi_core import validate_request -from openapi_core.schema.specs import Spec -from openapi_core.validation.request.datatypes import RequestParameters -from openapi_core.validation.request.validators import RequestValidator -from openapi_spec_validator.exceptions import ( # pylint: disable=wrong-import-order - OpenAPIValidationError, -) -from openapi_spec_validator.schemas import ( # pylint: disable=wrong-import-order - read_yaml_file, -) -from werkzeug.datastructures import ( # pylint: disable=wrong-import-order - ImmutableMultiDict, -) - -from aea.common import Address -from aea.configurations.base import PublicId -from aea.connections.base import Connection, ConnectionStates -from aea.mail.base import Envelope, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.http.dialogues import HttpDialogue -from packages.valory.protocols.http.dialogues import HttpDialogues as BaseHttpDialogues -from packages.valory.protocols.http.message import HttpMessage - - -SUCCESS = 200 -NOT_FOUND = 404 -REQUEST_TIMEOUT = 408 -SERVER_ERROR = 500 - -_default_logger = logging.getLogger("aea.packages.valory.connections.http_server") - -RequestId = DialogueLabel -PUBLIC_ID = PublicId.from_str("valory/http_server:0.22.0") - - -class HttpDialogues(BaseHttpDialogues): - """The dialogues class keeps track of all http dialogues.""" - - def __init__(self, self_address: Address, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param self_address: address of the dialogues maintainer. - :param kwargs: keyword arguments. - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - # The server connection maintains the dialogue on behalf of the client - return HttpDialogue.Role.CLIENT - - BaseHttpDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - **kwargs, - ) - - -def headers_to_string(headers: Dict) -> str: - """ - Convert headers to string. - - :param headers: dict - - :return: str - """ - msg = email.message.Message() - for name, value in headers.items(): - msg.add_header(name, value) - return msg.as_string() - - -class Request: - """Generic request object.""" - - def __init__( - self, - host_url: str, - path: str, - full_url_pattern: str, - method: str, - parameters: RequestParameters, - body: bytes, - mimetype: str, - ) -> None: - """Initialize Request object.""" - self.host_url = host_url - self.path = path - self.full_url_pattern = full_url_pattern - self.method = method - self.parameters = parameters - self.body = body - self.mimetype = mimetype - - @property - def is_id_set(self) -> bool: - """Check if id is set.""" - return self._id is not None - - @property - def id(self) -> RequestId: - """Get the request id.""" - return self._id - - @id.setter - def id(self, request_id: RequestId) -> None: - """Set the request id.""" - self._id = request_id - - @classmethod - async def create(cls, http_request: BaseRequest) -> "Request": - """ - Create a request. - - :param http_request: http_request - :return: a request - """ - method = http_request.method.lower() - parsed_path = urlparse(http_request.path_qs) - url = http_request.url - body = await http_request.read() - mimetype = http_request.content_type - query_params = parse_qs(parsed_path.query, keep_blank_values=True) - parameters = RequestParameters( - query=ImmutableMultiDict(query_params), # type: ignore - header=headers_to_string(dict(http_request.headers)), - path={}, - ) - - request = Request( - host_url=str(url.with_path("/")), - path=parsed_path.path, - full_url_pattern=str(url), - method=method, - parameters=parameters, - body=body, - mimetype=mimetype, - ) - return request - - def to_envelope_and_set_id( - self, - dialogues: HttpDialogues, - target_skill_id: PublicId, - ) -> Envelope: - """ - Process incoming API request by packaging into Envelope and sending it in-queue. - - :param dialogues: the http dialogues - :param target_skill_id: the target skill id - - :return: envelope - """ - url = self.full_url_pattern - http_message, http_dialogue = dialogues.create( - counterparty=str(target_skill_id), - performative=HttpMessage.Performative.REQUEST, - method=self.method, - url=url, - headers=self.parameters.header, - body=self.body if self.body is not None else b"", - version="", - ) - dialogue = cast(HttpDialogue, http_dialogue) - self.id = dialogue.incomplete_dialogue_label - envelope = Envelope( - to=http_message.to, - sender=http_message.sender, - message=http_message, - ) - return envelope - - -class Response(web.Response): - """Generic response object.""" - - @classmethod - def from_message(cls, http_message: HttpMessage) -> "Response": - """ - Turn an envelope into a response. - - :param http_message: the http_message - :return: the response - """ - if http_message.performative == HttpMessage.Performative.RESPONSE: - if http_message.is_set("headers") and http_message.headers: - headers: Optional[dict] = dict( - email.message_from_string(http_message.headers).items() - ) - else: - headers = None - - # if content length header provided, it should correspond to actuyal body length - if headers and "Content-Length" in headers: - headers["Content-Length"] = str(len(http_message.body or "")) - - response = cls( - status=http_message.status_code, - reason=http_message.status_text, - body=http_message.body, - headers=headers, - ) - else: # pragma: nocover - response = cls(status=SERVER_ERROR, text="Server error") - return response - - -class APISpec: - """API Spec class to verify a request against an OpenAPI/Swagger spec.""" - - def __init__( - self, - api_spec_path: Optional[str] = None, - server: Optional[str] = None, - logger: logging.Logger = _default_logger, - ): - """ - Initialize the API spec. - - :param api_spec_path: Directory API path and filename of the API spec YAML source file. - :param server: the server url - :param logger: the logger - """ - self._validator = None # type: Optional[RequestValidator] - self.logger = logger - if api_spec_path is not None: - try: - api_spec_dict = read_yaml_file(api_spec_path) - if server is not None: - api_spec_dict["servers"] = [{"url": server}] - self.api_spec = Spec.create(data=api_spec_dict) - self._validator = RequestValidator(self.api_spec) - except OpenAPIValidationError as e: # pragma: nocover - self.logger.error( - f"API specification YAML source file not correctly formatted: {str(e)}" - ) - except Exception: - self.logger.exception( - "API specification YAML source file not correctly formatted." - ) - raise - - def verify(self, request: Request) -> bool: - """ - Verify a http_method, url and param against the provided API spec. - - :param request: the request object - :return: whether or not the request conforms with the API spec - """ - if self._validator is None: - self.logger.debug("Skipping API verification!") - return True - - try: - validate_request( - spec=self.api_spec, - request=request, - validator=self._validator, - ) - except Exception: # pragma: nocover # pylint: disable=broad-except - self.logger.exception("APISpec verify error") - return False - return True - - -class BaseAsyncChannel(ABC): - """Base asynchronous channel class.""" - - def __init__(self, address: Address, connection_id: PublicId) -> None: - """ - Initialize a channel. - - :param address: the address of the agent. - :param connection_id: public id of connection using this channel. - """ - self._in_queue = None # type: Optional[asyncio.Queue] - self._loop = None # type: Optional[asyncio.AbstractEventLoop] - self.is_stopped = True - self.address = address - self.connection_id = connection_id - - @abstractmethod - async def connect(self, loop: AbstractEventLoop) -> None: - """ - Connect. - - Upon HTTP Channel connection, start the HTTP Server in its own thread. - - :param loop: asyncio event loop - """ - self._loop = loop - self._in_queue = asyncio.Queue() - self.is_stopped = False - - async def get_message(self) -> Optional["Envelope"]: - """ - Get http response from in-queue. - - :return: None or envelope with http response. - """ - if self._in_queue is None: - raise ValueError("Looks like channel is not connected!") - - try: - return await self._in_queue.get() - except CancelledError: # pragma: nocover - return None - - @abstractmethod - def send(self, envelope: Envelope) -> None: - """ - Send the envelope in_queue. - - :param envelope: the envelope - """ - - @abstractmethod - async def disconnect(self) -> None: - """ - Disconnect. - - Shut-off the HTTP Server. - """ - - -class HTTPChannel(BaseAsyncChannel): - """A wrapper for an RESTful API with an internal HTTPServer.""" - - RESPONSE_TIMEOUT = 5.0 - - def __init__( - self, - address: Address, - host: str, - port: int, - target_skill_id: PublicId, - api_spec_path: Optional[str], - connection_id: PublicId, - timeout_window: float = RESPONSE_TIMEOUT, - logger: logging.Logger = _default_logger, - ssl_cert_path: Optional[str] = None, - ssl_key_path: Optional[str] = None, - ): - """ - Initialize a channel and process the initial API specification from the file path (if given). - - :param address: the address of the agent. - :param host: RESTful API hostname / IP address - :param port: RESTful API port number - :param target_skill_id: the skill id which handles the requests - :param api_spec_path: Directory API path and filename of the API spec YAML source file. - :param connection_id: public id of connection using this channel. - :param timeout_window: the timeout (in seconds) for a request to be handled. - :param logger: the logger - :param ssl_cert_path: optional path to ssl certificate - :param ssl_key_path: optional path to ssl key - """ - super().__init__(address=address, connection_id=connection_id) - self.host = host - self.port = port - self.ssl_cert_path = ssl_cert_path - self.ssl_key_path = ssl_key_path - self.target_skill_id = target_skill_id - if self.ssl_cert_path and self.ssl_key_path: - self.server_address = "https://{}:{}".format(self.host, self.port) - else: - self.server_address = "http://{}:{}".format(self.host, self.port) - - self._api_spec = APISpec(api_spec_path, self.server_address, logger) - self.timeout_window = timeout_window - self.http_server: Optional[web.TCPSite] = None - self.pending_requests: Dict[RequestId, Future] = {} - self._dialogues = HttpDialogues(str(HTTPServerConnection.connection_id)) - self.logger = logger - - @property - def api_spec(self) -> APISpec: - """Get the api spec.""" - return self._api_spec - - async def connect(self, loop: AbstractEventLoop) -> None: - """ - Connect. - - Upon HTTP Channel connection, start the HTTP Server in its own thread. - - :param loop: asyncio event loop - """ - if self.is_stopped: - await super().connect(loop) - - try: - await self._start_http_server() - self.logger.info( - "HTTP Server has connected to port: {}.".format(self.port) - ) - except Exception: # pragma: nocover # pylint: disable=broad-except - self.is_stopped = True - self._in_queue = None - self.logger.exception( - "Failed to start server on {}:{}.".format(self.host, self.port) - ) - - async def _http_handler(self, http_request: BaseRequest) -> Response: - """ - Verify the request then send the request to Agent as an envelope. - - :param http_request: the request object - - :return: a tuple of response code and response description - """ - request = await Request.create(http_request) - if self._in_queue is None: # pragma: nocover - raise ValueError("Channel not connected!") - - is_valid_request = self.api_spec.verify(request) - - if not is_valid_request: - self.logger.warning(f"request is not valid: {request}") - return Response(status=NOT_FOUND, reason="Request Not Found") - - try: - # turn request into envelope - envelope = request.to_envelope_and_set_id( - self._dialogues, self.target_skill_id - ) - - self.pending_requests[request.id] = Future() - - # send the envelope to the agent's inbox (via self.in_queue) - await self._in_queue.put(envelope) - # wait for response envelope within given timeout window (self.timeout_window) to appear in dispatch_ready_envelopes - - response_message = await asyncio.wait_for( - self.pending_requests[request.id], - timeout=self.timeout_window, - ) - return Response.from_message(response_message) - - except asyncio.TimeoutError: - self.logger.warning( - f"Request timed out! Request={request} not handled as a result. Ensure requests (protocol_id={HttpMessage.protocol_id}) are handled by a skill!" - ) - return Response(status=REQUEST_TIMEOUT, reason="Request Timeout") - except FuturesCancelledError: - return Response( # pragma: nocover - status=SERVER_ERROR, reason="Server terminated unexpectedly." - ) - except BaseException: # pragma: nocover # pylint: disable=broad-except - self.logger.exception("Error during handling incoming request") - return Response( - status=SERVER_ERROR, reason="Server Error", text=format_exc() - ) - finally: - if request.is_id_set: - self.pending_requests.pop(request.id, None) - - async def _start_http_server(self) -> None: - """Start http server.""" - server = web.Server(self._http_handler) - runner = web.ServerRunner(server) - await runner.setup() - ssl_context = None - if self.ssl_cert_path and self.ssl_key_path: - ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) - ssl_context.load_cert_chain(self.ssl_cert_path, self.ssl_key_path) - self.http_server = web.TCPSite( - runner, self.host, self.port, ssl_context=ssl_context - ) - await self.http_server.start() - - def send(self, envelope: Envelope) -> None: - """ - Send the envelope in_queue. - - :param envelope: the envelope - """ - if self.http_server is None: # pragma: nocover - raise ValueError("Server not connected, call connect first!") - - message = cast(HttpMessage, envelope.message) - dialogue = self._dialogues.update(message) - - if dialogue is None: - self.logger.warning( - "Could not create dialogue for message={}".format(message) - ) - return - - future = self.pending_requests.pop(dialogue.incomplete_dialogue_label, None) - - if not future: - self.logger.warning( - "Dropping message={} for incomplete_dialogue_label={} which has timed out.".format( - message, dialogue.incomplete_dialogue_label - ) - ) - return - if not future.done(): - future.set_result(message) - - async def disconnect(self) -> None: - """ - Disconnect. - - Shut-off the HTTP Server. - """ - if self.http_server is None: # pragma: nocover - raise ValueError("Server not connected, call connect first!") - - if not self.is_stopped: - await self.http_server.stop() - self.logger.info("HTTP Server has shutdown on port: {}.".format(self.port)) - self.is_stopped = True - self._in_queue = None - - -class HTTPServerConnection(Connection): - """Proxy to the functionality of the http server implementing a RESTful API specification.""" - - connection_id = PUBLIC_ID - - def __init__(self, **kwargs: Any) -> None: - """Initialize a HTTP server connection.""" - super().__init__(**kwargs) - host = cast(Optional[str], self.configuration.config.get("host")) - port = cast(Optional[int], self.configuration.config.get("port")) - target_skill_id_ = cast( - Optional[str], self.configuration.config.get("target_skill_id") - ) - if host is None or port is None or target_skill_id_ is None: # pragma: nocover - raise ValueError("host and port and target_skill_id must be set!") - target_skill_id = PublicId.try_from_str(target_skill_id_) - if target_skill_id is None: # pragma: nocover - raise ValueError("Provided target_skill_id is not a valid public id.") - api_spec_path = cast( - Optional[str], self.configuration.config.get("api_spec_path") - ) - ssl_cert_path = cast(Optional[str], self.configuration.config.get("ssl_cert")) - ssl_key_path = cast(Optional[str], self.configuration.config.get("ssl_key")) - - if bool(ssl_cert_path) != bool(ssl_key_path): # pragma: nocover - raise ValueError("Please specify both ssl_cert and ssl_key or neither.") - - self.channel = HTTPChannel( - self.address, - host, - port, - target_skill_id, - api_spec_path, - connection_id=self.connection_id, - logger=self.logger, - ssl_cert_path=ssl_cert_path, - ssl_key_path=ssl_key_path, - ) - - async def connect(self) -> None: - """Connect to the http channel.""" - if self.is_connected: - return - - self.state = ConnectionStates.connecting - self.channel.logger = self.logger - await self.channel.connect(loop=self.loop) - if self.channel.is_stopped: - self.state = ConnectionStates.disconnected - else: - self.state = ConnectionStates.connected - - async def disconnect(self) -> None: - """Disconnect from HTTP channel.""" - if self.is_disconnected: - return - - self.state = ConnectionStates.disconnecting - await self.channel.disconnect() - self.state = ConnectionStates.disconnected - - async def send(self, envelope: "Envelope") -> None: - """ - Send an envelope. - - :param envelope: the envelop - """ - self._ensure_connected() - self.channel.send(envelope) - - async def receive(self, *args: Any, **kwargs: Any) -> Optional["Envelope"]: - """ - Receive an envelope. - - :param args: positional arguments - :param kwargs: keyword arguments - :return: the envelope received, or None. - """ - self._ensure_connected() - try: - return await self.channel.get_message() - except CancelledError: # pragma: no cover - return None diff --git a/trader_backup/vendor/valory/connections/http_server/connection.yaml b/trader_backup/vendor/valory/connections/http_server/connection.yaml deleted file mode 100644 index d19bee4c5..000000000 --- a/trader_backup/vendor/valory/connections/http_server/connection.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: http_server -author: valory -version: 0.22.0 -type: connection -description: The HTTP server connection that wraps http server implementing a RESTful - API specification. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeifepluovb4so2eem34ulpcp4svegb2dqfpmtojtofhfkb3j2xanui - __init__.py: bafybeifykou5sazojmc7hdqnsdp4mncd4zh3xys3mdgdzwks23mvhzu2ga - connection.py: bafybeie42txykvedioambi2dq4nurktilg5v6qleo2iaesc7psmrobdhva - tests/__init__.py: bafybeifqaf7cnc4oczjkbwmv4ahrkbiqxrojwgowej3kbri3skz4lzt43i - tests/data/certs/server.crt: bafybeiev5i3xxkvn36wflf633gkumuxexsw4y2bubwbvl7edrz4igfgv34 - tests/data/certs/server.csr: bafybeicvp7xdl5w3o4bzikkudpduitss3bpp6xqfwlxbw6kabdangohy5u - tests/data/certs/server.key: bafybeiabvpkpqr4fctrbssfal6pviv5otgmu32qyrfpyhcql5wgmlzjtoe - tests/data/petstore_sim.yaml: bafybeiaekkfxljlv57uviz4ug6isdqbzsnuxpsgy3dvhzh22daql3xh2i4 - tests/test_http_server.py: bafybeia2cax2paqaygr6xgzbgmiqepsyjkdx4joi5qukpg6ewnz5yckk7m -fingerprint_ignore_patterns: [] -connections: [] -protocols: -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -class_name: HTTPServerConnection -config: - api_spec_path: null - host: 127.0.0.1 - port: 8000 - ssl_cert: null - ssl_key: null - target_skill_id: null -excluded_protocols: [] -restricted_to_protocols: -- valory/http:1.0.0 -dependencies: - aiohttp: - version: <4.0.0,>=3.8.5 - openapi-core: - version: ==0.15.0 - openapi-spec-validator: - version: <0.5.0,>=0.4.0 - werkzeug: {} - attrs: {} -is_abstract: false diff --git a/trader_backup/vendor/valory/connections/http_server/tests/__init__.py b/trader_backup/vendor/valory/connections/http_server/tests/__init__.py deleted file mode 100644 index 27614bc9e..000000000 --- a/trader_backup/vendor/valory/connections/http_server/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2023 Valory AG -# Copyright 2018-2020 Fetch.AI Limited -# -# 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 the tests of the HTTP Server connection implementation.""" diff --git a/trader_backup/vendor/valory/connections/http_server/tests/data/certs/server.crt b/trader_backup/vendor/valory/connections/http_server/tests/data/certs/server.crt deleted file mode 100644 index b2ae04f89..000000000 --- a/trader_backup/vendor/valory/connections/http_server/tests/data/certs/server.crt +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICsTCCAZkCFGqNcoSHEADDJ5wZBtczunKoFWBVMA0GCSqGSIb3DQEBCwUAMBQx -EjAQBgNVBAMMCWxvY2FsaG9zdDAgFw0yMTA5MDYwOTU2MTVaGA8yMTIxMDgxMzA5 -NTYxNVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAxX8TpWN5cE9oGotbTlEDVst1at0ZgYlgKwCVconrOQ77AhD4 -MyJZ++Poy2i9N1JKYclT9ZrSRtqh+djILaCVeHHgwqFgwpGJuupunv/5o8fX9k1/ -YUs3MQou9STiOLS+B/MK25Fi/LUvr1ZYJzAViekgV1yv7Sn/n2mpQe66ByyNZt3D -Tzid9f3d7FHY6HBkxaoaUxkSIJeHcHy6qUXdiEeoPWBbkp6JjFqKW6mynwnDP4Wc -zGerRtLo69rxtaaES0aboOjA6bk1Ab+4XmSH+Kv6r7CzArLFHJO+ZUU6Pqxd2ehR -L9qicTzOQyN7ygVlBwZWpioOSRzGROgrNhQniQIDAQABMA0GCSqGSIb3DQEBCwUA -A4IBAQBxSEAWtXQUq8qW8XHRcw1loBoxIus1+ajkMX9/pN0SFuNBq8P61TLtMjM1 -G0czcgyXVqjMFtudY+CJa6yn+WWnp6oqDkjcu8Z5SdFfM677pQwF4R1nylb1aLP+ -X+7NxVIs2pHNzYvxRm/OQ1Q6rVWVq3omludCcxHd3+y5kW5enG1Dp2yLXsdatNjj -2DzLF2WNMVXuXmFC9GVZpSsP5qCYD8rfqNvLaV6oxZ+woJ+UX8Q5YlEB1/2LtRBf -x+XiiKXY2h4ZTHGjCO+Pu6FKOxf4JxWoBirCe7WOjfOJUdQYLOk6nT+qSP8iLFaS -/DBRpBw/kJjec5xedh2CZOEC8NLw ------END CERTIFICATE----- diff --git a/trader_backup/vendor/valory/connections/http_server/tests/data/certs/server.csr b/trader_backup/vendor/valory/connections/http_server/tests/data/certs/server.csr deleted file mode 100644 index b11586e88..000000000 --- a/trader_backup/vendor/valory/connections/http_server/tests/data/certs/server.csr +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIICWTCCAUECAQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEAxX8TpWN5cE9oGotbTlEDVst1at0ZgYlgKwCVconr -OQ77AhD4MyJZ++Poy2i9N1JKYclT9ZrSRtqh+djILaCVeHHgwqFgwpGJuupunv/5 -o8fX9k1/YUs3MQou9STiOLS+B/MK25Fi/LUvr1ZYJzAViekgV1yv7Sn/n2mpQe66 -ByyNZt3DTzid9f3d7FHY6HBkxaoaUxkSIJeHcHy6qUXdiEeoPWBbkp6JjFqKW6my -nwnDP4WczGerRtLo69rxtaaES0aboOjA6bk1Ab+4XmSH+Kv6r7CzArLFHJO+ZUU6 -Pqxd2ehRL9qicTzOQyN7ygVlBwZWpioOSRzGROgrNhQniQIDAQABoAAwDQYJKoZI -hvcNAQELBQADggEBAH9MeBQNrb081LoPDk3C/C4zH6BoVtxkQXoPXGv6+wijNju5 -wAUZc26VGdawW3Scqj9kboObi5NwI7o8ZMsOx2V8MT5FjSl79DoAszwww19J48J4 -6qGRPuph3c48Gz1eZCCQscaEG4pYqdL3aS6Jt/HmKkZGIAZvNGwzaBOGTIJTZHSU -9W9gV3RAL1unLgZKYAmKVStFtCOjARbn0wlBOeT2nkqRsckACgxxDNAjDPmKVmUK -x6BSPttFWIVc/FXvkIBpwbxKAlwK9amtko0VGgw3WC7kBq13/ijNeQV/PaqFbSWF -MshUv0YLv0aKVwFN1oRYiDYuwSXyRK5PYW4VNhQ= ------END CERTIFICATE REQUEST----- diff --git a/trader_backup/vendor/valory/connections/http_server/tests/data/certs/server.key b/trader_backup/vendor/valory/connections/http_server/tests/data/certs/server.key deleted file mode 100644 index a98c11c10..000000000 --- a/trader_backup/vendor/valory/connections/http_server/tests/data/certs/server.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAxX8TpWN5cE9oGotbTlEDVst1at0ZgYlgKwCVconrOQ77AhD4 -MyJZ++Poy2i9N1JKYclT9ZrSRtqh+djILaCVeHHgwqFgwpGJuupunv/5o8fX9k1/ -YUs3MQou9STiOLS+B/MK25Fi/LUvr1ZYJzAViekgV1yv7Sn/n2mpQe66ByyNZt3D -Tzid9f3d7FHY6HBkxaoaUxkSIJeHcHy6qUXdiEeoPWBbkp6JjFqKW6mynwnDP4Wc -zGerRtLo69rxtaaES0aboOjA6bk1Ab+4XmSH+Kv6r7CzArLFHJO+ZUU6Pqxd2ehR -L9qicTzOQyN7ygVlBwZWpioOSRzGROgrNhQniQIDAQABAoIBAHao81Tbf4tLKnFI -aYOUiT0M4W9jiH+b2nv7zc8TrpCJv6ZuK7INYaNGPAh61bT3bFl0bU2Tx+NqWQeU -iDFh2myTf0dxToGYj/gOAojlo0gUOl1yEqaSWobMZ4pCrukDL2n3TP6/S4oqEox2 -hGCHM2m4+AWFWu5T3ZIaGefTV1IXEqghj7L+53UI4qksnJDEQ9GT34KnlJhQKZmw -E6St5F2xfXTKq6EWBIC23RNo4kAgDHBTE8MVRZdUEPmipf564NEVtxLFTKUi+tue -GbiagtCWeGeEGZ2uFyr+HWIQUz4qLcMR6hp+hxh2VP3U52/0I5PKngSO0G6IemMD -Hxj6DEECgYEA/A7Vjy9Or7DEIWZcsm44kyl79qUbzAlqDtG2RmOc6DDiWM3jQ/OR -bOW4wNCFxv/KOsoeB7FxP7kKTupwj2u1Y9krAsHifXyFtHilZy9yTo4h8wHy40ae -4B8sP4+xEhppfjoFg5ySdF1BF1prwh34YSlFEkD+Q3Uu4Hr3+Ph8Pk8CgYEAyJXL -TKT3zUUD6BhtJ74jtmwSW7SZx+lgbgzEtAHTwcZZllaTCdBY6H3im5pJ9LettymT -PtSVn2EYVULtJJiT0qm3rqkqDQ8QImdx+T2V/GL9Oo8T1LdYud2J+f7+pEAn9Ud3 -/XL6kZUXm/CpwIGIx3tB09kSsLxCGRnyrdhR3qcCgYEA3TCLWg5yp5ygUIsKV45/ -2SxzWzsCzKeKSZzgrp5lqCCV0MZEZHIOsRhaa+HRM5NuPO73MVsWfYv9Lsluo30q -fYeqxc2s2t/2WSvyQj2RurvhsOWJ5sYnT5grdU+8XJ2O67Uw95DjuHfJUhwIKh2w -xFq6AU3Fkx73VwiyKOqt5OMCgYBiIh7/VWpCy/QYVfL5UaXpNsBYi2f9DSl3Tdni -c05lbCQiUCLJ11vYCtaV6Asspbxgcv+t6pV1Dyy3cfHRSLBxjUTnN63yC5+KJW/2 -T3IUs11Oi/dYx4aqED/TxjRQqW6jKp8CqYD7PqT5TunN29HOPng7K+VgAAqaez5m -XQHY2wKBgErzDsGHH+0XktR7HCZJMmuc/1HnDzfENnfpRIjjlwJF8xn/HymS0OP+ -3AsfN0g60Qutng62wthkzeUheD3UM2nwpmatuP4UXUFGkGcwmCdvzMf/SvyKIjmQ -Mxiu8flSlCWlvP5e+Rrmd3RitOXeCqZLKbywMnlWHHfL33d1LWlf ------END RSA PRIVATE KEY----- diff --git a/trader_backup/vendor/valory/connections/http_server/tests/data/petstore_sim.yaml b/trader_backup/vendor/valory/connections/http_server/tests/data/petstore_sim.yaml deleted file mode 100644 index dd8ea80ed..000000000 --- a/trader_backup/vendor/valory/connections/http_server/tests/data/petstore_sim.yaml +++ /dev/null @@ -1,111 +0,0 @@ -openapi: "3.0.0" -info: - version: 1.0.0 - title: Swagger Petstore - license: - name: MIT -servers: - - url: '' -paths: - /pets: - get: - summary: List all pets - operationId: listPets - tags: - - pets - parameters: - - name: limit - in: query - description: How many items to return at one time (max 100) - required: false - schema: - type: integer - format: int32 - responses: - '200': - description: A paged array of pets - headers: - x-next: - description: A link to the next page of responses - schema: - type: string - content: - application/json: - schema: - $ref: "#/components/schemas/Pets" - default: - description: unexpected error - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - post: - summary: Create a pet - operationId: createPets - tags: - - pets - responses: - '201': - description: Null response - default: - description: unexpected error - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - /pets/{petId}: - get: - summary: Info for a specific pet - operationId: showPetById - tags: - - pets - parameters: - - name: petId - in: path - required: true - description: The id of the pet to retrieve - schema: - type: string - responses: - '200': - description: Expected response to a valid request - content: - application/json: - schema: - $ref: "#/components/schemas/Pet" - default: - description: unexpected error - content: - application/json: - schema: - $ref: "#/components/schemas/Error" -components: - schemas: - Pet: - type: object - required: - - id - - name - properties: - id: - type: integer - format: int64 - name: - type: string - tag: - type: string - Pets: - type: array - items: - $ref: "#/components/schemas/Pet" - Error: - type: object - required: - - code - - message - properties: - code: - type: integer - format: int32 - message: - type: string \ No newline at end of file diff --git a/trader_backup/vendor/valory/connections/http_server/tests/test_http_server.py b/trader_backup/vendor/valory/connections/http_server/tests/test_http_server.py deleted file mode 100644 index cd08e0d08..000000000 --- a/trader_backup/vendor/valory/connections/http_server/tests/test_http_server.py +++ /dev/null @@ -1,597 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2023 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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 the tests of the HTTP Server connection module.""" -# pylint: skip-file - -import asyncio -import logging -import os -import ssl -from pathlib import Path -from traceback import print_exc -from typing import Tuple, cast -from unittest.mock import MagicMock, Mock, patch - -import aiohttp -import pytest -from aiohttp.client_reqrep import ClientResponse - -from aea.common import Address -from aea.configurations.base import ConnectionConfig -from aea.identity.base import Identity -from aea.mail.base import Envelope, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.test_tools.mocks import RegexComparator -from aea.test_tools.network import get_host, get_unused_tcp_port - -from packages.valory.connections.http_server.connection import ( - APISpec, - HTTPServerConnection, - Response, -) -from packages.valory.protocols.http.dialogues import HttpDialogue -from packages.valory.protocols.http.dialogues import HttpDialogues as BaseHttpDialogues -from packages.valory.protocols.http.message import HttpMessage - - -logger = logging.getLogger(__name__) - -DATA_DIR = str(Path(__file__).parent / "data") - - -class HttpDialogues(BaseHttpDialogues): - """The dialogues class keeps track of all http dialogues.""" - - def __init__(self, self_address: Address, **kwargs) -> None: - """ - Initialize dialogues. - - :param self_address: self address - :param kwargs: keyword arguments - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return HttpDialogue.Role.SERVER - - BaseHttpDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - ) - - -@pytest.mark.asyncio -class TestHTTPServer: - """Tests for HTTPServer connection.""" - - async def request(self, method: str, path: str, **kwargs) -> ClientResponse: - """ - Make a http request. - - :param method: HTTP method: GET, POST etc - :param path: path to request on server. full url constructed automatically - :param kwargs: keyword arguments - :return: http response - """ - try: - url = f"http://{self.host}:{self.port}{path}" - async with aiohttp.ClientSession() as session: - async with session.request(method, url, **kwargs) as resp: - await resp.read() - return resp - except Exception: - print_exc() - raise - - def setup(self): - """Initialise the test case.""" - self.identity = Identity("name", address="my_key", public_key="my_public_key") - self.agent_address = self.identity.address - self.host = get_host() - self.port = get_unused_tcp_port() - self.api_spec_path = os.path.join(DATA_DIR, "petstore_sim.yaml") - self.connection_id = HTTPServerConnection.connection_id - self.protocol_id = HttpMessage.protocol_id - self.target_skill_id = "some_author/some_skill:0.1.0" - - self.configuration = ConnectionConfig( - host=self.host, - port=self.port, - target_skill_id=self.target_skill_id, - api_spec_path=self.api_spec_path, - connection_id=HTTPServerConnection.connection_id, - restricted_to_protocols={HttpMessage.protocol_id}, - ) - self.http_connection = HTTPServerConnection( - configuration=self.configuration, - data_dir=MagicMock(), - identity=self.identity, - ) - self.loop = asyncio.get_event_loop() - self.loop.run_until_complete(self.http_connection.connect()) - self.connection_address = str(HTTPServerConnection.connection_id) - self._dialogues = HttpDialogues(self.target_skill_id) - self.original_timeout = self.http_connection.channel.timeout_window - - @pytest.mark.asyncio - async def test_http_connection_disconnect_channel(self): - """Test the disconnect.""" - await self.http_connection.channel.disconnect() - assert self.http_connection.channel.is_stopped - - def _get_message_and_dialogue( - self, envelope: Envelope - ) -> Tuple[HttpMessage, HttpDialogue]: - message = cast(HttpMessage, envelope.message) - dialogue = cast(HttpDialogue, self._dialogues.update(message)) - assert dialogue is not None - return message, dialogue - - @pytest.mark.asyncio - async def test_get_200(self): - """Test send get request w/ 200 response.""" - request_task = self.loop.create_task(self.request("get", "/pets")) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=20) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - message = dialogue.reply( - target_message=incoming_message, - performative=HttpMessage.Performative.RESPONSE, - version=incoming_message.version, - status_code=200, - status_text="Success", - body=b"Response body", - headers="Content-Length: 1", - ) - response_envelope = Envelope( - to=envelope.sender, - sender=envelope.to, - context=envelope.context, - message=message, - ) - await self.http_connection.send(response_envelope) - - response = await asyncio.wait_for( - request_task, - timeout=20, - ) - assert ( - response.status == 200 - and response.reason == "Success" - and await response.text() == "Response body" - and int(response.headers["Content-Length"]) == len("Response body") - ) - - @pytest.mark.asyncio - async def test_header_content_type(self): - """Test send get request w/ 200 response.""" - content_type = "something/unique" - request_task = self.loop.create_task(self.request("get", "/pets")) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=20) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - message = dialogue.reply( - target_message=incoming_message, - performative=HttpMessage.Performative.RESPONSE, - version=incoming_message.version, - headers=f"Content-Type: {content_type}", - status_code=200, - status_text="Success", - body=b"Response body", - ) - response_envelope = Envelope( - to=envelope.sender, - sender=envelope.to, - context=envelope.context, - message=message, - ) - await self.http_connection.send(response_envelope) - - response = await asyncio.wait_for( - request_task, - timeout=20, - ) - assert ( - response.status == 200 - and response.reason == "Success" - and await response.text() == "Response body" - ) - assert response.headers["Content-Type"] == content_type - - @pytest.mark.asyncio - async def test_bad_performative_get_timeout_error(self): - """Test send get request w/ 200 response.""" - self.http_connection.channel.timeout_window = 3 - request_task = self.loop.create_task(self.request("get", "/pets")) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=10) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - incorrect_message = HttpMessage( - performative=HttpMessage.Performative.REQUEST, - dialogue_reference=dialogue.dialogue_label.dialogue_reference, - target=incoming_message.message_id, - message_id=incoming_message.message_id + 1, - method="post", - url="/pets", - version=incoming_message.version, - headers=incoming_message.headers, - body=b"Request body", - ) - incorrect_message.to = incoming_message.sender - - # the incorrect message cannot be sent into a dialogue, so this is omitted. - - response_envelope = Envelope( - to=incorrect_message.to, - sender=envelope.to, - context=envelope.context, - message=incorrect_message, - ) - with patch.object(self.http_connection.logger, "warning") as mock_logger: - await self.http_connection.send(response_envelope) - mock_logger.assert_any_call( - f"Could not create dialogue for message={incorrect_message}" - ) - - response = await asyncio.wait_for(request_task, timeout=10) - - assert ( - response.status == 408 - and response.reason == "Request Timeout" - and await response.text() == "" - ) - - @pytest.mark.asyncio - async def test_late_message_get_timeout_error(self): - """Test send get request w/ 200 response.""" - self.http_connection.channel.timeout_window = 0.2 - request_task = self.loop.create_task(self.request("get", "/pets")) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=10) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - message = dialogue.reply( - target_message=incoming_message, - performative=HttpMessage.Performative.RESPONSE, - version=incoming_message.version, - headers=incoming_message.headers, - status_code=200, - status_text="Success", - body=b"Response body", - ) - response_envelope = Envelope( - to=message.to, - sender=envelope.to, - context=envelope.context, - message=message, - ) - await asyncio.sleep(0.4) - with patch.object(self.http_connection.logger, "warning") as mock_logger: - await self.http_connection.send(response_envelope) - mock_logger.assert_any_call( - RegexComparator( - "Dropping message=.* for incomplete_dialogue_label=.* which has timed out." - ) - ) - - response = await asyncio.wait_for(request_task, timeout=10) - - assert ( - response.status == 408 - and response.reason == "Request Timeout" - and await response.text() == "" - ) - - @pytest.mark.asyncio - async def test_post_201(self): - """Test send get request w/ 200 response.""" - request_task = self.loop.create_task( - self.request( - "post", - "/pets", - ) - ) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=20) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - message = dialogue.reply( - target_message=incoming_message, - performative=HttpMessage.Performative.RESPONSE, - version=incoming_message.version, - status_code=201, - status_text="Created", - body=b"Response body", - ) - response_envelope = Envelope( - to=message.to, - sender=envelope.to, - context=envelope.context, - message=message, - ) - - await self.http_connection.send(response_envelope) - - response = await asyncio.wait_for( - request_task, - timeout=20, - ) - assert ( - response.status == 201 - and response.reason == "Created" - and await response.text() == "Response body" - ) - - @pytest.mark.asyncio - async def test_get_404(self): - """Test send post request w/ 404 response.""" - response = await self.request("get", "/url-non-exists") - - assert ( - response.status == 404 - and response.reason == "Request Not Found" - and await response.text() == "" - ) - - @pytest.mark.asyncio - async def test_post_404(self): - """Test send post request w/ 404 response.""" - response = await self.request("get", "/url-non-exists", data="some data") - - assert ( - response.status == 404 - and response.reason == "Request Not Found" - and await response.text() == "" - ) - - @pytest.mark.asyncio - async def test_get_408(self): - """Test send post request w/ 404 response.""" - await self.http_connection.connect() - self.http_connection.channel.timeout_window = 0.1 - with patch.object( - self.http_connection.channel.logger, "warning" - ) as mock_logger: - response = await self.request("get", "/pets") - mock_logger.assert_any_call( - RegexComparator("Request timed out! Request=.*") - ) - - assert ( - response.status == 408 - and response.reason == "Request Timeout" - and await response.text() == "" - ) - - @pytest.mark.asyncio - async def test_post_408(self): - """Test send post request w/ 404 response.""" - self.http_connection.channel.timeout_window = 0.1 - response = await self.request("post", "/pets", data="somedata") - - assert ( - response.status == 408 - and response.reason == "Request Timeout" - and await response.text() == "" - ) - - @pytest.mark.asyncio - async def test_send_connection_drop(self): - """Test unexpected response.""" - message = HttpMessage( - performative=HttpMessage.Performative.RESPONSE, - dialogue_reference=("", ""), - target=1, - message_id=2, - headers="", - version="", - status_code=200, - status_text="Success", - body=b"", - ) - message.to = str(HTTPServerConnection.connection_id) - message.sender = self.target_skill_id - envelope = Envelope( - to=message.to, - sender=message.sender, - message=message, - ) - await self.http_connection.send(envelope) - - @pytest.mark.asyncio - async def test_get_message_channel_not_connected(self): - """Test error on channel get message if not connected.""" - await self.http_connection.disconnect() - with pytest.raises(ValueError): - await self.http_connection.channel.get_message() - - @pytest.mark.asyncio - async def test_fail_connect(self): - """Test error on server connection.""" - await self.http_connection.disconnect() - - with patch.object( - self.http_connection.channel, - "_start_http_server", - side_effect=Exception("expected"), - ): - await self.http_connection.connect() - assert not self.http_connection.is_connected - - @pytest.mark.asyncio - async def test_server_error_on_send_response(self): - """Test exception raised on response sending to the client.""" - request_task = self.loop.create_task( - self.request( - "post", - "/pets", - ) - ) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=20) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - message = dialogue.reply( - target_message=incoming_message, - performative=HttpMessage.Performative.RESPONSE, - version=incoming_message.version, - headers=incoming_message.headers, - status_code=201, - status_text="Created", - body=b"Response body", - ) - response_envelope = Envelope( - to=message.to, - sender=envelope.to, - context=envelope.context, - message=message, - ) - - with patch.object(Response, "from_message", side_effect=Exception("expected")): - await self.http_connection.send(response_envelope) - response = await asyncio.wait_for( - request_task, - timeout=20, - ) - - assert response and response.status == 500 and response.reason == "Server Error" - - def teardown(self): - """Teardown the test case.""" - self.loop.run_until_complete(self.http_connection.disconnect()) - self.http_connection.channel.timeout_window = self.original_timeout - - -def test_bad_api_spec(): - """Test error on apispec file is invalid.""" - with pytest.raises(FileNotFoundError): - APISpec("not_exist_file") - - -def test_apispec_verify_if_no_validator_set(): - """Test api spec ok if no spec file provided.""" - assert APISpec().verify(Mock()) - - -@pytest.mark.asyncio -class TestHTTPSServer: - """Tests for HTTPServer connection.""" - - async def request(self, method: str, path: str, **kwargs) -> ClientResponse: - """ - Make a http request. - - :param method: HTTP method: GET, POST etc - :param path: path to request on server. full url constructed automatically - :param kwargs: keyword arguments - :return: http response - """ - try: - url = f"https://{self.host}:{self.port}{path}" - sslcontext = ssl.create_default_context(cafile=self.ssl_cert) - async with aiohttp.ClientSession() as session: - async with session.request( - method, url, **kwargs, ssl=sslcontext - ) as resp: - await resp.read() - return resp - except Exception: - print_exc() - raise - - def setup(self): - """Initialise the test case.""" - self.identity = Identity("name", address="my_key", public_key="my_public_key") - self.agent_address = self.identity.address - self.host = "localhost" - self.port = get_unused_tcp_port() - self.api_spec_path = os.path.join(DATA_DIR, "petstore_sim.yaml") - self.connection_id = HTTPServerConnection.connection_id - self.protocol_id = HttpMessage.protocol_id - self.target_skill_id = "some_author/some_skill:0.1.0" - self.ssl_cert = os.path.join(DATA_DIR, "certs", "server.crt") - self.ssl_key = os.path.join(DATA_DIR, "certs", "server.key") - self.configuration = ConnectionConfig( - host=self.host, - port=self.port, - target_skill_id=self.target_skill_id, - api_spec_path=self.api_spec_path, - connection_id=HTTPServerConnection.connection_id, - restricted_to_protocols={HttpMessage.protocol_id}, - ssl_cert=self.ssl_cert, - ssl_key=self.ssl_key, - ) - self.http_connection = HTTPServerConnection( - configuration=self.configuration, - data_dir=MagicMock(), - identity=self.identity, - ) - self.loop = asyncio.get_event_loop() - self.loop.run_until_complete(self.http_connection.connect()) - self.connection_address = str(HTTPServerConnection.connection_id) - self._dialogues = HttpDialogues(self.target_skill_id) - self.original_timeout = self.http_connection.channel.timeout_window - - @pytest.mark.asyncio - async def test_get_200(self): - """Test send get request w/ 200 response.""" - request_task = self.loop.create_task(self.request("get", "/pets")) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=20) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - message = dialogue.reply( - target_message=incoming_message, - performative=HttpMessage.Performative.RESPONSE, - version=incoming_message.version, - status_code=200, - status_text="Success", - body=b"Response body", - ) - response_envelope = Envelope( - to=envelope.sender, - sender=envelope.to, - context=envelope.context, - message=message, - ) - await self.http_connection.send(response_envelope) - - response = await asyncio.wait_for( - request_task, - timeout=20, - ) - - assert ( - response.status == 200 - and response.reason == "Success" - and await response.text() == "Response body" - ) - - def _get_message_and_dialogue( - self, envelope: Envelope - ) -> Tuple[HttpMessage, HttpDialogue]: - message = cast(HttpMessage, envelope.message) - dialogue = cast(HttpDialogue, self._dialogues.update(message)) - assert dialogue is not None - return message, dialogue diff --git a/trader_backup/vendor/valory/connections/ipfs/__init__.py b/trader_backup/vendor/valory/connections/ipfs/__init__.py deleted file mode 100644 index 54c1c92f4..000000000 --- a/trader_backup/vendor/valory/connections/ipfs/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""A connection responsible for uploading and downloading files from IPFS.""" diff --git a/trader_backup/vendor/valory/connections/ipfs/connection.py b/trader_backup/vendor/valory/connections/ipfs/connection.py deleted file mode 100644 index 03de8b56e..000000000 --- a/trader_backup/vendor/valory/connections/ipfs/connection.py +++ /dev/null @@ -1,323 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ -"""A connection responsible for uploading and downloading files from IPFS.""" -import asyncio -import os -import tempfile -from asyncio import Task -from concurrent.futures import Executor -from pathlib import Path -from shutil import rmtree -from typing import Any, Callable, Dict, Optional, cast - -import requests -from aea.configurations.base import PublicId -from aea.connections.base import Connection, ConnectionStates -from aea.mail.base import Envelope -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea_cli_ipfs.exceptions import DownloadError -from aea_cli_ipfs.ipfs_utils import IPFSTool -from ipfshttpclient.exceptions import ErrorResponse - -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.protocols.ipfs.dialogues import IpfsDialogue -from packages.valory.protocols.ipfs.dialogues import IpfsDialogues as BaseIpfsDialogues - - -PUBLIC_ID = PublicId.from_str("valory/ipfs:0.1.0") - - -class IpfsDialogues(BaseIpfsDialogues): - """A class to keep track of IPFS dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return IpfsDialogue.Role.CONNECTION - - BaseIpfsDialogues.__init__( - self, - self_address=str(kwargs.pop("connection_id")), - role_from_first_message=role_from_first_message, - **kwargs, - ) - - -class IpfsConnection(Connection): - """An async connection for sending and receiving files to IPFS.""" - - connection_id = PUBLIC_ID - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize the connection. - - :param kwargs: keyword arguments passed to component base. - """ - super().__init__(**kwargs) # pragma: no cover - ipfs_domain = self.configuration.config.get("ipfs_domain") - self.ipfs_tool: IPFSTool = IPFSTool(ipfs_domain) - self.task_to_request: Dict[asyncio.Future, Envelope] = {} - self.loop_executor: Optional[Executor] = None - self.dialogues = IpfsDialogues(connection_id=PUBLIC_ID) - self._response_envelopes: Optional[asyncio.Queue] = None - - @property - def response_envelopes(self) -> asyncio.Queue: - """Returns the response envelopes queue.""" - if self._response_envelopes is None: - raise ValueError( - "`IPFSConnection.response_envelopes` is not yet initialized. Is the connection setup?" - ) - return self._response_envelopes - - async def connect(self) -> None: - """Set up the connection.""" - self.ipfs_tool.check_ipfs_node_running() - self._response_envelopes = asyncio.Queue() - self.state = ConnectionStates.connected - - async def disconnect(self) -> None: - """Tear down the connection.""" - if self.is_disconnected: # pragma: nocover - return - - self.state = ConnectionStates.disconnecting - - for task in self.task_to_request.keys(): - if not task.cancelled(): # pragma: nocover - task.cancel() - self._response_envelopes = None - - self.state = ConnectionStates.disconnected - - async def send(self, envelope: Envelope) -> None: - """Send an envelope.""" - task = self._handle_envelope(envelope) - task.add_done_callback(self._handle_done_task) - self.task_to_request[task] = envelope - - async def receive(self, *args: Any, **kwargs: Any) -> Optional[Envelope]: - """Receive an envelope.""" - return await self.response_envelopes.get() - - def run_async( - self, func: Callable, *args: Any, timeout: Optional[float] = None - ) -> Task: - """Run a function asynchronously by using threads.""" - ipfs_operation = self.loop.run_in_executor( - self.loop_executor, - func, - *args, - ) - timely_operation = asyncio.wait_for(ipfs_operation, timeout=timeout) - task = self.loop.create_task(timely_operation) - return task - - def _handle_envelope(self, envelope: Envelope) -> Task: - """Handle incoming envelopes by dispatching background tasks.""" - message = cast(IpfsMessage, envelope.message) - performative = message.performative - handler = getattr(self, f"_handle_{performative.value}", None) - if handler is None: - err = f"Performative `{performative.value}` is not supported." - self.logger.error(err) - task = self.run_async(self._handle_error, err) - return task - dialogue = self.dialogues.update(message) - task = self.run_async(handler, message, dialogue) - return task - - def _handle_store_files( - self, message: IpfsMessage, dialogue: BaseDialogue - ) -> IpfsMessage: - """ - Handle a STORE_FILES performative. - - Uploads the provided files to ipfs. - - :param message: The ipfs request. - :returns: the hash of the uploaded files. - """ - files = message.files - if len(files) == 0: - err = "No files were present." - self.logger.error(err) - return self._handle_error(err, dialogue) - if len(files) == 1: - # a single file needs to be stored, - # we don't need to create a dir - path, data = files.popitem() - self.__create_file(path, data) - else: - # multiple files are present, which means that it's a directory - # we begin by checking that they belong to the same directory - dirs = {os.path.dirname(path) for path in files.keys()} - if len(dirs) > 1: - err = f"Received files from different dirs {dirs}. " - self.logger.error(err) - self.logger.info( - "If you want to send multiple files as a single dir, " - "make sure the their path matches to one directory only." - ) - return self._handle_error(err, dialogue) - - # "path" is the directory, it's the same for all the files - path = dirs.pop() - os.makedirs(path, exist_ok=True) - for file_path, data in files.items(): - self.__create_file(file_path, data) - try: - # note that path will be a dir if multiple files - # are being uploaded. - _, hash_, _ = self.ipfs_tool.add(path) - self.logger.debug(f"Successfully stored files with hash: {hash_}.") - except ( - ValueError, - requests.exceptions.ChunkedEncodingError, - ) as e: # pragma: no cover - err = str(e) - self.logger.error(err) - return self._handle_error(err, dialogue) - finally: - self.__remove_filepath(path) - response_message = cast( - IpfsMessage, - dialogue.reply( - performative=IpfsMessage.Performative.IPFS_HASH, - target_message=message, - ipfs_hash=hash_, - ), - ) - return response_message - - def _handle_get_files( - self, message: IpfsMessage, dialogue: BaseDialogue - ) -> IpfsMessage: - """ - Handle GET_FILES performative. - - Downloads and returns the files resulting from the ipfs hash. - - :param message: The ipfs request. - :returns: the downloaded files. - """ - response_body: Dict[str, str] = {} - ipfs_hash = message.ipfs_hash - with tempfile.TemporaryDirectory() as tmp_dir: - try: - self.ipfs_tool.download(ipfs_hash, tmp_dir) - except ( - DownloadError, - PermissionError, - ErrorResponse, - ) as e: - err = str(e) - self.logger.error(err) - return self._handle_error(err, dialogue) - - files = os.listdir(tmp_dir) - if len(files) > 1: - self.logger.warning( - f"Multiple files or dirs found in {tmp_dir}. " - f"The first will be used. " - ) - downloaded_file = files.pop() - files_to_be_read = [downloaded_file] - base_dir = Path(tmp_dir) - if os.path.isdir(base_dir / downloaded_file): - base_dir = base_dir / downloaded_file - files_to_be_read = os.listdir(base_dir) - - for file_path in files_to_be_read: - with open(base_dir / file_path, encoding="utf-8", mode="r") as file: - response_body[file_path] = file.read() - - response_message = cast( - IpfsMessage, - dialogue.reply( - performative=IpfsMessage.Performative.FILES, - files=response_body, - target_message=message, - ), - ) - return response_message - - def _handle_error( # pylint: disable=no-self-use - self, reason: str, dialogue: BaseDialogue - ) -> IpfsMessage: - """Handler for error messages.""" - message = cast( - IpfsMessage, - dialogue.reply( - performative=IpfsMessage.Performative.ERROR, - reason=reason, - ), - ) - return message - - def _handle_done_task(self, task: asyncio.Future) -> None: - """ - Process a done receiving task. - - :param task: the done task. - """ - request = self.task_to_request.pop(task) - response_message: Optional[Message] = task.result() - - response_envelope = None - if response_message is not None: - response_envelope = Envelope( - to=request.sender, - sender=request.to, - message=response_message, - context=request.context, - ) - - # not handling `asyncio.QueueFull` exception, because the maxsize we defined for the Queue is infinite - self.response_envelopes.put_nowait(response_envelope) - - @staticmethod - def __create_file(path: str, data: str) -> None: - """Creates a file in the specified path.""" - with open(path, "w", encoding="utf-8") as f: - f.write(data) - - def __remove_filepath(self, filepath: str) -> None: - """Remove a file or a folder. If filepath is not a file or a folder, an `IPFSInteractionError` is raised.""" - if os.path.isfile(filepath): - os.remove(filepath) - elif os.path.isdir(filepath): - rmtree(filepath) - else: # pragma: no cover - self.logger.error(f"`{filepath}` is not an existing filepath!") diff --git a/trader_backup/vendor/valory/connections/ipfs/connection.yaml b/trader_backup/vendor/valory/connections/ipfs/connection.yaml deleted file mode 100644 index c29abbec8..000000000 --- a/trader_backup/vendor/valory/connections/ipfs/connection.yaml +++ /dev/null @@ -1,31 +0,0 @@ -name: ipfs -author: valory -version: 0.1.0 -type: connection -description: A connection responsible for uploading and downloading files from IPFS. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeiercvjoct4tygo4oif5y4chnst2y7b6mhdgdj3zvoeakstbn4m7g4 - connection.py: bafybeifnjyjqmhlxenw7m4rfnjw2b6mwaevdl3hrcalefptd2tpm5lrbcy - readme.md: bafybeihdrtloo2stz7frhfhtl5m7ewwigdeehnujf6julwj6c5pzr7iefu - tests/__init__.py: bafybeicqjmce5v5ympy2rcryfh644rxrtujvbcuzk7ylmfmzynoh6wujx4 - tests/test_connection.py: bafybeiedbdf5aumheq6cvtyeneoewmm5zslesvtqqx2ix3w2qqmfo3x26q -fingerprint_ignore_patterns: [] -connections: [] -protocols: -- valory/ipfs:0.1.0:bafybeiftxi2qhreewgsc5wevogi7yc5g6hbcbo4uiuaibauhv3nhfcdtvm -class_name: IpfsConnection -config: - ipfs_domain: null -excluded_protocols: [] -restricted_to_protocols: [] -dependencies: - ipfshttpclient: - version: ==0.8.0a2 - open-aea-cli-ipfs: - version: ==1.53.0 - requests: - version: <2.31.2,>=2.28.1 -is_abstract: false -cert_requests: [] diff --git a/trader_backup/vendor/valory/connections/ipfs/readme.md b/trader_backup/vendor/valory/connections/ipfs/readme.md deleted file mode 100644 index 20788e676..000000000 --- a/trader_backup/vendor/valory/connections/ipfs/readme.md +++ /dev/null @@ -1,2 +0,0 @@ -# IPFS Connection -A connection responsible for uploading and downloading files from IPFS. \ No newline at end of file diff --git a/trader_backup/vendor/valory/connections/ipfs/tests/__init__.py b/trader_backup/vendor/valory/connections/ipfs/tests/__init__.py deleted file mode 100644 index ccb977283..000000000 --- a/trader_backup/vendor/valory/connections/ipfs/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for ipfs connection.""" diff --git a/trader_backup/vendor/valory/connections/ipfs/tests/test_connection.py b/trader_backup/vendor/valory/connections/ipfs/tests/test_connection.py deleted file mode 100644 index 34be5c404..000000000 --- a/trader_backup/vendor/valory/connections/ipfs/tests/test_connection.py +++ /dev/null @@ -1,282 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ -# pylint: disable=protected-access,attribute-defined-outside-init - -"""Tests for ipfs connection.""" -import asyncio -import os -import platform -import tempfile -from typing import Dict, List, Optional -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from aea.configurations.base import ConnectionConfig -from aea.connections.base import ConnectionStates -from aea.mail.base import Envelope -from aea_cli_ipfs.exceptions import DownloadError -from aea_cli_ipfs.ipfs_utils import IPFSTool -from aea_test_autonomy.fixture_helpers import ( # noqa: F401; pylint: disable=unused-import - LOCAL_IPFS, - ipfs_daemon, - use_ipfs_daemon, -) - -from packages.valory.connections.ipfs.connection import ( - IpfsConnection, - IpfsDialogues, - PUBLIC_ID, -) -from packages.valory.protocols.ipfs import IpfsMessage - - -ANY_SKILL = "skill/any:0.1.0" - - -@use_ipfs_daemon -class TestIpfsConnection: - """Tests for IpfsConnection""" - - def setup(self) -> None: - """Set up the tests.""" - configuration = ConnectionConfig( - ipfs_domain=LOCAL_IPFS, - connection_id=IpfsConnection.connection_id, - ) - self.connection = IpfsConnection( - configuration=configuration, - data_dir=MagicMock(), - ) - self.dummy_msg = IpfsMessage(performative=IpfsMessage.Performative.GET_FILES) # type: ignore - self.dummy_envelope = Envelope( - to=str(PUBLIC_ID), sender=ANY_SKILL, message=self.dummy_msg - ) - - @pytest.mark.asyncio - async def test_connect(self) -> None: - """Test connect""" - await self.connection.connect() - assert self.connection.response_envelopes is not None - assert self.connection.state == ConnectionStates.connected - - @pytest.mark.asyncio - async def test_disconnect(self) -> None: - """Test disconnect""" - await self.connection.connect() - await self.connection.disconnect() - assert self.connection.state == ConnectionStates.disconnected - with pytest.raises(ValueError): - self.connection.response_envelopes # pylint: disable=pointless-statement - - @pytest.mark.parametrize( - ("performative", "expected_error"), - [ - (IpfsMessage.Performative.GET_FILES, False), - (IpfsMessage.Performative.STORE_FILES, False), - (IpfsMessage.Performative.IPFS_HASH, True), - (IpfsMessage.Performative.FILES, True), - ], - ) - def test_handle_envelope( - self, - performative: IpfsMessage.Performative, - expected_error: bool, - ) -> None: - """Tests for _handle_envelope.""" - dummy_msg = IpfsMessage(performative=performative) - envelope = Envelope(to=str(PUBLIC_ID), sender=ANY_SKILL, message=dummy_msg) - with mock.patch.object( - IpfsConnection, - "run_async", - return_value=MagicMock(), - ), mock.patch.object( - self.connection.logger, - "error", - ) as mock_logger: - self.connection._handle_envelope(envelope) - if expected_error: - mock_logger.assert_called_with( - f"Performative `{performative.value}` is not supported." - ) - - @pytest.mark.asyncio - async def test_send(self) -> None: - """Test send.""" - await self.connection.connect() - with mock.patch.object( - IpfsConnection, - "_handle_envelope", - return_value=MagicMock(add_done_callback=lambda *_: _), - ): - assert len(self.connection.task_to_request) == 0 - await self.connection.send(self.dummy_envelope) - assert len(self.connection.task_to_request) == 1 - - @pytest.mark.asyncio - async def test_receive(self) -> None: - """Tests receive.""" - await self.connection.connect() - expected_envelope = self.dummy_envelope - self.connection.response_envelopes.put_nowait(expected_envelope) - actual_envelope = await self.connection.receive() - - assert expected_envelope == actual_envelope - - @pytest.mark.asyncio - async def test_handle_done_task(self) -> None: - """Test _handle_done_tasks.""" - await self.connection.connect() - assert self.connection.response_envelopes.qsize() == 0 - dummy_task = MagicMock(result=lambda: self.dummy_msg) - dummy_request = MagicMock(to=ANY_SKILL, sender=str(PUBLIC_ID), context=None) - self.connection.task_to_request[dummy_task] = dummy_request - self.connection._handle_done_task(dummy_task) - assert self.connection.response_envelopes.qsize() == 1 - - def test_handle_error(self) -> None: - """Test handle_error.""" - message = self.connection._handle_error( - reason="dummy reason", - dialogue=MagicMock(), - ) - assert message is not None - - @pytest.mark.asyncio - async def test_run_async(self) -> None: - """Test run async.""" - dummy_log = "dummy operation is being performed" - - def dummy_operation() -> None: - """A dummy handler.""" - self.connection.logger.info(dummy_log) - - await self.connection.connect() - with mock.patch.object( - self.connection.logger, - "info", - ) as mock_logger: - task = self.connection.run_async(dummy_operation) - assert task is not None - - # give some time for the task to be scheduled and run - await asyncio.sleep(1) - mock_logger.assert_called_with(dummy_log) - - @pytest.mark.parametrize( - ("files", "expected_log", "log_level"), - [ - ({}, "No files were present.", "error"), - ( - {"dummy_filename": "dummy_content"}, - "Successfully stored files with hash: QmYn1qHyFMDdVxYcwseLBdooLAyc3orNBH8vvj4iPTXd4R.", - "debug", - ), - ( - { - "dummy_dir/dummy_filename1": "dummy_content", - "dummy_dir/dummy_filename2": "dummy_content", - }, - "Successfully stored files with hash: QmRP7wK1NZKwno9CFxQUeFaJip5eaaLBo1v8WFtyECgLCz.", - "debug", - ), - ( - { - "dummy_dir/dummy_dir_nested/dummy_filename1": "dummy_content", - "dummy_dir/dummy_dir_nested/dummy_filename2": "dummy_content", - }, - "Successfully stored files with hash: QmcYhNziJDuwmRVg8TYY5S5fUycuBguM6zxukgMDnVQt8H.", - "debug", - ), - ( - { - "dummy_dir1/dummy_filename1": "dummy_content", - "dummy_dir2/dummy_filename2": "dummy_content", - }, - "If you want to send multiple files as a single dir, " - "make sure the their path matches to one directory only.", - "info", - ), - ], - ) - def test_handle_store_files( - self, files: Dict[str, str], expected_log: str, log_level: str - ) -> None: - """Test _handle_store_files.""" - with mock.patch.object( - self.connection.logger, - log_level, - ) as mock_logger: - message = IpfsMessage( - performative=IpfsMessage.Performative.STORE_FILES, files=files # type: ignore - ) - dialogue = MagicMock() - message = self.connection._handle_store_files(message, dialogue) - assert message is not None - mock_logger.assert_called_with(expected_log) - - @pytest.mark.skipif( - platform.system() == "Windows", - reason="PermissionError: [Errno 13] Permission denied", - ) - @pytest.mark.parametrize( - ("extra_files", "download_side_effect", "is_dir"), - [ - ([], None, False), - (["dummy_unexpected_extra_file"], None, False), - ([], DownloadError, False), - ([], None, True), - ], - ) - def test_handle_get_files( - self, - extra_files: List[str], - download_side_effect: Optional[Exception], - is_dir: bool, - ) -> None: - """Test _handle_get_files""" - with tempfile.NamedTemporaryFile() as tmp_file, mock.patch.object( - os, - "listdir", - ) as mock_listdir, mock.patch.object( - IPFSTool, "download", side_effect=download_side_effect - ): - listdir_value = [extra_files + [tmp_file.name]] - if is_dir: - listdir_value = [["/tmp"]] + listdir_value # nosec - mock_listdir.side_effect = listdir_value - - tmp_file.write(b"dummy_data") - tmp_file.flush() - - _, ipfs_hash, _ = self.connection.ipfs_tool.add(tmp_file.name) - message = IpfsMessage( - performative=IpfsMessage.Performative.GET_FILES, ipfs_hash=ipfs_hash # type: ignore - ) - dialogue = MagicMock() - message = self.connection._handle_get_files(message, dialogue) - assert message is not None - - def test_ipfs_dialogue(self) -> None: # pylint: disable=no-self-use - """Test 'IpfsDialogues' creation.""" - dialogues = IpfsDialogues(connection_id=str(PUBLIC_ID)) - dialogues.create( - counterparty=ANY_SKILL, - performative=IpfsMessage.Performative.GET_FILES, - ) diff --git a/trader_backup/vendor/valory/connections/ledger/README.md b/trader_backup/vendor/valory/connections/ledger/README.md deleted file mode 100644 index fe01aea2b..000000000 --- a/trader_backup/vendor/valory/connections/ledger/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Ledger connection - -The ledger connection wraps the APIs needed to interact with multiple ledgers, including smart contracts deployed on those ledgers. - -The AEA communicates with the ledger connection via the `valory/ledger_api:1.0.0` and `valory/contract_api:1.0.0` protocols. - -The connection uses the ledger APIs registered in the ledger API registry. - -## Usage - -First, add the connection to your AEA project (`aea add connection valory/ledger:0.19.0`). Optionally, update the `ledger_apis` in `config` of `connection.yaml`. diff --git a/trader_backup/vendor/valory/connections/ledger/__init__.py b/trader_backup/vendor/valory/connections/ledger/__init__.py deleted file mode 100644 index ae0f10868..000000000 --- a/trader_backup/vendor/valory/connections/ledger/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Scaffold of a connection.""" diff --git a/trader_backup/vendor/valory/connections/ledger/base.py b/trader_backup/vendor/valory/connections/ledger/base.py deleted file mode 100644 index e5537187c..000000000 --- a/trader_backup/vendor/valory/connections/ledger/base.py +++ /dev/null @@ -1,217 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2023 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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 base classes for the ledger API connection.""" -import asyncio -import inspect -from abc import ABC, abstractmethod -from asyncio import Task -from concurrent.futures._base import Executor -from logging import Logger -from typing import Any, Callable, Dict, Optional, Union - -from aea.crypto.base import LedgerApi -from aea.crypto.registries import Registry, ledger_apis_registry -from aea.exceptions import enforce -from aea.helpers.async_utils import AsyncState -from aea.mail.base import Envelope -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, Dialogues - - -class RequestDispatcher(ABC): - """Base class for a request dispatcher.""" - - def __init__( # pylint: disable=too-many-arguments - self, - logger: Logger, - connection_state: AsyncState, - retry_attempts: int = 120, - retry_timeout: int = 3, - loop: Optional[asyncio.AbstractEventLoop] = None, - executor: Optional[Executor] = None, - api_configs: Optional[Dict[str, Dict[str, str]]] = None, - ): - """ - Initialize the request dispatcher. - - :param retry_attempts: the retry attempts for any api used. - :param retry_timeout: the retry timeout of any api used. - :param logger: the logger. - :param connection_state: connection state. - :param loop: the asyncio loop. - :param executor: an executor. - :param api_configs: api configs. - """ - self.connection_state = connection_state - self.loop = loop if loop is not None else asyncio.get_event_loop() - self.executor = executor - self._api_configs = api_configs - self.logger = logger - self.retry_attempts = retry_attempts - self.retry_timeout = retry_timeout - - def api_config(self, ledger_id: str) -> Dict[str, str]: - """Get api config.""" - config = {} # type: Dict[str, str] - if self._api_configs is not None and ledger_id in self._api_configs: - config = self._api_configs[ledger_id] - return config - - async def run_async( - self, - func: Callable[[Any], Task], - api: LedgerApi, - message: Message, - dialogue: Dialogue, - ) -> Union[Message, Task]: - """ - Run a function in executor. - - :param func: the function to execute. - :param api: the ledger api. - :param message: a Ledger API message. - :param dialogue: a Ledger API dialogue. - :return: the return value of the function. - """ - try: - if inspect.iscoroutinefunction(func): - # If it is a coroutine, no need to run it in an executor - # This can happen if the handler is async. - task = func(api, message, dialogue) # type: ignore - else: - task = self.loop.run_in_executor( # type: ignore - self.executor, func, api, message, dialogue - ) - response = await task - return response - except Exception as exception: # pylint: disable=broad-except - return self.get_error_message(exception, api, message, dialogue) - - async def wait_for( - self, func: Callable, *args: Any, timeout: Optional[float] = None - ) -> Any: - """ - Runs a non-coroutine callable async while enforcing a timeout. - - Warning: This function can be used with non-coroutine callables ONLY! - If you want the same functionality with coroutine callables, use asyncio.wait_for(). - - :param func: the callable (function) to run. - :param args: the function params. - :param timeout: for how long to run the function before cancelling it and raising TimeoutError. - :return: the return value of "func" if it finishes in "timeout", raises a TimeoutError otherwise. - """ - enforce( - not inspect.iscoroutinefunction(func), - 'A coroutine was passed to "RequestDispatcher.wait_for()", ' - '"RequestDispatcher.wait_for()" only works with non-coroutine callables. ' - 'Hint: Look at "asyncio.wait_for()". ', - ) - - # we run the passed function using the default executor - running_func = self.loop.run_in_executor(self.executor, func, *args) - - # func_result will carry the value the function returns - func_result = await asyncio.wait_for(running_func, timeout=timeout) - return func_result - - def set_extra_kwargs( # pylint: disable=no-self-use, unused-argument - 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. - - :param envelope: the envelope. - :return: an awaitable. - """ - if not isinstance(envelope.message, Message): # pragma: nocover - raise ValueError("Ledger connection expects non-serialized messages.") - message = envelope.message - ledger_id = self.get_ledger_id(message) - 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 - f"No dialogue created. Message={message} not valid." - ) - performative = message.performative - handler = self.get_handler(performative) - return self.loop.create_task(self.run_async(handler, api, message, dialogue)) - - def get_handler(self, performative: Any) -> Callable[[Any], Task]: - """ - Get the handler method, given the message performative. - - :param performative: the message performative. - :return: the method that will send the request. - """ - handler = getattr(self, performative.value, None) - if handler is None: - raise Exception("Performative not recognized.") # pragma: nocover - return handler - - @abstractmethod - def get_error_message( - self, - exception: Exception, - api: LedgerApi, - message: Message, - dialogue: Dialogue, - ) -> Message: - """ - Build an error message. - - :param exception: the exception - :param api: the ledger api - :param message: the received message. - :param dialogue: the dialogue. - :return: an error message response. - """ - - @property - @abstractmethod - def dialogues(self) -> Dialogues: - """Get the dialogues.""" - - @property - def ledger_api_registry(self) -> Registry: - """Get the registry.""" - return ledger_apis_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/trader_backup/vendor/valory/connections/ledger/connection.py b/trader_backup/vendor/valory/connections/ledger/connection.py deleted file mode 100644 index 4221b59cb..000000000 --- a/trader_backup/vendor/valory/connections/ledger/connection.py +++ /dev/null @@ -1,193 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2023 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Scaffold connection and channel.""" - -import asyncio -from typing import Any, Dict, Optional - -from aea.configurations.base import PublicId -from aea.connections.base import Connection, ConnectionStates -from aea.mail.base import Envelope -from aea.protocols.base import Message - -from packages.valory.connections.ledger.base import RequestDispatcher -from packages.valory.connections.ledger.contract_dispatcher import ( - ContractApiRequestDispatcher, -) -from packages.valory.connections.ledger.ledger_dispatcher import ( - LedgerApiRequestDispatcher, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.ledger_api import LedgerApiMessage - - -PUBLIC_ID = PublicId.from_str("valory/ledger:0.19.0") - - -class LedgerConnection(Connection): - """Proxy to the functionality of the SDK or API.""" - - connection_id = PUBLIC_ID - TIMEOUT = 3 - MAX_ATTEMPTS = 120 - - def __init__(self, **kwargs: Any): - """Initialize a connection to interact with a ledger APIs.""" - super().__init__(**kwargs) - - self._ledger_dispatcher: Optional[LedgerApiRequestDispatcher] = None - self._contract_dispatcher: Optional[ContractApiRequestDispatcher] = None - self._response_envelopes: Optional[asyncio.Queue] = None - - self.task_to_request: Dict[asyncio.Future, Envelope] = {} - self.api_configs = self.configuration.config.get( - "ledger_apis", {} - ) # type: Dict[str, Dict[str, str]] - self.request_retry_attempts = self.configuration.config.get( - "retry_attempts", self.MAX_ATTEMPTS - ) - self.request_retry_timeout = self.configuration.config.get( - "retry_timeout", self.TIMEOUT - ) - - @property - def response_envelopes(self) -> asyncio.Queue: - """Get the response envelopes. Only intended to be accessed when connected.""" - if self._response_envelopes is None: - raise ValueError( - "`asyncio.Queue` for `_response_envelopes` not set. Is the ledger connection active?" - ) - return self._response_envelopes - - async def connect(self) -> None: - """Set up the connection.""" - - if self.is_connected: # pragma: nocover - return - - self.state = ConnectionStates.connecting - - self._ledger_dispatcher = LedgerApiRequestDispatcher( - self._state, - loop=self.loop, - api_configs=self.api_configs, - logger=self.logger, - retry_attempts=self.request_retry_attempts, - retry_timeout=self.request_retry_timeout, - connection_id=self.connection_id, - ) - self._contract_dispatcher = ContractApiRequestDispatcher( - self._state, - loop=self.loop, - api_configs=self.api_configs, - logger=self.logger, - retry_attempts=self.request_retry_attempts, - retry_timeout=self.request_retry_timeout, - connection_id=self.connection_id, - ) - - self._response_envelopes = asyncio.Queue() - self.state = ConnectionStates.connected - - async def disconnect(self) -> None: - """Tear down the connection.""" - if self.is_disconnected: # pragma: nocover - return - - self.state = ConnectionStates.disconnecting - - for task in self.task_to_request.keys(): - if not task.cancelled(): # pragma: nocover - task.cancel() - self._ledger_dispatcher = None - self._contract_dispatcher = None - self._response_envelopes = None - - self.state = ConnectionStates.disconnected - - async def send(self, envelope: "Envelope") -> None: - """ - Send an envelope. - - :param envelope: the envelope to send. - """ - task = self._schedule_request(envelope) - task.add_done_callback(self._handle_done_task) - self.task_to_request[task] = envelope - - def _schedule_request(self, envelope: Envelope) -> asyncio.Task: - """ - Schedule a ledger API request. - - :param envelope: the message. - :return: task - """ - dispatcher: RequestDispatcher - if ( - envelope.protocol_specification_id - == LedgerApiMessage.protocol_specification_id - ): - if self._ledger_dispatcher is None: # pragma: nocover - raise ValueError("No ledger dispatcher set.") - dispatcher = self._ledger_dispatcher - elif ( - envelope.protocol_specification_id - == ContractApiMessage.protocol_specification_id - ): - if self._contract_dispatcher is None: # pragma: nocover - raise ValueError("No contract dispatcher set.") - dispatcher = self._contract_dispatcher - else: - raise ValueError("Protocol not supported") - - task = dispatcher.dispatch(envelope) - return task - - async def receive(self, *args: Any, **kwargs: Any) -> Optional["Envelope"]: - """ - Receive an envelope. Blocking. - - :param args: the arguments - :param kwargs: the keyword arguments - :return: the envelope received, or None. - """ - return await self.response_envelopes.get() - - def _handle_done_task(self, task: asyncio.Future) -> None: - """ - Process a done receiving task. - - :param task: the done task. - """ - request = self.task_to_request.pop(task) - response_message: Optional[Message] = task.result() - - response_envelope = None - if response_message is not None: - response_envelope = Envelope( - to=request.sender, - sender=request.to, - message=response_message, - context=request.context, - ) - - # not handling `asyncio.QueueFull` exception, because the maxsize we defined for the Queue is infinite - self.response_envelopes.put_nowait(response_envelope) diff --git a/trader_backup/vendor/valory/connections/ledger/connection.yaml b/trader_backup/vendor/valory/connections/ledger/connection.yaml deleted file mode 100644 index 4c7b71d91..000000000 --- a/trader_backup/vendor/valory/connections/ledger/connection.yaml +++ /dev/null @@ -1,115 +0,0 @@ -name: ledger -author: valory -version: 0.19.0 -type: connection -description: A connection to interact with any ledger API and contract API. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeihkgodu7o7v6pfazm7u6orlspsfrae3cyz36yc46x67phfmw3l57e - __init__.py: bafybeia3purd7y4b7tkdt2fcaxkdazos32criq5hx6fhufaislrdefe674 - base.py: bafybeifuoq2oqlcjlgeg2fg5l2ijiylb23v65xghv7u422helief2cjjuy - connection.py: bafybeicydkymhz2feqmihtkiwdfg7pp4pww2elqv4tijuhjcplyvawdk74 - contract_dispatcher.py: bafybeidf2wu3rsp5pm45qwjlievbpmueeaj6hjw3kdyn67xhbocylwg3d4 - ledger_dispatcher.py: bafybeicartiu3mcavtyd3eveonrbak3uaowqzymtaza6gqtoi5msid75ci - tests/__init__.py: bafybeifku7ttsmbj4gfx6dkgjvwypx7v5ysfqlzof6vh4p7gujakjtuwhe - tests/conftest.py: bafybeid7vo7e2m76ey5beeadtbxywxx5ukefd5slwbc362rwmhht6i45ou - tests/test_contract_dispatcher.py: bafybeiag5lnpc7h25w23ash4hk4cowxsy5buxgpr474l3tfewnhf56eqyq - tests/test_ledger.py: bafybeigcedfr3yv3jse3xwrerrgwbelgb56uhgrvdus527d3daekh6dx4m - tests/test_ledger_api.py: bafybeifw5smawex5m2fm6rt4kmunc22kpabalmshh45qb3xnuap33sfgyi -fingerprint_ignore_patterns: [] -connections: [] -protocols: -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -class_name: LedgerConnection -config: - ledger_apis: - ethereum: - address: http://127.0.0.1:8545 - chain_id: 1337 - default_gas_price_strategy: eip1559 - gas_price_strategies: &id001 - gas_station: - gas_price_api_key: null - gas_price_strategy: fast - eip1559: - max_gas_fast: 1500 - fee_history_blocks: 10 - fee_history_percentile: 5 - priority_fee_estimation_trigger: 100 - default_priority_fee: 3 - fallback_estimate: - maxFeePerGas: 20000000000 - maxPriorityFeePerGas: 3000000000 - baseFee: null - priority_fee_increase_boundary: 200 - is_gas_estimation_enabled: true - poa_chain: false - ethereum_flashbots: - 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 - authentication_private_key: null - flashbots_builders: [] - solana: - 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 - 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 - celo: - address: http://127.0.0.1:8545 - chain_id: 42220 - default_gas_price_strategy: eip1559 - gas_price_strategies: *id001 - is_gas_estimation_enabled: true - poa_chain: true - retry_attempts: 240 - retry_timeout: 3 -excluded_protocols: [] -restricted_to_protocols: -- valory/contract_api:1.0.0 -- valory/ledger_api:1.0.0 -dependencies: - pytest-asyncio: {} -is_abstract: false diff --git a/trader_backup/vendor/valory/connections/ledger/contract_dispatcher.py b/trader_backup/vendor/valory/connections/ledger/contract_dispatcher.py deleted file mode 100644 index dfcb42507..000000000 --- a/trader_backup/vendor/valory/connections/ledger/contract_dispatcher.py +++ /dev/null @@ -1,451 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2023 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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 the implementation of the contract API request dispatcher.""" -import inspect -import logging -from collections.abc import Mapping -from typing import Any, Callable, Optional, Union, cast - -from aea.common import JSONLike -from aea.contracts import Contract, contract_registry -from aea.contracts.base import snake_to_camel -from aea.crypto.base import LedgerApi -from aea.crypto.registries import Registry -from aea.exceptions import AEAException, parse_exception -from aea.helpers.transaction.base import RawMessage, RawTransaction, State -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import Dialogues as BaseDialogues - -from packages.valory.connections.ledger.base import RequestDispatcher -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.contract_api.dialogues import ContractApiDialogue -from packages.valory.protocols.contract_api.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) - - -_default_logger = logging.getLogger( - "aea.packages.valory.connections.ledger.contract_dispatcher" -) - - -class ContractApiDialogues(BaseContractApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - # The ledger connection maintains the dialogue on behalf of the ledger - return ContractApiDialogue.Role.LEDGER - - BaseContractApiDialogues.__init__( - self, - self_address=str(kwargs.pop("connection_id")), - role_from_first_message=role_from_first_message, - **kwargs, - ) - - -class ContractApiRequestDispatcher(RequestDispatcher): - """Implement the contract API request dispatcher.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the dispatcher.""" - logger = kwargs.pop("logger", None) - connection_id = kwargs.pop("connection_id") - logger = logger if logger is not None else _default_logger - super().__init__(logger, *args, **kwargs) - self._contract_api_dialogues = ContractApiDialogues(connection_id=connection_id) - - @property - def dialogues(self) -> BaseDialogues: - """Get the dialogues.""" - return self._contract_api_dialogues - - @property - def contract_registry(self) -> Registry[Contract]: - """Get the contract registry.""" - return contract_registry - - def get_ledger_id(self, message: Message) -> str: - """Get the ledger id.""" - if not isinstance(message, ContractApiMessage): # pragma: nocover - raise ValueError("argument is not a ContractApiMessage instance.") - message = cast(ContractApiMessage, message) - return message.ledger_id - - def get_error_message( - self, - exception: Exception, - api: LedgerApi, - message: Message, - dialogue: BaseDialogue, - ) -> ContractApiMessage: - """ - Build an error message. - - :param exception: the exception. - :param api: the Ledger API. - :param message: the request message. - :param dialogue: the Contract API dialogue. - :return: an error message response. - """ - response = cast( - ContractApiMessage, - dialogue.reply( - performative=ContractApiMessage.Performative.ERROR, - target_message=message, - code=500, - message=parse_exception(exception), - data=b"", - ), - ) - return response - - def dispatch_request( - self, - ledger_api: LedgerApi, - message: ContractApiMessage, - dialogue: ContractApiDialogue, - response_builder: Callable[ - [Union[bytes, JSONLike], ContractApiDialogue], ContractApiMessage - ], - ) -> ContractApiMessage: - """ - Dispatch a request to a user-defined contract method. - - :param ledger_api: the ledger apis. - :param message: the contract API request message. - :param dialogue: the contract API dialogue. - :param response_builder: callable that from bytes builds a contract API message. - :return: the response message. - """ - contract = self.contract_registry.make(message.contract_id) - try: - data = self._get_data(ledger_api, message, contract) - response = response_builder(data, dialogue) - except AEAException as exception: - self.logger.debug( - f"Whilst processing the contract api request:\n{message}\nthe following exception occured:\n{str(exception)}" - ) - response = self.get_error_message(exception, ledger_api, message, dialogue) - except ( - Exception # pylint: disable=broad-except # pragma: nocover - ) as exception: - self.logger.debug( - f"Whilst processing the contract api request:\n{message}\nthe following error occured:\n{parse_exception(exception)}" - ) - response = self.get_error_message(exception, ledger_api, message, dialogue) - return response - - def get_state( - self, - ledger_api: LedgerApi, - message: ContractApiMessage, - dialogue: ContractApiDialogue, - ) -> ContractApiMessage: - """ - Send the request 'get_state'. - - :param ledger_api: the API object. - :param message: the Ledger API message - :param dialogue: the contract API dialogue - :return: None - """ - - def build_response( - data: Union[bytes, JSONLike], dialogue: ContractApiDialogue - ) -> ContractApiMessage: - if not isinstance(data, Mapping): - raise ValueError( # pragma: nocover - f"Invalid state type, got={type(data)}, expected={JSONLike}." - ) - return cast( - ContractApiMessage, - dialogue.reply( - performative=ContractApiMessage.Performative.STATE, - state=State(message.ledger_id, data), - ), - ) - - return self.dispatch_request(ledger_api, message, dialogue, build_response) - - def get_deploy_transaction( - self, - ledger_api: LedgerApi, - message: ContractApiMessage, - dialogue: ContractApiDialogue, - ) -> ContractApiMessage: - """ - Send the request 'get_raw_transaction'. - - :param ledger_api: the API object. - :param message: the Ledger API message - :param dialogue: the contract API dialogue - :return: None - """ - - def build_response( - transaction: Union[bytes, JSONLike], dialogue: ContractApiDialogue - ) -> ContractApiMessage: - if not isinstance(transaction, Mapping): - raise ValueError( # pragma: nocover - f"Invalid transaction type, got={type(transaction)}, expected={JSONLike}." - ) - return cast( - ContractApiMessage, - dialogue.reply( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=RawTransaction(message.ledger_id, transaction), - ), - ) - - return self.dispatch_request(ledger_api, message, dialogue, build_response) - - def get_raw_transaction( - self, - ledger_api: LedgerApi, - message: ContractApiMessage, - dialogue: ContractApiDialogue, - ) -> ContractApiMessage: - """ - Send the request 'get_raw_transaction'. - - :param ledger_api: the API object. - :param message: the Ledger API message - :param dialogue: the contract API dialogue - :return: None - """ - - def build_response( - transaction: Union[bytes, JSONLike], dialogue: ContractApiDialogue - ) -> ContractApiMessage: - if isinstance(transaction, bytes): - raise ValueError( # pragma: nocover - f"Invalid transaction type, got={type(transaction)}, expected={JSONLike}." - ) - return cast( - ContractApiMessage, - dialogue.reply( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=RawTransaction(message.ledger_id, transaction), - ), - ) - - return self.dispatch_request(ledger_api, message, dialogue, build_response) - - def get_raw_message( - self, - ledger_api: LedgerApi, - message: ContractApiMessage, - dialogue: ContractApiDialogue, - ) -> ContractApiMessage: - """ - Send the request 'get_raw_message'. - - :param ledger_api: the ledger API object. - :param message: the Ledger API message - :param dialogue: the contract API dialogue - :return: None - """ - - def build_response( - raw_message: Union[bytes, JSONLike], dialogue: ContractApiDialogue - ) -> ContractApiMessage: - if not isinstance(raw_message, bytes): - raise ValueError( # pragma: nocover - f"Invalid message type, got={type(raw_message)}, expected=bytes." - ) - return cast( - ContractApiMessage, - dialogue.reply( - performative=ContractApiMessage.Performative.RAW_MESSAGE, - raw_message=RawMessage(message.ledger_id, raw_message), - ), - ) - - return self.dispatch_request(ledger_api, message, dialogue, build_response) - - def _get_data( - self, - api: LedgerApi, - message: ContractApiMessage, - contract: Contract, - ) -> Union[bytes, JSONLike]: - """Get the data from the contract method, either from the stub or from the callable specified by the message.""" - # first, check if the custom handler for this type of request has been implemented. - data = self._call_stub(api, message, contract) - if data is not None: - return data - - # then, check if there is the handler for the provided callable. - data = self._validate_and_call_callable(api, message, contract) - return data - - @staticmethod - def _call_stub( - ledger_api: LedgerApi, message: ContractApiMessage, contract: Contract - ) -> Optional[Union[bytes, JSONLike]]: - """Try to call stub methods associated to the contract API request performative.""" - try: - method: Callable = getattr(contract, message.performative.value) - if message.performative in [ - ContractApiMessage.Performative.GET_STATE, - ContractApiMessage.Performative.GET_RAW_MESSAGE, - ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ]: - args, kwargs = ( - [ledger_api, message.contract_address], - message.kwargs.body, - ) - elif message.performative in [ # pragma: nocover - ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - ]: - args, kwargs = [ledger_api], message.kwargs.body - else: # pragma: nocover - raise AEAException(f"Unexpected performative: {message.performative}") - data = method(*args, **kwargs) - return data - except (AttributeError, NotImplementedError): - return None - - @staticmethod - def _validate_and_call_callable( - api: LedgerApi, message: ContractApiMessage, contract: Contract - ) -> Union[bytes, JSONLike]: - """ - Validate a Contract callable, given the performative. - - In particular: - - if the performative is either 'get_state' or 'get_raw_transaction', the signature - must accept ledger api as first argument and contract address as second argument, - plus keyword arguments. - - if the performative is either 'get_deploy_transaction' or 'get_raw_message', the signature - must accept ledger api as first argument, plus keyword arguments. - - :param api: the ledger api object. - :param message: the contract api request. - :param contract: the contract instance. - :return: the data generated by the method. - """ - method_to_call: Optional[Callable] = None - try: - method_to_call = getattr(contract, message.callable) - except AttributeError: - _default_logger.info( - f"Contract method {message.callable} not found in the contract package {contract.contract_id}. Checking in the ABI..." - ) - - # Check for the method in the ABI - if not method_to_call: - try: - contract_instance = contract.get_instance(api, message.contract_address) - contract_instance.get_function_by_name(message.callable) - except ValueError: - raise AEAException( - f"Contract method {message.callable} not found in ABI of contract {type(contract)}" - ) - - default_method_call = contract.default_method_call - return default_method_call( # type: ignore - api, - message.contract_address, - snake_to_camel(message.callable), - **message.kwargs.body, - ) - - full_args_spec = inspect.getfullargspec(method_to_call) - if message.performative in [ - ContractApiMessage.Performative.GET_STATE, - ContractApiMessage.Performative.GET_RAW_MESSAGE, - ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ]: - if len(full_args_spec.args) < 2: # pragma: nocover - raise AEAException( - f"Expected two or more positional arguments, got {len(full_args_spec.args)}" - ) - for arg in ["ledger_api", "contract_address"]: # pragma: nocover - if arg not in full_args_spec.args: - raise AEAException( - f"Missing required argument `{arg}` in {method_to_call}" - ) - return method_to_call(api, message.contract_address, **message.kwargs.body) - if message.performative in [ - ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - ]: - if len(full_args_spec.args) < 1: # pragma: nocover - raise AEAException( - f"Expected one or more positional arguments, got {len(full_args_spec.args)}" - ) - if "ledger_api" not in full_args_spec.args: # pragma: nocover - raise AEAException( - f"Missing required argument `ledger_api` in {method_to_call}" - ) - return method_to_call(api, **message.kwargs.body) - 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 = cast(str, kwargs.pop("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 - """ - 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": cast(dict, self._api_configs).copy()} - ) diff --git a/trader_backup/vendor/valory/connections/ledger/ledger_dispatcher.py b/trader_backup/vendor/valory/connections/ledger/ledger_dispatcher.py deleted file mode 100644 index de927acf7..000000000 --- a/trader_backup/vendor/valory/connections/ledger/ledger_dispatcher.py +++ /dev/null @@ -1,474 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2023 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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 the implementation of the ledger API request dispatcher.""" -import asyncio -import logging -from typing import Any, cast - -from aea.common import JSONLike -from aea.connections.base import ConnectionStates -from aea.crypto.base import LedgerApi -from aea.helpers.transaction.base import RawTransaction, State, TransactionDigest -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import Dialogues as BaseDialogues - -from packages.valory.connections.ledger.base import RequestDispatcher -from packages.valory.protocols.ledger_api.custom_types import ( - TransactionDigests, - TransactionReceipt, -) -from packages.valory.protocols.ledger_api.dialogues import LedgerApiDialogue -from packages.valory.protocols.ledger_api.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.protocols.ledger_api.message import LedgerApiMessage - - -_default_logger = logging.getLogger( - "aea.packages.valory.connections.ledger.ledger_dispatcher" -) - - -class LedgerApiDialogues(BaseLedgerApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - # The ledger connection maintains the dialogue on behalf of the ledger - return LedgerApiDialogue.Role.LEDGER - - BaseLedgerApiDialogues.__init__( - self, - self_address=str(kwargs.pop("connection_id")), - role_from_first_message=role_from_first_message, - **kwargs, - ) - - -class LedgerApiRequestDispatcher(RequestDispatcher): - """Implement ledger API request dispatcher.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the dispatcher.""" - logger = kwargs.pop("logger", None) - connection_id = kwargs.pop("connection_id") - logger = logger if logger is not None else _default_logger - super().__init__(logger, *args, **kwargs) - self._ledger_api_dialogues = LedgerApiDialogues(connection_id=connection_id) - - def get_ledger_id(self, message: Message) -> str: - """Get the ledger id from message.""" - if not isinstance(message, LedgerApiMessage): # pragma: nocover - raise ValueError("argument is not a LedgerApiMessage instance.") - message = cast(LedgerApiMessage, message) - if message.performative is LedgerApiMessage.Performative.GET_RAW_TRANSACTION: - ledger_id = message.terms.ledger_id - elif ( - message.performative - is LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION - ): - ledger_id = message.signed_transaction.ledger_id - elif ( - message.performative - is LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS - ): - ledger_id = message.signed_transactions.ledger_id - elif ( - message.performative - is LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT - ): - ledger_id = message.transaction_digest.ledger_id - else: - ledger_id = message.ledger_id - return ledger_id - - @property - def dialogues(self) -> BaseDialogues: - """Get the dialogues.""" - return self._ledger_api_dialogues - - def get_balance( - self, - api: LedgerApi, - message: LedgerApiMessage, - dialogue: LedgerApiDialogue, - ) -> LedgerApiMessage: - """ - Send the request 'get_balance'. - - :param api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - try: - balance = api.get_balance(message.address, raise_on_try=True) - except Exception as e: # pylint: disable=broad-except # pragma: nocover - return self.get_error_message(e, api, message, dialogue) - - if balance is None: - response = self.get_error_message( - ValueError("No balance returned"), api, message, dialogue - ) - else: - response = cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.BALANCE, - target_message=message, - balance=balance, - ledger_id=message.ledger_id, - ), - ) - return response - - def get_state( - self, - api: LedgerApi, - message: LedgerApiMessage, - dialogue: LedgerApiDialogue, - ) -> LedgerApiMessage: - """ - Send the request 'get_state'. - - :param api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - try: - result = api.get_state( - message.callable, - *message.args, - raise_on_try=True, - **message.kwargs.body, - ) - except Exception as e: # pylint: disable=broad-except # pragma: nocover - return self.get_error_message(e, api, message, dialogue) - - if result is None: # pragma: nocover - response = self.get_error_message( - ValueError("Failed to get state"), api, message, dialogue - ) - else: - response = cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.STATE, - target_message=message, - state=State(message.ledger_id, result), - ledger_id=message.ledger_id, - ), - ) - return response - - def get_raw_transaction( - self, - api: LedgerApi, - message: LedgerApiMessage, - dialogue: LedgerApiDialogue, - ) -> LedgerApiMessage: - """ - Send the request 'get_raw_transaction'. - - :param api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - try: - raw_transaction = api.get_transfer_transaction( - sender_address=message.terms.sender_address, - destination_address=message.terms.counterparty_address, - amount=message.terms.sender_payable_amount, - tx_fee=message.terms.fee, - tx_nonce=message.terms.nonce, - raise_on_try=True, - **message.terms.kwargs, - ) - except Exception as e: # pylint: disable=broad-except # pragma: nocover - return self.get_error_message(e, api, message, dialogue) - - if raw_transaction is None: - response = self.get_error_message( - ValueError("No raw transaction returned"), api, message, dialogue - ) - else: - response = cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.RAW_TRANSACTION, - target_message=message, - raw_transaction=RawTransaction( - message.terms.ledger_id, raw_transaction - ), - ), - ) - return response - - async def get_transaction_receipt( - self, - api: LedgerApi, - message: LedgerApiMessage, - dialogue: LedgerApiDialogue, - ) -> LedgerApiMessage: - """ - Send the request 'get_transaction_receipt'. - - NOTE: Under no circumstance can async methods block! - All possible methods that can block here, should be run async. - - :param api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - retry_attempts = ( - self.retry_attempts - if message.retry_attempts is None - else message.retry_attempts - ) - retry_timeout = ( - self.retry_timeout - if message.retry_timeout is None - else message.retry_timeout - ) - - transaction_receipt = None - is_settled = False - attempts = 0 - while ( - not is_settled - and attempts < retry_attempts - and self.connection_state.get() == ConnectionStates.connected - ): - try: - transaction_receipt = await self.wait_for( - lambda: api.get_transaction_receipt( - message.transaction_digest.body, - raise_on_try=True, - ), - timeout=retry_timeout, - ) - except Exception as e: # pylint: disable=broad-except - self.logger.warning(e) - transaction_receipt = None - - if transaction_receipt is not None: - is_settled = api.is_transaction_settled(transaction_receipt) - attempts += 1 - await asyncio.sleep(retry_timeout * attempts) - self.logger.debug( - f"Transaction receipt: {transaction_receipt}, settled: {is_settled}" - ) - - attempts = 0 - transaction = None - while ( - transaction is None - and attempts < retry_attempts - and self.connection_state.get() == ConnectionStates.connected - ): - try: - transaction = await self.wait_for( - lambda: api.get_transaction( - message.transaction_digest.body, - raise_on_try=True, - ), - timeout=retry_timeout, - ) - except Exception as e: # pylint: disable=broad-except - self.logger.warning(e) - transaction = None - - attempts += 1 - await asyncio.sleep(retry_timeout * attempts) - self.logger.debug(f"Transaction: {transaction}") - - if not is_settled: - response = self.get_error_message( - ValueError("Transaction not settled within timeout"), - api, - message, - dialogue, - ) - elif transaction_receipt is None: # pragma: nocover - response = self.get_error_message( - ValueError("No transaction_receipt returned"), api, message, dialogue - ) - elif transaction is None: - response = self.get_error_message( - ValueError("No transaction returned"), api, message, dialogue - ) - else: - response = cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - target_message=message, - transaction_receipt=TransactionReceipt( - message.transaction_digest.ledger_id, - transaction_receipt, - transaction, - ), - ), - ) - return response - - def send_signed_transactions( - self, - api: LedgerApi, - message: LedgerApiMessage, - dialogue: LedgerApiDialogue, - ) -> LedgerApiMessage: - """ - Send the request 'send_signed_transactions'. - - :param api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - try: - signed_transactions = message.signed_transactions.signed_transactions - transaction_digests = api.send_signed_transactions( - signed_transactions, - raise_on_try=True, - **message.kwargs.body, - ) - except Exception as e: # pylint: disable=broad-except # pragma: nocover - return self.get_error_message(e, api, message, dialogue) - - if transaction_digests is None: # pragma: nocover - return self.get_error_message( - ValueError("No transaction_digest returned"), api, message, dialogue - ) - - ledger_id = self.get_ledger_id(message) - return cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGESTS, - target_message=message, - transaction_digests=TransactionDigests(ledger_id, transaction_digests), - ), - ) - - def send_signed_transaction( - self, - api: LedgerApi, - message: LedgerApiMessage, - dialogue: LedgerApiDialogue, - ) -> LedgerApiMessage: - """ - Send the request 'send_signed_tx'. - - :param api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - try: - transaction_digest = api.send_signed_transaction( - message.signed_transaction.body, - raise_on_try=True, - ) - except Exception as e: # pylint: disable=broad-except # pragma: nocover - return self.get_error_message(e, api, message, dialogue) - - if transaction_digest is None: # pragma: nocover - return self.get_error_message( - ValueError("No transaction_digest returned"), api, message, dialogue - ) - - return cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, - target_message=message, - transaction_digest=TransactionDigest( - message.signed_transaction.ledger_id, transaction_digest - ), - ), - ) - - def get_error_message( - self, - exception: Exception, - api: LedgerApi, - message: Message, - dialogue: BaseDialogue, - ) -> LedgerApiMessage: - """ - Build an error message. - - :param exception: the exception. - :param api: the Ledger API. - :param message: the request message. - :param dialogue: the Ledger API dialogue. - :return: an error message response. - """ - message = cast(LedgerApiMessage, message) - dialogue = cast(LedgerApiDialogue, dialogue) - response = cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.ERROR, - target_message=message, - code=500, - message=str(exception), - data=b"", - ), - ) - 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 - """ - if not isinstance(message, LedgerApiMessage): # pragma: nocover - raise ValueError("argument is not a LedgerApiMessage instance.") - message = cast(LedgerApiMessage, message) - kwargs = {} - if message.is_set("kwargs"): - # check if kwargs is set - kwargs = cast(JSONLike, message.kwargs.body) - # if the chain id is specified in the message, use it. - # otherwise, use the ledger id. - chain_id = cast(str, kwargs.pop("chain_id", self.get_ledger_id(message))) - return chain_id diff --git a/trader_backup/vendor/valory/connections/ledger/tests/__init__.py b/trader_backup/vendor/valory/connections/ledger/tests/__init__.py deleted file mode 100644 index 346bbd406..000000000 --- a/trader_backup/vendor/valory/connections/ledger/tests/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2023 Valory AG -# Copyright 2018-2020 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/ledger connection.""" diff --git a/trader_backup/vendor/valory/connections/ledger/tests/conftest.py b/trader_backup/vendor/valory/connections/ledger/tests/conftest.py deleted file mode 100644 index 8f7e518ec..000000000 --- a/trader_backup/vendor/valory/connections/ledger/tests/conftest.py +++ /dev/null @@ -1,148 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test confiugurations for the package.""" -# pylint: skip-file - -import logging -from pathlib import Path -from typing import Any, AsyncGenerator, Dict, Generator, cast -from unittest.mock import MagicMock - -import pytest -import pytest_asyncio -from aea_ledger_ethereum import EthereumCrypto -from aea_ledger_ethereum.test_tools.constants import ( - ETHEREUM_TESTNET_CONFIG as _DEFAULT_ETHEREUM_TESTNET_CONFIG, -) -from aea_ledger_ethereum.test_tools.fixture_helpers import ( - DEFAULT_GANACHE_ADDR, - DEFAULT_GANACHE_PORT, -) - -from aea.configurations.base import ComponentType, ContractConfig -from aea.configurations.constants import DEFAULT_LEDGER -from aea.configurations.loader import load_component_configuration -from aea.connections.base import Connection -from aea.contracts.base import Contract, contract_registry -from aea.crypto.ledger_apis import DEFAULT_LEDGER_CONFIGS, LedgerApi -from aea.crypto.registries import ledger_apis_registry, make_crypto -from aea.crypto.wallet import CryptoStore -from aea.identity.base import Identity - - -PACKAGE_DIR = Path(__file__).parent.parent - -DEFAULT_ETHEREUM_TESTNET_CONFIG = { - **_DEFAULT_ETHEREUM_TESTNET_CONFIG, - "default_gas_price_strategy": "eip1559", -} - - -def get_register_contract(directory: Path) -> Contract: - """Get and register the erc1155 contract package.""" - configuration = load_component_configuration(ComponentType.CONTRACT, directory) - configuration._directory = directory # pylint: disable=protected-access - configuration = cast(ContractConfig, configuration) - - if str(configuration.public_id) not in contract_registry.specs: - # load contract into sys modules - Contract.from_config(configuration) - - contract = contract_registry.make(str(configuration.public_id)) - return contract - - -@pytest.fixture() -def ganache_addr() -> str: - """Get the ganache addr""" - return DEFAULT_GANACHE_ADDR - - -@pytest.fixture() -def ganache_port() -> int: - """Get the ganache port""" - return DEFAULT_GANACHE_PORT - - -@pytest.fixture(scope="function") -def ethereum_testnet_config(ganache_addr: str, ganache_port: int) -> Dict: - """Get Ethereum ledger api configurations using Ganache.""" - new_uri = f"{ganache_addr}:{ganache_port}" - new_config = DEFAULT_ETHEREUM_TESTNET_CONFIG.copy() - new_config["address"] = new_uri - return new_config - - -@pytest.fixture(scope="function") -def update_default_ethereum_ledger_api(ethereum_testnet_config: Dict) -> Generator: - """Change temporarily default Ethereum ledger api configurations to interact with local Ganache.""" - old_config = DEFAULT_LEDGER_CONFIGS.pop(EthereumCrypto.identifier) - DEFAULT_LEDGER_CONFIGS[EthereumCrypto.identifier] = ethereum_testnet_config - yield - DEFAULT_LEDGER_CONFIGS.pop(EthereumCrypto.identifier) - DEFAULT_LEDGER_CONFIGS[EthereumCrypto.identifier] = old_config - - -def make_ledger_api_connection( - ethereum_testnet_config: Dict = DEFAULT_ETHEREUM_TESTNET_CONFIG, -) -> Connection: - """Make a connection.""" - crypto = make_crypto(DEFAULT_LEDGER) - identity = Identity("name", crypto.address, crypto.public_key) - crypto_store = CryptoStore() - directory = PACKAGE_DIR - connection = Connection.from_dir( - str(directory), - data_dir=MagicMock(), - identity=identity, - crypto_store=crypto_store, - ) - connection = cast(Connection, connection) - connection._logger = logging.getLogger("packages.valory.connections.ledger") - - # use testnet config - connection.configuration.config.get("ledger_apis", {})[ - "ethereum" - ] = ethereum_testnet_config - - connection.request_retry_attempts = 1 # type: ignore - connection.request_retry_attempts = 2 # type: ignore - return connection - - -@pytest_asyncio.fixture() -async def ledger_apis_connection( - request: Any, ethereum_testnet_config: Dict -) -> AsyncGenerator: - """Make a connection.""" - connection = make_ledger_api_connection(ethereum_testnet_config) - await connection.connect() - yield connection - await connection.disconnect() - - -@pytest.fixture() -def ledger_api( - ethereum_testnet_config: Dict, -) -> Generator[LedgerApi, None, None]: - """Ledger api fixture.""" - ledger_id, config = EthereumCrypto.identifier, ethereum_testnet_config - api = ledger_apis_registry.make(ledger_id, **config) - yield api diff --git a/trader_backup/vendor/valory/connections/ledger/tests/test_contract_dispatcher.py b/trader_backup/vendor/valory/connections/ledger/tests/test_contract_dispatcher.py deleted file mode 100644 index c5549b73f..000000000 --- a/trader_backup/vendor/valory/connections/ledger/tests/test_contract_dispatcher.py +++ /dev/null @@ -1,281 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the tests of the ledger connection module.""" - -from unittest import mock -from unittest.mock import ANY, MagicMock, Mock, patch - -import pytest -from aea_ledger_ethereum import EthereumCrypto - -from aea.common import Address -from aea.crypto.ledger_apis import ETHEREUM_DEFAULT_ADDRESS -from aea.crypto.registries import ledger_apis_registry -from aea.exceptions import AEAException -from aea.helpers.async_utils import AsyncState -from aea.multiplexer import MultiplexerStatus -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue - -from packages.valory.connections.ledger.contract_dispatcher import ( - ContractApiRequestDispatcher, -) - -# pylint: skip-file -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.contract_api.dialogues import ContractApiDialogue -from packages.valory.protocols.contract_api.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) - - -SOME_SKILL_ID = "some/skill:0.1.0" -NON_BLOCKING_TIME = 1 -BLOCKING_TIME = 100 -TOLERANCE = 1 -WAIT_TIME_AMONG_TASKS = 0.1 - - -class ContractApiDialogues(BaseContractApiDialogues): - """This class keeps track of all contract_api dialogues.""" - - def __init__(self, self_address: str) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> Dialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return ContractApiDialogue.Role.AGENT - - BaseContractApiDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - ) - - -def test_validate_and_call_callable() -> None: - """Tests a default method call through ContractApiRequestDispatcher.""" - - dummy_address = "0x0000000000000000000000000000000000000000" - contract_dispatcher = ContractApiRequestDispatcher( - connection_id=Mock(), connection_state=AsyncState() - ) - contract = Mock() - - def getAddress(ledger_api=None, contract_address=None, _addr=None): # type: ignore - return 0 - - contract.getAddress = getAddress - contract.dummy_method = None - contract_instance = Mock() - contract.get_instance.return_value = contract_instance - - ledger_api = ledger_apis_registry.make( - EthereumCrypto.identifier, - address=ETHEREUM_DEFAULT_ADDRESS, - ) - - message = MagicMock() - message.performative = ContractApiMessage.Performative.GET_STATE - message.kwargs.body = {"_addr": dummy_address} - - message.contract_address = dummy_address - - message.callable = "some" - contract.some = None - contract.default_method_call = lambda x, y, z, _addr: 12 - contract.get_state = Mock(side_effect=AttributeError()) - with patch.object( - contract_dispatcher.contract_registry, "make", return_value=contract - ): - assert ( - contract_dispatcher.dispatch_request( - dialogue=Mock(), - ledger_api=ledger_api, - message=message, - response_builder=lambda x, y: 12, # type: ignore - ) - == 12 - ) - - contract.some = Mock(side_effect=AEAException("expected")) - dialogue = Mock() - dialogue.reply = Mock(return_value=1234) - with patch.object( - contract_dispatcher.contract_registry, "make", return_value=contract - ): - assert ( - contract_dispatcher.dispatch_request( - dialogue=dialogue, - ledger_api=ledger_api, - message=message, - response_builder=lambda x, y: 12, # type: ignore - ) - == 1234 - ) - dialogue.reply.assert_called_once_with( - performative=ContractApiMessage.Performative.ERROR, - target_message=ANY, - code=500, - message=ANY, - data=ANY, - ) - - message.callable = "getAddress" - # Call a method present in the ABI but not in the contract package - with mock.patch("web3.contract.contract.ContractFunction.call", return_value=0): - result = ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, contract - ) - assert result == 0 - - # Call an non-existent method - message.callable = "dummy_method" - contract_instance.get_function_by_name = Mock(side_effect=ValueError()) - with pytest.raises( - AEAException, - match=f"Contract method dummy_method not found in ABI of contract {type(contract)}", - ): - ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, contract - ) - - message.performative = None - message.callable = "getAddress" - with pytest.raises(AEAException, match="Unexpected performative:"): - ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, contract - ) - - message.callable = "some_fn" - message.performative = ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION - contract.some_fn = lambda x: None - with pytest.raises(AEAException, match="Missing required argument `ledger_api`"): - ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, contract - ) - - contract.some_fn = lambda: None - with pytest.raises( - AEAException, match="Expected one or more positional arguments, got 0" - ): - ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, contract - ) - - contract.some_fn = lambda ledger_api, _addr: None - ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, contract - ) - - with pytest.raises( - AttributeError, - ): - ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, None # type: ignore - ) - - -def test_build_response_fails_on_bad_data_type() -> None: - """Test internal build_response functions for data type check.""" - dispatcher = ContractApiRequestDispatcher(MagicMock(), connection_id="test_id") - with patch.object( - dispatcher, - "dispatch_request", - lambda x, x1, x2, fn: fn(data=b"some_data", dialogue=MagicMock()), - ), pytest.raises( - ValueError, match=r"Invalid state type, got=, expected=typing.Dict" - ): - dispatcher.get_state(MagicMock(), MagicMock(), MagicMock()) - - with patch.object( - dispatcher, - "dispatch_request", - lambda x, x1, x2, fn: fn(raw_message=12, dialogue=MagicMock()), - ), pytest.raises(ValueError, match=r"Invalid message type"): - dispatcher.get_raw_message(MagicMock(), MagicMock(), MagicMock()) - - with patch.object( - dispatcher, - "dispatch_request", - lambda x, x1, x2, fn: fn(transaction=b"some_data", dialogue=MagicMock()), - ): - with pytest.raises( - ValueError, - match=r"Invalid transaction type, got=, expected=typing.Dict", - ): - dispatcher.get_deploy_transaction(MagicMock(), MagicMock(), MagicMock()) - with pytest.raises( - ValueError, - match=r"Invalid transaction type, got=, expected=typing.Dict", - ): - dispatcher.get_raw_transaction(MagicMock(), MagicMock(), MagicMock()) - - -@pytest.mark.asyncio -async def test_run_async() -> None: - """Test run async error handled.""" - - # for pydocstyle - def _raise(): # type: ignore - raise Exception("Expected") - - contract_api_dialogues = ContractApiDialogues(SOME_SKILL_ID) - request, dialogue = contract_api_dialogues.create( - counterparty="str(ledger_apis_connection.connection_id)", - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ledger_id=EthereumCrypto.identifier, - contract_id=str(SOME_SKILL_ID), - contract_address="test addr", - callable="get_create_batch_transaction", - kwargs=ContractApiMessage.Kwargs( - { - "deployer_address": "test_addr", - "token_ids": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - } - ), - ) - api = None - msg = await ContractApiRequestDispatcher( - MultiplexerStatus(), connection_id="test_id" - ).run_async( - _raise, api, request, dialogue # type: ignore - ) - assert msg.performative == ContractApiMessage.Performative.ERROR # type: ignore - - -@pytest.mark.asyncio -async def test_get_handler() -> None: - """Test failed to get handler.""" - with pytest.raises(Exception, match="Performative not recognized."): - ContractApiRequestDispatcher( - MultiplexerStatus(), connection_id="test_id" - ).get_handler(ContractApiMessage.Performative.ERROR) diff --git a/trader_backup/vendor/valory/connections/ledger/tests/test_ledger.py b/trader_backup/vendor/valory/connections/ledger/tests/test_ledger.py deleted file mode 100644 index ddfd8e75c..000000000 --- a/trader_backup/vendor/valory/connections/ledger/tests/test_ledger.py +++ /dev/null @@ -1,623 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the tests of the ledger connection module.""" - -import asyncio -import logging -import time -from asyncio import Task -from threading import Thread -from typing import Any, Callable, Dict, FrozenSet, Tuple, Type, cast -from unittest import mock - -import pytest -from aea_ledger_ethereum import EthereumCrypto - -from aea.common import Address -from aea.configurations.base import ConnectionConfig -from aea.connections.base import ConnectionStates -from aea.crypto.base import LedgerApi -from aea.exceptions import AEAEnforceError -from aea.helpers.async_utils import AsyncState -from aea.mail.base import Envelope -from aea.multiplexer import Multiplexer -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.connections.ledger.base import RequestDispatcher -from packages.valory.connections.ledger.connection import LedgerConnection, PUBLIC_ID -from packages.valory.connections.ledger.ledger_dispatcher import ( - LedgerApiRequestDispatcher, -) -from packages.valory.connections.ledger.tests.conftest import make_ledger_api_connection - -# pylint: skip-file -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.protocols.ledger_api.custom_types import Kwargs - - -SOME_SKILL_ID = "some/skill:0.1.0" -NON_BLOCKING_TIME = 1 -BLOCKING_TIME = 100 -TOLERANCE = 1 -WAIT_TIME_AMONG_TASKS = 0.1 - - -def dummy_task_wrapper(waiting_time: float, result_message: LedgerApiMessage) -> Task: - """Create a dummy task that simply waits for a given `waiting_time` and returns a given `result_message`.""" - - async def dummy_task(*_: Any) -> LedgerApiMessage: - """Wait for the given `waiting_time` and return the given `result_message`.""" - await asyncio.sleep(waiting_time) - return result_message - - task = asyncio.create_task(dummy_task()) - return task - - -class TestLedgerConnection: - """Test `LedgerConnection` class.""" - - @pytest.mark.asyncio - async def test_not_hanging(self) -> None: - """Test that the connection does not hang and that the tasks cannot get blocked.""" - # create configurations for the test, re bocking and non-blocking tasks' waiting times - assert ( - NON_BLOCKING_TIME + TOLERANCE + WAIT_TIME_AMONG_TASKS < BLOCKING_TIME - ), "`NON_BLOCKING_TIME + TOLERANCE + WAIT_TIME_AMONG_TASKS` should be less than the `BLOCKING_TIME`." - - # setup a dummy ledger connection - ledger_connection = LedgerConnection( - configuration=ConnectionConfig("ledger", "valory", "0.19.0"), - data_dir="test_data_dir", - ) - - # connect() is called by the multiplexer - await ledger_connection.connect() - - # once a connection is ready, `receive()` is called by the multiplexer - receive_task = asyncio.ensure_future(ledger_connection.receive()) - - # create a blocking task lasting `BLOCKING_TIME` secs - blocking_task = dummy_task_wrapper( - BLOCKING_TIME, - LedgerApiMessage( - LedgerApiMessage.Performative.ERROR, - _body={"data": b"blocking_task"}, # type: ignore - ), - ) - blocking_dummy_envelope = Envelope( - to="test_blocking_to", - sender="test_blocking_sender", - message=LedgerApiMessage( - LedgerApiMessage.Performative.ERROR - ), # type: ignore - ) - with mock.patch.object( - LedgerConnection, "_schedule_request", return_value=blocking_task - ): - await ledger_connection.send(blocking_dummy_envelope) - - # create a non-blocking task lasting `NON_BLOCKING_TIME` secs, after `WAIT_TIME_AMONG_TASKS` - await asyncio.sleep(WAIT_TIME_AMONG_TASKS) - normal_task = dummy_task_wrapper( - NON_BLOCKING_TIME, - LedgerApiMessage( - LedgerApiMessage.Performative.ERROR, _body={"data": b"normal_task"} - ), # type: ignore - ) - normal_dummy_envelope = Envelope( - to="test_normal_to", - sender="test_normal_sender", - message=LedgerApiMessage( - LedgerApiMessage.Performative.ERROR - ), # type: ignore - ) - with mock.patch.object( - LedgerConnection, "_schedule_request", return_value=normal_task - ): - await ledger_connection.send(normal_dummy_envelope) - - # sleep for `NON_BLOCKING_TIME + TOLERANCE` - await asyncio.sleep(NON_BLOCKING_TIME + TOLERANCE) - - # the normal task should be finished - assert normal_task.done(), "Normal task should be done at this point." - - # the `receive_task` should be done, and not await for the `blocking_task` - assert receive_task.done(), "Receive task is blocked by blocking task!" - - # the blocking task should not be done - assert not blocking_task.done(), "Blocking task should be still running." - # cancel remaining task before ending test - blocking_task.cancel() - - -class TestRequestDispatcher: - """Test `RequestDispatcher` class.""" - - dispatcher: RequestDispatcher - loop: asyncio.AbstractEventLoop - - def setup(self) -> None: - """Setup test vars.""" - logger = logging.getLogger(type(self).__class__.__name__) - state = AsyncState(ConnectionStates.connected) - self.loop = asyncio.get_event_loop() - self.dispatcher = DummyRequestDispatcher( - logger=logger, connection_state=state, loop=self.loop - ) - - def dummy_func(self, sleep: float) -> bool: - """A dummy function that sleeps and returns True.""" - time.sleep(sleep) - return True - - async def dummy_async_func(self, sleep: float) -> bool: - """A dummy async function that sleeps and returns True.""" - await asyncio.sleep(sleep) - return True - - @pytest.mark.asyncio - async def test_wait_for_happy_path(self) -> None: - """Tests that wait_for works when timeout is bigger than execution time of callable.""" - should_finish_in = 0.5 - tolerance = 0.5 - timeout = should_finish_in + tolerance - - return_value = await self.dispatcher.wait_for( - lambda: self.dummy_func(should_finish_in), timeout=timeout - ) - assert return_value, "dummy_func() should've returned True" - - @pytest.mark.asyncio - async def test_wait_for_raise_excp(self) -> None: - """Tests that wait_for works when timeout is less than execution time of callable.""" - timeout = 0.25 - timeout_increase = 0.5 - should_finish_in = timeout + timeout_increase - - with pytest.raises(asyncio.TimeoutError): - await self.dispatcher.wait_for( - lambda: self.dummy_func(should_finish_in), timeout=timeout - ) - - @pytest.mark.asyncio - async def test_wait_for_coroutine(self) -> None: - """Tests that an error is thrown when a coroutine is passed.""" - should_finish_in = 0.0 # this value is irrelevant to the result of the test - with pytest.raises(AEAEnforceError): - await self.dispatcher.wait_for(self.dummy_async_func, should_finish_in) - - -class DummyLedgerApiMessage(LedgerApiMessage): - """Implement a dummy `LedgerApiMessage`, which contains performatives for the normal and blocking tasks.""" - - class Performative(Message.Performative): - """Performatives for the ledger_api protocol.""" - - NORMAL = "normal" - BLOCKING = "blocking" - GET_NORMAL = "get_normal" - GET_BLOCKING = "get_blocking" - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """Initialise an instance of `DummyLedgerApiMessage`.""" - Message.__init__( - self, - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=DummyLedgerApiMessage.Performative(performative), - **kwargs, - ) - - def _is_consistent(self) -> bool: - """Dummy consistency checks.""" - return True - - -class DummyLedgerApiDialogue(Dialogue): - """Implement a dummy `LedgerApiDialogue`.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - DummyLedgerApiMessage.Performative.GET_NORMAL, - DummyLedgerApiMessage.Performative.GET_BLOCKING, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - DummyLedgerApiMessage.Performative.NORMAL, - DummyLedgerApiMessage.Performative.BLOCKING, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - DummyLedgerApiMessage.Performative.GET_NORMAL: frozenset( - {DummyLedgerApiMessage.Performative.NORMAL} - ), - DummyLedgerApiMessage.Performative.GET_BLOCKING: frozenset( - {DummyLedgerApiMessage.Performative.BLOCKING} - ), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a ledger_api dialogue.""" - - AGENT = "agent" - - class EndState(Dialogue.EndState): - """This class defines the end states of a ledger_api dialogue.""" - - SUCCESSFUL = 0 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[DummyLedgerApiMessage] = DummyLedgerApiMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class DummyLedgerApiDialogues(Dialogues): - """Implement a dummy `LedgerApiDialogues`.""" - - END_STATES = frozenset({DummyLedgerApiDialogue.EndState.SUCCESSFUL}) - - def __init__(self, self_address: Address, **kwargs: Any) -> None: - """Initialize dialogues.""" - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> Dialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message""" - return DummyLedgerApiDialogue.Role.AGENT - - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - role_from_first_message=role_from_first_message, - message_class=DummyLedgerApiMessage, - dialogue_class=DummyLedgerApiDialogue, - ) - - -class DummyRequestDispatcher(RequestDispatcher): - """Implement a dummy request dispatcher.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the dispatcher.""" - super().__init__(*args, **kwargs) - self.block = True - self._ledger_api_dialogues = DummyLedgerApiDialogues( - LedgerConnection.connection_id.__str__() - ) - - @staticmethod - def get_normal( - _api: LedgerApi, - message: DummyLedgerApiMessage, - dialogue: DummyLedgerApiDialogue, - ) -> DummyLedgerApiMessage: - """ - Send the request 'get_normal'. - - :param _api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - time.sleep(NON_BLOCKING_TIME) - - return cast( - DummyLedgerApiMessage, - dialogue.reply( - performative=DummyLedgerApiMessage.Performative.NORMAL, # type: ignore - target_message=message, - data=b"normal_task", - ledger_id=message.ledger_id, - ), - ) - - def get_blocking( - self, - _api: LedgerApi, - message: DummyLedgerApiMessage, - dialogue: DummyLedgerApiDialogue, - ) -> DummyLedgerApiMessage: - """ - Send the request 'get_blocking'. - - :param _api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - while self.block: - time.sleep(0.05) - - return cast( - DummyLedgerApiMessage, - dialogue.reply( - performative=DummyLedgerApiMessage.Performative.BLOCKING, # type: ignore - target_message=message, - data=b"blocking_task", - ledger_id=message.ledger_id, - ), - ) - - @property - def dialogues(self) -> Dialogues: - """Dummy dialogues property.""" - return self._ledger_api_dialogues - - def get_error_message( - self, exception: Exception, api: LedgerApi, message: Message, dialogue: Dialogue - ) -> Message: - """Dummy `get_error_message`.""" - return cast( - DummyLedgerApiMessage, - dialogue.reply( - performative=DummyLedgerApiMessage.Performative.ERROR, # type: ignore - target_message=message, - data=f"{exception}".encode("utf-8"), - ledger_id=cast(DummyLedgerApiMessage, message).ledger_id, - ), - ) - - def get_ledger_id(self, message: Message) -> str: - """Dummy `get_ledger_id`.""" - if not isinstance(message, DummyLedgerApiMessage): # pragma: nocover - raise ValueError("argument is not a `DummyLedgerApiMessage` instance.") - return message.ledger_id - - def get_chain_id(self, message: Message) -> str: - """Extract the chain id from the message.""" - return self.get_ledger_id(message=message) - - -class LedgerConnectionWithDummyDispatcher(LedgerConnection): - """An extended `LedgerConnection` which utilizes the `DummyDispatcher`.""" - - async def connect(self) -> None: - """Set up the connection.""" - if self.is_connected: # pragma: nocover - return - - self.state = ConnectionStates.connecting - - self._ledger_dispatcher = DummyRequestDispatcher( # type: ignore - logger=self.logger, - connection_state=self._state, - loop=self.loop, - api_configs=self.api_configs, - retry_attempts=self.request_retry_attempts, - retry_timeout=self.request_retry_timeout, - ) - - self._response_envelopes = asyncio.Queue() - self.state = ConnectionStates.connected - - -class TestLedgerConnectionWithMultiplexer: - """Test `LedgerConnection` class, using the multiplexer.""" - - running_loop: asyncio.AbstractEventLoop - thread_loop: Thread - multiplexer: Multiplexer - ledger_connection: LedgerConnectionWithDummyDispatcher - make_ledger_connection_callable: Callable = make_ledger_api_connection - ledger_api_dialogues: DummyLedgerApiDialogues - - @classmethod - def setup_class(cls) -> None: - """Setup the test class.""" - # set up a multiplexer with the required ledger connection - cls.running_loop = asyncio.new_event_loop() - cls.thread_loop = Thread(target=cls.running_loop.run_forever) - cls.thread_loop.start() - cls.multiplexer = Multiplexer( - [ - LedgerConnectionWithDummyDispatcher( - configuration=ConnectionConfig("ledger", "valory", "0.19.0"), - data_dir="test_data_dir", - ) - ], - loop=cls.running_loop, - ) - cls.multiplexer.connect() - # the ledger connection's connect() is called by the multiplexer - # once a connection is ready, `receive()` is called by the multiplexer - cls.ledger_connection = cast( - LedgerConnectionWithDummyDispatcher, cls.multiplexer.connections[0] - ) - assert cls.ledger_connection._ledger_dispatcher is not None - cls.ledger_api_dialogues = cast( - DummyLedgerApiDialogues, - cls.ledger_connection._ledger_dispatcher._ledger_api_dialogues, - ) - - @classmethod - def teardown_class(cls) -> None: - """Tear down the multiplexer.""" - cls.ledger_connection._ledger_dispatcher.block = False # type: ignore - if cls.multiplexer.is_connected: - cls.multiplexer.disconnect() - cls.running_loop.call_soon_threadsafe(cls.running_loop.stop) - cls.thread_loop.join() - - def create_ledger_dialogues( - self, blocking: bool = True - ) -> Tuple[DummyLedgerApiMessage, DummyLedgerApiDialogues]: - """Create a dialogue.""" - if blocking: - performative = DummyLedgerApiMessage.Performative.GET_BLOCKING - _callable = "get_blocking" - else: - performative = DummyLedgerApiMessage.Performative.GET_NORMAL - _callable = "get_normal" - - return cast( - Tuple[DummyLedgerApiMessage, DummyLedgerApiDialogues], - self.ledger_api_dialogues.create( - counterparty=str(self.ledger_connection.connection_id), - performative=performative, # type: ignore - ledger_id=EthereumCrypto.identifier, - callable=_callable, - args=(), - kwargs=Kwargs({}), - ), - ) - - @staticmethod - def create_envelope(request: DummyLedgerApiMessage) -> Envelope: - """Create a dummy envelope.""" - return Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - @pytest.mark.asyncio - async def test_not_hanging_with_multiplexer(self) -> None: - """Test that the connection does not hang and that the tasks cannot get blocked, using the multiplexer.""" - # create configurations for the test, re bocking and non-blocking tasks' waiting times - assert ( - NON_BLOCKING_TIME + TOLERANCE + WAIT_TIME_AMONG_TASKS < BLOCKING_TIME - ), "`NON_BLOCKING_TIME + TOLERANCE + WAIT_TIME_AMONG_TASKS` should be less than the `blocking_time`." - assert self.ledger_connection._ledger_dispatcher.block # type: ignore - - # create a blocking task lasting `BLOCKING_TIME` secs - request, _ = self.create_ledger_dialogues() - request._sender = SOME_SKILL_ID - blocking_dummy_envelope = TestLedgerConnectionWithMultiplexer.create_envelope( - request - ) - self.multiplexer.put(blocking_dummy_envelope) - - # create a non-blocking task lasting `NON_BLOCKING_TIME` secs, after `WAIT_TIME_AMONG_TASKS` - await asyncio.sleep(WAIT_TIME_AMONG_TASKS) - - request, _ = self.create_ledger_dialogues(blocking=False) - request._sender = SOME_SKILL_ID - normal_dummy_envelope = TestLedgerConnectionWithMultiplexer.create_envelope( - request - ) - self.multiplexer.put(normal_dummy_envelope) - - # the response envelopes of the ledger connection should be empty - assert ( - self.ledger_connection.response_envelopes.empty() - ), "The response envelopes of the ledger connection should be empty." - # `receive()` should not be done, - # and multiplexer's `_receiving_loop` should be still running and have an empty `in_queue` - assert ( - len(self.multiplexer.in_queue.queue) == 0 - ), "The multiplexer's `in_queue` should not contain anything." - - # sleep for `NON_BLOCKING_TIME + TOLERANCE` - await asyncio.sleep(NON_BLOCKING_TIME + TOLERANCE) - - # `receive()` should be done, - # and multiplexer's `_receiving_loop` should have put the `normal_dummy_envelope` in the `in_queue` - envelope = self.multiplexer.get(block=True) - assert envelope is not None - message = envelope.message - assert isinstance(message, DummyLedgerApiMessage) - assert ( - message.data == b"normal_task" - ), "Normal task should be the first item in the multiplexer's `in_queue`." - assert self.ledger_connection._ledger_dispatcher.block # type: ignore - - -@pytest.mark.asyncio -async def test_request_dispatcher_run_async() -> None: - """Test request dispatcher run async.""" - dispatcher = LedgerApiRequestDispatcher( - logger=mock.Mock(), connection_id=PUBLIC_ID, connection_state=AsyncState() - ) - assert ( - await dispatcher.run_async( - lambda x, y, z: 12, mock.Mock(), mock.Mock(), mock.Mock() # type: ignore - ) - == 12 - ) - - def raise_exc(*args): # type: ignore - raise ValueError("expected") - - dialogue = mock.Mock() - dialogue.reply = mock.Mock(return_value=124) - assert ( - await dispatcher.run_async( - raise_exc, mock.Mock(), mock.Mock(), dialogue=dialogue - ) - == 124 - ) - dialogue.reply.assert_called_once_with( - performative=mock.ANY, - target_message=mock.ANY, - code=500, - message="expected", - data=b"", - ) - - -def test_ledger_connection_exceptions() -> None: - """Test exception.""" - configuration = mock.Mock() - configuration.public_id = LedgerConnection.connection_id - connection = LedgerConnection(data_dir="", configuration=configuration) - with pytest.raises( - ValueError, - match="`asyncio.Queue` for `_response_envelopes` not set. Is the ledger connection active?", - ): - connection.response_envelopes - - envelope = mock.Mock() - envelope.protocol_specification_id = ContractApiMessage.protocol_specification_id - connection._contract_dispatcher = mock.Mock() - connection._contract_dispatcher.dispatch.return_value = 12 - assert connection._schedule_request(envelope) == 12 diff --git a/trader_backup/vendor/valory/connections/ledger/tests/test_ledger_api.py b/trader_backup/vendor/valory/connections/ledger/tests/test_ledger_api.py deleted file mode 100644 index c7b85f2df..000000000 --- a/trader_backup/vendor/valory/connections/ledger/tests/test_ledger_api.py +++ /dev/null @@ -1,682 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2023 Valory AG -# Copyright 2018-2019 Fetch.AI Limited -# -# 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 the tests of the ledger API connection module.""" -# pylint: skip-file - -import asyncio -import logging -import platform -import time -from pathlib import Path -from typing import Any, Dict, List, Optional, cast -from unittest.mock import Mock, patch - -import pytest -from aea_ledger_ethereum import EthereumCrypto -from aea_ledger_ethereum.test_tools.constants import ETHEREUM_PRIVATE_KEY_PATH -from aea_ledger_ethereum.test_tools.fixture_helpers import ( # noqa: F401 pylint: disable=unsed-import - DEFAULT_GANACHE_CHAIN_ID, - ganache, -) -from web3.eth import Eth - -from aea.common import Address -from aea.configurations.data_types import PublicId -from aea.connections.base import Connection, ConnectionStates -from aea.crypto.ledger_apis import LedgerApis -from aea.crypto.registries import make_crypto, make_ledger_api -from aea.helpers.async_utils import AsyncState -from aea.helpers.transaction.base import ( - RawTransaction, - SignedTransaction, - Terms, - TransactionDigest, - TransactionReceipt, -) -from aea.mail.base import Envelope, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue - -from packages.valory.connections.ledger.connection import LedgerConnection -from packages.valory.connections.ledger.ledger_dispatcher import ( - LedgerApiRequestDispatcher, -) -from packages.valory.protocols.ledger_api.custom_types import ( - Kwargs, - SignedTransactions, - TransactionDigests, -) -from packages.valory.protocols.ledger_api.dialogues import LedgerApiDialogue -from packages.valory.protocols.ledger_api.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.protocols.ledger_api.message import LedgerApiMessage - - -SOME_SKILL_ID = "some/skill:0.1.0" -PACKAGE_DIR = Path(__file__).parent.parent - -skip_docker_tests = pytest.mark.skipif( - platform.system() != "Linux", - reason="Docker daemon is not available in Windows and macOS CI containers.", -) -logger = logging.getLogger(__name__) -ledger_ids = pytest.mark.parametrize( - "ledger_id,address", - [ - (EthereumCrypto.identifier, EthereumCrypto(ETHEREUM_PRIVATE_KEY_PATH).address), - ], -) -# TODO: uncomment gas station strategy config after the gasstation API start -gas_strategies = pytest.mark.parametrize( - "gas_strategies", - [ - {"gas_price_strategy": None}, - # {"gas_price_strategy": "gas_station"}, # noqa:E800 - {"gas_price_strategy": "eip1559"}, - { - "max_fee_per_gas": 1_000_000_000, - "max_priority_fee_per_gas": 1_000_000_000, - }, - ], -) - - -class LedgerApiDialogues(BaseLedgerApiDialogues): - """The dialogues class keeps track of all ledger_api dialogues.""" - - def __init__(self, self_address: Address, **kwargs: Any) -> None: - """Initialize dialogues.""" - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message""" - return LedgerApiDialogue.Role.AGENT - - BaseLedgerApiDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - ) - - -@pytest.mark.usefixtures("ganache") -@skip_docker_tests -class TestLedgerDispatcher: - """Tests for ledger dispatcher.""" - - @pytest.mark.asyncio - @ledger_ids - async def test_get_balance( - self, - ledger_id: str, - address: str, - ledger_apis_connection: Connection, - update_default_ethereum_ledger_api: None, - ethereum_testnet_config: Dict, - ) -> None: - """Test get balance method.""" - - config = ethereum_testnet_config - ledger_api_dialogues = LedgerApiDialogues(SOME_SKILL_ID) - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.GET_BALANCE, # type: ignore - ledger_id=ledger_id, - address=address, - ) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_msg = cast(LedgerApiMessage, response.message) - response_dialogue = ledger_api_dialogues.update(response_msg) - assert response_dialogue == ledger_api_dialogue - assert response_msg.performative == LedgerApiMessage.Performative.BALANCE - actual_balance_amount = response_msg.balance - expected_balance_amount = make_ledger_api(ledger_id, **config).get_balance( - address - ) - assert actual_balance_amount == expected_balance_amount - - @pytest.mark.asyncio - @ledger_ids - async def test_get_state( - self, - ledger_id: str, - address: str, - ledger_apis_connection: Connection, - update_default_ethereum_ledger_api: None, - ethereum_testnet_config: Dict, - ) -> None: - """Test get state.""" - - config = ethereum_testnet_config - - if "ethereum" in ledger_id: - callable_name = "get_block" - else: - callable_name = "blocks" - args = ("latest",) - kwargs = Kwargs({}) - - ledger_api_dialogues = LedgerApiDialogues(SOME_SKILL_ID) - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.GET_STATE, # type: ignore - ledger_id=ledger_id, - callable=callable_name, - args=args, - kwargs=kwargs, - ) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_msg = cast(LedgerApiMessage, response.message) - response_dialogue = ledger_api_dialogues.update(response_msg) - assert response_dialogue == ledger_api_dialogue - - assert ( - response_msg.performative == LedgerApiMessage.Performative.STATE - ), response_msg - actual_block = response_msg.state.body - expected_block = make_ledger_api(ledger_id, **config).get_state( - callable_name, *args - ) - assert actual_block == expected_block - - @pytest.mark.asyncio - @gas_strategies - async def test_get_raw_transaction( - self, - gas_strategies: Dict, - ledger_apis_connection: Connection, - update_default_ethereum_ledger_api: None, - ) -> None: - """Test get raw transaction with Ethereum APIs.""" - import aea # noqa # to load registries - - crypto1 = make_crypto( - EthereumCrypto.identifier, private_key_path=ETHEREUM_PRIVATE_KEY_PATH - ) - crypto2 = make_crypto(EthereumCrypto.identifier) - ledger_api_dialogues = LedgerApiDialogues(SOME_SKILL_ID) - - amount = 40000 - fee = 10**7 - - # Create ledger_api dialogue: get raw transaction - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - terms=Terms( - ledger_id=EthereumCrypto.identifier, - sender_address=crypto1.address, - counterparty_address=crypto2.address, - amount_by_currency_id={"ETH": -amount}, - quantities_by_good_id={"some_service_id": 1}, - is_sender_payable_tx_fee=True, - nonce="", - fee_by_currency_id={"ETH": fee}, - chain_id=DEFAULT_GANACHE_CHAIN_ID, - **gas_strategies, - ), - ) - request = cast(LedgerApiMessage, request) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - - # Raw transaction - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_message = cast(LedgerApiMessage, response.message) - assert ( - response_message.performative - == LedgerApiMessage.Performative.RAW_TRANSACTION - ) - response_dialogue = ledger_api_dialogues.update(response_message) - assert response_dialogue == ledger_api_dialogue - assert isinstance(response_message.raw_transaction, RawTransaction) - assert response_message.raw_transaction.ledger_id == request.terms.ledger_id - - @pytest.mark.asyncio - @gas_strategies - async def test_send_signed_transaction_ethereum( - self, gas_strategies: Dict, ledger_apis_connection: LedgerConnection - ) -> None: - """Test send signed transaction with Ethereum APIs.""" - ledger_api_dialogues = LedgerApiDialogues(SOME_SKILL_ID) - - crypto1 = make_crypto( - EthereumCrypto.identifier, private_key_path=ETHEREUM_PRIVATE_KEY_PATH - ) - crypto2 = make_crypto(EthereumCrypto.identifier) - - # First, send a transaction so we can get a digest at the end - amount = 40000 - fee = 10**7 - - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - terms=Terms( - ledger_id=EthereumCrypto.identifier, - sender_address=crypto1.address, - counterparty_address=crypto2.address, - amount_by_currency_id={"ETH": -amount}, - quantities_by_good_id={"some_service_id": 1}, - is_sender_payable_tx_fee=True, - nonce="", - fee_by_currency_id={"ETH": fee}, - chain_id=DEFAULT_GANACHE_CHAIN_ID, - **gas_strategies, - ), - ) - request = cast(LedgerApiMessage, request) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - # Check that we got the correct transaction response - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_message = cast(LedgerApiMessage, response.message) - assert ( - response_message.performative - == LedgerApiMessage.Performative.RAW_TRANSACTION - ) - response_dialogue = ledger_api_dialogues.update(response_message) - assert response_dialogue == ledger_api_dialogue - assert isinstance(response_message.raw_transaction, RawTransaction) - assert response_message.raw_transaction.ledger_id == request.terms.ledger_id - - # Sign the transaction - signed_transaction = crypto1.sign_transaction( - response_message.raw_transaction.body - ) - - # Create new dialogue starting with signed transaction - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, # type: ignore - signed_transaction=SignedTransaction( - EthereumCrypto.identifier, signed_transaction - ), - ) - request = cast(LedgerApiMessage, request) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - - # Transaction digest - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_message = cast(LedgerApiMessage, response.message) - assert ( - response_message.performative != LedgerApiMessage.Performative.ERROR - ), f"Received error: {response_message.message}" - assert ( - response_message.performative - == LedgerApiMessage.Performative.TRANSACTION_DIGEST - ) - response_dialogue = ledger_api_dialogues.update(response_message) - assert response_dialogue == ledger_api_dialogue - assert isinstance(response_message.transaction_digest, TransactionDigest) - assert isinstance(response_message.transaction_digest.body, str) - assert ( - response_message.transaction_digest.ledger_id - == request.signed_transaction.ledger_id - ) - await asyncio.sleep(0.01) - # Create new dialogue starting with GET_TRANSACTION_RECEIPT - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, # type: ignore - transaction_digest=response_message.transaction_digest, - ) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - - # Transaction receipt - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_message = cast(LedgerApiMessage, response.message) - assert ( - response_message.performative - == LedgerApiMessage.Performative.TRANSACTION_RECEIPT - ) - response_dialogue = ledger_api_dialogues.update(response_message) - assert response_dialogue == ledger_api_dialogue - assert isinstance(response_message.transaction_receipt, TransactionReceipt) - assert response_message.transaction_receipt.receipt is not None - assert response_message.transaction_receipt.transaction is not None - assert ( - response_message.transaction_receipt.ledger_id - == request.transaction_digest.ledger_id # type: ignore - ) - assert LedgerApis.is_transaction_settled( - response_message.transaction_receipt.ledger_id, - response_message.transaction_receipt.receipt, - ), "Transaction not settled." - - @pytest.mark.asyncio - async def test_send_signed_transactions( - self, ledger_apis_connection: LedgerConnection - ) -> None: - """Test the send_signed_transactions.""" - ledger_api_dialogues = LedgerApiDialogues(SOME_SKILL_ID) - - # Create new dialogue starting with signed transaction - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS, # type: ignore - signed_transactions=SignedTransactions( - EthereumCrypto.identifier, - [{"raw_transaction": "test_tx"}], - ), - kwargs=LedgerApiMessage.Kwargs({}), - ) - request = cast(LedgerApiMessage, request) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - expected_transaction_digests = ["transaction_digest_1", "transaction_digest_2"] - # create a mock for api.send_signed_transactions - with patch( - "aea_ledger_ethereum.ethereum.EthereumApi.send_signed_transactions" - ) as mock_send_signed_transactions: - # configure the mock to return a specific value - mock_send_signed_transactions.return_value = expected_transaction_digests - - # call the function under test - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - - # Transaction digest - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_message = cast(LedgerApiMessage, response.message) - assert ( - response_message.performative != LedgerApiMessage.Performative.ERROR - ), f"Received error: {response_message.message}" - assert ( - response_message.performative - == LedgerApiMessage.Performative.TRANSACTION_DIGESTS - ) - response_dialogue = ledger_api_dialogues.update(response_message) - assert response_dialogue == ledger_api_dialogue - assert isinstance(response_message.transaction_digests, TransactionDigests) - assert isinstance( - response_message.transaction_digests.transaction_digests, List - ) - assert ( - response_message.transaction_digests.ledger_id - == request.signed_transactions.ledger_id - ) - assert ( - response_message.transaction_digests.transaction_digests - == expected_transaction_digests - ) - - @pytest.mark.asyncio - async def test_unsupported_protocol( - self, ledger_apis_connection: LedgerConnection - ) -> None: - """Test fail on protocol not supported.""" - envelope = Envelope( - to=str(ledger_apis_connection.connection_id), - sender="test/skill:0.1.0", - protocol_specification_id=PublicId.from_str("author/package_name:0.1.0"), - message=b"message", - ) - with pytest.raises(ValueError, match="Protocol not supported"): - ledger_apis_connection._schedule_request(envelope) - - @pytest.mark.asyncio - async def test_no_balance( - self, - ) -> None: - """Test no balance.""" - dispatcher = LedgerApiRequestDispatcher( - AsyncState(), connection_id=LedgerConnection.connection_id - ) - mock_api = Mock() - message = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, # type: ignore - dialogue_reference=dispatcher.dialogues.new_self_initiated_dialogue_reference(), - ledger_id=EthereumCrypto.identifier, - address="test", - ) - message.to = dispatcher.dialogues.self_address - message.sender = "test" - dialogue = cast( - Optional[LedgerApiDialogue], dispatcher.dialogues.update(message) - ) - assert dialogue is not None - - mock_api.get_balance.return_value = None - msg = dispatcher.get_balance(mock_api, message, dialogue) - assert msg.performative == LedgerApiMessage.Performative.ERROR - - @pytest.mark.asyncio - async def test_no_raw_tx( - self, - ) -> None: - """Test no raw tx returned.""" - dispatcher = LedgerApiRequestDispatcher( - AsyncState(), connection_id=LedgerConnection.connection_id - ) - mock_api = Mock() - message = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - dialogue_reference=dispatcher.dialogues.new_self_initiated_dialogue_reference(), - terms=Terms( - ledger_id=EthereumCrypto.identifier, - sender_address="1111", - counterparty_address="22222", - amount_by_currency_id={"ETH": -1}, - quantities_by_good_id={"some_service_id": 1}, - is_sender_payable_tx_fee=True, - nonce="", - fee_by_currency_id={"ETH": 10}, - chain_id=3, - ), - ) - message.to = dispatcher.dialogues.self_address - message.sender = "test" - dialogue = cast( - Optional[LedgerApiDialogue], dispatcher.dialogues.update(message) - ) - assert dialogue is not None - - mock_api.get_transfer_transaction.return_value = None - msg = dispatcher.get_raw_transaction(mock_api, message, dialogue) - assert msg.performative == LedgerApiMessage.Performative.ERROR - - @pytest.mark.asyncio - @pytest.mark.parametrize( - "failing_ledger_method_name", - ("get_transaction_receipt", "is_transaction_settled", "get_transaction"), - ) - @pytest.mark.parametrize("retries", (0, 5, 20)) - @pytest.mark.parametrize("retry_timeout", (0.1,)) - @pytest.mark.parametrize("ledger_raise_error", (True, False)) - async def test_attempts_get_transaction_receipt( - self, - failing_ledger_method_name: str, - retries: int, - retry_timeout: float, - ledger_raise_error: bool, - ) -> None: - """Test retry and sleep.""" - dispatcher = LedgerApiRequestDispatcher( - AsyncState(ConnectionStates.connected), - connection_id=LedgerConnection.connection_id, - ) - mock_api = Mock() - message = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, # type: ignore - dialogue_reference=dispatcher.dialogues.new_self_initiated_dialogue_reference(), - transaction_digest=TransactionDigest("asdad", "sdfdsf"), - ) - message.to = dispatcher.dialogues.self_address - message.sender = "test" - dialogue = dispatcher.dialogues.update(message) - assert dialogue is not None - assert isinstance(dialogue, LedgerApiDialogue) - - mock_api.is_transaction_settled.return_value = ( - True if failing_ledger_method_name == "get_transaction" else False - ) - failing_ledger_method = getattr(mock_api, failing_ledger_method_name) - if ( - ledger_raise_error - and failing_ledger_method_name != "is_transaction_settled" - ): - failing_ledger_method.side_effect = ValueError() - elif failing_ledger_method_name != "is_transaction_settled": - failing_ledger_method.return_value = None - - with patch.object(dispatcher, "retry_attempts", retries): - with patch.object(dispatcher, "retry_timeout", retry_timeout): - msg = await dispatcher.get_transaction_receipt( - mock_api, message, dialogue - ) - - assert ( - msg.performative == LedgerApiMessage.Performative.ERROR - ), "performative should be `ERROR`, please revisit the test's implementation." - times_called = failing_ledger_method.call_count - expected_times = retries - assert times_called == expected_times, "Tried more times than expected!" - - @pytest.mark.asyncio - @ledger_ids - async def test_get_transaction_receipt_node_blocking( - self, - ledger_id: str, - address: str, - ledger_apis_connection: LedgerConnection, - update_default_ethereum_ledger_api: None, - ethereum_testnet_config: Dict, - ) -> None: - """Test retry strategy when the node is blocking.""" - retry_attempts = expected_times_called = 2 - retry_timeout = 0.001 - blocking_duration = 1 - - # the retry strategy's total duration is an arithmetic progression - expected_duration = sum(i * retry_timeout for i in range(retry_attempts)) - assert expected_duration < blocking_duration, ( - "The purpose of this test is to check whether the retry strategy works if a node is blocking." - f"Therefore, the blocking time ({blocking_duration}) must be larger than the expected duration " - f"({expected_duration}) of the retry strategy." - ) - - ledger_api_dialogues = LedgerApiDialogues(SOME_SKILL_ID) - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, # type: ignore - ledger_id=ledger_id, - address=address, - transaction_digest=TransactionDigest(ledger_id="ethereum", body="tx_hash"), - ) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - with patch.object( - ledger_apis_connection._ledger_dispatcher, "retry_attempts", retry_attempts - ), patch.object( - ledger_apis_connection._ledger_dispatcher, "retry_timeout", retry_timeout - ), patch.object( - Eth, - "get_transaction_receipt", - side_effect=lambda *_: time.sleep(blocking_duration), - ) as get_transaction_receipt_mock: - await ledger_apis_connection.send(envelope) - - try: - await asyncio.wait_for( - ledger_apis_connection.receive(), timeout=blocking_duration - ) - except asyncio.exceptions.TimeoutError: - raise AssertionError( - "The retry strategy did not finish before the given `blocking_duration`, " - "which suggests that the ledger api's call was also blocked, " - "and the dispatcher was waiting for its response." - ) - - actual_times_called = get_transaction_receipt_mock.call_count - assert ( - actual_times_called == expected_times_called - ), f"Tried {actual_times_called} times, {expected_times_called} were expected!" diff --git a/trader_backup/vendor/valory/connections/p2p_libp2p_client/README.md b/trader_backup/vendor/valory/connections/p2p_libp2p_client/README.md deleted file mode 100644 index f2c31c230..000000000 --- a/trader_backup/vendor/valory/connections/p2p_libp2p_client/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# P2P Libp2p Client Connection - -A lightweight TCP connection to a libp2p DHT node. - -It allows for using the DHT without having to deploy a node by delegating its communication traffic to an already running DHT node with delegate service enabled. - - -## Usage - -First, add the connection to your AEA project: `aea add connection valory/p2p_libp2p_client:0.1.0`. - -Next, ensure that the connection is properly configured by setting: - -- `nodes` to a list of `uri`s, connection will choose the delegate randomly -- `uri` to the public IP address and port number of the delegate service of a running DHT node, in format `${ip|dns}:${port}` diff --git a/trader_backup/vendor/valory/connections/p2p_libp2p_client/__init__.py b/trader_backup/vendor/valory/connections/p2p_libp2p_client/__init__.py deleted file mode 100644 index b1456be04..000000000 --- a/trader_backup/vendor/valory/connections/p2p_libp2p_client/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 Valory AG -# Copyright 2018-2019 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Implementation of the libp2p client connection.""" diff --git a/trader_backup/vendor/valory/connections/p2p_libp2p_client/connection.py b/trader_backup/vendor/valory/connections/p2p_libp2p_client/connection.py deleted file mode 100644 index be999f719..000000000 --- a/trader_backup/vendor/valory/connections/p2p_libp2p_client/connection.py +++ /dev/null @@ -1,688 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2023 Valory AG -# Copyright 2018-2019 Fetch.AI Limited -# -# 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 the libp2p client connection.""" -# pylint: disable-all -import asyncio -import contextlib -import hashlib -import logging -import random -import ssl -from asyncio import CancelledError -from asyncio.events import AbstractEventLoop -from asyncio.streams import StreamWriter -from pathlib import Path -from typing import Any, Dict, List, Optional - -from asn1crypto import x509 # type: ignore -from ecdsa.curves import SECP256k1 # type: ignore -from ecdsa.keys import BadSignatureError, VerifyingKey # type: ignore -from ecdsa.util import sigdecode_der # type: ignore - -from aea.configurations.base import PublicId -from aea.configurations.constants import DEFAULT_LEDGER -from aea.connections.base import Connection, ConnectionStates -from aea.crypto.registries import make_crypto -from aea.exceptions import enforce -from aea.helpers.acn.agent_record import AgentRecord -from aea.helpers.acn.uri import Uri -from aea.helpers.pipe import IPCChannelClient, TCPSocketChannelClient, TCPSocketProtocol -from aea.mail.base import Envelope - -from packages.valory.protocols.acn import acn_pb2 -from packages.valory.protocols.acn.message import AcnMessage - - -try: - from asyncio.streams import ( # type: ignore # pylint: disable=ungrouped-imports - IncompleteReadError, - ) -except ImportError: # pragma: nocover - from asyncio import IncompleteReadError # pylint: disable=ungrouped-imports - - -_default_logger = logging.getLogger("aea.packages.valory.connections.p2p_libp2p_client") - -PUBLIC_ID = PublicId.from_str("valory/p2p_libp2p_client:0.1.0") - -SUPPORTED_LEDGER_IDS = ["fetchai", "cosmos", "ethereum"] - -POR_DEFAULT_SERVICE_ID = "acn" - -ACN_CURRENT_VERSION = "0.1.0" - - -class NodeClient: - """Client to communicate with node using ipc channel(pipe).""" - - ACN_ACK_TIMEOUT = 5.0 - - def __init__(self, pipe: IPCChannelClient, node_por: AgentRecord) -> None: - """Set node client with pipe.""" - self.pipe = pipe - self._wait_status: Optional[asyncio.Future] = None - self.agent_record = node_por - - async def wait_for_status(self) -> Any: - """Get status.""" - if self._wait_status is None: # pragma: nocover - raise ValueError("waiter for status not set!") - return await asyncio.wait_for(self._wait_status, timeout=self.ACN_ACK_TIMEOUT) - - @staticmethod - def make_acn_envelope_message(envelope: Envelope) -> bytes: - """Make acn message with envelope in.""" - acn_msg = acn_pb2.AcnMessage() # type: ignore - performative = acn_pb2.AcnMessage.Aea_Envelope_Performative() # type: ignore - performative.envelope = envelope.encode() - acn_msg.aea_envelope.CopyFrom(performative) # pylint: disable=no-member - buf = acn_msg.SerializeToString() - return buf - - async def write_acn_status_ok(self) -> None: - """Send acn status ok.""" - acn_msg = acn_pb2.AcnMessage() # type: ignore - performative = acn_pb2.AcnMessage.Status_Performative() # type: ignore - status = AcnMessage.StatusBody( - status_code=AcnMessage.StatusBody.StatusCode.SUCCESS, msgs=[] - ) - AcnMessage.StatusBody.encode( - performative.body, status # pylint: disable=no-member - ) - acn_msg.status.CopyFrom(performative) # pylint: disable=no-member - buf = acn_msg.SerializeToString() - await self._write(buf) - - async def write_acn_status_error( - self, - msg: str, - status_code: AcnMessage.StatusBody.StatusCode = AcnMessage.StatusBody.StatusCode.ERROR_GENERIC, # type: ignore - ) -> None: - """Send acn status error generic.""" - acn_msg = acn_pb2.AcnMessage() # type: ignore - performative = acn_pb2.AcnMessage.Status_Performative() # type: ignore - status = AcnMessage.StatusBody(status_code=status_code, msgs=[msg]) - AcnMessage.StatusBody.encode( - performative.body, status # pylint: disable=no-member - ) - acn_msg.status.CopyFrom(performative) # pylint: disable=no-member - - buf = acn_msg.SerializeToString() - - await self._write(buf) - - async def connect(self) -> bool: - """Connect to node with pipe.""" - return await self.pipe.connect() - - async def send_envelope(self, envelope: Envelope) -> None: - """Send envelope to node.""" - self._wait_status = asyncio.Future() - buf = self.make_acn_envelope_message(envelope) - await self._write(buf) - try: - status = await self.wait_for_status() - if status.code != int(AcnMessage.StatusBody.StatusCode.SUCCESS): # type: ignore # pylint: disable=no-member - raise ValueError( # pragma: nocover - f"failed to send envelope. got error confirmation: {status}" - ) - except asyncio.TimeoutError: # pragma: nocover - if not self._wait_status.done(): # pragma: nocover - self._wait_status.set_exception(Exception("Timeout")) - await asyncio.sleep(0) - raise ValueError("acn status await timeout!") - finally: - self._wait_status = None - - def make_agent_record(self) -> AcnMessage.AgentRecord: # type: ignore - """Make acn agent record.""" - agent_record = AcnMessage.AgentRecord( - address=self.agent_record.address, - public_key=self.agent_record.public_key, - peer_public_key=self.agent_record.representative_public_key, - signature=self.agent_record.signature, - service_id=POR_DEFAULT_SERVICE_ID, - ledger_id=self.agent_record.ledger_id, - ) - return agent_record - - async def read_envelope(self) -> Optional[Envelope]: - """Read envelope from the node.""" - while True: - buf = await self._read() - - if not buf: - return None - - try: - acn_msg = acn_pb2.AcnMessage() # type: ignore - acn_msg.ParseFromString(buf) - - except Exception as e: # pragma: nocover - await self.write_acn_status_error( - f"Failed to parse acn message {e}", - status_code=AcnMessage.StatusBody.StatusCode.ERROR_DECODE, - ) - raise ValueError(f"Error parsing acn message: {e}") from e - - performative = acn_msg.WhichOneof("performative") - if performative == "aea_envelope": # pragma: nocover - aea_envelope = acn_msg.aea_envelope # pylint: disable=no-member - try: - envelope = Envelope.decode(aea_envelope.envelope) - await self.write_acn_status_ok() - return envelope - except Exception as e: - await self.write_acn_status_error( - f"Failed to decode envelope: {e}", - status_code=AcnMessage.StatusBody.StatusCode.ERROR_DECODE, - ) - raise - - elif performative == "status": - if self._wait_status is not None: - self._wait_status.set_result( - acn_msg.status.body # pylint: disable=no-member - ) - else: # pragma: nocover - await self.write_acn_status_error( - f"Bad acn message {performative}", - status_code=AcnMessage.StatusBody.StatusCode.ERROR_UNEXPECTED_PAYLOAD, - ) - - async def _write(self, data: bytes) -> None: - """ - Write to the writer stream. - - :param data: data to write to stream - """ - await self.pipe.write(data) - - async def _read(self) -> Optional[bytes]: - """ - Read from the reader stream. - - :return: bytes - """ - return await self.pipe.read() - - async def register( - self, - ) -> None: - """Register agent on the remote node.""" - agent_record = self.make_agent_record() - acn_msg = acn_pb2.AcnMessage() # type: ignore - performative = acn_pb2.AcnMessage.Register_Performative() # type: ignore - AcnMessage.AgentRecord.encode( - performative.record, agent_record # pylint: disable=no-member - ) - acn_msg.register.CopyFrom(performative) # pylint: disable=no-member - - buf = acn_msg.SerializeToString() - await self._write(buf) - - try: - buf = await asyncio.wait_for(self._read(), timeout=self.ACN_ACK_TIMEOUT) - except ConnectionError as e: # pragma: nocover - raise e - except IncompleteReadError as e: # pragma: no cover - raise e - - if buf is None: # pragma: nocover - raise ConnectionError( - "Error on connection setup. Incoming buffer is empty!" - ) - acn_msg = acn_pb2.AcnMessage() # type: ignore - acn_msg.ParseFromString(buf) - performative = acn_msg.WhichOneof("performative") - if performative != "status": # pragma: nocover - raise Exception(f"Wrong response message from peer: {performative}") - response = acn_msg.status # pylint: disable=no-member - - if response.body.code != int(AcnMessage.StatusBody.StatusCode.SUCCESS): # type: ignore # pylint: disable=no-member - raise Exception( # pragma: nocover - "Registration to peer failed: {}".format( - AcnMessage.StatusBody.StatusCode(response.body.code) # type: ignore # pylint: disable=no-member - ) - ) - - async def close(self) -> None: - """Close client and pipe.""" - await self.pipe.close() - - -class P2PLibp2pClientConnection(Connection): - """ - A libp2p client connection. - - Send and receive envelopes to and from agents on the p2p network without deploying a libp2p node. - Connect to the libp2p node using traffic delegation service. - """ - - connection_id = PUBLIC_ID - - DEFAULT_CONNECT_RETRIES = 3 - DEFAULT_TLS_CONNECTION_SIGNATURE_TIMEOUT = 5.0 - - def __init__(self, **kwargs: Any) -> None: - """Initialize a libp2p client connection.""" - super().__init__(**kwargs) - - self.tls_connection_signature_timeout = self.configuration.config.get( - "tls_connection_signature_timeout", - self.DEFAULT_TLS_CONNECTION_SIGNATURE_TIMEOUT, - ) - self.connect_retries = self.configuration.config.get( - "connect_retries", self.DEFAULT_CONNECT_RETRIES - ) - ledger_id = self.configuration.config.get("ledger_id", DEFAULT_LEDGER) - if ledger_id not in SUPPORTED_LEDGER_IDS: - raise ValueError( # pragma: nocover - "Ledger id '{}' is not supported. Supported ids: '{}'".format( - ledger_id, SUPPORTED_LEDGER_IDS - ) - ) - - key_file: Optional[str] = self.configuration.config.get("tcp_key_file") - nodes: Optional[List[Dict[str, Any]]] = self.configuration.config.get("nodes") - - if nodes is None: - raise ValueError("At least one node should be provided") - nodes = list(nodes) - - nodes_uris = [node.get("uri", None) for node in nodes] - enforce( - len(nodes_uris) == len(nodes) and None not in nodes_uris, - "Delegate 'uri' should be provided for each node", - ) - - nodes_public_keys = [node.get("public_key", None) for node in nodes] - enforce( - len(nodes_public_keys) == len(nodes) and None not in nodes_public_keys, - "Delegate 'public_key' should be provided for each node", - ) - - cert_requests = self.configuration.cert_requests - if cert_requests is None or len(cert_requests) != len(nodes): - raise ValueError( # pragma: nocover - "cert_requests field must be set and contain exactly as many entries as 'nodes'!" - ) - for cert_request in cert_requests: - save_path = cert_request.get_absolute_save_path(Path(self.data_dir)) - if not save_path.is_file(): - raise Exception( # pragma: nocover - f"cert_request 'save_path' field is not a file:\n{save_path}\n" - "Please ensure that 'issue-certificates' command is called beforehand" - ) - - # we cannot use the key from the connection's crypto store as - # the key will be used for TLS tcp connection, whereas the - # connection's crypto store key is used for PoR - if key_file is not None: - key = make_crypto(ledger_id, private_key_path=key_file) - else: - key = make_crypto(ledger_id) - - # client connection id - self.key = key - self.logger.debug("Public key used for TCP: {}".format(key.public_key)) - - # delegate uris - self.delegate_uris = [Uri(node_uri) for node_uri in nodes_uris] - - # delegates PoRs - self.delegate_pors: List[AgentRecord] = [] - for i, cert_request in enumerate(cert_requests): - agent_record = AgentRecord.from_cert_request( - cert_request, self.address, nodes_public_keys[i], self.data_dir - ) - self.delegate_pors.append(agent_record) - - # select a delegate - index = random.randint(0, len(self.delegate_uris) - 1) # nosec - self.node_uri = self.delegate_uris[index] - self.node_por = self.delegate_pors[index] - self.logger.debug("Node to use as delegate: {}".format(self.node_uri)) - - self._in_queue = None # type: Optional[asyncio.Queue] - self._process_messages_task = None # type: Optional[asyncio.Future] - self._node_client: Optional[NodeClient] = None - - self._send_queue: Optional[asyncio.Queue] = None - self._send_task: Optional[asyncio.Task] = None - - async def _send_loop(self) -> None: - """Handle message in the send queue.""" - - if not self._send_queue or not self._node_client: # pragma: nocover - self.logger.error("Send loop not started cause not connected properly.") - return - try: - while self.is_connected: - envelope = await self._send_queue.get() - await self._send_envelope_with_node_client(envelope) - except asyncio.CancelledError: # pylint: disable=try-except-raise - raise # pragma: nocover - except Exception: # pylint: disable=broad-except # pragma: nocover - self.logger.exception( - f"Failed to send an envelope {envelope}. Stop connection." - ) - await asyncio.shield(self.disconnect()) - - async def _send_envelope_with_node_client(self, envelope: Envelope) -> None: - """Send envelope with node client, reconnect and retry on fail.""" - if not self._node_client: # pragma: nocover - raise ValueError("Connection not connected to node!") - - self._ensure_valid_envelope_for_external_comms(envelope) - try: - await self._node_client.send_envelope(envelope) - except Exception: # pylint: disable=broad-except - self.logger.exception( - "Exception raised on message send. Try reconnect and send again." - ) - await self._perform_connection_to_node() - await self._node_client.send_envelope(envelope) - - async def connect(self) -> None: - """Set up the connection.""" - if self.is_connected: # pragma: nocover - return - - with self._connect_context(): - # connect libp2p client - - await self._perform_connection_to_node() - # start receiving msgs - self._in_queue = asyncio.Queue() - self._process_messages_task = asyncio.ensure_future( - self._process_messages(), loop=self.loop - ) - self._send_queue = asyncio.Queue() - self._send_task = self.loop.create_task(self._send_loop()) - - async def _perform_connection_to_node(self) -> None: - """Connect to node with retries.""" - for attempt in range(self.connect_retries): - if self.state not in [ # type: ignore - ConnectionStates.connecting, - ConnectionStates.connected, - ]: - # do nothing if disconnected, or disconnecting - return # pragma: nocover - try: - self.logger.info( - "Connecting to libp2p node {}. Attempt {}".format( - str(self.node_uri), attempt + 1 - ) - ) - pipe = TCPSocketChannelClientTLS( - f"{self.node_uri.host}:{self.node_uri._port}", # pylint: disable=protected-access - "", - server_pub_key=self.node_por.representative_public_key, - verification_signature_wait_timeout=self.tls_connection_signature_timeout, - ) - if not await pipe.connect(): - raise ValueError( - f"Pipe connection error: {pipe.last_exception or ''}" - ) - - self._node_client = NodeClient(pipe, self.node_por) - await self._setup_connection() - - self.logger.info( - "Successfully connected to libp2p node {}".format( - str(self.node_uri) - ) - ) - return - except Exception as e: # pylint: disable=broad-except - if attempt == self.connect_retries - 1: - self.logger.error( - "Connection to libp2p node {} failed: error: {}. It was the last attempt, exception will be raised".format( - str(self.node_uri), str(e) - ) - ) - self.state = ConnectionStates.disconnected - raise - sleep_time = attempt * 2 + 1 - self.logger.error( - "Connection to libp2p node {} failed: error: {}. Another attempt will be performed in {} seconds".format( - str(self.node_uri), str(e), sleep_time - ) - ) - await asyncio.sleep(sleep_time) - - async def _setup_connection(self) -> None: - """Set up connection to node over tcp connection.""" - if not self._node_client: # pragma: nocover - raise ValueError("Connection was not connected!") - - await self._node_client.register() - - async def disconnect(self) -> None: - """Disconnect from the channel.""" - if self.is_disconnected: # pragma: nocover - return - - self.state = ConnectionStates.disconnecting - self.logger.debug("disconnecting libp2p client connection...") - - if self._process_messages_task is not None: - if not self._process_messages_task.done(): - self._process_messages_task.cancel() - self._process_messages_task = None - - if self._send_task is not None: - if not self._send_task.done(): - self._send_task.cancel() - self._send_task = None - - try: - self.logger.debug("disconnecting libp2p node client connection...") - if self._node_client is not None: - await self._node_client.close() - except Exception: # pragma: nocover # pylint:disable=broad-except - self.logger.exception("exception on node client close") - raise - finally: - # set disconnected state anyway - if self._in_queue is not None: - self._in_queue.put_nowait(None) - - self.state = ConnectionStates.disconnected - self.logger.debug("libp2p client connection disconnected.") - - async def receive(self, *args: Any, **kwargs: Any) -> Optional["Envelope"]: - """ - Receive an envelope. Blocking. - - :param args: positional arguments - :param kwargs: keyword arguments - :return: the envelope received, or None. - """ - try: - if self._in_queue is None: - raise ValueError("Input queue not initialized.") # pragma: nocover - envelope = await self._in_queue.get() - if envelope is None: # pragma: no cover - self.logger.debug("Received None.") - return None - self.logger.debug("Received envelope: {}".format(envelope)) - return envelope - except CancelledError: # pragma: no cover - self.logger.debug("Receive cancelled.") - return None - except Exception as e: # pragma: no cover # pylint: disable=broad-except - self.logger.exception(e) - return None - - async def send(self, envelope: Envelope) -> None: - """ - Send messages. - - :param envelope: the envelope - """ - if not self._node_client or not self._send_queue: - raise ValueError("Node is not connected!") # pragma: nocover - - self._ensure_valid_envelope_for_external_comms(envelope) - await self._send_queue.put(envelope) - - async def _read_envelope_from_node(self) -> Optional[Envelope]: - """Read envelope from node, reconnec on error.""" - if not self._node_client: # pragma: nocover - raise ValueError("Connection not connected to node!") - - try: - self.logger.debug("Waiting for messages...") - envelope = await self._node_client.read_envelope() - return envelope - except ConnectionError as e: # pragma: nocover - self.logger.error(f"Connection error: {e}. Try to reconnect and read again") - except IncompleteReadError as e: # pragma: no cover - self.logger.error( - "Connection disconnected while reading from node ({}/{})".format( - len(e.partial), e.expected - ) - ) - except Exception as e: # pylint: disable=broad-except # pragma: nocover - self.logger.exception(f"On envelope read: {e}") - - try: - self.logger.debug("Read envelope retry! Reconnect first!") - await self._perform_connection_to_node() - envelope = await self._node_client.read_envelope() - return envelope - except Exception: # pragma: no cover # pylint: disable=broad-except - self.logger.exception("Failed to read with reconnect!") - return None - - async def _process_messages(self) -> None: - """Receive data from node.""" - if not self._node_client: # pragma: nocover - raise ValueError("Connection not connected to node!") - - while True: - envelope = await self._read_envelope_from_node() - if self._in_queue is None: - raise ValueError("Input queue not initialized.") # pragma: nocover - self._in_queue.put_nowait(envelope) - if envelope is None: - break # pragma: no cover - - -class TCPSocketChannelClientTLS(TCPSocketChannelClient): - """Interprocess communication channel client using tcp sockets with TLS.""" - - DEFAULT_VERIFICATION_SIGNATURE_WAIT_TIMEOUT = 5.0 - - def __init__( - self, - in_path: str, - out_path: str, - server_pub_key: str, - logger: logging.Logger = _default_logger, - loop: Optional[AbstractEventLoop] = None, - verification_signature_wait_timeout: Optional[float] = None, - ) -> None: - """ - Initialize a tcp socket communication channel client. - - :param in_path: rendezvous point for incoming data - :param out_path: rendezvous point for outgoing data - :param server_pub_key: str, server public key to verify identity - :param logger: the logger - :param loop: the event loop - :param verification_signature_wait_timeout: optional float, if not provided, default value will be used - """ - super().__init__(in_path, out_path, logger, loop) - self.verification_signature_wait_timeout = ( - self.DEFAULT_VERIFICATION_SIGNATURE_WAIT_TIMEOUT - if verification_signature_wait_timeout is None - else verification_signature_wait_timeout - ) - self.server_pub_key = server_pub_key - - @staticmethod - def _get_session_pub_key(writer: StreamWriter) -> bytes: # pragma: nocover - """Get session public key from tls stream writer.""" - cert_data = writer.get_extra_info("ssl_object").getpeercert(binary_form=True) - - cert = x509.Certificate.load(cert_data) - session_pub_key = VerifyingKey.from_der(cert.public_key.dump()).to_string( - "uncompressed" - ) - return session_pub_key - - async def _open_connection(self) -> TCPSocketProtocol: - """Open a connection with TLS support and verify peer.""" - sock = await self._open_tls_connection() - session_pub_key = self._get_session_pub_key(sock.writer) - - try: - signature = await asyncio.wait_for( - sock.read(), timeout=self.verification_signature_wait_timeout - ) - except asyncio.TimeoutError: # pragma: nocover - raise ValueError( - f"Failed to get peer verification record in timeout: {self.verification_signature_wait_timeout}" - ) - - if not signature: # pragma: nocover - raise ValueError("Unexpected socket read data!") - - try: - self._verify_session_key_signature(signature, session_pub_key) - except BadSignatureError as e: # pragma: nocover - with contextlib.suppress(Exception): - await sock.close() - raise ValueError(f"Invalid TLS session key signature: {e}") - return sock - - async def _open_tls_connection(self) -> TCPSocketProtocol: - """Open a connection with TLS support.""" - cadata = await asyncio.get_event_loop().run_in_executor( - None, lambda: ssl.get_server_certificate((self._host, self._port)) - ) - - ssl_ctx = ssl.create_default_context(cadata=cadata) - ssl_ctx.check_hostname = False - ssl_ctx.verify_mode = ssl.CERT_REQUIRED - reader, writer = await asyncio.open_connection( - self._host, - self._port, - ssl=ssl_ctx, - ) - return TCPSocketProtocol(reader, writer, logger=self.logger, loop=self._loop) - - def _verify_session_key_signature( - self, signature: bytes, session_pub_key: bytes - ) -> None: - """ - Validate signature of session public key. - - :param signature: bytes, signature of session public key made with server private key - :param session_pub_key: session public key to check signature for. - """ - vk = VerifyingKey.from_string(bytes.fromhex(self.server_pub_key), SECP256k1) - vk.verify( - signature, session_pub_key, hashfunc=hashlib.sha256, sigdecode=sigdecode_der - ) diff --git a/trader_backup/vendor/valory/connections/p2p_libp2p_client/connection.yaml b/trader_backup/vendor/valory/connections/p2p_libp2p_client/connection.yaml deleted file mode 100644 index 53576dcdc..000000000 --- a/trader_backup/vendor/valory/connections/p2p_libp2p_client/connection.yaml +++ /dev/null @@ -1,51 +0,0 @@ -name: p2p_libp2p_client -author: valory -version: 0.1.0 -type: connection -description: The libp2p client connection implements a tcp connection to a running - libp2p node as a traffic delegate to send/receive envelopes to/from agents in the - DHT. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeiaf5kdnfdc2jifojgniib76zl2c4utnx7ofewc3szqkrxsby62ulu - __init__.py: bafybeid2azroxglu6fl7bxdfcsv3j77vyzgpikjnfwpxg73zeb5orez6ju - connection.py: bafybeiauso3ectgdvbhkt5j6wstfev5mnxiuj6hrkczyqgxurnvva3loqm -fingerprint_ignore_patterns: [] -connections: [] -protocols: -- valory/acn:1.1.0:bafybeidluaoeakae3exseupaea4i3yvvk5vivyt227xshjlffywwxzcxqe -class_name: P2PLibp2pClientConnection -config: - connect_retries: 3 - ledger_id: cosmos - nodes: - - uri: acn.staging.autonolas.tech:9005 - public_key: 02d3a830c9d6ea1ae91936951430dee11f4662f33118b02190693be835359a9d77 - - uri: acn.staging.autonolas.tech:9006 - public_key: 02e741c62d706e1dcf6986bf37fa74b98681bc32669623ac9ee6ff72488d4f59e8 - tls_connection_signature_timeout: 5.0 -cert_requests: -- identifier: acn - ledger_id: ethereum - message_format: '{public_key}' - not_after: '2025-01-01' - not_before: '2024-01-01' - public_key: 02d3a830c9d6ea1ae91936951430dee11f4662f33118b02190693be835359a9d77 - save_path: .certs/acn_cosmos_9005.txt -- identifier: acn - ledger_id: ethereum - message_format: '{public_key}' - not_after: '2025-01-01' - not_before: '2024-01-01' - public_key: 02e741c62d706e1dcf6986bf37fa74b98681bc32669623ac9ee6ff72488d4f59e8 - save_path: .certs/acn_cosmos_9006.txt -excluded_protocols: [] -restricted_to_protocols: [] -dependencies: - asn1crypto: - version: <1.5.0,>=1.4.0 - ecdsa: {} - open-aea-ledger-cosmos: {} - open-aea-ledger-ethereum: {} -is_abstract: false diff --git a/trader_backup/vendor/valory/contracts/__init__.py b/trader_backup/vendor/valory/contracts/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_backup/vendor/valory/contracts/agent_registry/__init__.py b/trader_backup/vendor/valory/contracts/agent_registry/__init__.py deleted file mode 100644 index cf1e8467e..000000000 --- a/trader_backup/vendor/valory/contracts/agent_registry/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for the agent registry contract.""" diff --git a/trader_backup/vendor/valory/contracts/agent_registry/build/AgentRegistry.json b/trader_backup/vendor/valory/contracts/agent_registry/build/AgentRegistry.json deleted file mode 100644 index 79a56dba2..000000000 --- a/trader_backup/vendor/valory/contracts/agent_registry/build/AgentRegistry.json +++ /dev/null @@ -1,1046 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "AgentRegistry", - "sourceName": "contracts/AgentRegistry.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - }, - { - "internalType": "string", - "name": "_baseURI", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "AgentInstanceRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentInstancesSlotsFilled", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "AgentNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentNotInService", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "componentId", - "type": "uint256" - } - ], - "name": "ComponentNotFound", - "type": "error" - }, - { - "inputs": [], - "name": "HashExists", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectAgentBondingValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectRegistrationDepositValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "provided", - "type": "address" - }, - { - "internalType": "address", - "name": "expected", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OnlyOwnServiceMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorHasNoInstances", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "OperatorOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "Overflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerOnly", - "type": "error" - }, - { - "inputs": [], - "name": "Paused", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrancyGuard", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceMustBeInactive", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "TransferFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "UnauthorizedMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "WrongAgentId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "numValues1", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numValues2", - "type": "uint256" - } - ], - "name": "WrongArrayLength", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongOperator", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "state", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceState", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "currentThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxThreshold", - "type": "uint256" - } - ], - "name": "WrongThreshold", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "string", - "name": "baseURI", - "type": "string" - } - ], - "name": "BaseURIChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "agentHash", - "type": "bytes32" - } - ], - "name": "CreateAgent", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "agentHash", - "type": "bytes32" - } - ], - "name": "UpdateAgentHash", - "type": "event" - }, - { - "inputs": [], - "name": "CID_PREFIX", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newManager", - "type": "address" - } - ], - "name": "changeManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "changeOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "agentOwner", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "agentHash", - "type": "bytes32" - } - ], - "name": "create", - "outputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "name": "exists", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "getHashes", - "outputs": [ - { - "internalType": "uint256", - "name": "numHashes", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "agentHashes", - "type": "bytes32[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "manager", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapAgentIdHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "bURI", - "type": "string" - } - ], - "name": "setBaseURI", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "tokenByIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "agentHash", - "type": "bytes32" - } - ], - "name": "updateHash", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/agent_registry/contract.py b/trader_backup/vendor/valory/contracts/agent_registry/contract.py deleted file mode 100644 index 9acf29aad..000000000 --- a/trader_backup/vendor/valory/contracts/agent_registry/contract.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- 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 the class to connect to the Agent Registry contract.""" - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi - - -class AgentRegistryContract(Contract): - """The Agent Registry contract.""" - - contract_id = PublicId.from_str("valory/agent_registry:0.1.0") - - @classmethod - def get_hash( - cls, - ledger_api: LedgerApi, - contract_address: str, - agent_id: int, - ) -> JSONLike: - """Retrieve an operator given its agent instance.""" - - contract_instance = cls.get_instance(ledger_api, contract_address) - res = contract_instance.functions.getHashes(agent_id).call() - # ensure that the returned object has the expected format - if len(res) != 2: - msg = f"The `getHashes` method for {contract_address=} returned data in an unexpected format: {res}" - return dict(error=msg) - - # get the agent hashes - hashes = res.pop(-1) - # ensure that there are hashes returned for the agent - if len(hashes) == 0: - msg = f"The `getHashes` method for {contract_address=} returned no hashes for {agent_id=}: {res}" - return dict(error=msg) - - # get the most recent agent hash - hash_ = hashes.pop(-1) - # ensure that the hash is in bytes - if not isinstance(hash_, bytes): - msg = f"The `getHashes` method for {contract_address=} returned non-bytes {hash_=} for {agent_id=}: {res}" - return dict(error=msg) - - # return the hash in hex - return dict(hash=hash_.hex()) diff --git a/trader_backup/vendor/valory/contracts/agent_registry/contract.yaml b/trader_backup/vendor/valory/contracts/agent_registry/contract.yaml deleted file mode 100644 index c0207fc24..000000000 --- a/trader_backup/vendor/valory/contracts/agent_registry/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: agent_registry -author: valory -version: 0.1.0 -type: contract -description: Agent Registry contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeid3wfzglolebuo6jrrsopswzu4lk77bm76mvw3euizlsjtnt3wmgu - build/AgentRegistry.json: bafybeicoe5elvvsv2neiirsdn4uddrilizmyib3x4mvpklr7olhj2kh4ue - contract.py: bafybeihrv6blme3v6diwci6zxxn72qbg5sanzmfq5tobhs4375ebcuyday -fingerprint_ignore_patterns: [] -contracts: [] -class_name: AgentRegistryContract -contract_interface_paths: - ethereum: build/AgentRegistry.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - web3: - version: <7,>=6.0.0 diff --git a/trader_backup/vendor/valory/contracts/conditional_tokens/__init__.py b/trader_backup/vendor/valory/contracts/conditional_tokens/__init__.py deleted file mode 100644 index 047a3b03a..000000000 --- a/trader_backup/vendor/valory/contracts/conditional_tokens/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for the ConditionalTokens contract.""" diff --git a/trader_backup/vendor/valory/contracts/conditional_tokens/build/ConditionalTokens.json b/trader_backup/vendor/valory/contracts/conditional_tokens/build/ConditionalTokens.json deleted file mode 100644 index 3906d3592..000000000 --- a/trader_backup/vendor/valory/contracts/conditional_tokens/build/ConditionalTokens.json +++ /dev/null @@ -1,708 +0,0 @@ -{ - "abi": [ - { - "constant": true, - "inputs": [ - { - "name": "owner", - "type": "address" - }, - { - "name": "id", - "type": "uint256" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "collateralToken", - "type": "address" - }, - { - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "name": "conditionId", - "type": "bytes32" - }, - { - "name": "indexSets", - "type": "uint256[]" - } - ], - "name": "redeemPositions", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - }, - { - "name": "", - "type": "uint256" - } - ], - "name": "payoutNumerators", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "from", - "type": "address" - }, - { - "name": "to", - "type": "address" - }, - { - "name": "ids", - "type": "uint256[]" - }, - { - "name": "values", - "type": "uint256[]" - }, - { - "name": "data", - "type": "bytes" - } - ], - "name": "safeBatchTransferFrom", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "collateralToken", - "type": "address" - }, - { - "name": "collectionId", - "type": "bytes32" - } - ], - "name": "getPositionId", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "pure", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "owners", - "type": "address[]" - }, - { - "name": "ids", - "type": "uint256[]" - } - ], - "name": "balanceOfBatch", - "outputs": [ - { - "name": "", - "type": "uint256[]" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "collateralToken", - "type": "address" - }, - { - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "name": "conditionId", - "type": "bytes32" - }, - { - "name": "partition", - "type": "uint256[]" - }, - { - "name": "amount", - "type": "uint256" - } - ], - "name": "splitPosition", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "oracle", - "type": "address" - }, - { - "name": "questionId", - "type": "bytes32" - }, - { - "name": "outcomeSlotCount", - "type": "uint256" - } - ], - "name": "getConditionId", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "pure", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "name": "conditionId", - "type": "bytes32" - }, - { - "name": "indexSet", - "type": "uint256" - } - ], - "name": "getCollectionId", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "collateralToken", - "type": "address" - }, - { - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "name": "conditionId", - "type": "bytes32" - }, - { - "name": "partition", - "type": "uint256[]" - }, - { - "name": "amount", - "type": "uint256" - } - ], - "name": "mergePositions", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "operator", - "type": "address" - }, - { - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "questionId", - "type": "bytes32" - }, - { - "name": "payouts", - "type": "uint256[]" - } - ], - "name": "reportPayouts", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "conditionId", - "type": "bytes32" - } - ], - "name": "getOutcomeSlotCount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "oracle", - "type": "address" - }, - { - "name": "questionId", - "type": "bytes32" - }, - { - "name": "outcomeSlotCount", - "type": "uint256" - } - ], - "name": "prepareCondition", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "payoutDenominator", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "owner", - "type": "address" - }, - { - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "from", - "type": "address" - }, - { - "name": "to", - "type": "address" - }, - { - "name": "id", - "type": "uint256" - }, - { - "name": "value", - "type": "uint256" - }, - { - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "conditionId", - "type": "bytes32" - }, - { - "indexed": true, - "name": "oracle", - "type": "address" - }, - { - "indexed": true, - "name": "questionId", - "type": "bytes32" - }, - { - "indexed": false, - "name": "outcomeSlotCount", - "type": "uint256" - } - ], - "name": "ConditionPreparation", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "conditionId", - "type": "bytes32" - }, - { - "indexed": true, - "name": "oracle", - "type": "address" - }, - { - "indexed": true, - "name": "questionId", - "type": "bytes32" - }, - { - "indexed": false, - "name": "outcomeSlotCount", - "type": "uint256" - }, - { - "indexed": false, - "name": "payoutNumerators", - "type": "uint256[]" - } - ], - "name": "ConditionResolution", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "stakeholder", - "type": "address" - }, - { - "indexed": false, - "name": "collateralToken", - "type": "address" - }, - { - "indexed": true, - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "indexed": true, - "name": "conditionId", - "type": "bytes32" - }, - { - "indexed": false, - "name": "partition", - "type": "uint256[]" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "PositionSplit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "stakeholder", - "type": "address" - }, - { - "indexed": false, - "name": "collateralToken", - "type": "address" - }, - { - "indexed": true, - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "indexed": true, - "name": "conditionId", - "type": "bytes32" - }, - { - "indexed": false, - "name": "partition", - "type": "uint256[]" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "PositionsMerge", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "redeemer", - "type": "address" - }, - { - "indexed": true, - "name": "collateralToken", - "type": "address" - }, - { - "indexed": true, - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "indexed": false, - "name": "conditionId", - "type": "bytes32" - }, - { - "indexed": false, - "name": "indexSets", - "type": "uint256[]" - }, - { - "indexed": false, - "name": "payout", - "type": "uint256" - } - ], - "name": "PayoutRedemption", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "name": "from", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" - }, - { - "indexed": false, - "name": "id", - "type": "uint256" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "TransferSingle", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "name": "from", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" - }, - { - "indexed": false, - "name": "ids", - "type": "uint256[]" - }, - { - "indexed": false, - "name": "values", - "type": "uint256[]" - } - ], - "name": "TransferBatch", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "value", - "type": "string" - }, - { - "indexed": true, - "name": "id", - "type": "uint256" - } - ], - "name": "URI", - "type": "event" - } - ], - "bytecode": "6080604052620000387f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b036200007216565b6200006c7fd9b67a26000000000000000000000000000000000000000000000000000000006001600160e01b036200007216565b62000141565b7fffffffff0000000000000000000000000000000000000000000000000000000080821614156200010457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152602081905260409020805460ff19166001179055565b6139b380620001516000396000f3fe608060405234801561001057600080fd5b50600436106101155760003560e01c8063856296f7116100a2578063d42dc0c211610071578063d42dc0c21461071a578063d96ee75414610737578063dd34de6714610769578063e985e9c514610786578063f242432a146107b457610115565b8063856296f7146105c45780639e7212ad146105ed578063a22cb46514610677578063c49298ac146106a557610115565b80632eb2c2d6116100e95780632eb2c2d61461024257806339dd7530146103695780634e1273f41461039557806372ce427514610508578063852c6ae21461059257610115565b8062fdd58e1461011a57806301b7037c1461015857806301ffc9a7146101e45780630504c8141461021f575b600080fd5b6101466004803603604081101561013057600080fd5b506001600160a01b038135169060200135610847565b60408051918252519081900360200190f35b6101e26004803603608081101561016e57600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b8111156101a457600080fd5b8201836020820111156101b657600080fd5b803590602001918460208302840111600160201b831117156101d757600080fd5b5090925090506108b9565b005b61020b600480360360208110156101fa57600080fd5b50356001600160e01b031916610c38565b604080519115158252519081900360200190f35b6101466004803603604081101561023557600080fd5b5080359060200135610c57565b6101e2600480360360a081101561025857600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561028b57600080fd5b82018360208201111561029d57600080fd5b803590602001918460208302840111600160201b831117156102be57600080fd5b919390929091602081019035600160201b8111156102db57600080fd5b8201836020820111156102ed57600080fd5b803590602001918460208302840111600160201b8311171561030e57600080fd5b919390929091602081019035600160201b81111561032b57600080fd5b82018360208201111561033d57600080fd5b803590602001918460018302840111600160201b8311171561035e57600080fd5b509092509050610c85565b6101466004803603604081101561037f57600080fd5b506001600160a01b038135169060200135611012565b6104b8600480360360408110156103ab57600080fd5b810190602081018135600160201b8111156103c557600080fd5b8201836020820111156103d757600080fd5b803590602001918460208302840111600160201b831117156103f857600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561044757600080fd5b82018360208201111561045957600080fd5b803590602001918460208302840111600160201b8311171561047a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611025945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156104f45781810151838201526020016104dc565b505050509050019250505060405180910390f35b6101e2600480360360a081101561051e57600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b81111561055457600080fd5b82018360208201111561056657600080fd5b803590602001918460208302840111600160201b8311171561058757600080fd5b91935091503561118c565b610146600480360360608110156105a857600080fd5b506001600160a01b038135169060208101359060400135611573565b610146600480360360608110156105da57600080fd5b5080359060208101359060400135611588565b6101e2600480360360a081101561060357600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b81111561063957600080fd5b82018360208201111561064b57600080fd5b803590602001918460208302840111600160201b8311171561066c57600080fd5b919350915035611595565b6101e26004803603604081101561068d57600080fd5b506001600160a01b038135169060200135151561198c565b6101e2600480360360408110156106bb57600080fd5b81359190810190604081016020820135600160201b8111156106dc57600080fd5b8201836020820111156106ee57600080fd5b803590602001918460208302840111600160201b8311171561070f57600080fd5b5090925090506119fa565b6101466004803603602081101561073057600080fd5b5035611ce4565b6101e26004803603606081101561074d57600080fd5b506001600160a01b038135169060208101359060400135611cf6565b6101466004803603602081101561077f57600080fd5b5035611e8e565b61020b6004803603604081101561079c57600080fd5b506001600160a01b0381358116916020013516611ea0565b6101e2600480360360a08110156107ca57600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b81111561080957600080fd5b82018360208201111561081b57600080fd5b803590602001918460018302840111600160201b8311171561083c57600080fd5b509092509050611ece565b60006001600160a01b03831661088e5760405162461bcd60e51b815260040180806020018281038252602b8152602001806136fc602b913960400191505060405180910390fd5b5060008181526001602090815260408083206001600160a01b03861684529091529020545b92915050565b600083815260046020526040902054806109045760405162461bcd60e51b81526004018080602001828103825260258152602001806136d76025913960400191505060405180910390fd5b60008481526003602052604090205480610962576040805162461bcd60e51b815260206004820152601a60248201527918dbdb991a5d1a5bdb881b9bdd081c1c995c185c9959081e595d60321b604482015290519081900360640190fd5b60006000196001831b01815b85811015610aba57600087878381811061098457fe5b90506020020135905060008111801561099c57508281105b6109e5576040805162461bcd60e51b815260206004820152601560248201527419dbdd081a5b9d985b1a59081a5b99195e081cd95d605a1b604482015290519081900360640190fd5b60006109fb8c6109f68d8d866120aa565b6123d9565b90506000805b87811015610a58576001811b841615610a505760008c81526003602052604090208054610a4d919083908110610a3357fe5b90600052602060002001548361241d90919063ffffffff16565b91505b600101610a01565b506000610a653384610847565b90508015610aaa57610a9d610a908a610a84848663ffffffff61247716565b9063ffffffff6124d016565b889063ffffffff61241d16565b9650610aaa33848361253a565b50506001909201915061096e9050565b508115610ba55787610b81576040805163a9059cbb60e01b81523360048201526024810184905290516001600160a01b038b169163a9059cbb9160448083019260209291908290030181600087803b158015610b1557600080fd5b505af1158015610b29573d6000803e3d6000fd5b505050506040513d6020811015610b3f57600080fd5b5051610b7c5760405162461bcd60e51b815260040180806020018281038252602b815260200180613727602b913960400191505060405180910390fd5b610ba5565b610ba533610b8f8b8b6123d9565b84604051806020016040528060008152506125d5565b87896001600160a01b0316336001600160a01b03167f2682012a4a4f1973119f1c9b90745d1bd91fa2bab387344f044cb3586864d18d8a8a8a8860405180858152602001806020018381526020018281038252858582818152602001925060200280828437600083820152604051601f909101601f191690920182900397509095505050505050a4505050505050505050565b6001600160e01b03191660009081526020819052604090205460ff1690565b60036020528160005260406000208181548110610c7057fe5b90600052602060002001600091509150505481565b848314610cc35760405162461bcd60e51b815260040180806020018281038252602e815260200180613876602e913960400191505060405180910390fd5b6001600160a01b038716610d085760405162461bcd60e51b81526004018080602001828103825260288152602001806137526028913960400191505060405180910390fd5b6001600160a01b038816331480610d4757506001600160a01b038816600090815260026020908152604080832033845290915290205460ff1615156001145b610d825760405162461bcd60e51b81526004018080602001828103825260388152602001806138a46038913960400191505060405180910390fd5b60005b85811015610eb2576000878783818110610d9b57fe5b9050602002013590506000868684818110610db257fe5b905060200201359050610e04816001600085815260200190815260200160002060008e6001600160a01b03166001600160a01b03168152602001908152602001600020546126c390919063ffffffff16565b6001600084815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002081905550610e876001600084815260200190815260200160002060008c6001600160a01b03166001600160a01b03168152602001908152602001600020548261241d90919063ffffffff16565b60009283526001602081815260408086206001600160a01b038f168752909152909320555001610d85565b50866001600160a01b0316886001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb898989896040518080602001806020018381038352878782818152602001925060200280828437600083820152601f01601f19169091018481038352858152602090810191508690860280828437600083820152604051601f909101601f19169092018290039850909650505050505050a461100833898989898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b91829185019084908082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a915089908190840183828082843760009201919091525061272092505050565b5050505050505050565b600061101e83836123d9565b9392505050565b606081518351146110675760405162461bcd60e51b815260040180806020018281038252602e815260200180613848602e913960400191505060405180910390fd5b60608351604051908082528060200260200182016040528015611094578160200160208202803883390190505b50905060005b84518110156111845760006001600160a01b03168582815181106110ba57fe5b60200260200101516001600160a01b031614156111085760405162461bcd60e51b81526004018080602001828103825260348152602001806137f36034913960400191505060405180910390fd5b6001600085838151811061111857fe5b60200260200101518152602001908152602001600020600086838151811061113c57fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061117157fe5b602090810291909101015260010161109a565b509392505050565b600182116111e1576040805162461bcd60e51b815260206004820181905260248201527f676f7420656d707479206f722073696e676c65746f6e20706172746974696f6e604482015290519081900360640190fd5b6000848152600360205260409020548061123f576040805162461bcd60e51b815260206004820152601a60248201527918dbdb991a5d1a5bdb881b9bdd081c1c995c185c9959081e595d60321b604482015290519081900360640190fd5b6040805184815260208086028201019091526000196001831b01908190606090868015611276578160200160208202803883390190505b5090506060878790506040519080825280602002602001820160405280156112a8578160200160208202803883390190505b50905060005b878110156113c05760008989838181106112c457fe5b9050602002013590506000811180156112dc57508581105b611325576040805162461bcd60e51b815260206004820152601560248201527419dbdd081a5b9d985b1a59081a5b99195e081cd95d605a1b604482015290519081900360640190fd5b8085821614611374576040805162461bcd60e51b81526020600482015260166024820152751c185c9d1a5d1a5bdb881b9bdd08191a5cda9bda5b9d60521b604482015290519081900360640190fd5b938418936113878d6109f68e8e856120aa565b84838151811061139357fe5b602002602001018181525050878383815181106113ac57fe5b6020908102919091010152506001016112ae565b50826114a5578961148c57604080516323b872dd60e01b81523360048201523060248201526044810188905290516001600160a01b038d16916323b872dd9160648083019260209291908290030181600087803b15801561142057600080fd5b505af1158015611434573d6000803e3d6000fd5b505050506040513d602081101561144a57600080fd5b50516114875760405162461bcd60e51b81526004018080602001828103825260238152602001806137d06023913960400191505060405180910390fd5b6114a0565b6114a03361149a8d8d6123d9565b8861253a565b6114ba565b6114ba3361149a8d6109f68e8e898b186120aa565b6114d5338383604051806020016040528060008152506128fd565b888a336001600160a01b03167f2e6bb91f8cbcda0c93623c54d0403a43514fabc40084ec96b6d5379a747862988e8c8c8c60405180856001600160a01b03166001600160a01b03168152602001806020018381526020018281038252858582818152602001925060200280828437600083820152604051601f909101601f191690920182900397509095505050505050a45050505050505050505050565b6000611580848484612b30565b949350505050565b60006115808484846120aa565b600182116115ea576040805162461bcd60e51b815260206004820181905260248201527f676f7420656d707479206f722073696e676c65746f6e20706172746974696f6e604482015290519081900360640190fd5b60008481526003602052604090205480611648576040805162461bcd60e51b815260206004820152601a60248201527918dbdb991a5d1a5bdb881b9bdd081c1c995c185c9959081e595d60321b604482015290519081900360640190fd5b6040805184815260208086028201019091526000196001831b0190819060609086801561167f578160200160208202803883390190505b5090506060878790506040519080825280602002602001820160405280156116b1578160200160208202803883390190505b50905060005b878110156117c95760008989838181106116cd57fe5b9050602002013590506000811180156116e557508581105b61172e576040805162461bcd60e51b815260206004820152601560248201527419dbdd081a5b9d985b1a59081a5b99195e081cd95d605a1b604482015290519081900360640190fd5b808582161461177d576040805162461bcd60e51b81526020600482015260166024820152751c185c9d1a5d1a5bdb881b9bdd08191a5cda9bda5b9d60521b604482015290519081900360640190fd5b938418936117908d6109f68e8e856120aa565b84838151811061179c57fe5b602002602001018181525050878383815181106117b557fe5b6020908102919091010152506001016116b7565b506117d5338383612b7d565b826118d957896118b0576040805163a9059cbb60e01b81523360048201526024810188905290516001600160a01b038d169163a9059cbb9160448083019260209291908290030181600087803b15801561182e57600080fd5b505af1158015611842573d6000803e3d6000fd5b505050506040513d602081101561185857600080fd5b50516118ab576040805162461bcd60e51b815260206004820181905260248201527f636f756c64206e6f742073656e6420636f6c6c61746572616c20746f6b656e73604482015290519081900360640190fd5b6118d4565b6118d4336118be8d8d6123d9565b88604051806020016040528060008152506125d5565b6118ee565b6118ee336118be8d6109f68e8e898b186120aa565b888a336001600160a01b03167f6f13ca62553fcc2bcd2372180a43949c1e4cebba603901ede2f4e14f36b282ca8e8c8c8c60405180856001600160a01b03166001600160a01b03168152602001806020018381526020018281038252858582818152602001925060200280828437600083820152604051601f909101601f191690920182900397509095505050505050a45050505050505050505050565b3360008181526002602090815260408083206001600160a01b03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b8060018111611a3a5760405162461bcd60e51b815260040180806020018281038252602a8152602001806138dc602a913960400191505060405180910390fd5b6000611a47338684612b30565b6000818152600360205260409020549091508214611aac576040805162461bcd60e51b815260206004820152601f60248201527f636f6e646974696f6e206e6f74207072657061726564206f7220666f756e6400604482015290519081900360640190fd5b60008181526004602052604090205415611b0d576040805162461bcd60e51b815260206004820152601e60248201527f7061796f75742064656e6f6d696e61746f7220616c7265616479207365740000604482015290519081900360640190fd5b6000805b83811015611bf2576000868683818110611b2757fe5b905060200201359050611b43818461241d90919063ffffffff16565b600085815260036020526040902080549194509083908110611b6157fe5b9060005260206000200154600014611bc0576040805162461bcd60e51b815260206004820152601c60248201527f7061796f7574206e756d657261746f7220616c72656164792073657400000000604482015290519081900360640190fd5b6000848152600360205260409020805482919084908110611bdd57fe5b60009182526020909120015550600101611b11565b5060008111611c3f576040805162461bcd60e51b81526020600482015260146024820152737061796f757420697320616c6c207a65726f657360601b604482015290519081900360640190fd5b60008281526004602090815260408083208490556003825291829020825186815291820183815281549383018490528993339387937fb44d84d3289691f71497564b85d4233648d9dbae8cbdbb4329f301c3a0185894938a93919291606083019084908015611ccd57602002820191906000526020600020905b815481526020019060010190808311611cb9575b5050935050505060405180910390a4505050505050565b60009081526003602052604090205490565b610100811115611d46576040805162461bcd60e51b8152602060048201526016602482015275746f6f206d616e79206f7574636f6d6520736c6f747360501b604482015290519081900360640190fd5b60018111611d855760405162461bcd60e51b815260040180806020018281038252602a8152602001806138dc602a913960400191505060405180910390fd5b6000611d92848484612b30565b60008181526003602052604090205490915015611df6576040805162461bcd60e51b815260206004820152601a60248201527f636f6e646974696f6e20616c7265616479207072657061726564000000000000604482015290519081900360640190fd5b81604051908082528060200260200182016040528015611e20578160200160208202803883390190505b5060008281526003602090815260409091208251611e44939192919091019061366e565b5082846001600160a01b0316827fab3760c3bd2bb38b5bcf54dc79802ed67338b4cf29f3054ded67ed24661e4177856040518082815260200191505060405180910390a450505050565b60046020526000908152604090205481565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205460ff1690565b6001600160a01b038516611f135760405162461bcd60e51b81526004018080602001828103825260288152602001806137526028913960400191505060405180910390fd5b6001600160a01b038616331480611f5257506001600160a01b038616600090815260026020908152604080832033845290915290205460ff1615156001145b611f8d5760405162461bcd60e51b81526004018080602001828103825260388152602001806138a46038913960400191505060405180910390fd5b60008481526001602090815260408083206001600160a01b038a168452909152902054611fc0908463ffffffff6126c316565b60008581526001602090815260408083206001600160a01b038b81168552925280832093909355871681522054611ff890849061241d565b60008581526001602090815260408083206001600160a01b03808b16808652918452938290209490945580518881529182018790528051928a169233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a46120a2338787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612d6192505050565b505050505050565b6040805160208082018590528183018490528251808303840181526060909201909252805191012060009060ff81901c151582805b60008051602061377a83398151915260018508935060008051602061377a833981519152600360008051602061377a83398151915280878809870908905061212681612ec3565b91508060008051602061377a83398151915283840914156120df5782801561214f575060028206155b806121665750821580156121665750600282066001145b1561217f578160008051602061377a8339815191520391505b8780156123b65760fe81901c151593506001600160fe1b031660008051602061377a833981519152600360008051602061377a83398151915280848509840908915060006121cc83612ec3565b90508480156121dc575060028106155b806121f35750841580156121f35750600281066001145b156122095760008051602061377a833981519152035b8260008051602061377a8339815191528283091461226e576040805162461bcd60e51b815260206004820152601c60248201527f696e76616c696420706172656e7420636f6c6c656374696f6e20494400000000604482015290519081900360640190fd5b6000606060066001600160a01b031688878686604051602001808581526020018481526020018381526020018281526020019450505050506040516020818303038152906040526040518082805190602001908083835b602083106122e45780518252601f1990920191602091820191016122c5565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114612344576040519150601f19603f3d011682016040523d82523d6000602084013e612349565b606091505b50915091508161238f576040805162461bcd60e51b815260206004820152600c60248201526b1958d859190819985a5b195960a21b604482015290519081900360640190fd5b8080602001905160408110156123a457600080fd5b50805160209091015190985095505050505b60028306600114156123cc57600160fe1b851894505b5092979650505050505050565b6040805160609390931b6bffffffffffffffffffffffff19166020808501919091526034808501939093528151808503909301835260549093019052805191012090565b60008282018381101561101e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082612486575060006108b3565b8282028284828161249357fe5b041461101e5760405162461bcd60e51b81526004018080602001828103825260218152602001806138276021913960400191505060405180910390fd5b6000808211612526576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848161253157fe5b04949350505050565b60008281526001602090815260408083206001600160a01b038716845290915290205461256d908263ffffffff6126c316565b60008381526001602090815260408083206001600160a01b038816808552908352818420949094558051868152918201859052805192939233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a4505050565b6001600160a01b03841661261a5760405162461bcd60e51b815260040180806020018281038252602181526020018061392d6021913960400191505060405180910390fd5b60008381526001602090815260408083206001600160a01b038816845290915290205461264e90839063ffffffff61241d16565b60008481526001602090815260408083206001600160a01b038916808552908352818420949094558051878152918201869052805133927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a46126bd33600086868686612d61565b50505050565b60008282111561271a576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b612732846001600160a01b0316613668565b156120a25760405163bc197c8160e01b8082526001600160a01b0388811660048401908152888216602485015260a060448501908152875160a4860152875193949289169363bc197c81938c938c938b938b938b9392916064820191608481019160c4909101906020808a01910280838360005b838110156127be5781810151838201526020016127a6565b50505050905001848103835286818151815260200191508051906020019060200280838360005b838110156127fd5781810151838201526020016127e5565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015612839578181015183820152602001612821565b50505050905090810190601f1680156128665780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b15801561288b57600080fd5b505af115801561289f573d6000803e3d6000fd5b505050506040513d60208110156128b557600080fd5b50516001600160e01b031916146120a25760405162461bcd60e51b815260040180806020018281038252603681526020018061379a6036913960400191505060405180910390fd5b6001600160a01b0384166129425760405162461bcd60e51b81526004018080602001828103825260278152602001806139066027913960400191505060405180910390fd5b81518351146129825760405162461bcd60e51b815260040180806020018281038252602e815260200180613876602e913960400191505060405180910390fd5b60005b8351811015612a46576129fd600160008684815181106129a157fe5b602002602001015181526020019081526020016000206000876001600160a01b03166001600160a01b03168152602001908152602001600020548483815181106129e757fe5b602002602001015161241d90919063ffffffff16565b60016000868481518110612a0d57fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038a168252909252902055600101612985565b50836001600160a01b031660006001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015612acd578181015183820152602001612ab5565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612b0c578181015183820152602001612af4565b5050505090500194505050505060405180910390a46126bd33600086868686612720565b6040805160609490941b6bffffffffffffffffffffffff19166020808601919091526034850193909352605480850192909252805180850390920182526074909301909252815191012090565b8051825114612bbd5760405162461bcd60e51b815260040180806020018281038252602e815260200180613876602e913960400191505060405180910390fd5b60005b8251811015612c8157612c38828281518110612bd857fe5b602002602001015160016000868581518110612bf057fe5b602002602001015181526020019081526020016000206000876001600160a01b03166001600160a01b03168152602001908152602001600020546126c390919063ffffffff16565b60016000858481518110612c4857fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b0389168252909252902055600101612bc0565b5060006001600160a01b0316836001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8585604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015612d08578181015183820152602001612cf0565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612d47578181015183820152602001612d2f565b5050505090500194505050505060405180910390a4505050565b612d73846001600160a01b0316613668565b156120a25760405163f23a6e6160e01b8082526001600160a01b03888116600484019081528882166024850152604484018790526064840186905260a060848501908152855160a4860152855193949289169363f23a6e61938c938c938b938b938b93929160c490910190602085019080838360005b83811015612e01578181015183820152602001612de9565b50505050905090810190601f168015612e2e5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b158015612e5157600080fd5b505af1158015612e65573d6000803e3d6000fd5b505050506040513d6020811015612e7b57600080fd5b50516001600160e01b031916146120a25760405162461bcd60e51b815260040180806020018281038252603181526020018061394e6031913960400191505060405180910390fd5b600060008051602061377a833981519152808380099150808283098181820990508181840992508183850993508184840992508183840990508181820982818309905082818209905082818209905082818309915082828609945082858609915082828309915082828509935082848509915082828309915082828309915082828509915082828609945082858609915082828309915082828309915082828609915082828509935082848609945082858609915082828309915082828509935082848509915082828309905082818209905082818209905082818309915082828609945082858509935082848509915082828309915082828309915082828609945082858609915082828309915082828609915082828309915082828309915082828609915082828509935082848509915082828309905082818209905082818309905082818509905082818209905082818209905082818209905082818209905082818309915082828609945082858609915082828609915082828509935082848509915082828509915082828309915082828309905082818309905082818209838182099050838182099050838182099050838182099050838183099150508281830991508282860994508285850993508284850991508282860994508285850993508284860994508285850993508284860994508285860991508282860991508282830991508282850993508284850991508282830991508282860994508285850993508284850991508282850991508282860994508285850993508284860994508285850993508284850991508282830991508282850991508282860994508285860991508282860991508282850993508284860994508285850993508284860994508285850993508284850991508282850991508282830991508282860994508285850993508284850991508282850991508282830991508282860994508285860991508282830990508281820990508281830990508281860990508281820990508281820990508281820990508281820990508281830991508282850993508284860994508285850993508284860994508285860991508282860991508282830991508282830991508282830991508282860991508282850993508284850991508282850991508282830991508282860994508285860991508282860991508282850993508284860994508285860991508282830991508282850993508284860994508285860991508282850993508284860994508285850993508284850991508282850991508282860994508285850993508284850991508282850991508282830991508282830991508282860994508285860991508282830991508282830991508282860991508282850993508284860994508285860991508282860990508281820990508281820990508281830991508282850993508284850991508282860994508285850993508284860994508285850993508284860994508285850993508284850991508282850990508281850991508282830991508282830991508282820991505081818509935081848409925081838509935081848409925081838509935081848509905081818509905081818409925050808284099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808383099392505050565b3b151590565b8280548282559060005260206000209081019282156136a9579160200282015b828111156136a957825182559160200191906001019061368e565b506136b59291506136b9565b5090565b6136d391905b808211156136b557600081556001016136bf565b9056fe726573756c7420666f7220636f6e646974696f6e206e6f7420726563656976656420796574455243313135353a2062616c616e636520717565727920666f7220746865207a65726f2061646472657373636f756c64206e6f74207472616e73666572207061796f757420746f206d6573736167652073656e646572455243313135353a207461726765742061646472657373206d757374206265206e6f6e2d7a65726f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47455243313135353a20676f7420756e6b6e6f776e2076616c75652066726f6d206f6e4552433131353542617463685265636569766564636f756c64206e6f74207265636569766520636f6c6c61746572616c20746f6b656e73455243313135353a20736f6d65206164647265737320696e2062617463682062616c616e6365207175657279206973207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77455243313135353a206f776e65727320616e6420494473206d75737420686176652073616d65206c656e67746873455243313135353a2049447320616e642076616c756573206d75737420686176652073616d65206c656e67746873455243313135353a206e656564206f70657261746f7220617070726f76616c20666f7220337264207061727479207472616e73666572732e74686572652073686f756c64206265206d6f7265207468616e206f6e65206f7574636f6d6520736c6f74455243313135353a206261746368206d696e7420746f20746865207a65726f2061646472657373455243313135353a206d696e7420746f20746865207a65726f2061646472657373455243313135353a20676f7420756e6b6e6f776e2076616c75652066726f6d206f6e455243313135355265636569766564a265627a7a72305820bb492e79ca824aaf4ea2279d9e6fd09603dd4860390a782c93aaffb1144f4b5064736f6c634300050a0032" -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/conditional_tokens/contract.py b/trader_backup/vendor/valory/contracts/conditional_tokens/contract.py deleted file mode 100644 index bc7485e15..000000000 --- a/trader_backup/vendor/valory/contracts/conditional_tokens/contract.py +++ /dev/null @@ -1,420 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the conditional tokens contract definition.""" -import concurrent.futures -from typing import List, Any, Dict, Union, Callable - -from requests.exceptions import ReadTimeout as RequestsReadTimeoutError -from urllib3.exceptions import ReadTimeoutError as Urllib3ReadTimeoutError -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from hexbytes import HexBytes -from web3.types import BlockIdentifier - - -FIVE_MINUTES = 300.0 -DEFAULT_OUTCOME_SLOT = 2 - -class ConditionalTokensContract(Contract): - """The ConditionalTokens smart contract.""" - - contract_id = PublicId.from_str("valory/conditional_tokens:0.1.0") - - @staticmethod - def execute_with_timeout(func: Callable, timeout: float) -> Any: - """Execute a function with a timeout.""" - - # Create a ProcessPoolExecutor with a maximum of 1 worker (process) - with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: - # Submit the function to the executor - future = executor.submit( - func, - ) - - try: - # Wait for the result with a 5-minute timeout - data = future.result(timeout=timeout) - except TimeoutError: - # Handle the case where the execution times out - err = f"The RPC didn't respond in {timeout}." - return None, err - - # Check if an error occurred - if isinstance(data, str): - # Handle the case where the execution failed - return None, data - - return data, None - - @classmethod - def check_redeemed( - cls, - ledger_api: LedgerApi, - contract_address: str, - redeemer: str, - from_block: int, - to_block: int, - collateral_tokens: List[str], - parent_collection_ids: List[bytes], - condition_ids: List[HexBytes], - index_sets: List[List[int]], - timeout: float = FIVE_MINUTES, - ) -> JSONLike: - """Filter to find out whether a position has already been redeemed.""" - - def get_redeem_events() -> Union[List[Dict[str, Any]], str]: - """Get the redeem events.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - to_checksum = ledger_api.api.to_checksum_address - redeemer_checksummed = to_checksum(redeemer) - collateral_tokens_checksummed = [ - to_checksum(token) for token in collateral_tokens - ] - try: - payout_filter = contract_instance.events.PayoutRedemption.build_filter() - payout_filter.args.redeemer.match_single(redeemer_checksummed) - payout_filter.args.collateralToken.match_any(*collateral_tokens_checksummed) - payout_filter.args.parentCollectionId.match_any(*parent_collection_ids) - payout_filter.args.conditionId.match_any(*condition_ids) - payout_filter.args.indexSets.match_any(*index_sets) - payout_filter.fromBlock = from_block - payout_filter.toBlock = to_block - redeemed = list(payout_filter.deploy(ledger_api.api).get_all_entries()) - return redeemed - - except (Urllib3ReadTimeoutError, RequestsReadTimeoutError): - msg = ( - "The RPC timed out! This usually happens if the filtering is too wide. " - f"The service tried to filter from block {from_block} to {to_block}. " - f"If this issue persists, please try lowering the `EVENT_FILTERING_BATCH_SIZE`!" - ) - return msg - - redeemed, err = cls.execute_with_timeout(get_redeem_events, timeout) - if err is not None: - return dict(error=err) - - payouts = {} - for redeeming in redeemed: - args = redeeming.get("args", {}) - condition_id = args.get("conditionId", None) - payout = args.get("payout", 0) - if condition_id is not None and payout > 0: - if isinstance(condition_id, bytes): - condition_id = condition_id.hex() - payouts[condition_id] = payout - - return dict(payouts=payouts) - - @classmethod - def check_resolved( - cls, - ledger_api: LedgerApi, - contract_address: str, - condition_id: HexBytes, - ) -> JSONLike: - """Check whether a position has already been resolved.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - payout_denominator = contract_instance.functions.payoutDenominator - payout = payout_denominator(condition_id).call() - if payout == 0: - return dict(resolved=False) - return dict(resolved=True) - - @classmethod - def build_redeem_positions_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - collateral_token: str, - parent_collection_id: bytes, - condition_id: HexBytes, - index_sets: List[int], - ) -> JSONLike: - """Build a `redeemPositions` tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI( - fn_name="redeemPositions", - args=[ - ledger_api.api.to_checksum_address(collateral_token), - parent_collection_id, - condition_id, - index_sets, - ], - ) - return dict(data=data) - - @classmethod - def get_raw_transaction( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> JSONLike: - """ - Handler method for the 'GET_RAW_TRANSACTION' requests. - - Implement this method in the sub class if you want - to handle the contract requests manually. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param kwargs: the keyword arguments. - :return: the tx # noqa: DAR202 - """ - raise NotImplementedError - - @classmethod - def get_raw_message( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> bytes: - """ - Handler method for the 'GET_RAW_MESSAGE' requests. - - Implement this method in the sub class if you want - to handle the contract requests manually. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param kwargs: the keyword arguments. - :return: the tx # noqa: DAR202 - """ - raise NotImplementedError - - @classmethod - def get_state( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> JSONLike: - """ - Handler method for the 'GET_STATE' requests. - - Implement this method in the sub class if you want - to handle the contract requests manually. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param kwargs: the keyword arguments. - :return: the tx # noqa: DAR202 - """ - raise NotImplementedError - - @classmethod - def get_prepare_condition_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: str, - oracle_contract: str, - outcome_slot_count: int = DEFAULT_OUTCOME_SLOT, - ) -> JSONLike: - """Tx for preparing condition for marker maker.""" - kwargs = { - "oracle": ledger_api.api.to_checksum_address(oracle_contract), - "questionId": question_id, - "outcomeSlotCount": outcome_slot_count, - } - return ledger_api.build_transaction( - contract_instance=cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ), - method_name="prepareCondition", - method_args=kwargs, - ) - - @classmethod - def get_prepare_condition_tx_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: str, - oracle_contract: str, - outcome_slot_count: int = DEFAULT_OUTCOME_SLOT, - ) -> JSONLike: - """Tx for preparing condition for marker maker.""" - kwargs = { - "oracle": ledger_api.api.to_checksum_address(oracle_contract), - "questionId": question_id, - "outcomeSlotCount": outcome_slot_count, - } - contract_instance = cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - data = contract_instance.encodeABI(fn_name="prepareCondition", kwargs=kwargs) - return {"data": bytes.fromhex(data[2:])} - - @classmethod - def calculate_condition_id( - cls, - ledger_api: LedgerApi, - contract_address: str, - oracle_contract: str, - question_id: str, - outcome_slot_count: int, - ) -> str: - """Calculate condition ID.""" - return { - "condition_id": ledger_api.api.solidity_keccak( - ["address", "bytes32", "uint256"], - [ - ledger_api.api.to_checksum_address(oracle_contract), - bytes.fromhex(question_id[2:]), - outcome_slot_count, - ], - ).hex() - } - - @classmethod - def get_condition_id( - cls, - ledger_api: LedgerApi, - contract_address: str, - tx_digest: str, # retrieved from `prepareCondition` tx - ) -> JSONLike: - """Tx for preparing condition for marker maker.""" - contract_instance = cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - tx_receipt = ledger_api.api.eth.getTransactionReceipt(tx_digest) - (log,) = contract_instance.events.ConditionPreparation().process_receipt( - tx_receipt - ) - return "0x" + log["args"]["conditionId"].hex() - - @classmethod - def get_condition_preparation_events( - cls, - ledger_api: LedgerApi, - contract_address: str, - condition_ids: List[bytes], - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - ) -> JSONLike: - """Get condition preparation events.""" - contract_instance = cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - entries = ( - contract_instance.events.ConditionPreparation() - .create_filter( - fromBlock=from_block, - toBlock=to_block, - argument_filters={ - "conditionId": condition_ids, - }, - ) - .get_all_entries() - ) - events = list( - dict( - tx_hash=entry.transactionHash.hex(), - block_number=entry.blockNumber, - condition_id=entry["args"]["conditionId"], - oracle=entry["args"]["oracle"], - question_id=entry["args"]["questionId"], - outcome_slot_count=entry["args"]["outcomeSlotCount"], - ) - for entry in entries - ) - return dict(data=events) - - @staticmethod - def get_partitions(count: int) -> List[int]: - """Calculate and return partitions.""" - return list(map(lambda x: 1 << x, range(count))) - - @classmethod - def get_user_holdings( - cls, - ledger_api: LedgerApi, - contract_address: str, - outcome_slot_count: int, - condition_id: str, - creator: str, - collateral_token: str, - market: str, - parent_collection_id: str, - ) -> JSONLike: - """Returns user holding.""" - holdings = [] - shares = [] - instance = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - for i in cls.get_partitions(count=outcome_slot_count): - collection_id = int.from_bytes( - instance.functions.getCollectionId( - parent_collection_id, condition_id, i - ).call(), - "big", - ) - position_id = int.from_bytes( - ledger_api.api.solidity_keccak( - ["address", "uint256"], - [ - ledger_api.api.to_checksum_address(collateral_token), - collection_id, - ], - ), - "big", - ) - holdings.append( - instance.functions.balanceOf( - ledger_api.api.to_checksum_address(market), - position_id, - ).call() - ) - shares.append( - instance.functions.balanceOf( - ledger_api.api.to_checksum_address(creator), position_id - ).call() - ) - return dict( - holdings=holdings, - shares=shares, - ) - - @classmethod - def build_merge_positions_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - collateral_token: str, - parent_collection_id: bytes, - condition_id: bytes, - outcome_slot_count: int, - amount: int, - **kwargs: Any - ) -> JSONLike: - """Build mergePositions tx.""" - instance = cls.get_instance(ledger_api, contract_address) - partition = cls.get_partitions(count=outcome_slot_count) - data = instance.encodeABI( - fn_name="mergePositions", - args=[ - ledger_api.api.to_checksum_address(collateral_token), - parent_collection_id, - condition_id, - partition, - amount, - ], - ) - return dict( - data=data, - ) diff --git a/trader_backup/vendor/valory/contracts/conditional_tokens/contract.yaml b/trader_backup/vendor/valory/contracts/conditional_tokens/contract.yaml deleted file mode 100644 index d5b5b8def..000000000 --- a/trader_backup/vendor/valory/contracts/conditional_tokens/contract.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: conditional_tokens -author: valory -version: 0.1.0 -type: contract -description: ConditionalTokens contract. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeidhdxio3oq5gqdnxmngumvt3fcd6zyiyrpk5f2k4dwhflbg4e5iky - build/ConditionalTokens.json: bafybeia2ahis7zx2yhhf23kpkcxu56hto6fwg6ptjg5ld46lp4dgz7cz3e - contract.py: bafybeigdhjd2qvkmawsxd4afufr6uy3hufxwi3chcne5gba5i6whitn2r4 -fingerprint_ignore_patterns: [] -class_name: ConditionalTokensContract -contract_interface_paths: - ethereum: build/ConditionalTokens.json -dependencies: - hexbytes: {} - web3: - version: <7,>=6.0.0 - requests: - version: ==2.28.1 - urllib3: - version: ==1.26.16 -contracts: [] diff --git a/trader_backup/vendor/valory/contracts/erc20/README.md b/trader_backup/vendor/valory/contracts/erc20/README.md deleted file mode 100644 index 8c0c7780b..000000000 --- a/trader_backup/vendor/valory/contracts/erc20/README.md +++ /dev/null @@ -1 +0,0 @@ -# ERC20 token contract diff --git a/trader_backup/vendor/valory/contracts/erc20/__init__.py b/trader_backup/vendor/valory/contracts/erc20/__init__.py deleted file mode 100644 index dce069dfb..000000000 --- a/trader_backup/vendor/valory/contracts/erc20/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the support resources for an ERC20 token.""" diff --git a/trader_backup/vendor/valory/contracts/erc20/build/ERC20.json b/trader_backup/vendor/valory/contracts/erc20/build/ERC20.json deleted file mode 100644 index da6252cad..000000000 --- a/trader_backup/vendor/valory/contracts/erc20/build/ERC20.json +++ /dev/null @@ -1,288 +0,0 @@ -{ - "_format": "", - "contractName": "", - "sourceName": "", - "abi": [ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "guy", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "src", - "type": "address" - }, - { - "name": "dst", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "wad", - "type": "uint256" - } - ], - "name": "withdraw", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "dst", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "deposit", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": true, - "name": "guy", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": true, - "name": "dst", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "dst", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Withdrawal", - "type": "event" - } - ], - "bytecode": "", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/erc20/contract.py b/trader_backup/vendor/valory/contracts/erc20/contract.py deleted file mode 100644 index 9ad5c0686..000000000 --- a/trader_backup/vendor/valory/contracts/erc20/contract.py +++ /dev/null @@ -1,101 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the class to connect to an ERC20 token contract.""" - -from typing import Dict - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi - - -PUBLIC_ID = PublicId.from_str("valory/erc20:0.1.0") - - -class ERC20(Contract): - """The ERC20 contract.""" - - contract_id = PUBLIC_ID - - @classmethod - def check_balance( - cls, - ledger_api: EthereumApi, - contract_address: str, - account: str, - ) -> JSONLike: - """Check the balance of the given account.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - balance_of = getattr(contract_instance.functions, "balanceOf") # noqa - token_balance = balance_of(account).call() - wallet_balance = ledger_api.api.eth.get_balance(account) - return dict(token=token_balance, wallet=wallet_balance) - - @classmethod - def get_allowance( - cls, - ledger_api: EthereumApi, - contract_address: str, - owner: str, - spender: str, - ) -> JSONLike: - """Check the balance of the given account.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - allowance = contract_instance.functions.allowance(owner, spender).call() - return dict(data=allowance) - - @classmethod - def build_deposit_tx( - cls, - ledger_api: EthereumApi, - contract_address: str, - ) -> Dict[str, bytes]: - """Build a deposit transaction.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("deposit") - return {"data": bytes.fromhex(data[2:])} - - @classmethod - def build_withdraw_tx( - cls, - ledger_api: EthereumApi, - contract_address: str, - amount: int, - ) -> Dict[str, bytes]: - """Build a deposit transaction.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("withdraw", args=(amount,)) - return {"data": bytes.fromhex(data[2:])} - - @classmethod - def build_approval_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - spender: str, - amount: int, - ) -> Dict[str, bytes]: - """Build an ERC20 approval.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - checksumed_spender = ledger_api.api.to_checksum_address(spender) - data = contract_instance.encodeABI("approve", args=(checksumed_spender, amount)) - return {"data": bytes.fromhex(data[2:])} diff --git a/trader_backup/vendor/valory/contracts/erc20/contract.yaml b/trader_backup/vendor/valory/contracts/erc20/contract.yaml deleted file mode 100644 index 060881677..000000000 --- a/trader_backup/vendor/valory/contracts/erc20/contract.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: erc20 -author: valory -version: 0.1.0 -type: contract -description: ERC20 token contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeifmfma6rglvpa22odtozyosnp5mwljum64utxip2wgmezuhnjjjyi - __init__.py: bafybeif5vpc3dfrlxlch7brbhmdwksabyzddpfqgm56vdbbkek3t3br6ke - build/ERC20.json: bafybeiemn5b5nszuss7xj6lmvmjuendltp6wz7ubihdvd7c6wqw4bohbpa - contract.py: bafybeien5pkaqqlwhp76r2jepzh4c2ww7nbyuyhwxqseeeojxpcmulxixm -fingerprint_ignore_patterns: [] -contracts: [] -class_name: ERC20 -contract_interface_paths: - ethereum: build/ERC20.json -dependencies: - ecdsa: - version: '>=0.15' - eth_typing: {} - hexbytes: {} - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - packaging: {} - py-eth-sig-utils: {} - requests: - version: ==2.28.1 - web3: - version: <7,>=6.0.0 diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe/README.md b/trader_backup/vendor/valory/contracts/gnosis_safe/README.md deleted file mode 100644 index c9c48a5e5..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Gnosis Safe contract - -## Description - -## Functions - diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe/__init__.py b/trader_backup/vendor/valory/contracts/gnosis_safe/__init__.py deleted file mode 100644 index e394b583e..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the support resources for the gnosis_safe (GnosisSafeL2) contract.""" # pragma: nocover diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe/build/GnosisSafe_V1_3_0.json b/trader_backup/vendor/valory/contracts/gnosis_safe/build/GnosisSafe_V1_3_0.json deleted file mode 100644 index 7e0b017d2..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe/build/GnosisSafe_V1_3_0.json +++ /dev/null @@ -1,1179 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "GnosisSafeL2", - "sourceName": "contracts/GnosisSafeL2.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "AddedOwner", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "approvedHash", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "ApproveHash", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "handler", - "type": "address" - } - ], - "name": "ChangedFallbackHandler", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "guard", - "type": "address" - } - ], - "name": "ChangedGuard", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - } - ], - "name": "ChangedThreshold", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "DisabledModule", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "EnabledModule", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "txHash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "payment", - "type": "uint256" - } - ], - "name": "ExecutionFailure", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "ExecutionFromModuleFailure", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "ExecutionFromModuleSuccess", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "txHash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "payment", - "type": "uint256" - } - ], - "name": "ExecutionSuccess", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "RemovedOwner", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "module", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - } - ], - "name": "SafeModuleTransaction", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "safeTxGas", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "baseGas", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "gasPrice", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "gasToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "address payable", - "name": "refundReceiver", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "signatures", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "additionalInfo", - "type": "bytes" - } - ], - "name": "SafeMultiSigTransaction", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "SafeReceived", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "initiator", - "type": "address" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "owners", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "initializer", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "fallbackHandler", - "type": "address" - } - ], - "name": "SafeSetup", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "msgHash", - "type": "bytes32" - } - ], - "name": "SignMsg", - "type": "event" - }, - { - "stateMutability": "nonpayable", - "type": "fallback" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_threshold", - "type": "uint256" - } - ], - "name": "addOwnerWithThreshold", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "hashToApprove", - "type": "bytes32" - } - ], - "name": "approveHash", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "approvedHashes", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_threshold", - "type": "uint256" - } - ], - "name": "changeThreshold", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "signatures", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "requiredSignatures", - "type": "uint256" - } - ], - "name": "checkNSignatures", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "signatures", - "type": "bytes" - } - ], - "name": "checkSignatures", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "prevModule", - "type": "address" - }, - { - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "disableModule", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "domainSeparator", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "enableModule", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "safeTxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "baseGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gasPrice", - "type": "uint256" - }, - { - "internalType": "address", - "name": "gasToken", - "type": "address" - }, - { - "internalType": "address", - "name": "refundReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nonce", - "type": "uint256" - } - ], - "name": "encodeTransactionData", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "safeTxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "baseGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gasPrice", - "type": "uint256" - }, - { - "internalType": "address", - "name": "gasToken", - "type": "address" - }, - { - "internalType": "address payable", - "name": "refundReceiver", - "type": "address" - }, - { - "internalType": "bytes", - "name": "signatures", - "type": "bytes" - } - ], - "name": "execTransaction", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - } - ], - "name": "execTransactionFromModule", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - } - ], - "name": "execTransactionFromModuleReturnData", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "returnData", - "type": "bytes" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getChainId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "message", - "type": "bytes" - } - ], - "name": "getMessageHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "start", - "type": "address" - }, - { - "internalType": "uint256", - "name": "pageSize", - "type": "uint256" - } - ], - "name": "getModulesPaginated", - "outputs": [ - { - "internalType": "address[]", - "name": "array", - "type": "address[]" - }, - { - "internalType": "address", - "name": "next", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwners", - "outputs": [ - { - "internalType": "address[]", - "name": "", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "offset", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "length", - "type": "uint256" - } - ], - "name": "getStorageAt", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getThreshold", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "safeTxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "baseGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gasPrice", - "type": "uint256" - }, - { - "internalType": "address", - "name": "gasToken", - "type": "address" - }, - { - "internalType": "address", - "name": "refundReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nonce", - "type": "uint256" - } - ], - "name": "getTransactionHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "isModuleEnabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "isOwner", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "nonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "prevOwner", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_threshold", - "type": "uint256" - } - ], - "name": "removeOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - } - ], - "name": "requiredTxGas", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "handler", - "type": "address" - } - ], - "name": "setFallbackHandler", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "guard", - "type": "address" - } - ], - "name": "setGuard", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "_owners", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "_threshold", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "address", - "name": "fallbackHandler", - "type": "address" - }, - { - "internalType": "address", - "name": "paymentToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "payment", - "type": "uint256" - }, - { - "internalType": "address payable", - "name": "paymentReceiver", - "type": "address" - } - ], - "name": "setup", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "signMessage", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "signedMessages", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "targetContract", - "type": "address" - }, - { - "internalType": "bytes", - "name": "calldataPayload", - "type": "bytes" - } - ], - "name": "simulateAndRevert", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "prevOwner", - "type": "address" - }, - { - "internalType": "address", - "name": "oldOwner", - "type": "address" - }, - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "swapOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b506001600481905550615f6280620000296000396000f3fe6080604052600436106101f25760003560e01c8063a0e67e2b1161010d578063e009cfde116100a0578063e86637db1161006f578063e86637db14611620578063f08a0323146117bf578063f698da2514611810578063f8dc5dd91461183b578063ffa1ad74146118b657610247565b8063e009cfde146114a2578063e19a9dd914611513578063e318b52b14611564578063e75235b8146115f557610247565b8063c4ca3a9c116100dc578063c4ca3a9c1461118f578063cc2f845214611260578063d4d9bdcd1461132d578063d8d11f781461136857610247565b8063a0e67e2b14610ea0578063affed0e014610f0c578063b4faba0914610f37578063b63e800d1461101f57610247565b80635624b25b116101855780636a761202116101545780636a76120214610a865780637d83297414610c4257806385a5affe14610cb1578063934f3a1114610d3757610247565b80635624b25b146108ed5780635ae6bd37146109ab578063610b5925146109fa578063694e80c314610a4b57610247565b80632f54bf6e116101c15780632f54bf6e146105c55780633408e4701461062c578063468721a7146106575780635229073f1461076c57610247565b80630a1028c4146102b45780630d582f131461039057806312fb68e0146103eb5780632d9ad53d1461055e57610247565b36610247573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561025357600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061028857600080f35b36600080373360601b365260008060143601600080855af13d6000803e806102af573d6000fd5b3d6000f35b3480156102c057600080fd5b5061037a600480360360208110156102d757600080fd5b81019080803590602001906401000000008111156102f457600080fd5b82018360208201111561030657600080fd5b8035906020019184600183028401116401000000008311171561032857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611946565b6040518082815260200191505060405180910390f35b34801561039c57600080fd5b506103e9600480360360408110156103b357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611a3e565b005b3480156103f757600080fd5b5061055c6004803603608081101561040e57600080fd5b81019080803590602001909291908035906020019064010000000081111561043557600080fd5b82018360208201111561044757600080fd5b8035906020019184600183028401116401000000008311171561046957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156104cc57600080fd5b8201836020820111156104de57600080fd5b8035906020019184600183028401116401000000008311171561050057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611e2e565b005b34801561056a57600080fd5b506105ad6004803603602081101561058157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506126b0565b60405180821515815260200191505060405180910390f35b3480156105d157600080fd5b50610614600480360360208110156105e857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612782565b60405180821515815260200191505060405180910390f35b34801561063857600080fd5b50610641612854565b6040518082815260200191505060405180910390f35b34801561066357600080fd5b506107546004803603608081101561067a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106c157600080fd5b8201836020820111156106d357600080fd5b803590602001918460018302840111640100000000831117156106f557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050612861565b60405180821515815260200191505060405180910390f35b34801561077857600080fd5b506108696004803603608081101561078f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156107d657600080fd5b8201836020820111156107e857600080fd5b8035906020019184600183028401116401000000008311171561080a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff16906020019092919050505061296c565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156108b1578082015181840152602081019050610896565b50505050905090810190601f1680156108de5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b3480156108f957600080fd5b506109306004803603604081101561091057600080fd5b8101908080359060200190929190803590602001909291905050506129a2565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610970578082015181840152602081019050610955565b50505050905090810190601f16801561099d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156109b757600080fd5b506109e4600480360360208110156109ce57600080fd5b8101908080359060200190929190505050612a29565b6040518082815260200191505060405180910390f35b348015610a0657600080fd5b50610a4960048036036020811015610a1d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a41565b005b348015610a5757600080fd5b50610a8460048036036020811015610a6e57600080fd5b8101908080359060200190929190505050612dd3565b005b610c2a6004803603610140811015610a9d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610ae457600080fd5b820183602082011115610af657600080fd5b80359060200191846001830284011164010000000083111715610b1857600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ba457600080fd5b820183602082011115610bb657600080fd5b80359060200191846001830284011164010000000083111715610bd857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612f0d565b60405180821515815260200191505060405180910390f35b348015610c4e57600080fd5b50610c9b60048036036040811015610c6557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061314c565b6040518082815260200191505060405180910390f35b348015610cbd57600080fd5b50610d3560048036036020811015610cd457600080fd5b8101908080359060200190640100000000811115610cf157600080fd5b820183602082011115610d0357600080fd5b80359060200191846001830284011164010000000083111715610d2557600080fd5b9091929391929390505050613171565b005b348015610d4357600080fd5b50610e9e60048036036060811015610d5a57600080fd5b810190808035906020019092919080359060200190640100000000811115610d8157600080fd5b820183602082011115610d9357600080fd5b80359060200191846001830284011164010000000083111715610db557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610e1857600080fd5b820183602082011115610e2a57600080fd5b80359060200191846001830284011164010000000083111715610e4c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613215565b005b348015610eac57600080fd5b50610eb56132a4565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610ef8578082015181840152602081019050610edd565b505050509050019250505060405180910390f35b348015610f1857600080fd5b50610f2161344d565b6040518082815260200191505060405180910390f35b348015610f4357600080fd5b5061101d60048036036040811015610f5a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f9757600080fd5b820183602082011115610fa957600080fd5b80359060200191846001830284011164010000000083111715610fcb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613453565b005b34801561102b57600080fd5b5061118d600480360361010081101561104357600080fd5b810190808035906020019064010000000081111561106057600080fd5b82018360208201111561107257600080fd5b8035906020019184602083028401116401000000008311171561109457600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156110df57600080fd5b8201836020820111156110f157600080fd5b8035906020019184600183028401116401000000008311171561111357600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613475565b005b34801561119b57600080fd5b5061124a600480360360808110156111b257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156111f957600080fd5b82018360208201111561120b57600080fd5b8035906020019184600183028401116401000000008311171561122d57600080fd5b9091929391929390803560ff169060200190929190505050613633565b6040518082815260200191505060405180910390f35b34801561126c57600080fd5b506112b96004803603604081101561128357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061375b565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156113185780820151818401526020810190506112fd565b50505050905001935050505060405180910390f35b34801561133957600080fd5b506113666004803603602081101561135057600080fd5b810190808035906020019092919050505061394d565b005b34801561137457600080fd5b5061148c600480360361014081101561138c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156113d357600080fd5b8201836020820111156113e557600080fd5b8035906020019184600183028401116401000000008311171561140757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613aec565b6040518082815260200191505060405180910390f35b3480156114ae57600080fd5b50611511600480360360408110156114c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b19565b005b34801561151f57600080fd5b506115626004803603602081101561153657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613eaa565b005b34801561157057600080fd5b506115f36004803603606081101561158757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f2e565b005b34801561160157600080fd5b5061160a6145a0565b6040518082815260200191505060405180910390f35b34801561162c57600080fd5b50611744600480360361014081101561164457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561168b57600080fd5b82018360208201111561169d57600080fd5b803590602001918460018302840111640100000000831117156116bf57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506145aa565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611784578082015181840152602081019050611769565b50505050905090810190601f1680156117b15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156117cb57600080fd5b5061180e600480360360208110156117e257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614752565b005b34801561181c57600080fd5b506118256147b3565b6040518082815260200191505060405180910390f35b34801561184757600080fd5b506118b46004803603606081101561185e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614831565b005b3480156118c257600080fd5b506118cb614c64565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561190b5780820151818401526020810190506118f0565b50505050905090810190601f1680156119385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000807f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca60001b83805190602001206040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050601960f81b600160f81b6119b66147b3565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260010183815260200182815260200194505050505060405160208183030381529060405280519060200120915050919050565b611a46614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611ab05750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b8015611ae857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611b5a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611c5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611e2a57611e2981612dd3565b5b5050565b611e42604182614d4090919063ffffffff16565b82511015611eb8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b868110156126a457611ed48882614d7a565b80945081955082965050505060008460ff1614156122dd578260001c9450611f06604188614d4090919063ffffffff16565b8260001c1015611f7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611f9760208460001c614da990919063ffffffff16565b111561200b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a010151905088516120418261203360208760001c614da990919063ffffffff16565b614da990919063ffffffff16565b11156120b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561215757808201518184015260208101905061213c565b50505050905090810190601f1680156121845780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b838110156121bd5780820151818401526020810190506121a2565b50505050905090810190601f1680156121ea5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b15801561220957600080fd5b505afa15801561221d573d6000803e3d6000fd5b505050506040513d602081101561223357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146122d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5050612522565b60018460ff1614156123f1578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061237a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b6123ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612521565b601e8460ff1611156124b95760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156124a8573d6000803e3d6000fd5b505050602060405103519450612520565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612513573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156125e95750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156126225750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612694576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611ec2565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561277b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561284d5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b60007fb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e3386868686604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018360018111156128db57fe5b8152602001828103825284818151815260200191508051906020019080838360005b838110156129185780820151818401526020810190506128fd565b50505050905090810190601f1680156129455780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a161296285858585614dc8565b9050949350505050565b6000606061297c86868686612861565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff811180156129c057600080fd5b506040519080825280601f01601f1916602001820160405280156129f35781602001600182028036833780820191505090505b50905060005b83811015612a1e578085015480602083026020850101525080806001019150506129f9565b508091505092915050565b60076020528060005260406000206000915090505481565b612a49614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015612ab35750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612b25576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612c26576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612ddb614c9d565b600354811115612e53576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612eca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000606060055433600454604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405160208183030381529060405290507f66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed8d8d8d8d8d8d8d8d8d8d8d8c604051808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612fc057fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184810384528e8e82818152602001925080828437600081840152601f19601f820116905080830192505050848103835286818151815260200191508051906020019080838360005b8381101561307a57808201518184015260208101905061305f565b50505050905090810190601f1680156130a75780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b838110156130e05780820151818401526020810190506130c5565b50505050905090810190601f16801561310d5780820380516001836020036101000a031916815260200191505b509f5050505050505050505050505050505060405180910390a161313a8d8d8d8d8d8d8d8d8d8d8d614fae565b9150509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b613179614c9d565b60006131c883838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611946565b905060016007600083815260200190815260200160002081905550807fe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e460405160405180910390a2505050565b6000600454905060008111613292576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61329e84848484611e2e565b50505050565b6060600060035467ffffffffffffffff811180156132c157600080fd5b506040519080825280602002602001820160405280156132f05781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613444578083838151811061339b57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061335a565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6134c08a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505089615441565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146134fe576134fd84615941565b5b61354c8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615970565b60008211156135665761356482600060018685615bab565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a905061368a878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a615db1565b61369357600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613720578082015181840152602081019050613705565b50505050905090810190601f16801561374d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561377657600080fd5b506040519080825280602002602001820160405280156137a55781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156138785750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561388357508482105b1561393e578084838151811061389557fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061380e565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613a4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b6000613b018c8c8c8c8c8c8c8c8c8c8c6145aa565b8051906020012090509b9a5050505050505050505050565b613b21614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613b8b5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613bfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613cfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613eb2614c9d565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613f36614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613fa05750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015613fd857503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61404a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461414b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156141b55750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614227576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614327576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561463b57fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b6146c76147b3565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b61475a614c9d565b61476381615941565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6147e1612854565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b614839614c9d565b8060016003540310156148b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561491e5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614a90576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414614c5f57614c5e81612dd3565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614d3e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614d535760009050614d74565b6000828402905082848281614d6457fe5b0414614d6f57600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614dbe57600080fd5b8091505092915050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015614e935750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b614f05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b614f12858585855a615db1565b90508015614f62573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a2614fa6565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b6000806000614fc88e8e8e8e8e8e8e8e8e8e6005546145aa565b905060056000815480929190600101919050555080805190602001209150614ff1828286613215565b506000614ffc615dfd565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146151e2578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a600181111561509f57fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015615171578082015181840152602081019050615156565b50505050905090810190601f16801561519e5780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b1580156151c957600080fd5b505af11580156151dd573d6000803e3d6000fd5b505050505b506101f461520a6109c48a01603f60408c02816151fb57fe5b04615e2e90919063ffffffff16565b015a1015615280576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a90506152e98e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d60008c146152de578d6152e4565b6109c45a035b615db1565b92506152fe5a82615e4890919063ffffffff16565b9050828061530d575060008914155b80615319575060008714155b61538b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808811156153a5576153a2828a8a8a8a615bab565b90505b83156153ef577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8382604051808381526020018281526020019250505060405180910390a161542f565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238382604051808381526020018281526020019250505060405180910390a15b5050509b9a5050505050505050505050565b6000600454146154b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8151811115615530576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60018110156155a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b83518110156158ad5760008482815181106155c757fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561563b5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561567357503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156156ab57508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b61571d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461581e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506155b0565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615a72576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614615ba757615b348260008360015a615db1565b615ba6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614615be85782615bea565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615d0257615c543a8610615c31573a615c33565b855b615c46888a614da990919063ffffffff16565b614d4090919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615cfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615da7565b615d2785615d19888a614da990919063ffffffff16565b614d4090919063ffffffff16565b9150615d34848284615e68565b615da6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600180811115615dbf57fe5b836001811115615dcb57fe5b1415615de4576000808551602087018986f49050615df4565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015615e3e5781615e40565b825b905092915050565b600082821115615e5757600080fd5b600082840390508091505092915050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d60008114615f0f5760208114615f175760009350615f22565b819350615f22565b600051158215171593505b505050939250505056fea26469706673582212201626cf01be22a899e6f136e8877b04e8217b963c12508420280eb5a8dfe10fec64736f6c63430007060033", - "deployedBytecode": "0x6080604052600436106101f25760003560e01c8063a0e67e2b1161010d578063e009cfde116100a0578063e86637db1161006f578063e86637db14611620578063f08a0323146117bf578063f698da2514611810578063f8dc5dd91461183b578063ffa1ad74146118b657610247565b8063e009cfde146114a2578063e19a9dd914611513578063e318b52b14611564578063e75235b8146115f557610247565b8063c4ca3a9c116100dc578063c4ca3a9c1461118f578063cc2f845214611260578063d4d9bdcd1461132d578063d8d11f781461136857610247565b8063a0e67e2b14610ea0578063affed0e014610f0c578063b4faba0914610f37578063b63e800d1461101f57610247565b80635624b25b116101855780636a761202116101545780636a76120214610a865780637d83297414610c4257806385a5affe14610cb1578063934f3a1114610d3757610247565b80635624b25b146108ed5780635ae6bd37146109ab578063610b5925146109fa578063694e80c314610a4b57610247565b80632f54bf6e116101c15780632f54bf6e146105c55780633408e4701461062c578063468721a7146106575780635229073f1461076c57610247565b80630a1028c4146102b45780630d582f131461039057806312fb68e0146103eb5780632d9ad53d1461055e57610247565b36610247573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561025357600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061028857600080f35b36600080373360601b365260008060143601600080855af13d6000803e806102af573d6000fd5b3d6000f35b3480156102c057600080fd5b5061037a600480360360208110156102d757600080fd5b81019080803590602001906401000000008111156102f457600080fd5b82018360208201111561030657600080fd5b8035906020019184600183028401116401000000008311171561032857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611946565b6040518082815260200191505060405180910390f35b34801561039c57600080fd5b506103e9600480360360408110156103b357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611a3e565b005b3480156103f757600080fd5b5061055c6004803603608081101561040e57600080fd5b81019080803590602001909291908035906020019064010000000081111561043557600080fd5b82018360208201111561044757600080fd5b8035906020019184600183028401116401000000008311171561046957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156104cc57600080fd5b8201836020820111156104de57600080fd5b8035906020019184600183028401116401000000008311171561050057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611e2e565b005b34801561056a57600080fd5b506105ad6004803603602081101561058157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506126b0565b60405180821515815260200191505060405180910390f35b3480156105d157600080fd5b50610614600480360360208110156105e857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612782565b60405180821515815260200191505060405180910390f35b34801561063857600080fd5b50610641612854565b6040518082815260200191505060405180910390f35b34801561066357600080fd5b506107546004803603608081101561067a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106c157600080fd5b8201836020820111156106d357600080fd5b803590602001918460018302840111640100000000831117156106f557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050612861565b60405180821515815260200191505060405180910390f35b34801561077857600080fd5b506108696004803603608081101561078f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156107d657600080fd5b8201836020820111156107e857600080fd5b8035906020019184600183028401116401000000008311171561080a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff16906020019092919050505061296c565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156108b1578082015181840152602081019050610896565b50505050905090810190601f1680156108de5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b3480156108f957600080fd5b506109306004803603604081101561091057600080fd5b8101908080359060200190929190803590602001909291905050506129a2565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610970578082015181840152602081019050610955565b50505050905090810190601f16801561099d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156109b757600080fd5b506109e4600480360360208110156109ce57600080fd5b8101908080359060200190929190505050612a29565b6040518082815260200191505060405180910390f35b348015610a0657600080fd5b50610a4960048036036020811015610a1d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a41565b005b348015610a5757600080fd5b50610a8460048036036020811015610a6e57600080fd5b8101908080359060200190929190505050612dd3565b005b610c2a6004803603610140811015610a9d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610ae457600080fd5b820183602082011115610af657600080fd5b80359060200191846001830284011164010000000083111715610b1857600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ba457600080fd5b820183602082011115610bb657600080fd5b80359060200191846001830284011164010000000083111715610bd857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612f0d565b60405180821515815260200191505060405180910390f35b348015610c4e57600080fd5b50610c9b60048036036040811015610c6557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061314c565b6040518082815260200191505060405180910390f35b348015610cbd57600080fd5b50610d3560048036036020811015610cd457600080fd5b8101908080359060200190640100000000811115610cf157600080fd5b820183602082011115610d0357600080fd5b80359060200191846001830284011164010000000083111715610d2557600080fd5b9091929391929390505050613171565b005b348015610d4357600080fd5b50610e9e60048036036060811015610d5a57600080fd5b810190808035906020019092919080359060200190640100000000811115610d8157600080fd5b820183602082011115610d9357600080fd5b80359060200191846001830284011164010000000083111715610db557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610e1857600080fd5b820183602082011115610e2a57600080fd5b80359060200191846001830284011164010000000083111715610e4c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613215565b005b348015610eac57600080fd5b50610eb56132a4565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610ef8578082015181840152602081019050610edd565b505050509050019250505060405180910390f35b348015610f1857600080fd5b50610f2161344d565b6040518082815260200191505060405180910390f35b348015610f4357600080fd5b5061101d60048036036040811015610f5a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f9757600080fd5b820183602082011115610fa957600080fd5b80359060200191846001830284011164010000000083111715610fcb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613453565b005b34801561102b57600080fd5b5061118d600480360361010081101561104357600080fd5b810190808035906020019064010000000081111561106057600080fd5b82018360208201111561107257600080fd5b8035906020019184602083028401116401000000008311171561109457600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156110df57600080fd5b8201836020820111156110f157600080fd5b8035906020019184600183028401116401000000008311171561111357600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613475565b005b34801561119b57600080fd5b5061124a600480360360808110156111b257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156111f957600080fd5b82018360208201111561120b57600080fd5b8035906020019184600183028401116401000000008311171561122d57600080fd5b9091929391929390803560ff169060200190929190505050613633565b6040518082815260200191505060405180910390f35b34801561126c57600080fd5b506112b96004803603604081101561128357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061375b565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156113185780820151818401526020810190506112fd565b50505050905001935050505060405180910390f35b34801561133957600080fd5b506113666004803603602081101561135057600080fd5b810190808035906020019092919050505061394d565b005b34801561137457600080fd5b5061148c600480360361014081101561138c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156113d357600080fd5b8201836020820111156113e557600080fd5b8035906020019184600183028401116401000000008311171561140757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613aec565b6040518082815260200191505060405180910390f35b3480156114ae57600080fd5b50611511600480360360408110156114c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b19565b005b34801561151f57600080fd5b506115626004803603602081101561153657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613eaa565b005b34801561157057600080fd5b506115f36004803603606081101561158757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f2e565b005b34801561160157600080fd5b5061160a6145a0565b6040518082815260200191505060405180910390f35b34801561162c57600080fd5b50611744600480360361014081101561164457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561168b57600080fd5b82018360208201111561169d57600080fd5b803590602001918460018302840111640100000000831117156116bf57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506145aa565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611784578082015181840152602081019050611769565b50505050905090810190601f1680156117b15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156117cb57600080fd5b5061180e600480360360208110156117e257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614752565b005b34801561181c57600080fd5b506118256147b3565b6040518082815260200191505060405180910390f35b34801561184757600080fd5b506118b46004803603606081101561185e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614831565b005b3480156118c257600080fd5b506118cb614c64565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561190b5780820151818401526020810190506118f0565b50505050905090810190601f1680156119385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000807f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca60001b83805190602001206040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050601960f81b600160f81b6119b66147b3565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260010183815260200182815260200194505050505060405160208183030381529060405280519060200120915050919050565b611a46614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611ab05750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b8015611ae857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611b5a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611c5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611e2a57611e2981612dd3565b5b5050565b611e42604182614d4090919063ffffffff16565b82511015611eb8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b868110156126a457611ed48882614d7a565b80945081955082965050505060008460ff1614156122dd578260001c9450611f06604188614d4090919063ffffffff16565b8260001c1015611f7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611f9760208460001c614da990919063ffffffff16565b111561200b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a010151905088516120418261203360208760001c614da990919063ffffffff16565b614da990919063ffffffff16565b11156120b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561215757808201518184015260208101905061213c565b50505050905090810190601f1680156121845780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b838110156121bd5780820151818401526020810190506121a2565b50505050905090810190601f1680156121ea5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b15801561220957600080fd5b505afa15801561221d573d6000803e3d6000fd5b505050506040513d602081101561223357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146122d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5050612522565b60018460ff1614156123f1578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061237a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b6123ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612521565b601e8460ff1611156124b95760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156124a8573d6000803e3d6000fd5b505050602060405103519450612520565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612513573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156125e95750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156126225750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612694576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611ec2565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561277b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561284d5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b60007fb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e3386868686604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018360018111156128db57fe5b8152602001828103825284818151815260200191508051906020019080838360005b838110156129185780820151818401526020810190506128fd565b50505050905090810190601f1680156129455780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a161296285858585614dc8565b9050949350505050565b6000606061297c86868686612861565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff811180156129c057600080fd5b506040519080825280601f01601f1916602001820160405280156129f35781602001600182028036833780820191505090505b50905060005b83811015612a1e578085015480602083026020850101525080806001019150506129f9565b508091505092915050565b60076020528060005260406000206000915090505481565b612a49614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015612ab35750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612b25576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612c26576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612ddb614c9d565b600354811115612e53576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612eca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000606060055433600454604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405160208183030381529060405290507f66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed8d8d8d8d8d8d8d8d8d8d8d8c604051808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612fc057fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184810384528e8e82818152602001925080828437600081840152601f19601f820116905080830192505050848103835286818151815260200191508051906020019080838360005b8381101561307a57808201518184015260208101905061305f565b50505050905090810190601f1680156130a75780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b838110156130e05780820151818401526020810190506130c5565b50505050905090810190601f16801561310d5780820380516001836020036101000a031916815260200191505b509f5050505050505050505050505050505060405180910390a161313a8d8d8d8d8d8d8d8d8d8d8d614fae565b9150509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b613179614c9d565b60006131c883838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611946565b905060016007600083815260200190815260200160002081905550807fe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e460405160405180910390a2505050565b6000600454905060008111613292576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61329e84848484611e2e565b50505050565b6060600060035467ffffffffffffffff811180156132c157600080fd5b506040519080825280602002602001820160405280156132f05781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613444578083838151811061339b57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061335a565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6134c08a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505089615441565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146134fe576134fd84615941565b5b61354c8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615970565b60008211156135665761356482600060018685615bab565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a905061368a878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a615db1565b61369357600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613720578082015181840152602081019050613705565b50505050905090810190601f16801561374d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561377657600080fd5b506040519080825280602002602001820160405280156137a55781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156138785750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561388357508482105b1561393e578084838151811061389557fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061380e565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613a4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b6000613b018c8c8c8c8c8c8c8c8c8c8c6145aa565b8051906020012090509b9a5050505050505050505050565b613b21614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613b8b5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613bfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613cfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613eb2614c9d565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613f36614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613fa05750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015613fd857503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61404a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461414b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156141b55750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614227576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614327576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561463b57fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b6146c76147b3565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b61475a614c9d565b61476381615941565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6147e1612854565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b614839614c9d565b8060016003540310156148b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561491e5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614a90576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414614c5f57614c5e81612dd3565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614d3e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614d535760009050614d74565b6000828402905082848281614d6457fe5b0414614d6f57600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614dbe57600080fd5b8091505092915050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015614e935750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b614f05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b614f12858585855a615db1565b90508015614f62573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a2614fa6565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b6000806000614fc88e8e8e8e8e8e8e8e8e8e6005546145aa565b905060056000815480929190600101919050555080805190602001209150614ff1828286613215565b506000614ffc615dfd565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146151e2578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a600181111561509f57fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015615171578082015181840152602081019050615156565b50505050905090810190601f16801561519e5780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b1580156151c957600080fd5b505af11580156151dd573d6000803e3d6000fd5b505050505b506101f461520a6109c48a01603f60408c02816151fb57fe5b04615e2e90919063ffffffff16565b015a1015615280576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a90506152e98e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d60008c146152de578d6152e4565b6109c45a035b615db1565b92506152fe5a82615e4890919063ffffffff16565b9050828061530d575060008914155b80615319575060008714155b61538b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808811156153a5576153a2828a8a8a8a615bab565b90505b83156153ef577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8382604051808381526020018281526020019250505060405180910390a161542f565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238382604051808381526020018281526020019250505060405180910390a15b5050509b9a5050505050505050505050565b6000600454146154b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8151811115615530576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60018110156155a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b83518110156158ad5760008482815181106155c757fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561563b5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561567357503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156156ab57508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b61571d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461581e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506155b0565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615a72576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614615ba757615b348260008360015a615db1565b615ba6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614615be85782615bea565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615d0257615c543a8610615c31573a615c33565b855b615c46888a614da990919063ffffffff16565b614d4090919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615cfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615da7565b615d2785615d19888a614da990919063ffffffff16565b614d4090919063ffffffff16565b9150615d34848284615e68565b615da6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600180811115615dbf57fe5b836001811115615dcb57fe5b1415615de4576000808551602087018986f49050615df4565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015615e3e5781615e40565b825b905092915050565b600082821115615e5757600080fd5b600082840390508091505092915050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d60008114615f0f5760208114615f175760009350615f22565b819350615f22565b600051158215171593505b505050939250505056fea26469706673582212201626cf01be22a899e6f136e8877b04e8217b963c12508420280eb5a8dfe10fec64736f6c63430007060033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe/contract.py b/trader_backup/vendor/valory/contracts/gnosis_safe/contract.py deleted file mode 100644 index 417a3913d..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe/contract.py +++ /dev/null @@ -1,1004 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the class to connect to an Gnosis Safe contract.""" -import binascii -import logging -import secrets -from enum import Enum -from typing import Any, Dict, List, Optional, Tuple, Union, cast - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi -from eth_typing import ChecksumAddress, HexAddress, HexStr -from hexbytes import HexBytes -from packaging.version import Version -from requests import HTTPError -from web3.exceptions import ContractLogicError, TransactionNotFound -from web3.types import BlockIdentifier, Nonce, TxData, TxParams, Wei - -from packages.valory.contracts.gnosis_safe.encode import encode_typed_data -from packages.valory.contracts.gnosis_safe_proxy_factory.contract import ( - GnosisSafeProxyFactoryContract, -) - - -PUBLIC_ID = PublicId.from_str("valory/gnosis_safe:0.1.0") -MIN_GAS = MIN_GASPRICE = 1 -# see https://github.com/safe-global/safe-eth-py/blob/6c0e0d80448e5f3496d0d94985bca239df6eb399/gnosis/safe/safe_tx.py#L354 -GAS_ADJUSTMENT = 75_000 - -_logger = logging.getLogger( - f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" -) - -NULL_ADDRESS: str = "0x" + "0" * 40 -SAFE_CONTRACT = "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552" -DEFAULT_CALLBACK_HANDLER = "0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4" -PROXY_FACTORY_CONTRACT = "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2" -SAFE_DEPLOYED_BYTECODE = "0x608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea2646970667358221220d1429297349653a4918076d650332de1a1068c5f3e07c5c82360c277770b955264736f6c63430007060033" - - -def _get_nonce() -> int: - """Generate a nonce for the Safe deployment.""" - return secrets.SystemRandom().randint(0, 2**256 - 1) - - -def checksum_address(agent_address: str) -> ChecksumAddress: - """Get the checksum address.""" - return ChecksumAddress(HexAddress(HexStr(agent_address))) - - -class SafeOperation(Enum): - """Operation types.""" - - CALL = 0 - DELEGATE_CALL = 1 - CREATE = 2 - - -class GnosisSafeContract(Contract): - """The Gnosis Safe contract.""" - - contract_id = PUBLIC_ID - _SENTINEL_OWNERS = "0x0000000000000000000000000000000000000001" - - @classmethod - def get_raw_transaction( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get the Safe transaction.""" - raise NotImplementedError - - @classmethod - def get_raw_message( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[bytes]: - """Get raw message.""" - raise NotImplementedError - - @classmethod - def get_state( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get state.""" - raise NotImplementedError - - @classmethod - def get_deploy_transaction( - cls, ledger_api: LedgerApi, deployer_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """ - Get deploy transaction. - - :param ledger_api: ledger API object. - :param deployer_address: the deployer address. - :param kwargs: the keyword arguments. - :return: an optional JSON-like object. - """ - owners = kwargs.pop("owners") - threshold = kwargs.pop("threshold") - ledger_api = cast(EthereumApi, ledger_api) - tx_params, contract_address = cls._get_deploy_transaction( - ledger_api, deployer_address, owners=owners, threshold=threshold, **kwargs - ) - result = dict(cast(Dict, tx_params)) - # piggyback the contract address - result["contract_address"] = contract_address - return result - - @classmethod - def _get_deploy_transaction( # pylint: disable=too-many-locals,too-many-arguments - cls, - ledger_api: EthereumApi, - deployer_address: str, - owners: List[str], - threshold: int, - salt_nonce: Optional[int] = None, - gas: int = 0, - gas_price: Optional[int] = None, - max_fee_per_gas: Optional[int] = None, - max_priority_fee_per_gas: Optional[int] = None, - ) -> Tuple[TxParams, str]: - """ - Get the deployment transaction of the new Safe. - - Taken from: - https://github.com/gnosis/safe-cli/blob/contracts_v1.3.0/safe_creator.py - - :param ledger_api: Ethereum APIs. - :param deployer_address: public key of the sender of the transaction - :param owners: a list of public keys - :param threshold: the signature threshold - :param salt_nonce: Use a custom nonce for the deployment. Defaults to random nonce. - :param gas: gas cost - :param gas_price: Gas price that should be used for the payment calculation - :param max_fee_per_gas: max - :param max_priority_fee_per_gas: max - :return: transaction params and contract address - """ - salt_nonce = salt_nonce if salt_nonce is not None else _get_nonce() - salt_nonce = cast(int, salt_nonce) - to_address = NULL_ADDRESS - data = b"" - payment_token = NULL_ADDRESS - payment = 0 - payment_receiver = NULL_ADDRESS - - if len(owners) < threshold: - raise ValueError( - "Threshold cannot be bigger than the number of unique owners" - ) - - safe_contract_address = SAFE_CONTRACT - proxy_factory_address = PROXY_FACTORY_CONTRACT - fallback_handler = DEFAULT_CALLBACK_HANDLER - - account_address = checksum_address(deployer_address) - account_balance: int = ledger_api.api.eth.get_balance(account_address) - if not account_balance: - raise ValueError("Client does not have any funds") - - ether_account_balance = round( - ledger_api.api.from_wei(account_balance, "ether"), 6 - ) - _logger.info( - "Network %s - Sender %s - Balance: %sΞ", - ledger_api.api.net.version, - account_address, - ether_account_balance, - ) - - if not ledger_api.api.eth.get_code( - safe_contract_address - ) or not ledger_api.api.eth.get_code(proxy_factory_address): - raise ValueError("Network not supported") # pragma: nocover - - _logger.info( - "Creating new Safe with owners=%s threshold=%s " - "fallback-handler=%s salt-nonce=%s", - owners, - threshold, - fallback_handler, - salt_nonce, - ) - safe_contract = cls.get_instance(ledger_api, safe_contract_address) - safe_creation_tx_data = HexBytes( - safe_contract.functions.setup( - owners, - threshold, - to_address, - data, - fallback_handler, - payment_token, - payment, - payment_receiver, - ).build_transaction({"gas": MIN_GAS, "gasPrice": MIN_GASPRICE})["data"] - ) - - nonce = ( - ledger_api._try_get_transaction_count( # pylint: disable=protected-access - account_address - ) - ) - if nonce is None: - raise ValueError("No nonce returned.") # pragma: nocover - - ( - tx_params, - contract_address, - ) = GnosisSafeProxyFactoryContract.build_tx_deploy_proxy_contract_with_nonce( - ledger_api, - proxy_factory_address, - safe_contract_address, - account_address, - safe_creation_tx_data, - salt_nonce, - nonce=nonce, - gas=gas, - gas_price=gas_price, - max_fee_per_gas=max_fee_per_gas, - max_priority_fee_per_gas=max_priority_fee_per_gas, - ) - return tx_params, contract_address - - @classmethod - def get_raw_safe_transaction_hash( # pylint: disable=too-many-arguments,too-many-locals - cls, - ledger_api: EthereumApi, - contract_address: str, - to_address: str, - value: int, - data: bytes, - operation: int = SafeOperation.CALL.value, - safe_tx_gas: int = 0, - base_gas: int = 0, - gas_price: int = 0, - gas_token: str = NULL_ADDRESS, - refund_receiver: str = NULL_ADDRESS, - safe_nonce: Optional[int] = None, - safe_version: Optional[str] = None, - chain_id: Optional[int] = None, - ) -> JSONLike: - """ - Get the hash of the raw Safe transaction. - - Adapted from https://github.com/gnosis/gnosis-py/blob/69f1ee3263086403f6017effa0841c6a2fbba6d6/gnosis/safe/safe_tx.py#L125 - - Note, because safe_nonce is included in the tx_hash the agents implicitly agree on the order of txs if they agree on a tx_hash. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param to_address: the tx recipient address - :param value: the ETH value of the transaction - :param data: the data of the transaction - :param operation: Operation type of Safe transaction - :param safe_tx_gas: Gas that should be used for the Safe transaction - :param base_gas: Gas costs for that are independent of the transaction execution - (e.g. base transaction fee, signature check, payment of the refund) - :param gas_price: Gas price that should be used for the payment calculation - :param gas_token: Token address (or `0x000..000` if ETH) that is used for the payment - :param refund_receiver: Address of receiver of gas payment (or `0x000..000` if tx.origin). - :param safe_nonce: Current nonce of the Safe. If not provided, it will be retrieved from network - :param safe_version: Safe version 1.0.0 renamed `baseGas` to `dataGas`. Safe version 1.3.0 added `chainId` to the `domainSeparator`. If not provided, it will be retrieved from network - :param chain_id: Ethereum network chain_id is used in hash calculation for Safes >= 1.3.0. If not provided, it will be retrieved from the provided ethereum_client - :return: the hash of the raw Safe transaction - """ - safe_contract = cls.get_instance(ledger_api, contract_address) - if safe_nonce is None: - safe_nonce = safe_contract.functions.nonce().call(block_identifier="latest") - if safe_version is None: - safe_version = safe_contract.functions.VERSION().call( - block_identifier="latest" - ) - if chain_id is None: - chain_id = ledger_api.api.eth.chain_id - - data_ = HexBytes(data).hex() - - # Safes >= 1.0.0 Renamed `baseGas` to `dataGas` - safe_version_ = Version(safe_version) - base_gas_name = "baseGas" if safe_version_ >= Version("1.0.0") else "dataGas" - - structured_data = { - "types": { - "EIP712Domain": [ - {"name": "verifyingContract", "type": "address"}, - ], - "SafeTx": [ - {"name": "to", "type": "address"}, - {"name": "value", "type": "uint256"}, - {"name": "data", "type": "bytes"}, - {"name": "operation", "type": "uint8"}, - {"name": "safeTxGas", "type": "uint256"}, - {"name": base_gas_name, "type": "uint256"}, - {"name": "gasPrice", "type": "uint256"}, - {"name": "gasToken", "type": "address"}, - {"name": "refundReceiver", "type": "address"}, - {"name": "nonce", "type": "uint256"}, - ], - }, - "primaryType": "SafeTx", - "domain": { - "verifyingContract": contract_address, - }, - "message": { - "to": to_address, - "value": value, - "data": data_, - "operation": operation, - "safeTxGas": safe_tx_gas, - base_gas_name: base_gas, - "gasPrice": gas_price, - "gasToken": gas_token, - "refundReceiver": refund_receiver, - "nonce": safe_nonce, - }, - } - - # Safes >= 1.3.0 Added `chainId` to the domain - if safe_version_ >= Version("1.3.0"): - # EIP712Domain(uint256 chainId,address verifyingContract) - structured_data["types"]["EIP712Domain"].insert( # type: ignore - 0, {"name": "chainId", "type": "uint256"} - ) - structured_data["domain"]["chainId"] = chain_id # type: ignore - - return dict(tx_hash=HexBytes(encode_typed_data(structured_data)).hex()) - - @classmethod - def get_packed_signatures( - cls, owners: Tuple[str], signatures_by_owner: Dict[str, str] - ) -> bytes: - """Get the packed signatures.""" - sorted_owners = sorted(owners, key=str.lower) - signatures = b"" - for signer in sorted_owners: - if signer not in signatures_by_owner: - continue # pragma: nocover - signature = signatures_by_owner[signer] - signature_bytes = binascii.unhexlify(signature) - signatures += signature_bytes - # Packed signature data ({bytes32 r}{bytes32 s}{uint8 v}) - return signatures - - @classmethod - def get_raw_safe_transaction( # pylint: disable=too-many-arguments,too-many-locals - cls, - ledger_api: EthereumApi, - contract_address: str, - sender_address: str, - owners: Tuple[str], - to_address: str, - value: int, - data: bytes, - signatures_by_owner: Dict[str, str], - operation: int = SafeOperation.CALL.value, - safe_tx_gas: int = 0, - base_gas: int = 0, - safe_gas_price: int = 0, - gas_token: str = NULL_ADDRESS, - refund_receiver: str = NULL_ADDRESS, - gas_price: Optional[int] = None, - nonce: Optional[Nonce] = None, - max_fee_per_gas: Optional[int] = None, - max_priority_fee_per_gas: Optional[int] = None, - old_price: Optional[Dict[str, Wei]] = None, - fallback_gas: int = 0, - ) -> JSONLike: - """ - Get the raw Safe transaction - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param sender_address: the address of the sender - :param owners: the sequence of owners - :param to_address: Destination address of Safe transaction - :param value: Ether value of Safe transaction - :param data: Data payload of Safe transaction - :param signatures_by_owner: mapping from owners to signatures - :param operation: Operation type of Safe transaction - :param safe_tx_gas: Gas that should be used for the Safe transaction - :param base_gas: Gas costs for that are independent of the transaction execution - (e.g. base transaction fee, signature check, payment of the refund) - :param safe_gas_price: Gas price that should be used for the payment calculation - :param gas_token: Token address (or `0x000..000` if ETH) that is used for the payment - :param refund_receiver: Address of receiver of gas payment (or `0x000..000` if tx.origin). - :param gas_price: gas price - :param nonce: the nonce - :param max_fee_per_gas: max - :param max_priority_fee_per_gas: max - :param old_price: the old gas price params in case that we are trying to resubmit a transaction. - :param fallback_gas: (external) gas to spend when base_gas and safe_tx_gas are zero and no gas estimation is possible. - :return: the raw Safe transaction - """ - sender_address = ledger_api.api.to_checksum_address(sender_address) - to_address = ledger_api.api.to_checksum_address(to_address) - ledger_api = cast(EthereumApi, ledger_api) - signatures = cls.get_packed_signatures(owners, signatures_by_owner) - safe_contract = cls.get_instance(ledger_api, contract_address) - - w3_tx = safe_contract.functions.execTransaction( - to_address, - value, - data, - operation, - safe_tx_gas, - base_gas, - safe_gas_price, - gas_token, - refund_receiver, - signatures, - ) - # see https://github.com/safe-global/safe-eth-py/blob/6c0e0d80448e5f3496d0d94985bca239df6eb399/gnosis/safe/safe_tx.py#L354 - configured_gas = ( - base_gas + safe_tx_gas + GAS_ADJUSTMENT - if base_gas != 0 or safe_tx_gas != 0 - else MIN_GAS - ) - tx_parameters: Dict[str, Union[str, int]] = { - "from": sender_address, - "gas": configured_gas, - } - actual_nonce = ledger_api.api.eth.get_transaction_count( - ledger_api.api.to_checksum_address(sender_address) - ) - if actual_nonce != nonce: - nonce = actual_nonce - old_price = None - if gas_price is not None: - tx_parameters["gasPrice"] = gas_price - if max_fee_per_gas is not None: - tx_parameters["maxFeePerGas"] = max_fee_per_gas # pragma: nocover - if max_priority_fee_per_gas is not None: # pragma: nocover - tx_parameters["maxPriorityFeePerGas"] = max_priority_fee_per_gas - if ( - gas_price is None - and max_fee_per_gas is None - and max_priority_fee_per_gas is None - ): - tx_parameters.update(ledger_api.try_get_gas_pricing(old_price=old_price)) - # note, the next line makes an eth_estimateGas call if gas is not set! - transaction_dict = w3_tx.build_transaction(tx_parameters) - if configured_gas != MIN_GAS: - transaction_dict["gas"] = Wei(configured_gas) - else: - gas_estimate = ( - ledger_api._try_get_gas_estimate( # pylint: disable=protected-access - transaction_dict - ) - ) - transaction_dict["gas"] = ( - Wei(gas_estimate) if gas_estimate is not None else fallback_gas - ) - transaction_dict["nonce"] = nonce # pragma: nocover - return transaction_dict - - @classmethod - def verify_contract(cls, ledger_api: LedgerApi, contract_address: str) -> JSONLike: - """ - Verify the contract's bytecode - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :return: the verified status - """ - ledger_api = cast(EthereumApi, ledger_api) - deployed_bytecode = ledger_api.api.eth.get_code(contract_address).hex() - # we cannot use cls.contract_interface["ethereum"]["deployedBytecode"] because the - # contract is created via a proxy - local_bytecode = SAFE_DEPLOYED_BYTECODE - verified = deployed_bytecode == local_bytecode - return dict(verified=verified) - - @classmethod - def verify_tx( # pylint: disable=too-many-arguments,too-many-locals - cls, - ledger_api: EthereumApi, - contract_address: str, - tx_hash: str, - owners: Tuple[str], - to_address: str, - value: int, - data: bytes, - signatures_by_owner: Dict[str, str], - operation: int = SafeOperation.CALL.value, - safe_tx_gas: int = 0, - base_gas: int = 0, - gas_price: int = 0, - gas_token: str = NULL_ADDRESS, - refund_receiver: str = NULL_ADDRESS, - safe_version: Optional[str] = None, - ) -> JSONLike: - """ - Verify a tx hash exists on the blockchain. - - Currently, the implementation is an overkill as most of the verification is implicit by the acceptance of the transaction in the Safe. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param tx_hash: the transaction hash - :param owners: the sequence of owners - :param to_address: Destination address of Safe transaction - :param value: Ether value of Safe transaction - :param data: Data payload of Safe transaction - :param signatures_by_owner: mapping from owners to signatures - :param operation: Operation type of Safe transaction - :param safe_tx_gas: Gas that should be used for the Safe transaction - :param base_gas: Gas costs for that are independent of the transaction execution - (e.g. base transaction fee, signature check, payment of the refund) - :param gas_price: Gas price that should be used for the payment calculation - :param gas_token: Token address (or `0x000..000` if ETH) that is used for the payment - :param refund_receiver: Address of receiver of gas payment (or `0x000..000` if tx.origin). - :param safe_version: Safe version 1.0.0 renamed `baseGas` to `dataGas`. Safe version 1.3.0 added `chainId` to the `domainSeparator`. If not provided, it will be retrieved from network - :return: the verified status - """ - to_address = ledger_api.api.to_checksum_address(to_address) - ledger_api = cast(EthereumApi, ledger_api) - safe_contract = cls.get_instance(ledger_api, contract_address) - signatures = cls.get_packed_signatures(owners, signatures_by_owner) - - if safe_version is None: - safe_version = safe_contract.functions.VERSION().call( - block_identifier="latest" - ) - # Safes >= 1.0.0 Renamed `baseGas` to `dataGas` - safe_version_ = Version(safe_version) - base_gas_name = "baseGas" if safe_version_ >= Version("1.0.0") else "dataGas" - - try: - _logger.info(f"Trying to get transaction and receipt from hash {tx_hash}") - transaction = ledger_api.api.eth.get_transaction(tx_hash) - receipt = ledger_api.get_transaction_receipt(tx_hash) - _logger.info( - f"Received transaction: {transaction}, with receipt: {receipt}." - ) - if receipt is None: - raise ValueError # pragma: nocover - except (TransactionNotFound, ValueError): # pragma: nocover - return dict(verified=False, status=-1) - - expected = dict( - contract_address=contract_address, - to_address=to_address, - value=value, - data=data, - operation=operation, - safe_tx_gas=safe_tx_gas, - base_gas=base_gas, - gas_price=gas_price, - gas_token=gas_token, - refund_receiver=refund_receiver, - signatures=signatures, - ) - decoded: Tuple[Any, Dict] = (None, {}) - diff: Dict = {} - try: - decoded = safe_contract.decode_function_input(transaction["input"]) - actual = dict( - contract_address=transaction["to"], - to_address=decoded[1]["to"], - value=decoded[1]["value"], - data=decoded[1]["data"], - operation=decoded[1]["operation"], - safe_tx_gas=decoded[1]["safeTxGas"], - base_gas=decoded[1][base_gas_name], - gas_price=decoded[1]["gasPrice"], - gas_token=decoded[1]["gasToken"], - refund_receiver=decoded[1]["refundReceiver"], - signatures=decoded[1]["signatures"], - ) - diff = {k: (v, actual[k]) for k, v in expected.items() if v != actual[k]} - verified = ( - receipt["status"] - and "execTransaction" in str(decoded[0]) - and len(diff) == 0 - ) - except (TransactionNotFound, KeyError, ValueError): # pragma: nocover - verified = False - return dict( - verified=verified, - status=receipt["status"], - transaction=transaction, - actual=decoded, # type: ignore - expected=expected, - diff=diff, - ) - - @classmethod - def revert_reason( # pylint: disable=unused-argument - cls, - ledger_api: EthereumApi, - contract_address: str, - tx: TxData, - ) -> JSONLike: - """Check the revert reason of a transaction. - - :param ledger_api: the ledger API object. - :param contract_address: the contract address - :param tx: the transaction for which we want to get the revert reason. - - :return: the revert reason message. - """ - ledger_api = cast(EthereumApi, ledger_api) - - # build a new transaction to replay: - replay_tx = { - "to": tx["to"], - "from": tx["from"], - "value": tx["value"], - "data": tx["input"], - } - - try: - # replay the transaction locally: - ledger_api.api.eth.call(replay_tx, tx["blockNumber"] - 1) - except ContractLogicError as e: - # execution reverted exception - return dict(revert_reason=repr(e)) - except HTTPError as e: # pragma: nocover - # http exception - raise e - else: - # given tx not reverted - raise ValueError(f"The given transaction has not been reverted!\ntx: {tx}") - - @classmethod - def get_safe_nonce(cls, ledger_api: EthereumApi, contract_address: str) -> JSONLike: - """ - Retrieve the safe's nonce - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :return: the safe nonce - """ - safe_contract = cls.get_instance(ledger_api, contract_address) - safe_nonce = safe_contract.functions.nonce().call(block_identifier="latest") - return dict(safe_nonce=safe_nonce) - - @classmethod - def get_ingoing_transfers( - cls, - ledger_api: EthereumApi, - contract_address: str, - from_block: Optional[str] = None, - to_block: Optional[str] = "latest", - ) -> JSONLike: - """ - A list of transfers into the contract. - - :param ledger_api: the ledger API object - :param contract_address: the contract address, - :param from_block: from which block to start tje search - :param to_block: at which block to end the search - :return: list of transfers - """ - safe_contract = cls.get_instance(ledger_api, contract_address) - - if from_block is None: - logging.info( - "'from_block' not provided, checking for transfers to the safe contract in the last 50 blocks." - ) - current_block = ledger_api.api.eth.get_block("latest")["number"] - from_block = hex(max(0, current_block - 50)) # check in the last ~10 min - - safe_filter = safe_contract.events.SafeReceived.create_filter( - fromBlock=from_block, toBlock=to_block - ) - all_entries = safe_filter.get_all_entries() - - return { - "data": list( - map( - lambda entry: { - "sender": entry["args"]["sender"], - "amount": int(entry["args"]["value"]), - "blockNumber": entry["blockNumber"], - }, - all_entries, - ) - ) - } - - @classmethod - def get_balance(cls, ledger_api: EthereumApi, contract_address: str) -> JSONLike: - """ - Retrieve the safe's balance - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :return: the safe balance (in wei) - """ - return dict(balance=ledger_api.get_balance(address=contract_address)) - - @classmethod - def get_amount_spent( # pylint: disable=unused-argument - cls, - ledger_api: EthereumApi, - contract_address: str, - tx_hash: str, - ) -> JSONLike: - """ - Get the amount of ether spent in a tx. - - :param ledger_api: the ledger API object - :param contract_address: the contract address (not used) - :param tx_hash: the settled tx hash - :return: the safe balance (in wei) - """ - tx_receipt = ledger_api.get_transaction_receipt(tx_hash) - tx = ledger_api.get_transaction(tx_hash) - - tx_value = int(tx["value"]) - gas_price = int(tx["gasPrice"]) - gas_used = int(tx_receipt["gasUsed"]) - total_spent = tx_value + (gas_price * gas_used) - - return dict(amount_spent=total_spent) - - @classmethod - def get_safe_txs( - cls, - ledger_api: EthereumApi, - contract_address: str, - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - ) -> JSONLike: - """ - Get all the safe tx hashes. - - :param ledger_api: the ledger API object - :param contract_address: the contract address (not used) - :param from_block: from which block to search for events - :param to_block: to which block to search for events - :return: the safe txs - """ - - ledger_api = cast(EthereumApi, ledger_api) - factory_contract = cls.get_instance(ledger_api, contract_address) - entries = factory_contract.events.ExecutionSuccess.create_filter( - fromBlock=from_block, - toBlock=to_block, - ).get_all_entries() - - return dict( - txs=list( - map( - lambda entry: dict( - tx_hash=entry.transactionHash.hex(), - block_number=entry.blockNumber, - ), - entries, - ) - ) - ) - - @classmethod - def get_removed_owner_events( - cls, - ledger_api: EthereumApi, - contract_address: str, - removed_owner: Optional[str] = None, - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - ) -> JSONLike: - """ - Get all RemovedOwner events for a safe contract. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param removed_owner: the owner to check for, any owner qualifies if not provided. - :param from_block: from which block to search for events - :param to_block: to which block to search for events - :return: the added owner events - """ - ledger_api = cast(EthereumApi, ledger_api) - safe_contract = cls.get_instance(ledger_api, contract_address) - entries = safe_contract.events.RemovedOwner.create_filter( - fromBlock=from_block, - toBlock=to_block, - ).get_all_entries() - if removed_owner is None: - removed_owner_events = list( - dict( - tx_hash=entry.transactionHash.hex(), - block_number=entry.blockNumber, - owner=entry["args"]["owner"], - ) - for entry in entries - ) - return dict( - data=removed_owner_events, - ) - - checksummed_removed_owner = ledger_api.api.to_checksum_address(removed_owner) - removed_owner_events = list( - dict( - tx_hash=entry.transactionHash.hex(), - block_number=entry.blockNumber, - owner=entry["args"]["owner"], - ) - for entry in entries - if ( - ledger_api.api.to_checksum_address(entry["args"]["owner"]) - == checksummed_removed_owner - ) - ) - return dict( - data=removed_owner_events, - ) - - @classmethod - def get_zero_transfer_events( - cls, - ledger_api: EthereumApi, - contract_address: str, - sender_address: str, - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - ) -> JSONLike: - """ - Get all zero transfer events from a given sender to the safe address. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param sender_address: the owner of the service, ie the address that triggers termination - :param from_block: from which block to search for events - :param to_block: to which block to search for events - :return: the zero transfer events - """ - ledger_api = cast(EthereumApi, ledger_api) - safe_contract = cls.get_instance(ledger_api, contract_address) - sender_address = ledger_api.api.to_checksum_address(sender_address) - entries = safe_contract.events.SafeReceived.create_filter( - fromBlock=from_block, - toBlock=to_block, - argument_filters=dict(sender=sender_address), - ).get_all_entries() - zero_transfer_events = list( - dict( - tx_hash=entry.transactionHash.hex(), - block_number=entry.blockNumber, - sender=ledger_api.api.to_checksum_address(entry["args"]["sender"]), - ) - for entry in entries - if int(entry["args"]["value"]) == 0 - ) - return dict( - data=zero_transfer_events, - ) - - @classmethod - def get_remove_owner_data( - cls, - ledger_api: EthereumApi, - contract_address: str, - owner: str, - threshold: int, - ) -> JSONLike: - """ - Get a removeOwner() encoded tx. - - This method acts as a wrapper for `removeOwner()` - https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/base/OwnerManager.sol#L70 - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param owner: the owner to be removed - :param threshold: the new safe threshold to be set - :return: the zero transfer events - """ - ledger_api = cast(EthereumApi, ledger_api) - safe_contract = cls.get_instance(ledger_api, contract_address) - # Note that owners in the safe are stored as a linked list, we need to know the parent (prev_owner) of an owner - # when removing. https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/base/OwnerManager.sol#L15 - owners = [ - ledger_api.api.to_checksum_address(owner) - for owner in safe_contract.functions.getOwners().call() - ] - owner = ledger_api.api.to_checksum_address(owner) - prev_owner = cls._get_prev_owner(owners, owner) - data = safe_contract.encodeABI( - fn_name="removeOwner", - args=[ - ledger_api.api.to_checksum_address(prev_owner), - owner, - threshold, - ], - ) - return dict( - data=data, - ) - - @classmethod - def get_swap_owner_data( - cls, - ledger_api: EthereumApi, - contract_address: str, - old_owner: str, - new_owner: str, - ) -> JSONLike: - """ - Get a swapOwner() encoded tx. - - This method acts as a wrapper for `swapOwner()` - https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/base/OwnerManager.sol#L94 - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param old_owner: the owner to be replaced - :param new_owner: owner to replace old_owner - :return: the zero transfer events - """ - ledger_api = cast(EthereumApi, ledger_api) - safe_contract = cls.get_instance(ledger_api, contract_address) - # Note that owners in the safe are stored as a linked list, we need to know the parent (prev_owner) of an owner - # when swapping. https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/base/OwnerManager.sol#L15 - owners = [ - ledger_api.api.to_checksum_address(owner) - for owner in safe_contract.functions.getOwners().call() - ] - old_owner = ledger_api.api.to_checksum_address(old_owner) - prev_owner = cls._get_prev_owner(owners, old_owner) - data = safe_contract.encodeABI( - fn_name="swapOwner", - args=[ - ledger_api.api.to_checksum_address(prev_owner), - old_owner, - ledger_api.api.to_checksum_address(new_owner), - ], - ) - return dict( - data=data, - ) - - @classmethod - def _get_prev_owner(cls, linked_list: List[str], target: str) -> str: - """Given a linked list of strings, it returns the one pointing to target.""" - root = cls._SENTINEL_OWNERS - index = linked_list.index(target) - 1 - if index < 0: - # if target is the first element in the list, the root is pointing to it - return root - return linked_list[index] - - @classmethod - def get_owners( - cls, - ledger_api: EthereumApi, - contract_address: str, - ) -> JSONLike: - """ - Get the safe owners. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :return: the safe owners - """ - ledger_api = cast(EthereumApi, ledger_api) - safe_contract = cls.get_instance(ledger_api, contract_address) - owners = [ - ledger_api.api.to_checksum_address(owner) - for owner in safe_contract.functions.getOwners().call() - ] - return dict(owners=owners) - - @classmethod - def get_approve_hash_tx( - cls, - ledger_api: EthereumApi, - contract_address: str, - tx_hash: str, - sender: str, - ) -> JSONLike: - """Get approve has tx.""" - ledger_api = cast(EthereumApi, ledger_api) - return ledger_api.build_transaction( - contract_instance=cls.get_instance(ledger_api, contract_address), - method_name="approveHash", - method_args={ - "hashToApprove": tx_hash, - }, - tx_args={ - "sender_address": sender, - }, - ) diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe/contract.yaml b/trader_backup/vendor/valory/contracts/gnosis_safe/contract.yaml deleted file mode 100644 index 0576cf599..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe/contract.yaml +++ /dev/null @@ -1,40 +0,0 @@ -name: gnosis_safe -author: valory -version: 0.1.0 -type: contract -description: Gnosis Safe (GnosisSafeL2) contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeig26vrs7tcobu4cgk3fpqhvlzjwmb4nqsc7u66n4yhd2dh2rt7ff4 - __init__.py: bafybeib4nfvueif2tkc7migc73qopyjvrbzedyehrexjx4y5vav3clmf34 - build/GnosisSafe_V1_3_0.json: bafybeifxc4pnyus43qfrvxrqunlmkzvwfr5chyjesyobbk5m4smb2hkd4y - contract.py: bafybeiasa5rs5axojfmuztc6powf7twkpwjiacw2fef3xymmd5jd6hz354 - encode.py: bafybeiez2siif4cpntxjvzcxsgpv2xcdgco4xtnr26pjqzwrlu62tmn2na - tests/__init__.py: bafybeihbclcqwfoxoljzwnbg3nf22srsyx5dgdbcyj27irwizktg4ygujy - tests/test_contract.py: bafybeidb4mrkkj6esxejlqdwx3m7skh2fdskqermxpuiuqpkyvkzb4ndyy -fingerprint_ignore_patterns: [] -contracts: -- valory/gnosis_safe_proxy_factory:0.1.0:bafybeieg57u3z7cdlmdamad5e6lk7kmsli2zurzkg3sl4y7lhekcu4y3au -class_name: GnosisSafeContract -contract_interface_paths: - ethereum: build/GnosisSafe_V1_3_0.json -dependencies: - ecdsa: - version: '>=0.15' - eth-abi: - version: ==4.0.0 - eth-utils: - version: ==2.2.0 - eth_typing: {} - hexbytes: {} - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - packaging: {} - pycryptodome: - version: ==3.18.0 - requests: {} - web3: - version: <7,>=6.0.0 diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe/encode.py b/trader_backup/vendor/valory/contracts/gnosis_safe/encode.py deleted file mode 100644 index e65cf5e0a..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe/encode.py +++ /dev/null @@ -1,155 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""ETH encoder.""" - -import typing as t - -from Crypto.Hash import keccak # nosec -from eth_abi.abi import default_codec # nosec -from eth_utils import decode_hex - - -def encode(typ: t.Any, arg: t.Any) -> bytes: - """Encode by type.""" - encoder = default_codec._registry.get_encoder( # pylint: disable=protected-access - typ - ) - return encoder(arg) - - -def to_string(value: t.Union[bytes, str, int]) -> bytes: - """Convert to byte string.""" - if isinstance(value, bytes): - return value - if isinstance(value, str): - return bytes(value, "utf-8") - if isinstance(value, int): - return bytes(str(value), "utf-8") - raise ValueError("Invalid data") - - -def sha3_256(x: bytes) -> bytes: - """Calculate SHA3-256 hash.""" - return keccak.new(digest_bits=256, data=x).digest() - - -def sha3(seed: t.Union[bytes, str, int]) -> bytes: - """Calculate SHA3-256 hash.""" - return sha3_256(to_string(seed)) - - -def scan_bin(v: str) -> bytes: - """Scan bytes.""" - if v[:2] in ("0x", b"0x"): - return decode_hex(v[2:]) - return decode_hex(v) - - -def create_struct_definition(name: str, schema: t.List[t.Dict[str, str]]) -> str: - """Create method struction defintion.""" - schema_types = [ - (schema_type["type"] + " " + schema_type["name"]) for schema_type in schema - ] - return name + "(" + ",".join(schema_types) + ")" - - -def find_dependencies( - name: str, types: t.Dict[str, t.Any], dependencies: t.Set -) -> None: - """Find dependencies.""" - if name in dependencies: - return - schema = types.get(name) - if not schema: - return - dependencies.add(name) - for schema_type in schema: - find_dependencies(schema_type["type"], types, dependencies) - - -def create_schema(name: str, types: t.Dict) -> str: - """Create schema.""" - array_start = name.find("[") - clean_name = name if array_start < 0 else name[:array_start] - dependencies: t.Set = set() - find_dependencies(clean_name, types, dependencies) - dependencies.discard(clean_name) - dependency_definitions = [ - create_struct_definition(dependency, types[dependency]) - for dependency in sorted(dependencies) - if types.get(dependency) - ] - return create_struct_definition(clean_name, types[clean_name]) + "".join( - dependency_definitions - ) - - -def create_schema_hash(name: str, types: t.Dict) -> bytes: - """Create schema hash.""" - return encode("bytes32", sha3(create_schema(name, types))) - - -def encode_value(data_type: str, value: t.Any, types: t.Dict) -> bytes: - """Encode value.""" - if data_type == "string": - return encode("bytes32", sha3(value)) - if data_type == "bytes": - return encode("bytes32", sha3(scan_bin(value))) - if types.get(data_type): - return encode("bytes32", sha3(encode_data(data_type, value, types))) - if data_type.endswith("]"): - arrayType = data_type[: data_type.index("[")] - return encode( - "bytes32", - sha3( - b"".join( - [encode_data(arrayType, arrayValue, types) for arrayValue in value] - ) - ), - ) - return encode(data_type, value) - - -def encode_data(name: str, data: t.Dict[str, t.Dict[str, str]], types: t.Dict) -> bytes: - """Encode data.""" - return create_schema_hash(name, types) + b"".join( - [ - encode_value(schema_type["type"], data[schema_type["name"]], types) - for schema_type in types[name] - ] - ) - - -def create_struct_hash( - name: str, data: t.Dict[str, t.Dict[str, str]], types: t.Dict -) -> bytes: - """Create struct hash.""" - return sha3(encode_data(name, data, types)) - - -def encode_typed_data(data: t.Dict[str, t.Any]) -> bytes: - """Encode typed data.""" - types = t.cast(t.Dict, data.get("types")) - primary_type = t.cast(str, data.get("primaryType")) - domain = t.cast(t.Dict[str, t.Dict[str, str]], data.get("domain")) - message = t.cast(t.Dict[str, t.Any], data.get("message")) - domain_hash = create_struct_hash("EIP712Domain", domain, types) - message_hash = create_struct_hash(primary_type, message, types) - return sha3(bytes.fromhex("19") + bytes.fromhex("01") + domain_hash + message_hash) diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe/tests/__init__.py b/trader_backup/vendor/valory/contracts/gnosis_safe/tests/__init__.py deleted file mode 100644 index 2d8e4570c..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/gnosis_safe contract.""" diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe/tests/test_contract.py b/trader_backup/vendor/valory/contracts/gnosis_safe/tests/test_contract.py deleted file mode 100644 index 8e938bb1d..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe/tests/test_contract.py +++ /dev/null @@ -1,845 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/gnosis contract.""" - -import binascii -import secrets -import time -from pathlib import Path -from typing import Any, Dict, List, Optional, Tuple, cast -from unittest import mock - -import pytest -from aea.common import JSONLike -from aea.crypto.registries import crypto_registry -from aea_ledger_ethereum import EthereumApi, EthereumCrypto -from aea_test_autonomy.base_test_classes.contracts import ( - BaseGanacheContractTest, - BaseHardhatGnosisContractTest, -) -from aea_test_autonomy.configurations import ( - ETHEREUM_KEY_PATH_1, - ETHEREUM_KEY_PATH_2, - ETHEREUM_KEY_PATH_3, - KEY_PAIRS, -) -from aea_test_autonomy.docker.base import skip_docker_tests -from aea_test_autonomy.helpers.contracts import get_register_contract -from hexbytes import HexBytes -from web3 import Web3 -from web3.datastructures import AttributeDict -from web3.eth import Eth -from web3.exceptions import ContractLogicError -from web3.types import TxData - -from packages.valory.contracts.gnosis_safe.contract import ( - GnosisSafeContract, - SAFE_CONTRACT, -) -from packages.valory.contracts.gnosis_safe_proxy_factory.tests.test_contract import ( - PACKAGE_DIR as PROXY_DIR, -) - - -PACKAGE_DIR = Path(__file__).parent.parent - -DEFAULT_GAS = 1000000 -DEFAULT_MAX_FEE_PER_GAS = 10**15 -DEFAULT_MAX_PRIORITY_FEE_PER_GAS = 10**15 -EXPECTED_TX_KEYS = { - "chainId", - "data", - "from", - "gas", - "maxFeePerGas", - "maxPriorityFeePerGas", - "nonce", - "to", - "value", -} - - -class BaseContractTest(BaseGanacheContractTest): - """Base test case for GnosisSafeContract""" - - NB_OWNERS: int = 4 - THRESHOLD: int = 1 - SALT_NONCE: Optional[int] = None - contract_directory = PACKAGE_DIR - contract: GnosisSafeContract - - @classmethod - def setup_class( - cls, - ) -> None: - """Setup test.""" - # workaround for the fact that contract dependencies are not possible yet - _ = get_register_contract(PROXY_DIR) - super().setup_class() - - @classmethod - def deployment_kwargs(cls) -> Dict[str, Any]: - """Get deployment kwargs.""" - return dict( - owners=cls.owners(), - threshold=int(cls.threshold()), - gas=DEFAULT_GAS, - ) - - @classmethod - def owners(cls) -> List[str]: - """Get the owners.""" - return [ - Web3.to_checksum_address(t[0]) for t in cls.key_pairs()[: cls.NB_OWNERS] - ] - - @classmethod - def deployer(cls) -> Tuple[str, str]: - """Get the key pair of the deployer.""" - # for simplicity, get the first owner - return cls.key_pairs()[0] - - @classmethod - def threshold( - cls, - ) -> int: - """Returns the amount of threshold.""" - return cls.THRESHOLD - - @classmethod - def get_nonce(cls) -> int: - """Get the nonce.""" - if cls.SALT_NONCE is not None: - return cls.SALT_NONCE - return secrets.SystemRandom().randint(0, 2**256 - 1) - - -class BaseContractTestHardHatSafeNet(BaseHardhatGnosisContractTest): - """Base test case for GnosisSafeContract""" - - NB_OWNERS: int = 4 - THRESHOLD: int = 1 - SALT_NONCE: Optional[int] = None - contract_directory = PACKAGE_DIR - sanitize_from_deploy_tx = ["contract_address"] - contract: GnosisSafeContract - - @classmethod - def setup_class( - cls, - ) -> None: - """Setup test.""" - _ = get_register_contract(PROXY_DIR) - super().setup_class() - - @classmethod - def deployment_kwargs(cls) -> Dict[str, Any]: - """Get deployment kwargs.""" - return dict( - owners=cls.owners(), - threshold=int(cls.threshold()), - gas=DEFAULT_GAS, - ) - - @classmethod - def owners(cls) -> List[str]: - """Get the owners.""" - return [ - Web3.to_checksum_address(t[0]) for t in cls.key_pairs()[: cls.NB_OWNERS] - ] - - @classmethod - def deployer(cls) -> Tuple[str, str]: - """Get the key pair of the deployer.""" - # for simplicity, get the first owner - return cls.key_pairs()[0] - - @classmethod - def threshold( - cls, - ) -> int: - """Returns the amount of threshold.""" - return cls.THRESHOLD - - @classmethod - def get_nonce(cls) -> int: - """Get the nonce.""" - if cls.SALT_NONCE is not None: - return cls.SALT_NONCE - return secrets.SystemRandom().randint(0, 2**256 - 1) - - def _verify_safe_tx( - self, - tx_hash: str, - value: int, - data: bytes, - to_address: str, - signatures_by_owners: Dict, - ) -> bool: - """Helper to verify tx.""" - ledger_api = cast(EthereumApi, self.ledger_api) - contract_address = cast(str, self.contract_address) - return self.contract.verify_tx( - ledger_api=ledger_api, - contract_address=contract_address, - tx_hash=tx_hash, - owners=(self.deployer_crypto.address.lower(),), - to_address=to_address, - value=value, - data=data, - signatures_by_owner={ - self.deployer_crypto.address.lower(): signatures_by_owners[ - self.deployer_crypto.address - ] - }, - )["verified"] - - def _get_raw_safe_tx( - self, - sender_address: str, - value: int, - data: bytes, - to_address: str, - signatures_by_owners: Dict, - ) -> JSONLike: - """Helper to prepare a safe tx.""" - ledger_api = cast(EthereumApi, self.ledger_api) - contract_address = cast(str, self.contract_address) - tx = self.contract.get_raw_safe_transaction( - ledger_api=ledger_api, - contract_address=contract_address, - sender_address=sender_address, - owners=(self.deployer_crypto.address.lower(),), - to_address=to_address, - value=value, - data=data, - signatures_by_owner={ - self.deployer_crypto.address.lower(): signatures_by_owners[ - self.deployer_crypto.address - ] - }, - ) - return tx - - -@skip_docker_tests -class TestDeployTransactionHardhat(BaseContractTestHardHatSafeNet): - """Test.""" - - ledger_api: EthereumApi - - def test_deployed(self) -> None: - """Run tests.""" - result = self.contract.get_deploy_transaction( - ledger_api=self.ledger_api, - deployer_address=str(self.deployer_crypto.address), - owners=self.owners(), - threshold=int(self.threshold()), - gas=DEFAULT_GAS, - ) - assert isinstance(result, dict) - assert len(result) == 10 - data = result.pop("data") - assert isinstance(data, str) - assert len(data) > 0 and data.startswith("0x") - # there is no "data" field on the deploy tx - # but there is contract_address - expected_deploy_tx_fields = EXPECTED_TX_KEYS - {"data"} - expected_deploy_tx_fields.add("contract_address") - assert all( - key in result.keys() for key in expected_deploy_tx_fields - ), "Error, found: {}".format(result) - - def test_exceptions( - self, - ) -> None: - """Test exceptions.""" - - with pytest.raises( - ValueError, - match="Threshold cannot be bigger than the number of unique owners", - ): - # Tests for `ValueError("Threshold cannot be bigger than the number of unique owners")`.` - self.contract.get_deploy_transaction( - ledger_api=self.ledger_api, - deployer_address=str(self.deployer_crypto.address), - owners=[], - threshold=1, - ) - - with pytest.raises(ValueError, match="Client does not have any funds"): - # Tests for `ValueError("Client does not have any funds")`. - self.contract.get_deploy_transaction( - ledger_api=self.ledger_api, - deployer_address=crypto_registry.make( - EthereumCrypto.identifier - ).address, - owners=self.owners(), - threshold=int(self.threshold()), - ) - - def test_non_implemented_methods( - self, - ) -> None: - """Test not implemented methods.""" - with pytest.raises(NotImplementedError): - self.contract.get_raw_transaction(self.ledger_api, "") - - with pytest.raises(NotImplementedError): - self.contract.get_raw_message(self.ledger_api, "") - - with pytest.raises(NotImplementedError): - self.contract.get_state(self.ledger_api, "") - - def test_verify(self) -> None: - """Run verify test.""" - assert self.contract_address is not None - result = self.contract.verify_contract( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - ) - assert result["verified"], "Contract not verified." - - verified = self.contract.verify_contract( - ledger_api=self.ledger_api, - contract_address=SAFE_CONTRACT, - )["verified"] - assert not verified, "Not verified" - - def test_get_safe_nonce(self) -> None: - """Run get_safe_nonce test.""" - safe_nonce = self.contract.get_safe_nonce( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - )["safe_nonce"] - assert safe_nonce == 0 - - def test_revert_reason( - self, - ) -> None: - """Test `revert_reason` method.""" - tx = { - "to": "to", - "from": "from", - "value": "value", - "input": "input", - "blockNumber": 1, - } - - def _raise_solidity_error(*_: Any) -> None: - raise ContractLogicError("reason") - - with mock.patch.object( - self.ledger_api.api.eth, "call", new=_raise_solidity_error - ): - reason = self.contract.revert_reason( - self.ledger_api, "contract_address", cast(TxData, tx) - ) - assert "revert_reason" in reason - assert ( - reason["revert_reason"] == "ContractLogicError('reason')" - or reason["revert_reason"] == "ContractLogicError('reason', None)" - ) - - with mock.patch.object(self.ledger_api.api.eth, "call"), pytest.raises( - ValueError, match=f"The given transaction has not been reverted!\ntx: {tx}" - ): - self.contract.revert_reason( - self.ledger_api, "contract_address", cast(TxData, tx) - ) - - def test_get_incoming_transfers(self) -> None: - """Run get_incoming txs.""" - from_block = cast(int, self.ledger_api.api.eth.get_block_number()) + 1 - self.ledger_api.api.eth.send_transaction( - { - "to": self.contract_address, - "from": self.deployer_crypto.address, - "value": 10, - } - ) - - res = cast( - JSONLike, - self.contract.get_ingoing_transfers( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - from_block=hex(from_block), - ), - ) - data = cast(List[JSONLike], res["data"]) - - time.sleep(1) - - assert len(res) == 1, "one transfer should exist" - assert data[0]["amount"] == 10, "transfer amount should be 10" - assert ( - data[0]["sender"] == self.deployer_crypto.address - ), f"{data[0]['sender']} should be the sender" - assert data[0]["blockNumber"] is not None, "tx is still pending" - assert ( - self.ledger_api.api.eth.get_balance(self.contract_address) == 10 - ), "incorrect balance" - - self.ledger_api.api.eth.send_transaction( - { - "to": self.contract_address, - "from": self.deployer_crypto.address, - "value": 100, - } - ) - from_block = cast(int, data[0]["blockNumber"]) + 1 - - time.sleep(3) - res = self.contract.get_ingoing_transfers( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - from_block=hex(from_block), - ) - data = cast(List[JSONLike], res["data"]) - - assert len(res) == 1, "one transfer should exist" - assert data[0]["amount"] == 100, "transfer amount should be 100" - assert ( - data[0]["sender"] == self.deployer_crypto.address - ), f"{data[0]['sender']} should be the sender" - assert data[0]["blockNumber"] is not None, "tx is still pending" - assert ( - self.ledger_api.api.eth.get_balance(self.contract_address) == 110 - ), "incorrect balance" - - def test_get_zero_transfer_events(self) -> None: - """Test get_zero_transfer_events.""" - # check that the safe has no zero transfers - res = cast( - JSONLike, - self.contract.get_zero_transfer_events( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - sender_address=self.deployer_crypto.address, - ), - ) - data = cast(List[JSONLike], res["data"]) - assert len(data) == 0, "no zero transfers should be in the safe" - - # make a zero transfer - self.ledger_api.api.eth.send_transaction( - { - "to": self.contract_address, - "from": self.deployer_crypto.address, - "value": 0, - } - ) - - time.sleep(3) - - res = cast( - JSONLike, - self.contract.get_zero_transfer_events( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - sender_address=self.deployer_crypto.address, - ), - ) - data = cast(List[JSONLike], res["data"]) - - assert len(res) == 1, "one zero transfer should exist" - assert ( - data[0]["sender"] == self.deployer_crypto.address - ), f"{data[0]['sender']} should be the sender" - assert data[0]["block_number"] is not None, "tx is still pending" - - # make a second zero transfer - prev_block = cast(int, self.ledger_api.api.eth.get_block_number()) + 1 - self.ledger_api.api.eth.send_transaction( - { - "to": self.contract_address, - "from": self.deployer_crypto.address, - "value": 0, - } - ) - time.sleep(3) - - res = self.contract.get_zero_transfer_events( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - sender_address=self.deployer_crypto.address, - from_block=prev_block, - ) - data = cast(List[JSONLike], res["data"]) - - assert len(res) == 1, "one zero transfer should exist" - assert ( - data[0]["sender"] == self.deployer_crypto.address - ), f"{data[0]['sender']} should be the sender" - assert data[0]["block_number"] is not None, "tx is still pending" - - def test_get_owners(self) -> None: - """Test the owners are as expected.""" - owners = self.contract.get_owners( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - )["owners"] - assert owners == self.owners() - - -@skip_docker_tests -class TestRawSafeTransaction(BaseContractTestHardHatSafeNet): - """Test `get_raw_safe_transaction`""" - - ledger_api: EthereumApi - - def test_run(self) -> None: - """Run tests.""" - assert self.contract_address is not None - value = 0 - data = b"" - sender = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_1 - ) - assert sender.address == self.owners()[1] - receiver = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_2 - ) - assert receiver.address == self.owners()[2] - fourth = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_3 - ) - assert fourth.address == self.owners()[3] - cryptos = [self.deployer_crypto, sender, receiver, fourth] - tx_hash = self.contract.get_raw_safe_transaction_hash( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - to_address=receiver.address, - value=value, - data=data, - )["tx_hash"] - b_tx_hash = binascii.unhexlify(cast(str, tx_hash)[2:]) - signatures_by_owners = { - crypto.address: crypto.sign_message(b_tx_hash, is_deprecated_mode=True)[2:] - for crypto in cryptos - } - assert list(signatures_by_owners.keys()) == self.owners() - - tx = self._get_raw_safe_tx( - sender_address=sender.address, - value=value, - data=data, - signatures_by_owners=signatures_by_owners, - to_address=receiver.address, - ) - assert all(key in tx.keys() for key in EXPECTED_TX_KEYS), "Missing key" - - tx_signed = sender.sign_transaction(tx) - tx_hash = self.ledger_api.send_signed_transaction(tx_signed) - assert tx_hash is not None, "Tx hash is `None`" - - verified = self._verify_safe_tx( - tx_hash, value, data, receiver.address, signatures_by_owners - ) - assert verified, f"Not verified: {verified}" - - def test_verify_negative(self) -> None: - """Test verify negative.""" - assert self.contract_address is not None - verified = self.contract.verify_tx( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - tx_hash="0xfc6d7c491688840e79ed7d8f0fc73494be305250f0d5f62d04c41bc4467e8603", - owners=("",), - to_address=crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_1 - ).address, - value=0, - data=b"", - signatures_by_owner={}, - )["verified"] - assert not verified, "Should not be verified" - - # mock `get_transaction` and `get_transaction_receipt` using a copy of a real reverted tx and its receipt - @mock.patch.object( - Eth, - "get_transaction", - return_value=AttributeDict( - { - "accessList": [], - "blockHash": HexBytes( - "0x8543592f08d1d9e6d722ba9d600270d7e7789ecc9b66f27ca81b104df9c5dd4a" - ), - "blockNumber": 31190129, - "chainId": "0x89", - "from": "0x5eF6567079c6c26d8ebf61AC0716163367E9B3cf", - "gas": 270000, - "gasPrice": 36215860217, - "hash": HexBytes( - "0x09d5be525caea564b2d4fd31af424c8f0414a9b270937a1bee29167a883e6ce5" - ), - "input": "0x6a7612020000000000000000000000003d9e92b0fe7673dda3d7c33b9ff302768a03de190000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000000000000000001d4c0000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000" - "0000000000000000000000000000000000000000000000000000000000000846b0bac970000000000000000000000" - "000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000" - "000000000004000000000000000000000000000000000000000000000000000000000001df5000000000000000000" - "00000000000000000000000000000487da3583c85e1e0000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000104c292f99a14d354c669" - "3f9037a4a3d09c85c8ad5f1ab4de79bbc8bab845560f797f385ecbe77e90245b7b45e218a2c56fec17c9d38729264" - "83d0ed800df46daa71c3afaa87b5959d644cd0d311a93acb398ec4f9d4c545c54ea6f4adbaa3e99dd9668f948eb64" - "10f1b2105e2f6ca762badf17539d9221cef7af55a244c6ae3c6b401cfd01fe829d711a372b9d8ad5b91e0956a4da1" - "6929d04a2581b10f9f4599899b625c367bef18656c90efcf9d9ee5063860774f08517488b05ef5090acd31aa9d91b" - "7df8080d69fdddfe9b326f3ae0cb95227e21d2d265b6a83861998dd9e91fb980415e78c2bb0b10dbe3b4d7bead977" - "2f32fa26b738c5670aa69ee9d09973ea2b81c00000000000000000000000000000000000000000000000000000000", - "maxFeePerGas": 36215860217, - "maxPriorityFeePerGas": 36215860202, - "nonce": 2231, - "r": HexBytes( - "0x5d5d369d5fc30c5604d974761d41b08118120eb94fd65a827bab1f6ea558d67c" - ), - "s": HexBytes( - "0x12f68826bd41989335e62d43fd36547fe171ad536b99bc93766622438d3f8355" - ), - "to": "0x37ba5291A5bE8cbE44717a0673fe2c5a45B4B6A8", - "transactionIndex": 28, - "type": "0x2", - "v": 1, - "value": 0, - } - ), - ) - @mock.patch.object( - EthereumApi, - "get_transaction_receipt", - return_value={ - "blockHash": "0x8543592f08d1d9e6d722ba9d600270d7e7789ecc9b66f27ca81b104df9c5dd4a", - "blockNumber": 31190129, - "contractAddress": None, - "cumulativeGasUsed": 5167853, - "effectiveGasPrice": 36215860217, - "from": "0x5eF6567079c6c26d8ebf61AC0716163367E9B3cf", - "gasUsed": 48921, - "logs": [ - { - "address": "0x0000000000000000000000000000000000001010", - "blockHash": "0x8543592f08d1d9e6d722ba9d600270d7e7789ecc9b66f27ca81b104df9c5dd4a", - "blockNumber": 31190129, - "data": "0x00000000000000000000000000000000000000000000000000064b5dcc9920c1000000000000000000000000" - "00000000000000000000000032116d529b00f7490000000000000000000000000000000000000000000004353d" - "1a5e0a73394e1e000000000000000000000000000000000000000000000000320b21f4ce67d688000000000000" - "0000000000000000000000000000000004353d20a9683fd26edf", - "logIndex": 115, - "removed": False, - "topics": [ - "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", - "0x0000000000000000000000000000000000000000000000000000000000001010", - "0x0000000000000000000000005ef6567079c6c26d8ebf61ac0716163367e9b3cf", - "0x000000000000000000000000f0245f6251bef9447a08766b9da2b07b28ad80b0", - ], - "transactionHash": "0x09d5be525caea564b2d4fd31af424c8f0414a9b270937a1bee29167a883e6ce5", - "transactionIndex": 28, - } - ], - "logsBloom": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000" - "000000000800000000000000000000000000000008000000000000000000000000080000000000000000000010000" - "000000000000000000000000000000000000000000000000000000008000000000000000000000008000000000000" - "000000000000000000000000000000000000088000020000000000000000000000000000000000000000000000000" - "000000000000400000000000000000000100000000000000000000000000000010000000000000000000000000000" - "0000000800000000000000000000000000000000000100000", - "status": 0, - "to": "0x37ba5291A5bE8cbE44717a0673fe2c5a45B4B6A8", - "transactionHash": "0x09d5be525caea564b2d4fd31af424c8f0414a9b270937a1bee29167a883e6ce5", - "transactionIndex": 28, - "type": "0x2", - "revert_reason": "execution reverted: GS026", - }, - ) - def test_verify_reverted(self, *_: Any) -> None: - """Test verify for reverted tx.""" - assert self.contract_address is not None - res = self.contract.verify_tx( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - tx_hash="test", - owners=("",), - to_address=crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_1 - ).address, - value=0, - data=b"", - signatures_by_owner={}, - ) - assert not res["verified"], "Should not be verified" - - -@skip_docker_tests -class TestOwnerManagement(BaseContractTestHardHatSafeNet): - """Test owner management related .""" - - ledger_api: EthereumApi - - def test_remove(self) -> None: # pylint: disable=too-many-locals - """Test owner removal.""" - assert self.contract_address is not None - owner_to_be_removed = self.owners()[2] - threshold = max(self.threshold() - 1, 1) - value = 0 - data_str = self.contract.get_remove_owner_data( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - owner=owner_to_be_removed, - threshold=threshold, - ).get("data") - data = bytes.fromhex(data_str[2:]) # strip 0x before converting to bytes - - sender = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_1 - ) - assert sender.address == self.owners()[1] - receiver = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_2 - ) - assert receiver.address == self.owners()[2] - fourth = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_3 - ) - assert fourth.address == self.owners()[3] - cryptos = [self.deployer_crypto, sender, receiver, fourth] - tx_hash = self.contract.get_raw_safe_transaction_hash( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - to_address=self.contract_address, - value=value, - data=data, - )["tx_hash"] - b_tx_hash = binascii.unhexlify(cast(str, tx_hash)[2:]) - signatures_by_owners = { - crypto.address: crypto.sign_message(b_tx_hash, is_deprecated_mode=True)[2:] - for crypto in cryptos - } - assert list(signatures_by_owners.keys()) == self.owners() - - tx = self._get_raw_safe_tx( - sender_address=sender.address, - value=value, - data=data, - to_address=self.contract_address, - signatures_by_owners=signatures_by_owners, - ) - assert all(key in tx.keys() for key in EXPECTED_TX_KEYS), "Missing key" - - prev_block = cast(int, self.ledger_api.api.eth.get_block_number()) + 1 - tx_signed = sender.sign_transaction(tx) - tx_hash = self.ledger_api.send_signed_transaction(tx_signed) - - assert tx_hash is not None, "Tx hash is `None`" - - verified = self._verify_safe_tx( - tx_hash, value, data, self.contract_address, signatures_by_owners - ) - assert verified, f"Not verified: {verified}" - time.sleep(1) - remove_events = self.contract.get_removed_owner_events( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - removed_owner=owner_to_be_removed, - from_block=prev_block, - ).get("data") - - assert remove_events is not None, "a RemovedOwner event was expected" - assert len(remove_events) == 1, "1 RemovedOwner event was expected" - assert ( - remove_events[0].get("owner") == owner_to_be_removed - ), "a different owner than expected was removed" - - def test_swap(self) -> None: # pylint: disable=too-many-locals - """Test owner swapping.""" - assert self.contract_address is not None - old_owner = self.owners()[1] - new_owner = KEY_PAIRS[-1][0] - value = 0 - data_str = self.contract.get_swap_owner_data( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - old_owner=old_owner, - new_owner=new_owner, - ).get("data") - data = bytes.fromhex(data_str[2:]) # strip 0x before converting to bytes - - sender = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_1 - ) - assert sender.address == self.owners()[1] - receiver = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_2 - ) - assert receiver.address == self.owners()[2] - fourth = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_3 - ) - assert fourth.address == self.owners()[3] - cryptos = [self.deployer_crypto, sender, receiver, fourth] - tx_hash = self.contract.get_raw_safe_transaction_hash( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - to_address=self.contract_address, - value=value, - data=data, - )["tx_hash"] - b_tx_hash = binascii.unhexlify(cast(str, tx_hash)[2:]) - signatures_by_owners = { - crypto.address: crypto.sign_message(b_tx_hash, is_deprecated_mode=True)[2:] - for crypto in cryptos - } - assert list(signatures_by_owners.keys()) == self.owners() - - tx = self._get_raw_safe_tx( - sender_address=sender.address, - to_address=self.contract_address, - value=value, - data=data, - signatures_by_owners=signatures_by_owners, - ) - assert all(key in tx.keys() for key in EXPECTED_TX_KEYS), "Missing key" - - prev_block = cast(int, self.ledger_api.api.eth.get_block_number()) + 1 - tx_signed = sender.sign_transaction(tx) - tx_hash = self.ledger_api.send_signed_transaction(tx_signed) - - assert tx_hash is not None, "Tx hash is `None`" - - verified = self._verify_safe_tx( - tx_hash, value, data, self.contract_address, signatures_by_owners - ) - assert verified, f"Not verified: {verified}" - time.sleep(1) - remove_events = self.contract.get_removed_owner_events( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - removed_owner=old_owner, - from_block=prev_block, - ).get("data") - - assert remove_events is not None, "a RemovedOwner event was expected" - assert len(remove_events) == 1, "1 RemovedOwner event was expected" - assert ( - remove_events[0].get("owner") == old_owner - ), "a different owner than expected was removed" diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/README.md b/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/README.md deleted file mode 100644 index 0fe891711..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Gnosis Safe Proxy Factory contract - -## Description - -## Functions - diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/__init__.py b/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/__init__.py deleted file mode 100644 index d0992d1cb..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the support resources for the gnosis_safe_proxy_contract (GnosisSafeProxyFactory) contract.""" diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/build/ProxyFactory_V1_3_0.json b/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/build/ProxyFactory_V1_3_0.json deleted file mode 100644 index ef03cd84a..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/build/ProxyFactory_V1_3_0.json +++ /dev/null @@ -1,172 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "GnosisSafeProxyFactory", - "sourceName": "contracts/proxies/GnosisSafeProxyFactory.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "contract GnosisSafeProxy", - "name": "proxy", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "singleton", - "type": "address" - } - ], - "name": "ProxyCreation", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_singleton", - "type": "address" - }, - { - "internalType": "bytes", - "name": "initializer", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "saltNonce", - "type": "uint256" - } - ], - "name": "calculateCreateProxyWithNonceAddress", - "outputs": [ - { - "internalType": "contract GnosisSafeProxy", - "name": "proxy", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "singleton", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "createProxy", - "outputs": [ - { - "internalType": "contract GnosisSafeProxy", - "name": "proxy", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_singleton", - "type": "address" - }, - { - "internalType": "bytes", - "name": "initializer", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "saltNonce", - "type": "uint256" - }, - { - "internalType": "contract IProxyCreationCallback", - "name": "callback", - "type": "address" - } - ], - "name": "createProxyWithCallback", - "outputs": [ - { - "internalType": "contract GnosisSafeProxy", - "name": "proxy", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_singleton", - "type": "address" - }, - { - "internalType": "bytes", - "name": "initializer", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "saltNonce", - "type": "uint256" - } - ], - "name": "createProxyWithNonce", - "outputs": [ - { - "internalType": "contract GnosisSafeProxy", - "name": "proxy", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "proxyCreationCode", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "proxyRuntimeCode", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "pure", - "type": "function" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610ebe806100206000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80631688f0b9146100675780632500510e1461017657806353e5d9351461024357806361b69abd146102c6578063addacc0f146103cb578063d18af54d1461044e575b600080fd5b61014a6004803603606081101561007d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156100ba57600080fd5b8201836020820111156100cc57600080fd5b803590602001918460018302840111640100000000831117156100ee57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919050505061057d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102176004803603606081101561018c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156101c957600080fd5b8201836020820111156101db57600080fd5b803590602001918460018302840111640100000000831117156101fd57600080fd5b909192939192939080359060200190929190505050610624565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61024b610751565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561028b578082015181840152602081019050610270565b50505050905090810190601f1680156102b85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61039f600480360360408110156102dc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561031957600080fd5b82018360208201111561032b57600080fd5b8035906020019184600183028401116401000000008311171561034d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061077c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103d3610861565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104135780820151818401526020810190506103f8565b50505050905090810190601f1680156104405780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6105516004803603608081101561046457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156104a157600080fd5b8201836020820111156104b357600080fd5b803590602001918460018302840111640100000000831117156104d557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061088c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600061058a848484610a3b565b90506000835111156105b25760008060008551602087016000865af114156105b157600080fd5b5b7f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2358185604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a19392505050565b60006106758585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084610a3b565b905080604051602001808273ffffffffffffffffffffffffffffffffffffffff1660601b81526014019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156107165780820151818401526020810190506106fb565b50505050905090810190601f1680156107435780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60606040518060200161076390610bde565b6020820181038252601f19601f82011660405250905090565b60008260405161078b90610bde565b808273ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f0801580156107c7573d6000803e3d6000fd5b5090506000825111156107f05760008060008451602086016000865af114156107ef57600080fd5b5b7f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2358184604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a192915050565b60606040518060200161087390610beb565b6020820181038252601f19601f82011660405250905090565b6000808383604051602001808381526020018273ffffffffffffffffffffffffffffffffffffffff1660601b8152601401925050506040516020818303038152906040528051906020012060001c90506108e786868361057d565b9150600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610a32578273ffffffffffffffffffffffffffffffffffffffff16631e52b518838888886040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156109ca5780820151818401526020810190506109af565b50505050905090810190601f1680156109f75780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015610a1957600080fd5b505af1158015610a2d573d6000803e3d6000fd5b505050505b50949350505050565b6000808380519060200120836040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050600060405180602001610a8890610bde565b6020820181038252601f19601f820116604052508673ffffffffffffffffffffffffffffffffffffffff166040516020018083805190602001908083835b60208310610ae95780518252602082019150602081019050602083039250610ac6565b6001836020036101000a038019825116818451168082178552505050505050905001828152602001925050506040516020818303038152906040529050818151826020016000f59250600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610bd5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f437265617465322063616c6c206661696c65640000000000000000000000000081525060200191505060405180910390fd5b50509392505050565b6101e680610bf883390190565b60ab80610dde8339019056fe608060405234801561001057600080fd5b506040516101e63803806101e68339818101604052602081101561003357600080fd5b8101908080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156100ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101c46022913960400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505060ab806101196000396000f3fe608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea2646970667358221220d1429297349653a4918076d650332de1a1068c5f3e07c5c82360c277770b955264736f6c63430007060033496e76616c69642073696e676c65746f6e20616464726573732070726f7669646564608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea2646970667358221220d1429297349653a4918076d650332de1a1068c5f3e07c5c82360c277770b955264736f6c63430007060033a26469706673582212200c75fe2196b9f752c82794253f2ebce0d821afef5997e1d5a35ec316ce592f6664736f6c63430007060033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c80631688f0b9146100675780632500510e1461017657806353e5d9351461024357806361b69abd146102c6578063addacc0f146103cb578063d18af54d1461044e575b600080fd5b61014a6004803603606081101561007d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156100ba57600080fd5b8201836020820111156100cc57600080fd5b803590602001918460018302840111640100000000831117156100ee57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919050505061057d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102176004803603606081101561018c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156101c957600080fd5b8201836020820111156101db57600080fd5b803590602001918460018302840111640100000000831117156101fd57600080fd5b909192939192939080359060200190929190505050610624565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61024b610751565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561028b578082015181840152602081019050610270565b50505050905090810190601f1680156102b85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61039f600480360360408110156102dc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561031957600080fd5b82018360208201111561032b57600080fd5b8035906020019184600183028401116401000000008311171561034d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061077c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103d3610861565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104135780820151818401526020810190506103f8565b50505050905090810190601f1680156104405780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6105516004803603608081101561046457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156104a157600080fd5b8201836020820111156104b357600080fd5b803590602001918460018302840111640100000000831117156104d557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061088c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600061058a848484610a3b565b90506000835111156105b25760008060008551602087016000865af114156105b157600080fd5b5b7f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2358185604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a19392505050565b60006106758585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084610a3b565b905080604051602001808273ffffffffffffffffffffffffffffffffffffffff1660601b81526014019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156107165780820151818401526020810190506106fb565b50505050905090810190601f1680156107435780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60606040518060200161076390610bde565b6020820181038252601f19601f82011660405250905090565b60008260405161078b90610bde565b808273ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f0801580156107c7573d6000803e3d6000fd5b5090506000825111156107f05760008060008451602086016000865af114156107ef57600080fd5b5b7f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2358184604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a192915050565b60606040518060200161087390610beb565b6020820181038252601f19601f82011660405250905090565b6000808383604051602001808381526020018273ffffffffffffffffffffffffffffffffffffffff1660601b8152601401925050506040516020818303038152906040528051906020012060001c90506108e786868361057d565b9150600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610a32578273ffffffffffffffffffffffffffffffffffffffff16631e52b518838888886040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156109ca5780820151818401526020810190506109af565b50505050905090810190601f1680156109f75780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015610a1957600080fd5b505af1158015610a2d573d6000803e3d6000fd5b505050505b50949350505050565b6000808380519060200120836040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050600060405180602001610a8890610bde565b6020820181038252601f19601f820116604052508673ffffffffffffffffffffffffffffffffffffffff166040516020018083805190602001908083835b60208310610ae95780518252602082019150602081019050602083039250610ac6565b6001836020036101000a038019825116818451168082178552505050505050905001828152602001925050506040516020818303038152906040529050818151826020016000f59250600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610bd5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f437265617465322063616c6c206661696c65640000000000000000000000000081525060200191505060405180910390fd5b50509392505050565b6101e680610bf883390190565b60ab80610dde8339019056fe608060405234801561001057600080fd5b506040516101e63803806101e68339818101604052602081101561003357600080fd5b8101908080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156100ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101c46022913960400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505060ab806101196000396000f3fe608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea2646970667358221220d1429297349653a4918076d650332de1a1068c5f3e07c5c82360c277770b955264736f6c63430007060033496e76616c69642073696e676c65746f6e20616464726573732070726f7669646564608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea2646970667358221220d1429297349653a4918076d650332de1a1068c5f3e07c5c82360c277770b955264736f6c63430007060033a26469706673582212200c75fe2196b9f752c82794253f2ebce0d821afef5997e1d5a35ec316ce592f6664736f6c63430007060033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.py b/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.py deleted file mode 100644 index 0294e5be0..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the class to connect to an Gnosis Safe Proxy Factory contract.""" -import logging -from typing import Any, Optional, Tuple, cast - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi -from web3.types import Nonce, TxParams, Wei - - -PUBLIC_ID = PublicId.from_str("valory/gnosis_safe_proxy_factory:0.1.0") -MIN_GAS = 1 -# see https://github.com/valory-xyz/open-autonomy/pull/1209#discussion_r950129886 -GAS_ESTIMATE_ADJUSTMENT = 50_000 - - -_logger = logging.getLogger( - f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" -) - -PROXY_FACTORY_CONTRACT = "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2" - - -class GnosisSafeProxyFactoryContract(Contract): - """The Gnosis Safe Proxy Factory contract.""" - - contract_id = PUBLIC_ID - - @classmethod - def get_raw_transaction( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get the raw transaction.""" - raise NotImplementedError # pragma: nocover - - @classmethod - def get_raw_message( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[bytes]: - """Get raw message.""" - raise NotImplementedError # pragma: nocover - - @classmethod - def get_state( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get state.""" - raise NotImplementedError # pragma: nocover - - @classmethod - def get_deploy_transaction( - cls, ledger_api: LedgerApi, deployer_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """ - Get deploy transaction. - - :param ledger_api: ledger API object. - :param deployer_address: the deployer address. - :param kwargs: the keyword arguments. - :return: an optional JSON-like object. - """ - return super().get_deploy_transaction(ledger_api, deployer_address, **kwargs) - - @classmethod - def build_tx_deploy_proxy_contract_with_nonce( # pylint: disable=too-many-arguments,too-many-locals - cls, - ledger_api: EthereumApi, - proxy_factory_address: str, - master_copy: str, - address: str, - initializer: bytes, - salt_nonce: int, - gas: int = MIN_GAS, - gas_price: Optional[int] = None, - max_fee_per_gas: Optional[int] = None, - max_priority_fee_per_gas: Optional[int] = None, - nonce: Optional[int] = None, - ) -> Tuple[TxParams, str]: - """ - Deploy proxy contract via Proxy Factory using `createProxyWithNonce` (create2) - - :param ledger_api: ledger API object - :param proxy_factory_address: the address of the proxy factory - :param address: Ethereum address - :param master_copy: Address the proxy will point at - :param initializer: Data for safe creation - :param salt_nonce: Uint256 for `create2` salt - :param gas: Gas - :param gas_price: Gas Price - :param max_fee_per_gas: max - :param max_priority_fee_per_gas: max - :param nonce: Nonce - :return: Tuple(tx-hash, tx, deployed contract address) - """ - proxy_factory_contract = cls.get_instance(ledger_api, proxy_factory_address) - - create_proxy_fn = proxy_factory_contract.functions.createProxyWithNonce( - master_copy, initializer, salt_nonce - ) - - tx_parameters = TxParams({"from": address}) - contract_address = create_proxy_fn.call(tx_parameters) - - if gas_price is not None: - tx_parameters["gasPrice"] = Wei(gas_price) # pragma: nocover - - if max_fee_per_gas is not None: - tx_parameters["maxFeePerGas"] = Wei(max_fee_per_gas) # pragma: nocover - - if max_priority_fee_per_gas is not None: - tx_parameters["maxPriorityFeePerGas"] = Wei( # pragma: nocover - max_priority_fee_per_gas - ) - - if ( - gas_price is None - and max_fee_per_gas is None - and max_priority_fee_per_gas is None - ): - tx_parameters.update(ledger_api.try_get_gas_pricing()) - - # we set a value to avoid triggering the gas estimation during `buildTransaction` below - tx_parameters["gas"] = Wei(max(gas, MIN_GAS)) - - if nonce is not None: - tx_parameters["nonce"] = Nonce(nonce) - - transaction_dict = create_proxy_fn.build_transaction(tx_parameters) - gas_estimate = ( - ledger_api._try_get_gas_estimate( # pylint: disable=protected-access - transaction_dict - ) - ) - # see https://github.com/valory-xyz/open-autonomy/pull/1209#discussion_r950129886 - transaction_dict["gas"] = ( - Wei(max(gas_estimate + GAS_ESTIMATE_ADJUSTMENT, gas)) - if gas_estimate is not None - else Wei(gas) - ) - return transaction_dict, contract_address - - @classmethod - def verify_contract( - cls, ledger_api: EthereumApi, contract_address: str - ) -> JSONLike: - """ - Verify the contract's bytecode - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :return: the verified status - """ - ledger_api = cast(EthereumApi, ledger_api) - deployed_bytecode = ledger_api.api.eth.get_code(contract_address).hex() - local_bytecode = cls.contract_interface["ethereum"]["deployedBytecode"] - verified = deployed_bytecode == local_bytecode - return dict(verified=verified) diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.yaml b/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.yaml deleted file mode 100644 index 7a8bf9e9f..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: gnosis_safe_proxy_factory -author: valory -version: 0.1.0 -type: contract -description: Gnosis Safe proxy factory (GnosisSafeProxyFactory) contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeibobgyzn3kozckup5uxbugbgkiqrc7d5okmj6gahctccqfifu7e4e - __init__.py: bafybeif32mykzila23udgceziog2zr4tkreij6zn43ybbtzonojsfmy5ee - build/ProxyFactory_V1_3_0.json: bafybeibmhgw6us3nzg5d4vb3krg3udxgnux66vuz26pjcigdjc7zn5jrxm - contract.py: bafybeiefqqgav5dfw5p7nnwd3yq7ls4636dgsaolkau2nd5tslsvp66m6u - tests/__init__.py: bafybeied5o76k2pgmpqlofnfo2mhoncecnigkm24t26qrnhhqzvtg3g3b4 - tests/test_contract.py: bafybeidgcxvkl4xjg5dbjzl3o6ffoylkdewrpni6lxm3624qrebbwmqeay -fingerprint_ignore_patterns: [] -contracts: [] -class_name: GnosisSafeProxyFactoryContract -contract_interface_paths: - ethereum: build/ProxyFactory_V1_3_0.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - web3: - version: <7,>=6.0.0 diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/__init__.py b/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/__init__.py deleted file mode 100644 index 8e71b2cb5..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/gnosis_safe_proxy_factory contract.""" diff --git a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/test_contract.py b/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/test_contract.py deleted file mode 100644 index 8c106a1f8..000000000 --- a/trader_backup/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/test_contract.py +++ /dev/null @@ -1,103 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/gnosis contract.""" - -from pathlib import Path -from typing import Any, Dict - -from aea_test_autonomy.base_test_classes.contracts import BaseGanacheContractTest -from aea_test_autonomy.docker.base import skip_docker_tests - -from packages.valory.contracts.gnosis_safe_proxy_factory.contract import ( - GnosisSafeProxyFactoryContract, - PROXY_FACTORY_CONTRACT, -) - - -PACKAGE_DIR = Path(__file__).parent.parent - -DEFAULT_GAS = 1000000 -DEFAULT_MAX_FEE_PER_GAS = 10**10 -DEFAULT_MAX_PRIORITY_FEE_PER_GAS = 10**10 -SAFE_CONTRACT = "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552" - - -@skip_docker_tests -class TestGnosisSafeProxyFactory(BaseGanacheContractTest): - """Test deployment of the proxy to Ganache.""" - - contract_directory = PACKAGE_DIR - contract: GnosisSafeProxyFactoryContract - - @classmethod - def deployment_kwargs(cls) -> Dict[str, Any]: - """Get deployment kwargs.""" - return dict( - gas=DEFAULT_GAS, - ) - - def test_deploy(self) -> None: - """Test deployment results.""" - assert ( - self.contract_address != PROXY_FACTORY_CONTRACT - ), "Contract addresses should differ as we don't use deterministic deployment here." - - def test_build_tx_deploy_proxy_contract_with_nonce(self) -> None: - """Test build_tx_deploy_proxy_contract_with_nonce method.""" - assert self.contract_address is not None - result = self.contract.build_tx_deploy_proxy_contract_with_nonce( - self.ledger_api, - self.contract_address, - SAFE_CONTRACT, - self.deployer_crypto.address, - b"", - 1, - gas=DEFAULT_GAS, - nonce=1, - ) - assert len(result) == 2 - assert len(result[0]) == 9 - assert all( - [ - key - in [ - "value", - "gas", - "maxFeePerGas", - "maxPriorityFeePerGas", - "chainId", - "from", - "to", - "data", - "nonce", - ] - for key in result[0].keys() - ] - ) - - def test_verify(self) -> None: - """Test verification of deployed contract results.""" - assert self.contract_address is not None - result = self.contract.verify_contract( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - ) - - assert result["verified"], "Contract not verified." diff --git a/trader_backup/vendor/valory/contracts/market_maker/README.md b/trader_backup/vendor/valory/contracts/market_maker/README.md deleted file mode 100644 index 6c58c0f7e..000000000 --- a/trader_backup/vendor/valory/contracts/market_maker/README.md +++ /dev/null @@ -1 +0,0 @@ -# Market Maker contract diff --git a/trader_backup/vendor/valory/contracts/market_maker/__init__.py b/trader_backup/vendor/valory/contracts/market_maker/__init__.py deleted file mode 100644 index 85fd10b57..000000000 --- a/trader_backup/vendor/valory/contracts/market_maker/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for the market maker contract.""" diff --git a/trader_backup/vendor/valory/contracts/market_maker/build/FixedProductMarketMaker.json b/trader_backup/vendor/valory/contracts/market_maker/build/FixedProductMarketMaker.json deleted file mode 100644 index b6d1ea43f..000000000 --- a/trader_backup/vendor/valory/contracts/market_maker/build/FixedProductMarketMaker.json +++ /dev/null @@ -1,662 +0,0 @@ -{ - "_format": "", - "contractName": "", - "sourceName": "", - "abi": [ - { - "constant": true, - "inputs": [ - { - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "spender", - "type": "address" - }, - { - "name": "amount", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "account", - "type": "address" - } - ], - "name": "withdrawFees", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "account", - "type": "address" - } - ], - "name": "feesWithdrawableBy", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "sender", - "type": "address" - }, - { - "name": "recipient", - "type": "address" - }, - { - "name": "amount", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "spender", - "type": "address" - }, - { - "name": "addedValue", - "type": "uint256" - } - ], - "name": "increaseAllowance", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "investmentAmount", - "type": "uint256" - }, - { - "name": "outcomeIndex", - "type": "uint256" - }, - { - "name": "minOutcomeTokensToBuy", - "type": "uint256" - } - ], - "name": "buy", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "returnAmount", - "type": "uint256" - }, - { - "name": "outcomeIndex", - "type": "uint256" - } - ], - "name": "calcSellAmount", - "outputs": [ - { - "name": "outcomeTokenSellAmount", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "conditionalTokens", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "account", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "collectedFees", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "spender", - "type": "address" - }, - { - "name": "subtractedValue", - "type": "uint256" - } - ], - "name": "decreaseAllowance", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "recipient", - "type": "address" - }, - { - "name": "amount", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "collateralToken", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "operator", - "type": "address" - }, - { - "name": "from", - "type": "address" - }, - { - "name": "ids", - "type": "uint256[]" - }, - { - "name": "values", - "type": "uint256[]" - }, - { - "name": "data", - "type": "bytes" - } - ], - "name": "onERC1155BatchReceived", - "outputs": [ - { - "name": "", - "type": "bytes4" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "returnAmount", - "type": "uint256" - }, - { - "name": "outcomeIndex", - "type": "uint256" - }, - { - "name": "maxOutcomeTokensToSell", - "type": "uint256" - } - ], - "name": "sell", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "addedFunds", - "type": "uint256" - }, - { - "name": "distributionHint", - "type": "uint256[]" - } - ], - "name": "addFunding", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "conditionIds", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "owner", - "type": "address" - }, - { - "name": "spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "fee", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "sharesToBurn", - "type": "uint256" - } - ], - "name": "removeFunding", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "operator", - "type": "address" - }, - { - "name": "from", - "type": "address" - }, - { - "name": "id", - "type": "uint256" - }, - { - "name": "value", - "type": "uint256" - }, - { - "name": "data", - "type": "bytes" - } - ], - "name": "onERC1155Received", - "outputs": [ - { - "name": "", - "type": "bytes4" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "investmentAmount", - "type": "uint256" - }, - { - "name": "outcomeIndex", - "type": "uint256" - } - ], - "name": "calcBuyAmount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "funder", - "type": "address" - }, - { - "indexed": false, - "name": "amountsAdded", - "type": "uint256[]" - }, - { - "indexed": false, - "name": "sharesMinted", - "type": "uint256" - } - ], - "name": "FPMMFundingAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "funder", - "type": "address" - }, - { - "indexed": false, - "name": "amountsRemoved", - "type": "uint256[]" - }, - { - "indexed": false, - "name": "collateralRemovedFromFeePool", - "type": "uint256" - }, - { - "indexed": false, - "name": "sharesBurnt", - "type": "uint256" - } - ], - "name": "FPMMFundingRemoved", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "buyer", - "type": "address" - }, - { - "indexed": false, - "name": "investmentAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "feeAmount", - "type": "uint256" - }, - { - "indexed": true, - "name": "outcomeIndex", - "type": "uint256" - }, - { - "indexed": false, - "name": "outcomeTokensBought", - "type": "uint256" - } - ], - "name": "FPMMBuy", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "seller", - "type": "address" - }, - { - "indexed": false, - "name": "returnAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "feeAmount", - "type": "uint256" - }, - { - "indexed": true, - "name": "outcomeIndex", - "type": "uint256" - }, - { - "indexed": false, - "name": "outcomeTokensSold", - "type": "uint256" - } - ], - "name": "FPMMSell", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "from", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - ], - "bytecode": "", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/market_maker/contract.py b/trader_backup/vendor/valory/contracts/market_maker/contract.py deleted file mode 100644 index e77c282ca..000000000 --- a/trader_backup/vendor/valory/contracts/market_maker/contract.py +++ /dev/null @@ -1,186 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the class to connect to a Market Maker contract.""" - -from typing import Any, Dict - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract as BaseContract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi - -PUBLIC_ID = PublicId.from_str("valory/market_maker:0.1.0") - - -class Contract(BaseContract): - """Extended abstract definition of a contract.""" - - @classmethod - def _method_call( - cls, - ledger_api: EthereumApi, - contract_address: str, - method_name: str, - **kwargs: Any, - ): - """Call a contract's method. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param method_name: the contract method to call - :param kwargs: the contract call parameters - :return: the call result - """ - contract_instance = cls.get_instance(ledger_api, contract_address) - return ledger_api.contract_method_call( - contract_instance, - method_name, - **kwargs, - ) - - @classmethod - def _encode_abi( - cls, - ledger_api: LedgerApi, - contract_address: str, - method_name: str, - **kwargs: Any, - ) -> Dict[str, bytes]: - """Gets the encoded data for a contract's method call. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param method_name: the contract method to call - :param kwargs: the contract call parameters - :return: the call result - """ - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI(method_name, kwargs=kwargs) - return {"data": bytes.fromhex(data[2:])} - - -class FixedProductMarketMakerContract(Contract): - """The Market Maker contract.""" - - contract_id = PUBLIC_ID - - @classmethod - def calc_buy_amount( - cls, - ledger_api: EthereumApi, - contract_address: str, - investment_amount: int, - outcome_index: int, - ) -> JSONLike: - """ - Calculate the buy amount. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param investment_amount: the amount the user is willing to invest for an answer - :param outcome_index: the index of the answer's outcome that the user wants to vote for - :return: the buy amount - """ - amount = cls._method_call( - ledger_api, - contract_address, - "calcBuyAmount", - investmentAmount=investment_amount, - outcomeIndex=outcome_index, - ) - return dict(amount=amount) - - @classmethod - def get_buy_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - investment_amount: int, - outcome_index: int, - min_outcome_tokens_to_buy: int, - ) -> Dict[str, bytes]: - """Gets the encoded arguments for a buy tx, which should only be called via the multisig. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param investment_amount: the amount the user is willing to invest for an answer - :param outcome_index: the index of the answer's outcome that the user wants to vote for - :param min_outcome_tokens_to_buy: the output of the `calcBuyAmount` contract method - """ - return cls._encode_abi( - ledger_api, - contract_address, - "buy", - investmentAmount=investment_amount, - outcomeIndex=outcome_index, - minOutcomeTokensToBuy=min_outcome_tokens_to_buy, - ) - - @classmethod - def calc_sell_amount( - cls, - ledger_api: EthereumApi, - contract_address: str, - return_amount: int, - outcome_index: int, - ) -> JSONLike: - """ - Calculate the buy amount. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param return_amount: the amount the user will have returned - :param outcome_index: the index of the answer's outcome that the user wants to sell for - :return: the outcomeTokenSellAmount - """ - outcome_token_sell_amount = cls._method_call( - ledger_api, - contract_address, - "calcSellAmount", - returnAmount=return_amount, - outcomeIndex=outcome_index, - ) - return dict(outcomeTokenSellAmount=outcome_token_sell_amount) - - def get_sell_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - return_amount: int, - outcome_index: int, - max_outcome_tokens_to_sell: int, - ) -> Dict[str, bytes]: - """Gets the encoded arguments for a sell tx, which should only be called via the multisig. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param return_amount: the amount the user have returned - :param outcome_index: the index of the answer's outcome that the user wants to sell tokens for - :param max_outcome_tokens_to_sell: the output of the `calcSellAmount` contract method - """ - return cls._encode_abi( - ledger_api, - contract_address, - "sell", - returnAmount=return_amount, - outcomeIndex=outcome_index, - maxOutcomeTokenSellAmount=max_outcome_tokens_to_sell, - ) diff --git a/trader_backup/vendor/valory/contracts/market_maker/contract.yaml b/trader_backup/vendor/valory/contracts/market_maker/contract.yaml deleted file mode 100644 index 0065c491b..000000000 --- a/trader_backup/vendor/valory/contracts/market_maker/contract.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: market_maker -author: valory -version: 0.1.0 -type: contract -description: Fixed product market maker contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeiegnihrovfkk5big52pl4bo6evt5toqvvmft2jgnq6ofdbhfp7xwa - __init__.py: bafybeicoucixii3fv5xlpk3zfewm4ys4okidcng54bhtjxvwup7g2jcjza - build/FixedProductMarketMaker.json: bafybeigim7n3f67r5czfc5wp2m7cxzxwvnhxops3n5j2zlawenan7qrrtu - contract.py: bafybeifcopgnnts3dbfh636vvdsgporlkt2olwr2iwuwaom5vjcrtbe5wi -fingerprint_ignore_patterns: [] -contracts: [] -class_name: FixedProductMarketMakerContract -contract_interface_paths: - ethereum: build/FixedProductMarketMaker.json -dependencies: - ecdsa: - version: '>=0.15' - eth_typing: {} - hexbytes: {} - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - packaging: {} - py-eth-sig-utils: {} - requests: - version: ==2.28.1 - web3: - version: <7,>=6.0.0 diff --git a/trader_backup/vendor/valory/contracts/mech/README.md b/trader_backup/vendor/valory/contracts/mech/README.md deleted file mode 100644 index c321ae231..000000000 --- a/trader_backup/vendor/valory/contracts/mech/README.md +++ /dev/null @@ -1 +0,0 @@ -# Agent Mech contract diff --git a/trader_backup/vendor/valory/contracts/mech/__init__.py b/trader_backup/vendor/valory/contracts/mech/__init__.py deleted file mode 100644 index e34c6e4ef..000000000 --- a/trader_backup/vendor/valory/contracts/mech/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for an agent Mech.""" diff --git a/trader_backup/vendor/valory/contracts/mech/build/mech.json b/trader_backup/vendor/valory/contracts/mech/build/mech.json deleted file mode 100644 index 18aa41151..000000000 --- a/trader_backup/vendor/valory/contracts/mech/build/mech.json +++ /dev/null @@ -1,746 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "AgentMech", - "sourceName": "contracts/AgentMech.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_price", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "AgentNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "NotEnoughPaid", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "Overflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "name": "RequestIdNotFound", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "Deliver", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "price", - "type": "uint256" - } - ], - "name": "PriceUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "Request", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "deliver", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "entryPoint", - "outputs": [ - { - "internalType": "contract IEntryPoint", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "txGas", - "type": "uint256" - } - ], - "name": "exec", - "outputs": [ - { - "internalType": "bytes", - "name": "returnData", - "type": "bytes" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "getRequestId", - "outputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "getRequestsCount", - "outputs": [ - { - "internalType": "uint256", - "name": "requestsCount", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "size", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "offset", - "type": "uint256" - } - ], - "name": "getUndeliveredRequestIds", - "outputs": [ - { - "internalType": "uint256[]", - "name": "requestIds", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "signer", - "type": "address" - } - ], - "name": "isOperator", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "hash", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "signature", - "type": "bytes" - } - ], - "name": "isValidSignature", - "outputs": [ - { - "internalType": "bytes4", - "name": "magicValue", - "type": "bytes4" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapRequestIds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapRequestsCounts", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "nonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "numUndeliveredRequests", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC1155BatchReceived", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC1155Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC721Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "price", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "request", - "outputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "newPrice", - "type": "uint256" - } - ], - "name": "setPrice", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "initParams", - "type": "bytes" - } - ], - "name": "setUp", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "token", - "outputs": [ - { - "internalType": "contract IERC721", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "tokenId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "tokensReceived", - "outputs": [], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "initCode", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "callData", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "callGasLimit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "verificationGasLimit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "preVerificationGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxFeePerGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxPriorityFeePerGas", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "paymasterAndData", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "signature", - "type": "bytes" - } - ], - "internalType": "struct UserOperation", - "name": "userOp", - "type": "tuple" - }, - { - "internalType": "bytes32", - "name": "userOpHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "missingAccountFunds", - "type": "uint256" - } - ], - "name": "validateUserOp", - "outputs": [ - { - "internalType": "uint256", - "name": "validationData", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapUndeliveredRequestsCounts", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x60806040525f805534801562000013575f80fd5b50604051620026cc380380620026cc833981016040819052620000369162000391565b604080516001600160a01b03851660208201528082018490528151808203830181526060909101909152839083906200006f8162000145565b5050506001600160a01b0383166200009a5760405163d92e233d60e01b815260040160405180910390fd5b6040516331a9108f60e11b8152600481018390525f906001600160a01b03851690636352211e90602401602060405180830381865afa158015620000e0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001069190620003c6565b90506001600160a01b0381166200013857604051630ede975960e01b8152600481018490526024015b60405180910390fd5b50600155506200049a9050565b6200014f620001ad565b51156200019f5760405162461bcd60e51b815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016200012f565b620001aa8162000218565b50565b6060620002136200020d604051606b60f91b6020820152602560fa1b60218201526001600160601b03193060601b166022820152600160f81b60368201525f90603701604051602081830303815290604052805190602001205f1c905090565b620002e1565b905090565b5f620002248262000339565b90505f8151602083015ff090506200028b604051606b60f91b6020820152602560fa1b60218201526001600160601b03193060601b166022820152600160f81b60368201525f90603701604051602081830303815290604052805190602001205f1c905090565b6001600160a01b0316816001600160a01b031614620002dc5760405162461bcd60e51b815260206004820152600c60248201526b15dc9a5d194819985a5b195960a21b60448201526064016200012f565b505050565b6060813b600181116200030357505060408051602081019091525f8152919050565b806200030f81620003fd565b9150506040519150601f19601f602083010116820160405280825280600160208401853c50919050565b6060815160016200034b919062000415565b826040516020016200035f92919062000431565b6040516020818303038152906040529050919050565b80516001600160a01b03811681146200038c575f80fd5b919050565b5f805f60608486031215620003a4575f80fd5b620003af8462000375565b925060208401519150604084015190509250925092565b5f60208284031215620003d7575f80fd5b620003e28262000375565b9392505050565b634e487b7160e01b5f52601160045260245ffd5b5f816200040e576200040e620003e9565b505f190190565b808201808211156200042b576200042b620003e9565b92915050565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b60058201525f600e82018190528251815b8181101562000489576020818601810151600f8684010152016200046a565b505f9201600f019182525092915050565b61222480620004a85f395ff3fe60806040526004361061017a575f3560e01c8063a035b1fe116100d1578063bdf863171161007c578063f23a6e6111610057578063f23a6e61146104d2578063f6171e4414610517578063fc0c546a14610536575f80fd5b8063bdf8631714610472578063c7dec3fc14610487578063e00b9118146104b3575f80fd5b8063b0d691fe116100ac578063b0d691fe146103d1578063b94207d314610418578063bc197c811461042b575f80fd5b8063a035b1fe1461038a578063a4f9edbf1461039f578063affed0e0146103be575f80fd5b80633a871cdd116101315780636d70f7ae1161010c5780636d70f7ae146102fb5780637af734731461032a57806391b7f5ed1461036b575f80fd5b80633a871cdd1461028557806358ce0909146102a45780635fee6085146102d0575f80fd5b8063157305fe11610161578063157305fe146102255780631626ba7e1461024457806317d70f7c14610263575f80fd5b806223de2914610185578063150b7a02146101ab575f80fd5b3661018157005b5f80fd5b348015610190575f80fd5b506101a961019f366004611943565b5050505050505050565b005b3480156101b6575f80fd5b506101ef6101c53660046119ed565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b348015610230575f80fd5b506101a961023f366004611b2f565b61054a565b34801561024f575f80fd5b506101ef61025e366004611b2f565b610771565b34801561026e575f80fd5b50610277610914565b60405190815260200161021c565b348015610290575f80fd5b5061027761029f366004611b73565b610938565b3480156102af575f80fd5b506102c36102be366004611bc2565b610974565b60405161021c9190611be2565b3480156102db575f80fd5b506102776102ea366004611c25565b60036020525f908152604090205481565b348015610306575f80fd5b5061031a610315366004611c25565b610ada565b604051901515815260200161021c565b348015610335575f80fd5b50610277610344366004611c25565b73ffffffffffffffffffffffffffffffffffffffff165f9081526003602052604090205490565b348015610376575f80fd5b506101a9610385366004611c40565b610bac565b348015610395575f80fd5b5061027760015481565b3480156103aa575f80fd5b506101a96103b9366004611c57565b610c9a565b3480156103c9575f80fd5b505f54610277565b3480156103dc575f80fd5b50730576a174d229e3cfa37253523e645a78a0c91b575b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021c565b610277610426366004611c57565b610d16565b348015610436575f80fd5b506101ef610445366004611cd2565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561047d575f80fd5b5061027760025481565b348015610492575f80fd5b506104a66104a1366004611d68565b610e63565b60405161021c9190611e45565b3480156104be575f80fd5b506102776104cd366004611e57565b610f4d565b3480156104dd575f80fd5b506101ef6104ec366004611e8e565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b348015610522575f80fd5b50610277610531366004611bc2565b610f9e565b348015610541575f80fd5b506103f3610fc0565b61055333610ada565b80610571575033730576a174d229e3cfa37253523e645a78a0c91b57145b610602576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084015b60405180910390fd5b5f828152600460205260408082208151808301928390529160029082845b8154815260200190600101908083116106205750505050509050805f6002811061064c5761064c611f05565b602002015115801561066057506020810151155b801561069557505f805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed548314155b156106cf576040517ffe239804000000000000000000000000000000000000000000000000000000008152600481018490526024016105f9565b6020818101805183515f908152600490935260408084206001908101929092558451925184528084209290925585835290822082815501819055600280549161071783611f5f565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f0cd979445339c62199996f208428d987b1cea24d18e62b79ec24d94b636e8b708484604051610764929190611f93565b60405180910390a2505050565b5f805f8061079185602081015160408201516060909201515f1a92909190565b9094509250905060ff81165f036108a757828583016020016107b282610ada565b1580156107d5575073ffffffffffffffffffffffffffffffffffffffff82163014155b1561080857507fffffffff00000000000000000000000000000000000000000000000000000000945061090e9350505050565b6040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831690631626ba7e9061085c908b908590600401611f93565b602060405180830381865afa158015610877573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061089b9190611fab565b9550505050505061090e565b6108b661031587838686610fdd565b156108e757507f1626ba7e00000000000000000000000000000000000000000000000000000000925061090e915050565b507fffffffff00000000000000000000000000000000000000000000000000000000925050505b92915050565b5f8061091e610ff9565b8060200190518101906109319190611fea565b9392505050565b5f6109416110cd565b61094b848461114c565b905061095a6040850185612016565b90505f0361096b5761096b8461124c565b610931826112ca565b6002546060905f849003610986578093505b806109918486612077565b11156109de576109a18385612077565b6040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016105f9565b8315610ad3578367ffffffffffffffff8111156109fd576109fd611a5b565b604051908082528060200260200182016040528015610a26578160200160208202803683370190505b505f80805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed549193505b84811015610a81575f828152600460205260409020600101549150610a7a8161208a565b9050610a56565b505f5b85811015610ad05781848281518110610a9f57610a9f611f05565b6020908102919091018101919091525f9283526004905260409091206001015490610ac98161208a565b9050610a84565b50505b5092915050565b5f805f610ae5610ff9565b806020019051810190610af89190611fea565b915091508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610b4e91815260200190565b602060405180830381865afa158015610b69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b8d91906120c1565b73ffffffffffffffffffffffffffffffffffffffff1614949350505050565b610bb533610ada565b80610bd3575033730576a174d229e3cfa37253523e645a78a0c91b57145b610c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b60018190556040518181527f66cbca4f3c64fecf1dcb9ce094abcf7f68c3450a1d4e3a8e917dd621edb4ebe09060200160405180910390a150565b610ca2610ff9565b5115610d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016105f9565b610d138161133e565b50565b5f600154341015610d60576001546040517fb489782800000000000000000000000000000000000000000000000000000000815234600482015260248101919091526044016105f9565b610d6a3383610f4d565b335f908152600360205260408120805492935090610d878361208a565b909155505060046020525f81815260408082207f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed80546001830181905590859055808452918320849055600280547f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec94929392909190610e068361208a565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f4bda649efe6b98b0f9c1d5e859c29e20910f45c66dabfe6fad4a4881f7faf9cc8587604051610e53929190611f93565b60405180910390a2505050919050565b6060610e6e33610ada565b80610e8c575033730576a174d229e3cfa37253523e645a78a0c91b57145b610f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b5f610f32878787878715610f2c57876114b3565b5a6114b3565b9250905080610f4357815160208301fd5b5095945050505050565b5f8282604051602001610f619291906120dc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6004602052815f5260405f208160028110610fb7575f80fd5b01549150829050565b5f80610fca610ff9565b80602001905181019061090e91906120c1565b5f805f610fec878787876115b6565b91509150610f438161169e565b60606110c86110c36040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b611850565b905090565b33730576a174d229e3cfa37253523e645a78a0c91b571461114a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016105f9565b565b5f806111a4836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018290525f90605c01604051602081830303815290604052805190602001209050919050565b90507f1626ba7e00000000000000000000000000000000000000000000000000000000611212826111d9610140880188612016565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061077192505050565b7fffffffff00000000000000000000000000000000000000000000000000000000161461124357600191505061090e565b505f9392505050565b5f80546020830135918061125f8361208a565b9190505514610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c6964206e6f6e63650000000000000000000000000000000000000060448201526064016105f9565b8015610d13576040515f9033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d805f8114611332576040519150601f19603f3d011682016040523d82523d5f602084013e611337565b606091505b5050505050565b5f611348826118a5565b90505f8151602083015ff0905061141a6040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146114ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5772697465206661696c6564000000000000000000000000000000000000000060448201526064016105f9565b505050565b5f606060018460018111156114ca576114ca61210a565b0361153e578673ffffffffffffffffffffffffffffffffffffffff1683866040516114f59190612137565b5f604051808303818686f4925050503d805f811461152e576040519150601f19603f3d011682016040523d82523d5f602084013e611533565b606091505b5090925090506115ac565b8673ffffffffffffffffffffffffffffffffffffffff168387876040516115659190612137565b5f60405180830381858888f193505050503d805f81146115a0576040519150601f19603f3d011682016040523d82523d5f602084013e6115a5565b606091505b5090925090505b9550959350505050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156115eb57505f90506003611695565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561163c573d5f803e3d5ffd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661168f575f60019250925050611695565b91505f90505b94509492505050565b5f8160048111156116b1576116b161210a565b036116b95750565b60018160048111156116cd576116cd61210a565b03611734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105f9565b60028160048111156117485761174861210a565b036117af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105f9565b60038160048111156117c3576117c361210a565b03610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105f9565b6060813b6001811161187157505060408051602081019091525f8152919050565b8061187b81611f5f565b9150506040519150601f19601f602083010116820160405280825280600160208401853c50919050565b6060815160016118b59190612077565b826040516020016118c7929190612152565b6040516020818303038152906040529050919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d13575f80fd5b5f8083601f84011261190e575f80fd5b50813567ffffffffffffffff811115611925575f80fd5b60208301915083602082850101111561193c575f80fd5b9250929050565b5f805f805f805f8060c0898b03121561195a575f80fd5b8835611965816118dd565b97506020890135611975816118dd565b96506040890135611985816118dd565b955060608901359450608089013567ffffffffffffffff808211156119a8575f80fd5b6119b48c838d016118fe565b909650945060a08b01359150808211156119cc575f80fd5b506119d98b828c016118fe565b999c989b5096995094979396929594505050565b5f805f805f60808688031215611a01575f80fd5b8535611a0c816118dd565b94506020860135611a1c816118dd565b935060408601359250606086013567ffffffffffffffff811115611a3e575f80fd5b611a4a888289016118fe565b969995985093965092949392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112611a97575f80fd5b813567ffffffffffffffff80821115611ab257611ab2611a5b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611af857611af8611a5b565b81604052838152866020858801011115611b10575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f8060408385031215611b40575f80fd5b82359150602083013567ffffffffffffffff811115611b5d575f80fd5b611b6985828601611a88565b9150509250929050565b5f805f60608486031215611b85575f80fd5b833567ffffffffffffffff811115611b9b575f80fd5b84016101608187031215611bad575f80fd5b95602085013595506040909401359392505050565b5f8060408385031215611bd3575f80fd5b50508035926020909101359150565b602080825282518282018190525f9190848201906040850190845b81811015611c1957835183529284019291840191600101611bfd565b50909695505050505050565b5f60208284031215611c35575f80fd5b8135610931816118dd565b5f60208284031215611c50575f80fd5b5035919050565b5f60208284031215611c67575f80fd5b813567ffffffffffffffff811115611c7d575f80fd5b611c8984828501611a88565b949350505050565b5f8083601f840112611ca1575f80fd5b50813567ffffffffffffffff811115611cb8575f80fd5b6020830191508360208260051b850101111561193c575f80fd5b5f805f805f805f8060a0898b031215611ce9575f80fd5b8835611cf4816118dd565b97506020890135611d04816118dd565b9650604089013567ffffffffffffffff80821115611d20575f80fd5b611d2c8c838d01611c91565b909850965060608b0135915080821115611d44575f80fd5b611d508c838d01611c91565b909650945060808b01359150808211156119cc575f80fd5b5f805f805f60a08688031215611d7c575f80fd5b8535611d87816118dd565b945060208601359350604086013567ffffffffffffffff811115611da9575f80fd5b611db588828901611a88565b935050606086013560028110611dc9575f80fd5b949793965091946080013592915050565b5f5b83811015611df4578181015183820152602001611ddc565b50505f910152565b5f8151808452611e13816020860160208601611dda565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081525f6109316020830184611dfc565b5f8060408385031215611e68575f80fd5b8235611e73816118dd565b9150602083013567ffffffffffffffff811115611b5d575f80fd5b5f805f805f8060a08789031215611ea3575f80fd5b8635611eae816118dd565b95506020870135611ebe816118dd565b94506040870135935060608701359250608087013567ffffffffffffffff811115611ee7575f80fd5b611ef389828a016118fe565b979a9699509497509295939492505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f81611f6d57611f6d611f32565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b828152604060208201525f611c896040830184611dfc565b5f60208284031215611fbb575f80fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114610931575f80fd5b5f8060408385031215611ffb575f80fd5b8251612006816118dd565b6020939093015192949293505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612049575f80fd5b83018035915067ffffffffffffffff821115612063575f80fd5b60200191503681900382131561193c575f80fd5b8082018082111561090e5761090e611f32565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036120ba576120ba611f32565b5060010190565b5f602082840312156120d1575f80fd5b8151610931816118dd565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f611c896040830184611dfc565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f8251612148818460208701611dda565b9190910192915050565b7f630000000000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008360e01b1660018201527f80600e6000396000f3000000000000000000000000000000000000000000000060058201525f600e8201525f82516121e081600f850160208701611dda565b91909101600f01939250505056fea2646970667358221220c1913351e275e1fecd00c79cd676ed135b575df5d3a88ccc57419dc3081980a264736f6c63430008150033", - "deployedBytecode": "0x60806040526004361061017a575f3560e01c8063a035b1fe116100d1578063bdf863171161007c578063f23a6e6111610057578063f23a6e61146104d2578063f6171e4414610517578063fc0c546a14610536575f80fd5b8063bdf8631714610472578063c7dec3fc14610487578063e00b9118146104b3575f80fd5b8063b0d691fe116100ac578063b0d691fe146103d1578063b94207d314610418578063bc197c811461042b575f80fd5b8063a035b1fe1461038a578063a4f9edbf1461039f578063affed0e0146103be575f80fd5b80633a871cdd116101315780636d70f7ae1161010c5780636d70f7ae146102fb5780637af734731461032a57806391b7f5ed1461036b575f80fd5b80633a871cdd1461028557806358ce0909146102a45780635fee6085146102d0575f80fd5b8063157305fe11610161578063157305fe146102255780631626ba7e1461024457806317d70f7c14610263575f80fd5b806223de2914610185578063150b7a02146101ab575f80fd5b3661018157005b5f80fd5b348015610190575f80fd5b506101a961019f366004611943565b5050505050505050565b005b3480156101b6575f80fd5b506101ef6101c53660046119ed565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b348015610230575f80fd5b506101a961023f366004611b2f565b61054a565b34801561024f575f80fd5b506101ef61025e366004611b2f565b610771565b34801561026e575f80fd5b50610277610914565b60405190815260200161021c565b348015610290575f80fd5b5061027761029f366004611b73565b610938565b3480156102af575f80fd5b506102c36102be366004611bc2565b610974565b60405161021c9190611be2565b3480156102db575f80fd5b506102776102ea366004611c25565b60036020525f908152604090205481565b348015610306575f80fd5b5061031a610315366004611c25565b610ada565b604051901515815260200161021c565b348015610335575f80fd5b50610277610344366004611c25565b73ffffffffffffffffffffffffffffffffffffffff165f9081526003602052604090205490565b348015610376575f80fd5b506101a9610385366004611c40565b610bac565b348015610395575f80fd5b5061027760015481565b3480156103aa575f80fd5b506101a96103b9366004611c57565b610c9a565b3480156103c9575f80fd5b505f54610277565b3480156103dc575f80fd5b50730576a174d229e3cfa37253523e645a78a0c91b575b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021c565b610277610426366004611c57565b610d16565b348015610436575f80fd5b506101ef610445366004611cd2565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561047d575f80fd5b5061027760025481565b348015610492575f80fd5b506104a66104a1366004611d68565b610e63565b60405161021c9190611e45565b3480156104be575f80fd5b506102776104cd366004611e57565b610f4d565b3480156104dd575f80fd5b506101ef6104ec366004611e8e565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b348015610522575f80fd5b50610277610531366004611bc2565b610f9e565b348015610541575f80fd5b506103f3610fc0565b61055333610ada565b80610571575033730576a174d229e3cfa37253523e645a78a0c91b57145b610602576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084015b60405180910390fd5b5f828152600460205260408082208151808301928390529160029082845b8154815260200190600101908083116106205750505050509050805f6002811061064c5761064c611f05565b602002015115801561066057506020810151155b801561069557505f805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed548314155b156106cf576040517ffe239804000000000000000000000000000000000000000000000000000000008152600481018490526024016105f9565b6020818101805183515f908152600490935260408084206001908101929092558451925184528084209290925585835290822082815501819055600280549161071783611f5f565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f0cd979445339c62199996f208428d987b1cea24d18e62b79ec24d94b636e8b708484604051610764929190611f93565b60405180910390a2505050565b5f805f8061079185602081015160408201516060909201515f1a92909190565b9094509250905060ff81165f036108a757828583016020016107b282610ada565b1580156107d5575073ffffffffffffffffffffffffffffffffffffffff82163014155b1561080857507fffffffff00000000000000000000000000000000000000000000000000000000945061090e9350505050565b6040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831690631626ba7e9061085c908b908590600401611f93565b602060405180830381865afa158015610877573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061089b9190611fab565b9550505050505061090e565b6108b661031587838686610fdd565b156108e757507f1626ba7e00000000000000000000000000000000000000000000000000000000925061090e915050565b507fffffffff00000000000000000000000000000000000000000000000000000000925050505b92915050565b5f8061091e610ff9565b8060200190518101906109319190611fea565b9392505050565b5f6109416110cd565b61094b848461114c565b905061095a6040850185612016565b90505f0361096b5761096b8461124c565b610931826112ca565b6002546060905f849003610986578093505b806109918486612077565b11156109de576109a18385612077565b6040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016105f9565b8315610ad3578367ffffffffffffffff8111156109fd576109fd611a5b565b604051908082528060200260200182016040528015610a26578160200160208202803683370190505b505f80805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed549193505b84811015610a81575f828152600460205260409020600101549150610a7a8161208a565b9050610a56565b505f5b85811015610ad05781848281518110610a9f57610a9f611f05565b6020908102919091018101919091525f9283526004905260409091206001015490610ac98161208a565b9050610a84565b50505b5092915050565b5f805f610ae5610ff9565b806020019051810190610af89190611fea565b915091508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610b4e91815260200190565b602060405180830381865afa158015610b69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b8d91906120c1565b73ffffffffffffffffffffffffffffffffffffffff1614949350505050565b610bb533610ada565b80610bd3575033730576a174d229e3cfa37253523e645a78a0c91b57145b610c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b60018190556040518181527f66cbca4f3c64fecf1dcb9ce094abcf7f68c3450a1d4e3a8e917dd621edb4ebe09060200160405180910390a150565b610ca2610ff9565b5115610d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016105f9565b610d138161133e565b50565b5f600154341015610d60576001546040517fb489782800000000000000000000000000000000000000000000000000000000815234600482015260248101919091526044016105f9565b610d6a3383610f4d565b335f908152600360205260408120805492935090610d878361208a565b909155505060046020525f81815260408082207f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed80546001830181905590859055808452918320849055600280547f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec94929392909190610e068361208a565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f4bda649efe6b98b0f9c1d5e859c29e20910f45c66dabfe6fad4a4881f7faf9cc8587604051610e53929190611f93565b60405180910390a2505050919050565b6060610e6e33610ada565b80610e8c575033730576a174d229e3cfa37253523e645a78a0c91b57145b610f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b5f610f32878787878715610f2c57876114b3565b5a6114b3565b9250905080610f4357815160208301fd5b5095945050505050565b5f8282604051602001610f619291906120dc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6004602052815f5260405f208160028110610fb7575f80fd5b01549150829050565b5f80610fca610ff9565b80602001905181019061090e91906120c1565b5f805f610fec878787876115b6565b91509150610f438161169e565b60606110c86110c36040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b611850565b905090565b33730576a174d229e3cfa37253523e645a78a0c91b571461114a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016105f9565b565b5f806111a4836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018290525f90605c01604051602081830303815290604052805190602001209050919050565b90507f1626ba7e00000000000000000000000000000000000000000000000000000000611212826111d9610140880188612016565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061077192505050565b7fffffffff00000000000000000000000000000000000000000000000000000000161461124357600191505061090e565b505f9392505050565b5f80546020830135918061125f8361208a565b9190505514610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c6964206e6f6e63650000000000000000000000000000000000000060448201526064016105f9565b8015610d13576040515f9033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d805f8114611332576040519150601f19603f3d011682016040523d82523d5f602084013e611337565b606091505b5050505050565b5f611348826118a5565b90505f8151602083015ff0905061141a6040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146114ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5772697465206661696c6564000000000000000000000000000000000000000060448201526064016105f9565b505050565b5f606060018460018111156114ca576114ca61210a565b0361153e578673ffffffffffffffffffffffffffffffffffffffff1683866040516114f59190612137565b5f604051808303818686f4925050503d805f811461152e576040519150601f19603f3d011682016040523d82523d5f602084013e611533565b606091505b5090925090506115ac565b8673ffffffffffffffffffffffffffffffffffffffff168387876040516115659190612137565b5f60405180830381858888f193505050503d805f81146115a0576040519150601f19603f3d011682016040523d82523d5f602084013e6115a5565b606091505b5090925090505b9550959350505050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156115eb57505f90506003611695565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561163c573d5f803e3d5ffd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661168f575f60019250925050611695565b91505f90505b94509492505050565b5f8160048111156116b1576116b161210a565b036116b95750565b60018160048111156116cd576116cd61210a565b03611734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105f9565b60028160048111156117485761174861210a565b036117af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105f9565b60038160048111156117c3576117c361210a565b03610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105f9565b6060813b6001811161187157505060408051602081019091525f8152919050565b8061187b81611f5f565b9150506040519150601f19601f602083010116820160405280825280600160208401853c50919050565b6060815160016118b59190612077565b826040516020016118c7929190612152565b6040516020818303038152906040529050919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d13575f80fd5b5f8083601f84011261190e575f80fd5b50813567ffffffffffffffff811115611925575f80fd5b60208301915083602082850101111561193c575f80fd5b9250929050565b5f805f805f805f8060c0898b03121561195a575f80fd5b8835611965816118dd565b97506020890135611975816118dd565b96506040890135611985816118dd565b955060608901359450608089013567ffffffffffffffff808211156119a8575f80fd5b6119b48c838d016118fe565b909650945060a08b01359150808211156119cc575f80fd5b506119d98b828c016118fe565b999c989b5096995094979396929594505050565b5f805f805f60808688031215611a01575f80fd5b8535611a0c816118dd565b94506020860135611a1c816118dd565b935060408601359250606086013567ffffffffffffffff811115611a3e575f80fd5b611a4a888289016118fe565b969995985093965092949392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112611a97575f80fd5b813567ffffffffffffffff80821115611ab257611ab2611a5b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611af857611af8611a5b565b81604052838152866020858801011115611b10575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f8060408385031215611b40575f80fd5b82359150602083013567ffffffffffffffff811115611b5d575f80fd5b611b6985828601611a88565b9150509250929050565b5f805f60608486031215611b85575f80fd5b833567ffffffffffffffff811115611b9b575f80fd5b84016101608187031215611bad575f80fd5b95602085013595506040909401359392505050565b5f8060408385031215611bd3575f80fd5b50508035926020909101359150565b602080825282518282018190525f9190848201906040850190845b81811015611c1957835183529284019291840191600101611bfd565b50909695505050505050565b5f60208284031215611c35575f80fd5b8135610931816118dd565b5f60208284031215611c50575f80fd5b5035919050565b5f60208284031215611c67575f80fd5b813567ffffffffffffffff811115611c7d575f80fd5b611c8984828501611a88565b949350505050565b5f8083601f840112611ca1575f80fd5b50813567ffffffffffffffff811115611cb8575f80fd5b6020830191508360208260051b850101111561193c575f80fd5b5f805f805f805f8060a0898b031215611ce9575f80fd5b8835611cf4816118dd565b97506020890135611d04816118dd565b9650604089013567ffffffffffffffff80821115611d20575f80fd5b611d2c8c838d01611c91565b909850965060608b0135915080821115611d44575f80fd5b611d508c838d01611c91565b909650945060808b01359150808211156119cc575f80fd5b5f805f805f60a08688031215611d7c575f80fd5b8535611d87816118dd565b945060208601359350604086013567ffffffffffffffff811115611da9575f80fd5b611db588828901611a88565b935050606086013560028110611dc9575f80fd5b949793965091946080013592915050565b5f5b83811015611df4578181015183820152602001611ddc565b50505f910152565b5f8151808452611e13816020860160208601611dda565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081525f6109316020830184611dfc565b5f8060408385031215611e68575f80fd5b8235611e73816118dd565b9150602083013567ffffffffffffffff811115611b5d575f80fd5b5f805f805f8060a08789031215611ea3575f80fd5b8635611eae816118dd565b95506020870135611ebe816118dd565b94506040870135935060608701359250608087013567ffffffffffffffff811115611ee7575f80fd5b611ef389828a016118fe565b979a9699509497509295939492505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f81611f6d57611f6d611f32565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b828152604060208201525f611c896040830184611dfc565b5f60208284031215611fbb575f80fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114610931575f80fd5b5f8060408385031215611ffb575f80fd5b8251612006816118dd565b6020939093015192949293505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612049575f80fd5b83018035915067ffffffffffffffff821115612063575f80fd5b60200191503681900382131561193c575f80fd5b8082018082111561090e5761090e611f32565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036120ba576120ba611f32565b5060010190565b5f602082840312156120d1575f80fd5b8151610931816118dd565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f611c896040830184611dfc565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f8251612148818460208701611dda565b9190910192915050565b7f630000000000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008360e01b1660018201527f80600e6000396000f3000000000000000000000000000000000000000000000060058201525f600e8201525f82516121e081600f850160208701611dda565b91909101600f01939250505056fea2646970667358221220c1913351e275e1fecd00c79cd676ed135b575df5d3a88ccc57419dc3081980a264736f6c63430008150033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/mech/contract.py b/trader_backup/vendor/valory/contracts/mech/contract.py deleted file mode 100644 index 55a5b54b5..000000000 --- a/trader_backup/vendor/valory/contracts/mech/contract.py +++ /dev/null @@ -1,401 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the class to connect to a Mech contract.""" - -import concurrent.futures -from typing import Any, Callable, Dict, List, cast - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi -from eth_typing import HexStr -from web3.types import BlockData, BlockIdentifier, EventData, TxReceipt - - -PUBLIC_ID = PublicId.from_str("valory/mech:0.1.0") -FIVE_MINUTES = 300.0 - - -partial_abis = [ - [ - { - "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256", - }, - { - "indexed": False, - "internalType": "bytes", - "name": "data", - "type": "bytes", - }, - ], - "name": "Deliver", - "type": "event", - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address", - }, - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256", - }, - { - "indexed": False, - "internalType": "bytes", - "name": "data", - "type": "bytes", - }, - ], - "name": "Request", - "type": "event", - }, - ], - [ - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address", - }, - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256", - }, - { - "indexed": False, - "internalType": "uint256", - "name": "requestIdWithNonce", - "type": "uint256", - }, - { - "indexed": False, - "internalType": "bytes", - "name": "data", - "type": "bytes", - }, - ], - "name": "Request", - "type": "event", - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address", - }, - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256", - }, - { - "indexed": False, - "internalType": "bytes", - "name": "data", - "type": "bytes", - }, - ], - "name": "Deliver", - "type": "event", - }, - ], -] - - -class Mech(Contract): - """The Mech contract.""" - - contract_id = PUBLIC_ID - - @staticmethod - def execute_with_timeout(func: Callable, timeout: float) -> Any: - """Execute a function with a timeout.""" - - # Create a ProcessPoolExecutor with a maximum of 1 worker (process) - with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: - # Submit the function to the executor - future = executor.submit( - func, - ) - - try: - # Wait for the result with a 5-minute timeout - data = future.result(timeout=timeout) - except TimeoutError: - # Handle the case where the execution times out - err = f"The RPC didn't respond in {timeout}." - return None, err - - # Check if an error occurred - if isinstance(data, str): - # Handle the case where the execution failed - return None, data - - return data, None - - @classmethod - def get_price( - cls, - ledger_api: EthereumApi, - contract_address: str, - **kwargs: Any - ) -> JSONLike: - """Get the price of a request.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - price = ledger_api.contract_method_call(contract_instance, "price") - return dict(price=price) - - @classmethod - def get_request_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - request_data: bytes, - **kwargs: Any - ) -> Dict[str, bytes]: - """Gets the encoded arguments for a request tx, which should only be called via the multisig. - - :param ledger_api: the ledger API object - :param contract_address: the contract's address - :param request_data: the request data - """ - contract_address = ledger_api.api.to_checksum_address(contract_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - encoded_data = contract_instance.encodeABI("request", args=(request_data,)) - return {"data": bytes.fromhex(encoded_data[2:])} - - @classmethod - def _process_event( - cls, - ledger_api: LedgerApi, - contract: Any, - tx_hash: HexStr, - expected_logs: int, - event_name: str, - *args: Any, - **kwargs: Any - ) -> JSONLike: - """Process the logs of the given event.""" - ledger_api = cast(EthereumApi, ledger_api) - receipt: TxReceipt = ledger_api.api.eth.get_transaction_receipt(tx_hash) - event_method = getattr(contract.events, event_name) - logs: List[EventData] = list(event_method().process_receipt(receipt)) - - n_logs = len(logs) - if n_logs != expected_logs: - error = f"{expected_logs} {event_name!r} events were expected. tx {tx_hash} emitted {n_logs} instead." - return {"error": error} - - results = [] - for log in logs: - event_args = log.get("args", None) - if event_args is None or any( - expected_key not in event_args for expected_key in args - ): - return {"error": f"The emitted event's ({event_name}) logs for tx {tx_hash} do not match the expected format: {log}"} - results.append({arg_name: event_args[arg_name] for arg_name in args}) - - return dict(results=results) - - @classmethod - def process_request_event( - cls, - ledger_api: LedgerApi, - contract_address: str, - tx_hash: HexStr, - expected_logs: int = 1, - **kwargs: Any - ) -> JSONLike: - """ - Process the request receipt to get the requestId and the given data from the `Request` event's logs. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param tx_hash: the hash of a request tx to be processed. - :param expected_logs: the number of logs expected. - :return: a dictionary with a key named `results` - which contains a list of dictionaries (as many as the expected logs) containing the request id and the data. - """ - contract_address = ledger_api.api.to_checksum_address(contract_address) - res = {} - for abi in partial_abis: - contract_instance = ledger_api.api.eth.contract(contract_address, abi=abi) - res = cls._process_event( - ledger_api, contract_instance, tx_hash, expected_logs, "Request", "requestId", "data" - ) - if "error" not in res: - return res - - return res - - @classmethod - def process_deliver_event( - cls, - ledger_api: LedgerApi, - contract_address: str, - tx_hash: HexStr, - expected_logs: int = 1, - **kwargs: Any - ) -> JSONLike: - """ - Process the request receipt to get the requestId and the delivered data if the `Deliver` event has been emitted. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param tx_hash: the hash of a request tx to be processed. - :param expected_logs: the number of logs expected. - :return: a dictionary with the request id and the data. - """ - contract_address = ledger_api.api.to_checksum_address(contract_address) - res = {} - for abi in partial_abis: - contract_instance = ledger_api.api.eth.contract(contract_address, abi=abi) - res = cls._process_event( - ledger_api, contract_instance, tx_hash, expected_logs, "Deliver", "requestId", "data" - ) - if "error" not in res: - return res - - return res - @classmethod - def get_block_number( - cls, - ledger_api: EthereumApi, - contract_address: str, - tx_hash: HexStr, - **kwargs: Any - ) -> JSONLike: - """Get the number of the block in which the tx of the given hash was settled.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - receipt: TxReceipt = ledger_api.api.eth.get_transaction_receipt(tx_hash) - block: BlockData = ledger_api.api.eth.get_block(receipt["blockNumber"]) - return dict(number=block["number"]) - - @classmethod - def get_response( - cls, - ledger_api: LedgerApi, - contract_address: str, - request_id: int, - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - timeout: float = FIVE_MINUTES, - **kwargs: Any - ) -> JSONLike: - """Filter the `Deliver` events emitted by the contract and get the data of the given `request_id`.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - ledger_api = cast(EthereumApi, ledger_api) - - def get_responses() -> Any: - """Get the responses from the contract.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - deliver_filter = contract_instance.events.Deliver.build_filter() - deliver_filter.fromBlock = from_block - deliver_filter.toBlock = to_block - deliver_filter.args.requestId.match_single(request_id) - delivered = list(deliver_filter.deploy(ledger_api.api).get_all_entries()) - n_delivered = len(delivered) - - if n_delivered == 0: - info = f"The mech ({contract_address}) has not delivered a response yet for request with id {request_id}." - return {"info": info} - - if n_delivered != 1: - error = ( - f"A single response was expected by the mech ({contract_address}) for request with id {request_id}. " - f"Received {n_delivered} responses: {delivered}." - ) - return error - - delivered_event = delivered.pop() - deliver_args = delivered_event.get("args", None) - if deliver_args is None or "data" not in deliver_args: - error = f"The mech's response does not match the expected format: {delivered_event}" - return error - - return dict(data=deliver_args["data"]) - - data, err = cls.execute_with_timeout(get_responses, timeout=timeout) - if err is not None: - return {"error": err} - - return data - - @classmethod - def get_mech_id( - cls, - ledger_api: EthereumApi, - contract_address: str, - **kwargs: Any - ) -> JSONLike: - """Get the price of a request.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - mech_id = ledger_api.contract_method_call(contract_instance, "tokenId") - return dict(id=mech_id) - - @classmethod - def get_requests_count( - cls, - ledger_api: EthereumApi, - contract_address: str, - address: str, - **kwargs: Any - ) -> JSONLike: - """Get the requests count.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - address = ledger_api.api.to_checksum_address(address) - contract_instance = cls.get_instance(ledger_api, contract_address) - requests_count = contract_instance.functions.getRequestsCount(address).call() - return {"requests_count": requests_count} - - @classmethod - def get_pending_requests(cls, ledger_api: EthereumApi, contract_address: str, sender_address: str, **kwargs: Any) -> JSONLike: - """Get the pending requests.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - sender_address = ledger_api.api.to_checksum_address(sender_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - pending_requests = contract_instance.functions.mapUndeliveredRequestsCounts(sender_address).call() - return {"pending_requests": pending_requests} diff --git a/trader_backup/vendor/valory/contracts/mech/contract.yaml b/trader_backup/vendor/valory/contracts/mech/contract.yaml deleted file mode 100644 index 17f9b747f..000000000 --- a/trader_backup/vendor/valory/contracts/mech/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: mech -author: valory -version: 0.1.0 -type: contract -description: Agent mech contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeibl4uw7rs6mwh7zuvdnqmj2o2xyr7nx5qk3w7torwx3jg6farn6ca - __init__.py: bafybeicx5pxh3cxnml2biuuoebvafvu5tvy6mgkzyjzuubuoeebb5yzjsm - build/mech.json: bafybeibrocnkmfe46ylcso7245qq5ysl5z6ydr4xumjt6zl4satc7uqt4m - contract.py: bafybeiavom4ssfo6qngem34ymifb6upx5fodafkfa27cmzifuln5jqg4xe -fingerprint_ignore_patterns: [] -contracts: [] -class_name: Mech -contract_interface_paths: - ethereum: build/mech.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - web3: - version: <7,>=6.0.0 - eth_typing: {} diff --git a/trader_backup/vendor/valory/contracts/mech_activity/__init__.py b/trader_backup/vendor/valory/contracts/mech_activity/__init__.py deleted file mode 100644 index 1120bac15..000000000 --- a/trader_backup/vendor/valory/contracts/mech_activity/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the support resources for the mech activity checker contract.""" diff --git a/trader_backup/vendor/valory/contracts/mech_activity/build/MechActivity.json b/trader_backup/vendor/valory/contracts/mech_activity/build/MechActivity.json deleted file mode 100644 index 67cb00fcf..000000000 --- a/trader_backup/vendor/valory/contracts/mech_activity/build/MechActivity.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ServiceStakingToken", - "sourceName": "contracts/staking/ServiceStakingToken.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_agentMech", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_livenessRatio", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "ZeroMechAgentAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "inputs": [], - "name": "agentMech", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "getMultisigNonces", - "outputs": [ - { - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256[]", - "name": "curNonces", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "lastNonces", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "ts", - "type": "uint256" - } - ], - "name": "isRatioPass", - "outputs": [ - { - "internalType": "bool", - "name": "ratioPass", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "livenessRatio", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x6102606040523480156200001257600080fd5b506040516200383a3803806200383a833981016040819052620000359162000453565b8484828260000151600014806200004e57506020830151155b806200005c575060a0830151155b806200006a575060c0830151155b8062000078575060e0830151155b806200008657506060830151155b806200009457506080830151155b15620000b357604051637c946ed760e01b815260040160405180910390fd5b826080015183606001511015620000f5576060830151608084015160405163491a2bb160e01b8152600481019290925260248201526044015b60405180910390fd5b6002836040015110156200012d57604080840151905163491a2bb160e01b8152600481019190915260026024820152604401620000ec565b6001600160a01b038216620001555760405163d92e233d60e01b815260040160405180910390fd5b82516080908152602084015160a0908152604085015160c09081529185015160e0908152908501516101005290840151610120908152908401516101409081526001600160a01b0384166101a0529084015161016052830151610180526000805b846101000151518110156200029257818561010001518281518110620001e057620001e062000576565b6020026020010151116200022d57846101000151818151811062000208576200020862000576565b6020026020010151604051632ab10b0b60e21b8152600401620000ec91815260200190565b846101000151818151811062000247576200024762000576565b602090810291909101015160048054600181810183556000929092527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0182905590925001620001b6565b5081620002b257604051637c946ed760e01b815260040160405180910390fd5b6101c0829052610100516060850151620002cd91906200058c565b6101e052610100516080850151620002e691906200058c565b6102005250504260035550506001600160a01b03821615806200031057506001600160a01b038316155b156200032f5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b0390811661024052166102205250620005b89050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b03811182821017156200038957620003896200034d565b60405290565b600082601f830112620003a157600080fd5b815160206001600160401b0380831115620003c057620003c06200034d565b8260051b604051601f19603f83011681018181108482111715620003e857620003e86200034d565b60405293845260208187018101949081019250878511156200040957600080fd5b6020870191505b848210156200042b5781518352918301919083019062000410565b979650505050505050565b80516001600160a01b03811681146200044e57600080fd5b919050565b600080600080600060a086880312156200046c57600080fd5b85516001600160401b03808211156200048457600080fd5b90870190610160828a0312156200049a57600080fd5b620004a462000363565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010080840151838111156200050357600080fd5b620005118c8287016200038f565b918301919091525061012083810151908201526101409283015192810192909252509450620005436020870162000436565b9350620005536040870162000436565b9250620005636060870162000436565b9150608086015190509295509295909350565b634e487b7160e01b600052603260045260246000fd5b8082028115828204841417620005b257634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161311962000721600039600081816104110152818161130901528181611c1401528181611d1e0152611d6201526000818161030501528181611ca40152611e0e01526000818161068e015281816118a50152611b1401526000818161024b0152818161074d015261079f01526000818161044b0152610fca0152600081816105cf01528181610a0101528181610d8601526111bd0152600081816105f601528181610e4e0152610e7d01526000818161036201528181610ec40152610ef80152600081816103c30152610e0c0152600081816103ea015261294a01526000818161038901528181611bc60152611fb80152600061049b01526000818161061d0152611d9901526000818161064401526122ae0152600081816102de01528181610d0d0152610d4101526131196000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c8063a0ed60e011610145578063cbcf252a116100bd578063eb338c961161008c578063f4dce71411610071578063f4dce71414610681578063f86ad2b614610689578063ffa1ad74146106b057600080fd5b8063eb338c9614610666578063f189e85a1461067957600080fd5b8063cbcf252a146105ca578063e1f1176d146105f1578063e77cdcc914610618578063eacdaabc1461063f57600080fd5b8063b69ef8a811610114578063c2c4c5c1116100f9578063c2c4c5c11461057e578063c889921d14610597578063cae2a5f0146105aa57600080fd5b8063b69ef8a814610562578063b6b55f251461056b57600080fd5b8063a0ed60e014610496578063a694fc3a146104bd578063a74466ad146104d0578063b15087601461054d57600080fd5b806352c824f5116101d857806372f702f3116101a7578063809cee2f1161018c578063809cee2f1461044657806382a8ea581461046d578063879d90901461048d57600080fd5b806372f702f31461040c57806378e061361461043357600080fd5b806352c824f51461038457806356e76058146103ab5780635829c5ec146103be578063592cf3fb146103e557600080fd5b8063287140511161021457806328714051146103005780632e17de781461033f5780633e7329971461035457806342cde4e81461035d57600080fd5b806308ae7e541461024657806314b19c5a14610280578063150b7a021461028957806316a75172146102d9575b600080fd5b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61026d60005481565b6102a8610297366004612a0a565b630a85bd0160e11b95945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610277565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b61035261034d366004612aa9565b6106e1565b005b61026d60035481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d6103b9366004612aa9565b610acf565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d610441366004612aa9565b610af0565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61048061047b366004612aa9565b610bba565b6040516102779190612afe565b61026d60025481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103526104cb366004612aa9565b610cb1565b61051a6104de366004612aa9565b6005602081905260009182526040909120805460018201546003830154600484015493909401546001600160a01b039283169492909116929085565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610277565b61055561127e565b6040516102779190612b65565b61026d60015481565b610352610579366004612aa9565b6112d6565b610586611378565b604051610277959493929190612b78565b61026d6105a5366004612aa9565b6119ad565b6105bd6105b8366004612aa9565b611a69565b6040516102779190612c3d565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d610674366004612aa9565b611b5c565b610555611b6c565b61026d611bc2565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6106d4604051806040016040528060058152602001640302e312e360dc1b81525081565b6040516102779190612c65565b600081815260056020526040902060018101546001600160a01b0316331461073857600181015460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b600381015460006107498242612cca565b90507f0000000000000000000000000000000000000000000000000000000000000000811115801561077d57506000600254115b156107cb5760405163ba2bbc6b60e01b815260048101859052602481018290527f0000000000000000000000000000000000000000000000000000000000000000604482015260640161072f565b6000806107d6611378565b945050505091508151600003610837576107ee611b6c565b9150815167ffffffffffffffff81111561080a5761080a612cdd565b604051908082528060200260200182016040528015610833578160200160208202803683370190505b5090505b6000805b8351821015610898578783838151811061085757610857612cf3565b60200260200101510315610898578784838151811061087857610878612cf3565b60200260200101510361088d57506001610898565b81600101915061083b565b600487015460028801805460408051602080840282018101909252828152600093909290918301828280156108ec57602002820191906000526020600020905b8154815260200190600101908083116108d8575b50508c5460008f8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff19908116825560018201805490911690559596506001600160a01b03909116949350915061094890506002830182612974565b506000600382018190556004820181905560059091015583156109d7576006805461097590600190612cca565b8154811061098557610985612cf3565b9060005260206000200154600686815481106109a3576109a3612cf3565b60009182526020909120015560068054806109c0576109c0612d09565b600190038181906000526020600020016000905590555b604051632142170760e11b8152306004820152336024820152604481018c90526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342842e0e90606401600060405180830381600087803b158015610a4557600080fd5b505af1158015610a59573d6000803e3d6000fd5b505050506000831115610a7057610a708184611bf7565b806001600160a01b0316336001600160a01b03168c7f950733f4c0bf951b8e770f3cc619a4288e7b59b1236d59aeaf2c238488e8ae816000548688604051610aba93929190612d1f565b60405180910390a45050505050505050505050565b60048181548110610adf57600080fd5b600091825260209091200154905081565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015610b7057602002820191906000526020600020905b815481526020019060010190808311610b5c575b505050505081526020016003820154815260200160048201548152602001600582015481525050905080608001519150610ba9836119ad565b610bb39083612d48565b9392505050565b610c056040518060c0016040528060006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016000815260200160008152602001600081525090565b600082815260056020908152604091829020825160c08101845281546001600160a01b0390811682526001830154168184015260028201805485518186028101860187528181529295939493860193830182828015610c8357602002820191906000526020600020905b815481526020019060010190808311610c6f575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050919050565b600254600003610cd45760405163afb0be3360e01b815260040160405180910390fd5b6000818152600560205260409020600381015415610d085760405163b4817ce760e01b81526004810183905260240161072f565b6006547f00000000000000000000000000000000000000000000000000000000000000008103610d6d5760405163fd20861560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260240161072f565b60405163ef0e239b60e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ef0e239b90602401600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dfd9190810190612e79565b9050806080015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014610e4c57604051637ad404bf60e11b81526004810185905260240161072f565b7f000000000000000000000000000000000000000000000000000000000000000015801590610e9f575080604001517f000000000000000000000000000000000000000000000000000000000000000014155b15610ec057604051637ad404bf60e11b81526004810185905260240161072f565b60007f0000000000000000000000000000000000000000000000000000000000000000118015610f1a5750806060015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014155b15610f3b57604051637ad404bf60e11b81526004810185905260240161072f565b60048160c001516005811115610f5357610f53612c27565b14610f92578060c001516005811115610f6e57610f6e612c27565b604051633c053f9d60e21b815260048101919091526024810185905260440161072f565b600081602001516001600160a01b0316803b806020016040519081016040528181526000908060200190933c805190602001209050807f00000000000000000000000000000000000000000000000000000000000000001461101757602082015160405162a2307960e51b81526001600160a01b03909116600482015260240161072f565b60045480156110e05760e08301515181811461104957604051637ad404bf60e11b81526004810188905260240161072f565b60005b818110156110dd578460e00151818151811061106a5761106a612cf3565b602002602001015163ffffffff166004828154811061108b5761108b612cf3565b9060005260206000200154146110d557600481815481106110ae576110ae612cf3565b9060005260206000200154604051632ab10b0b60e21b815260040161072f91815260200190565b60010161104c565b50505b6111018684600001516bffffffffffffffffffffffff168560e00151611c81565b602083015185546001600160a01b03821673ffffffffffffffffffffffffffffffffffffffff199182161787556001870180549091163317905560009061114790611f02565b805190915061115f9060028801906020840190612995565b50426003870155600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01879055604051632142170760e11b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342842e0e90606401600060405180830381600087803b15801561120957600080fd5b505af115801561121d573d6000803e3d6000fd5b5050505083602001516001600160a01b0316336001600160a01b0316887faa6b005b4958114a0c90492461c24af6525ae0178db7fbf44125ae9217c69ccb6000548560405161126d929190612f57565b60405180910390a450505050505050565b606060048054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020905b8154815260200190600101908083116112b8575b5050505050905090565b6000816001546112e69190612d48565b90506000826002546112f89190612d48565b6001839055600281905590506113307f0000000000000000000000000000000000000000000000000000000000000000333086611f13565b604080518481526020810184905290810182905233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9060600160405180910390a2505050565b6060806060806060600080600080600080600080611394611f9d565b97509750975097509750975097509750606080845167ffffffffffffffff8111156113c1576113c1612cdd565b6040519080825280602002602001820160405280156113ea578160200160208202803683370190505b509a506000891561177d578967ffffffffffffffff81111561140e5761140e612cdd565b604051908082528060200260200182016040528015611437578160200160208202803683370190505b5092508967ffffffffffffffff81111561145357611453612cdd565b60405190808252806020026020018201604052801561147c578160200160208202803683370190505b5091508a8911156116865760008060015b8c811015611579578b8e8b83815181106114a9576114a9612cf3565b60200260200101516114bb9190612f70565b6114c59190612f87565b92506114d18383612d48565b91508a81815181106114e5576114e5612cf3565b602002602001015193508a818151811061150157611501612cf3565b602002602001015186828151811061151b5761151b612cf3565b6020026020010181815250508285828151811061153a5761153a612cf3565b6020026020010181815250508260056000868152602001908152602001600020600401600082825461156c9190612d48565b909155505060010161148d565b508a8d8a60008151811061158f5761158f612cf3565b60200260200101516115a19190612f70565b6115ab9190612f87565b91506115b78282612d48565b9050896000815181106115cc576115cc612cf3565b60200260200101519250896000815181106115e9576115e9612cf3565b60200260200101518560008151811061160457611604612cf3565b602002602001018181525050808d111561162f57611622818e612cca565b61162c9083612d48565b91505b818460008151811061164357611643612cf3565b602002602001018181525050816005600085815260200190815260200160002060040160008282546116759190612d48565b9091555060009d5061177792505050565b60005b8a811015611769578881815181106116a3576116a3612cf3565b602002602001015191508881815181106116bf576116bf612cf3565b60200260200101518482815181106116d9576116d9612cf3565b6020026020010181815250508781815181106116f7576116f7612cf3565b602002602001015183828151811061171157611711612cf3565b60200260200101818152505087818151811061172f5761172f612cf3565b602002602001015160056000848152602001908152602001600020600401600082825461175c9190612d48565b9091555050600101611689565b50611774898c612cca565b9a505b60028b90555b855115611997576000995060005b8651811015611930578681815181106117a6576117a6612cf3565b602002602001015191508581815181106117c2576117c2612cf3565b60200260200101516005600084815260200190815260200160002060020190805190602001906117f3929190612995565b50600085828151811061180857611808612cf3565b602002602001015111156119155784818151811061182857611828612cf3565b602002602001015160056000848152602001908152602001600020600501546118519190612d48565b85828151811061186357611863612cf3565b60200260200101818152505084818151811061188157611881612cf3565b602002602001015160056000848152602001908152602001600020600501819055507f00000000000000000000000000000000000000000000000000000000000000008582815181106118d6576118d6612cf3565b6020026020010151111561191057818d82815181106118f7576118f7612cf3565b60209081029190910101528a61190c81612fa9565b9b50505b611928565b6000828152600560208190526040822001555b60010161178b565b508915611942576119428c858c61239b565b42600355600054611954816001612d48565b60005560405181907f06a98bdd4732811ab3214800ed1ada2dce66a2bce301d250c3ca7d6b461ee6669061198d908f9088908890612fc2565b60405180910390a2505b50939e929d509b50919950969750505050505050565b6000806000806000806119be611f9d565b5050509450945094509450945060005b84811015611a5e57878382815181106119e9576119e9612cf3565b602002602001015103611a565785841115611a35578386838381518110611a1257611a12612cf3565b6020026020010151611a249190612f70565b611a2e9190612f87565b9650611a5e565b818181518110611a4757611a47612cf3565b60200260200101519650611a5e565b6001016119ce565b505050505050919050565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015611ae957602002820191906000526020600020905b815481526020019060010190808311611ad5575b50505050508152602001600382015481526020016004820154815260200160058201548152505090507f00000000000000000000000000000000000000000000000000000000000000008160a001511115611b475760029150611b56565b606081015115611b5657600191505b50919050565b60068181548110610adf57600080fd5b606060068054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020908154815260200190600101908083116112b8575050505050905090565b60007f0000000000000000000000000000000000000000000000000000000000000000600354611bf29190612d48565b905090565b8060016000828254611c099190612cca565b90915550611c3a90507f00000000000000000000000000000000000000000000000000000000000000008383612760565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051611c7591815260200190565b60405180910390a25050565b604051633cebfa4f60e01b81526004810184905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633cebfa4f906024016040805180830381865afa158015611cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0e9190612ff7565b91509150816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611d9757604051630b80380d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161072f565b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff8216811115611dfe57604051632b30b24760e21b81526bffffffffffffffffffffffff831660048201526024810182905260440161072f565b60005b8451811015611ef95760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166375c1f93489888581518110611e4e57611e4e612cf3565b60200260200101516040518363ffffffff1660e01b8152600401611e8292919091825263ffffffff16602082015260400190565b602060405180830381865afa158015611e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec3919061302c565b905082811015611ef057604051632b30b24760e21b8152600481018290526024810184905260440161072f565b50600101611e01565b50505050505050565b6060611f0d826127e3565b92915050565b60006040516323b872dd60e01b6000528460045283602452826044526020600060646000808a5af13d15601f3d1160016000511416171691506000606052806040525080611f965760405163abae3d6d60e01b81526001600160a01b0380871660048301528086166024830152841660448201526064810183905260840161072f565b5050505050565b600080600060608060608060606000600354905060025498507f00000000000000000000000000000000000000000000000000000000000000008142611fe39190612cca565b10158015611ff15750600089115b15612390576006548067ffffffffffffffff81111561201257612012612cdd565b60405190808252806020026020018201604052801561203b578160200160208202803683370190505b5094508067ffffffffffffffff81111561205757612057612cdd565b604051908082528060200260200182016040528015612080578160200160208202803683370190505b5096508067ffffffffffffffff81111561209c5761209c612cdd565b6040519080825280602002602001820160405280156120c5578160200160208202803683370190505b5095508067ffffffffffffffff8111156120e1576120e1612cdd565b60405190808252806020026020018201604052801561211457816020015b60608152602001906001900390816120ff5790505b5093508067ffffffffffffffff81111561213057612130612cdd565b604051908082528060200260200182016040528015612159578160200160208202803683370190505b50925060005b8181101561238d576006818154811061217a5761217a612cf3565b906000526020600020015486828151811061219757612197612cf3565b6020026020010181815250506000600560008884815181106121bb576121bb612cf3565b602090810291909101810151825281019190915260400160002080549091506121ec906001600160a01b0316611f02565b8683815181106121fe576121fe612cf3565b6020908102919091010152600381015484908181111561221c578091505b6122268242612cca565b905060006122a089868151811061223f5761223f612cf3565b60200260200101518560020180548060200260200160405190810160405280929190818152602001828054801561229557602002820191906000526020600020905b815481526020019060010190808311612281575b50505050508461288b565b9050801561235e576122d2827f0000000000000000000000000000000000000000000000000000000000000000612f70565b8b8f815181106122e4576122e4612cf3565b6020026020010181815250508a8e8151811061230257612302612cf3565b60200260200101518d6123159190612d48565b9c5089858151811061232957612329612cf3565b60200260200101518c8f8151811061234357612343612cf3565b60209081029190910101526123578e612fa9565b9d5061237e565b8188868151811061237157612371612cf3565b6020026020010181815250505b5050505080600101905061215f565b50505b509091929394959697565b825160008267ffffffffffffffff8111156123b8576123b8612cdd565b6040519080825280602002602001820160405280156123e1578160200160208202803683370190505b50905060008367ffffffffffffffff8111156123ff576123ff612cdd565b604051908082528060200260200182016040528015612428578160200160208202803683370190505b50905060008467ffffffffffffffff81111561244657612446612cdd565b60405190808252806020026020018201604052801561246f578160200160208202803683370190505b50905060008567ffffffffffffffff81111561248d5761248d612cdd565b6040519080825280602002602001820160405280156124b6578160200160208202803683370190505b50905060008667ffffffffffffffff8111156124d4576124d4612cdd565b6040519080825280602002602001820160405280156124fd578160200160208202803683370190505b50905060008060005b8881101561265d5760008c828151811061252257612522612cf3565b60200260200101511115612655578b818151811061254257612542612cf3565b602002602001015191508188848151811061255f5761255f612cf3565b6020908102919091018101919091526000838152600590915260409020600181015488516001600160a01b03909116908990869081106125a1576125a1612cf3565b6001600160a01b039283166020918202929092010152815488519116908890869081106125d0576125d0612cf3565b60200260200101906001600160a01b031690816001600160a01b0316815250508b828151811061260257612602612cf3565b602002602001015186858151811061261c5761261c612cf3565b6020026020010181815250508185858151811061263b5761263b612cf3565b60209081029190910101528361265081612fa9565b945050505b600101612506565b50885b8015612712578861267081613045565b99506000905084612682600184612cca565b8151811061269257612692612cf3565b6020026020010151905060068a815481106126af576126af612cf3565b9060005260206000200154600682815481106126cd576126cd612cf3565b60009182526020909120015560068054806126ea576126ea612d09565b60019003818190600052602060002001600090559055508061270b90613045565b9050612660565b506000547fd19a3d42ed383465e4058c322d9411aeac76ddb8454d22e139fc99808bd569528888888860405161274b9493929190613096565b60405180910390a25050505050505050505050565b600060405163a9059cbb60e01b6000528360045282602452602060006044600080895af13d15601f3d11600160005114161716915060006060528060405250806127dd5760405163abae3d6d60e01b81526001600160a01b038086166004830152306024830152841660448201526064810183905260840161072f565b50505050565b60408051600180825281830190925260609160208083019080368337019050509050816001600160a01b031663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612843573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612867919061302c565b8160008151811061287a5761287a612cf3565b602002602001018181525050919050565b60006128988484846128a0565b949350505050565b600080821180156128e45750826000815181106128bf576128bf612cf3565b6020026020010151846000815181106128da576128da612cf3565b6020026020010151115b15610bb357600082846000815181106128ff576128ff612cf3565b60200260200101518660008151811061291a5761291a612cf3565b602002602001015161292c9190612cca565b61293e90670de0b6b3a7640000612f70565b6129489190612f87565b7f0000000000000000000000000000000000000000000000000000000000000000111595945050505050565b508054600082559060005260206000209081019061299291906129e0565b50565b8280548282559060005260206000209081019282156129d0579160200282015b828111156129d05782518255916020019190600101906129b5565b506129dc9291506129e0565b5090565b5b808211156129dc57600081556001016129e1565b6001600160a01b038116811461299257600080fd5b600080600080600060808688031215612a2257600080fd5b8535612a2d816129f5565b94506020860135612a3d816129f5565b935060408601359250606086013567ffffffffffffffff80821115612a6157600080fd5b818801915088601f830112612a7557600080fd5b813581811115612a8457600080fd5b896020828501011115612a9657600080fd5b9699959850939650602001949392505050565b600060208284031215612abb57600080fd5b5035919050565b60008151808452602080850194506020840160005b83811015612af357815187529582019590820190600101612ad7565b509495945050505050565b6020815260006001600160a01b0380845116602084015280602085015116604084015250604083015160c06060840152612b3b60e0840182612ac2565b905060608401516080840152608084015160a084015260a084015160c08401528091505092915050565b602081526000610bb36020830184612ac2565b60a081526000612b8b60a0830188612ac2565b6020838203818501528188518084528284019150828160051b850101838b0160005b83811015612bdb57601f19878403018552612bc9838351612ac2565b94860194925090850190600101612bad565b50508681036040880152612bef818b612ac2565b9450505050508281036060840152612c078186612ac2565b90508281036080840152612c1b8185612ac2565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6020810160038310612c5f57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020808352835180602085015260005b81811015612c9357858101830151858201604001528201612c77565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115611f0d57611f0d612cb4565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b838152606060208201526000612d386060830185612ac2565b9050826040830152949350505050565b80820180821115611f0d57611f0d612cb4565b604051610100810167ffffffffffffffff81118282101715612d7f57612d7f612cdd565b60405290565b80516bffffffffffffffffffffffff81168114612da157600080fd5b919050565b8051612da1816129f5565b805163ffffffff81168114612da157600080fd5b805160068110612da157600080fd5b600082601f830112612de557600080fd5b8151602067ffffffffffffffff80831115612e0257612e02612cdd565b8260051b604051601f19603f83011681018181108482111715612e2757612e27612cdd565b6040529384526020818701810194908101925087851115612e4757600080fd5b6020870191505b84821015612e6e57612e5f82612db1565b83529183019190830190612e4e565b979650505050505050565b600060208284031215612e8b57600080fd5b815167ffffffffffffffff80821115612ea357600080fd5b908301906101008286031215612eb857600080fd5b612ec0612d5b565b612ec983612d85565b8152612ed760208401612da6565b602082015260408301516040820152612ef260608401612db1565b6060820152612f0360808401612db1565b6080820152612f1460a08401612db1565b60a0820152612f2560c08401612dc5565b60c082015260e083015182811115612f3c57600080fd5b612f4887828601612dd4565b60e08301525095945050505050565b8281526040602082015260006128986040830184612ac2565b8082028115828204841417611f0d57611f0d612cb4565b600082612fa457634e487b7160e01b600052601260045260246000fd5b500490565b600060018201612fbb57612fbb612cb4565b5060010190565b838152606060208201526000612fdb6060830185612ac2565b8281036040840152612fed8185612ac2565b9695505050505050565b6000806040838503121561300a57600080fd5b8251613015816129f5565b915061302360208401612d85565b90509250929050565b60006020828403121561303e57600080fd5b5051919050565b60008161305457613054612cb4565b506000190190565b60008151808452602080850194506020840160005b83811015612af35781516001600160a01b031687529582019590820190600101613071565b6080815260006130a96080830187612ac2565b82810360208401526130bb818761305c565b905082810360408401526130cf818661305c565b90508281036060840152612e6e8185612ac256fea26469706673582212201cbb3243bdf2246a74a754c4b24385dc52b256b192f67778a3b3a76648374a5864736f6c63430008170033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102415760003560e01c8063a0ed60e011610145578063cbcf252a116100bd578063eb338c961161008c578063f4dce71411610071578063f4dce71414610681578063f86ad2b614610689578063ffa1ad74146106b057600080fd5b8063eb338c9614610666578063f189e85a1461067957600080fd5b8063cbcf252a146105ca578063e1f1176d146105f1578063e77cdcc914610618578063eacdaabc1461063f57600080fd5b8063b69ef8a811610114578063c2c4c5c1116100f9578063c2c4c5c11461057e578063c889921d14610597578063cae2a5f0146105aa57600080fd5b8063b69ef8a814610562578063b6b55f251461056b57600080fd5b8063a0ed60e014610496578063a694fc3a146104bd578063a74466ad146104d0578063b15087601461054d57600080fd5b806352c824f5116101d857806372f702f3116101a7578063809cee2f1161018c578063809cee2f1461044657806382a8ea581461046d578063879d90901461048d57600080fd5b806372f702f31461040c57806378e061361461043357600080fd5b806352c824f51461038457806356e76058146103ab5780635829c5ec146103be578063592cf3fb146103e557600080fd5b8063287140511161021457806328714051146103005780632e17de781461033f5780633e7329971461035457806342cde4e81461035d57600080fd5b806308ae7e541461024657806314b19c5a14610280578063150b7a021461028957806316a75172146102d9575b600080fd5b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61026d60005481565b6102a8610297366004612a0a565b630a85bd0160e11b95945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610277565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b61035261034d366004612aa9565b6106e1565b005b61026d60035481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d6103b9366004612aa9565b610acf565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d610441366004612aa9565b610af0565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61048061047b366004612aa9565b610bba565b6040516102779190612afe565b61026d60025481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103526104cb366004612aa9565b610cb1565b61051a6104de366004612aa9565b6005602081905260009182526040909120805460018201546003830154600484015493909401546001600160a01b039283169492909116929085565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610277565b61055561127e565b6040516102779190612b65565b61026d60015481565b610352610579366004612aa9565b6112d6565b610586611378565b604051610277959493929190612b78565b61026d6105a5366004612aa9565b6119ad565b6105bd6105b8366004612aa9565b611a69565b6040516102779190612c3d565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d610674366004612aa9565b611b5c565b610555611b6c565b61026d611bc2565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6106d4604051806040016040528060058152602001640302e312e360dc1b81525081565b6040516102779190612c65565b600081815260056020526040902060018101546001600160a01b0316331461073857600181015460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b600381015460006107498242612cca565b90507f0000000000000000000000000000000000000000000000000000000000000000811115801561077d57506000600254115b156107cb5760405163ba2bbc6b60e01b815260048101859052602481018290527f0000000000000000000000000000000000000000000000000000000000000000604482015260640161072f565b6000806107d6611378565b945050505091508151600003610837576107ee611b6c565b9150815167ffffffffffffffff81111561080a5761080a612cdd565b604051908082528060200260200182016040528015610833578160200160208202803683370190505b5090505b6000805b8351821015610898578783838151811061085757610857612cf3565b60200260200101510315610898578784838151811061087857610878612cf3565b60200260200101510361088d57506001610898565b81600101915061083b565b600487015460028801805460408051602080840282018101909252828152600093909290918301828280156108ec57602002820191906000526020600020905b8154815260200190600101908083116108d8575b50508c5460008f8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff19908116825560018201805490911690559596506001600160a01b03909116949350915061094890506002830182612974565b506000600382018190556004820181905560059091015583156109d7576006805461097590600190612cca565b8154811061098557610985612cf3565b9060005260206000200154600686815481106109a3576109a3612cf3565b60009182526020909120015560068054806109c0576109c0612d09565b600190038181906000526020600020016000905590555b604051632142170760e11b8152306004820152336024820152604481018c90526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342842e0e90606401600060405180830381600087803b158015610a4557600080fd5b505af1158015610a59573d6000803e3d6000fd5b505050506000831115610a7057610a708184611bf7565b806001600160a01b0316336001600160a01b03168c7f950733f4c0bf951b8e770f3cc619a4288e7b59b1236d59aeaf2c238488e8ae816000548688604051610aba93929190612d1f565b60405180910390a45050505050505050505050565b60048181548110610adf57600080fd5b600091825260209091200154905081565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015610b7057602002820191906000526020600020905b815481526020019060010190808311610b5c575b505050505081526020016003820154815260200160048201548152602001600582015481525050905080608001519150610ba9836119ad565b610bb39083612d48565b9392505050565b610c056040518060c0016040528060006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016000815260200160008152602001600081525090565b600082815260056020908152604091829020825160c08101845281546001600160a01b0390811682526001830154168184015260028201805485518186028101860187528181529295939493860193830182828015610c8357602002820191906000526020600020905b815481526020019060010190808311610c6f575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050919050565b600254600003610cd45760405163afb0be3360e01b815260040160405180910390fd5b6000818152600560205260409020600381015415610d085760405163b4817ce760e01b81526004810183905260240161072f565b6006547f00000000000000000000000000000000000000000000000000000000000000008103610d6d5760405163fd20861560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260240161072f565b60405163ef0e239b60e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ef0e239b90602401600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dfd9190810190612e79565b9050806080015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014610e4c57604051637ad404bf60e11b81526004810185905260240161072f565b7f000000000000000000000000000000000000000000000000000000000000000015801590610e9f575080604001517f000000000000000000000000000000000000000000000000000000000000000014155b15610ec057604051637ad404bf60e11b81526004810185905260240161072f565b60007f0000000000000000000000000000000000000000000000000000000000000000118015610f1a5750806060015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014155b15610f3b57604051637ad404bf60e11b81526004810185905260240161072f565b60048160c001516005811115610f5357610f53612c27565b14610f92578060c001516005811115610f6e57610f6e612c27565b604051633c053f9d60e21b815260048101919091526024810185905260440161072f565b600081602001516001600160a01b0316803b806020016040519081016040528181526000908060200190933c805190602001209050807f00000000000000000000000000000000000000000000000000000000000000001461101757602082015160405162a2307960e51b81526001600160a01b03909116600482015260240161072f565b60045480156110e05760e08301515181811461104957604051637ad404bf60e11b81526004810188905260240161072f565b60005b818110156110dd578460e00151818151811061106a5761106a612cf3565b602002602001015163ffffffff166004828154811061108b5761108b612cf3565b9060005260206000200154146110d557600481815481106110ae576110ae612cf3565b9060005260206000200154604051632ab10b0b60e21b815260040161072f91815260200190565b60010161104c565b50505b6111018684600001516bffffffffffffffffffffffff168560e00151611c81565b602083015185546001600160a01b03821673ffffffffffffffffffffffffffffffffffffffff199182161787556001870180549091163317905560009061114790611f02565b805190915061115f9060028801906020840190612995565b50426003870155600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01879055604051632142170760e11b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342842e0e90606401600060405180830381600087803b15801561120957600080fd5b505af115801561121d573d6000803e3d6000fd5b5050505083602001516001600160a01b0316336001600160a01b0316887faa6b005b4958114a0c90492461c24af6525ae0178db7fbf44125ae9217c69ccb6000548560405161126d929190612f57565b60405180910390a450505050505050565b606060048054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020905b8154815260200190600101908083116112b8575b5050505050905090565b6000816001546112e69190612d48565b90506000826002546112f89190612d48565b6001839055600281905590506113307f0000000000000000000000000000000000000000000000000000000000000000333086611f13565b604080518481526020810184905290810182905233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9060600160405180910390a2505050565b6060806060806060600080600080600080600080611394611f9d565b97509750975097509750975097509750606080845167ffffffffffffffff8111156113c1576113c1612cdd565b6040519080825280602002602001820160405280156113ea578160200160208202803683370190505b509a506000891561177d578967ffffffffffffffff81111561140e5761140e612cdd565b604051908082528060200260200182016040528015611437578160200160208202803683370190505b5092508967ffffffffffffffff81111561145357611453612cdd565b60405190808252806020026020018201604052801561147c578160200160208202803683370190505b5091508a8911156116865760008060015b8c811015611579578b8e8b83815181106114a9576114a9612cf3565b60200260200101516114bb9190612f70565b6114c59190612f87565b92506114d18383612d48565b91508a81815181106114e5576114e5612cf3565b602002602001015193508a818151811061150157611501612cf3565b602002602001015186828151811061151b5761151b612cf3565b6020026020010181815250508285828151811061153a5761153a612cf3565b6020026020010181815250508260056000868152602001908152602001600020600401600082825461156c9190612d48565b909155505060010161148d565b508a8d8a60008151811061158f5761158f612cf3565b60200260200101516115a19190612f70565b6115ab9190612f87565b91506115b78282612d48565b9050896000815181106115cc576115cc612cf3565b60200260200101519250896000815181106115e9576115e9612cf3565b60200260200101518560008151811061160457611604612cf3565b602002602001018181525050808d111561162f57611622818e612cca565b61162c9083612d48565b91505b818460008151811061164357611643612cf3565b602002602001018181525050816005600085815260200190815260200160002060040160008282546116759190612d48565b9091555060009d5061177792505050565b60005b8a811015611769578881815181106116a3576116a3612cf3565b602002602001015191508881815181106116bf576116bf612cf3565b60200260200101518482815181106116d9576116d9612cf3565b6020026020010181815250508781815181106116f7576116f7612cf3565b602002602001015183828151811061171157611711612cf3565b60200260200101818152505087818151811061172f5761172f612cf3565b602002602001015160056000848152602001908152602001600020600401600082825461175c9190612d48565b9091555050600101611689565b50611774898c612cca565b9a505b60028b90555b855115611997576000995060005b8651811015611930578681815181106117a6576117a6612cf3565b602002602001015191508581815181106117c2576117c2612cf3565b60200260200101516005600084815260200190815260200160002060020190805190602001906117f3929190612995565b50600085828151811061180857611808612cf3565b602002602001015111156119155784818151811061182857611828612cf3565b602002602001015160056000848152602001908152602001600020600501546118519190612d48565b85828151811061186357611863612cf3565b60200260200101818152505084818151811061188157611881612cf3565b602002602001015160056000848152602001908152602001600020600501819055507f00000000000000000000000000000000000000000000000000000000000000008582815181106118d6576118d6612cf3565b6020026020010151111561191057818d82815181106118f7576118f7612cf3565b60209081029190910101528a61190c81612fa9565b9b50505b611928565b6000828152600560208190526040822001555b60010161178b565b508915611942576119428c858c61239b565b42600355600054611954816001612d48565b60005560405181907f06a98bdd4732811ab3214800ed1ada2dce66a2bce301d250c3ca7d6b461ee6669061198d908f9088908890612fc2565b60405180910390a2505b50939e929d509b50919950969750505050505050565b6000806000806000806119be611f9d565b5050509450945094509450945060005b84811015611a5e57878382815181106119e9576119e9612cf3565b602002602001015103611a565785841115611a35578386838381518110611a1257611a12612cf3565b6020026020010151611a249190612f70565b611a2e9190612f87565b9650611a5e565b818181518110611a4757611a47612cf3565b60200260200101519650611a5e565b6001016119ce565b505050505050919050565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015611ae957602002820191906000526020600020905b815481526020019060010190808311611ad5575b50505050508152602001600382015481526020016004820154815260200160058201548152505090507f00000000000000000000000000000000000000000000000000000000000000008160a001511115611b475760029150611b56565b606081015115611b5657600191505b50919050565b60068181548110610adf57600080fd5b606060068054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020908154815260200190600101908083116112b8575050505050905090565b60007f0000000000000000000000000000000000000000000000000000000000000000600354611bf29190612d48565b905090565b8060016000828254611c099190612cca565b90915550611c3a90507f00000000000000000000000000000000000000000000000000000000000000008383612760565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051611c7591815260200190565b60405180910390a25050565b604051633cebfa4f60e01b81526004810184905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633cebfa4f906024016040805180830381865afa158015611cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0e9190612ff7565b91509150816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611d9757604051630b80380d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161072f565b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff8216811115611dfe57604051632b30b24760e21b81526bffffffffffffffffffffffff831660048201526024810182905260440161072f565b60005b8451811015611ef95760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166375c1f93489888581518110611e4e57611e4e612cf3565b60200260200101516040518363ffffffff1660e01b8152600401611e8292919091825263ffffffff16602082015260400190565b602060405180830381865afa158015611e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec3919061302c565b905082811015611ef057604051632b30b24760e21b8152600481018290526024810184905260440161072f565b50600101611e01565b50505050505050565b6060611f0d826127e3565b92915050565b60006040516323b872dd60e01b6000528460045283602452826044526020600060646000808a5af13d15601f3d1160016000511416171691506000606052806040525080611f965760405163abae3d6d60e01b81526001600160a01b0380871660048301528086166024830152841660448201526064810183905260840161072f565b5050505050565b600080600060608060608060606000600354905060025498507f00000000000000000000000000000000000000000000000000000000000000008142611fe39190612cca565b10158015611ff15750600089115b15612390576006548067ffffffffffffffff81111561201257612012612cdd565b60405190808252806020026020018201604052801561203b578160200160208202803683370190505b5094508067ffffffffffffffff81111561205757612057612cdd565b604051908082528060200260200182016040528015612080578160200160208202803683370190505b5096508067ffffffffffffffff81111561209c5761209c612cdd565b6040519080825280602002602001820160405280156120c5578160200160208202803683370190505b5095508067ffffffffffffffff8111156120e1576120e1612cdd565b60405190808252806020026020018201604052801561211457816020015b60608152602001906001900390816120ff5790505b5093508067ffffffffffffffff81111561213057612130612cdd565b604051908082528060200260200182016040528015612159578160200160208202803683370190505b50925060005b8181101561238d576006818154811061217a5761217a612cf3565b906000526020600020015486828151811061219757612197612cf3565b6020026020010181815250506000600560008884815181106121bb576121bb612cf3565b602090810291909101810151825281019190915260400160002080549091506121ec906001600160a01b0316611f02565b8683815181106121fe576121fe612cf3565b6020908102919091010152600381015484908181111561221c578091505b6122268242612cca565b905060006122a089868151811061223f5761223f612cf3565b60200260200101518560020180548060200260200160405190810160405280929190818152602001828054801561229557602002820191906000526020600020905b815481526020019060010190808311612281575b50505050508461288b565b9050801561235e576122d2827f0000000000000000000000000000000000000000000000000000000000000000612f70565b8b8f815181106122e4576122e4612cf3565b6020026020010181815250508a8e8151811061230257612302612cf3565b60200260200101518d6123159190612d48565b9c5089858151811061232957612329612cf3565b60200260200101518c8f8151811061234357612343612cf3565b60209081029190910101526123578e612fa9565b9d5061237e565b8188868151811061237157612371612cf3565b6020026020010181815250505b5050505080600101905061215f565b50505b509091929394959697565b825160008267ffffffffffffffff8111156123b8576123b8612cdd565b6040519080825280602002602001820160405280156123e1578160200160208202803683370190505b50905060008367ffffffffffffffff8111156123ff576123ff612cdd565b604051908082528060200260200182016040528015612428578160200160208202803683370190505b50905060008467ffffffffffffffff81111561244657612446612cdd565b60405190808252806020026020018201604052801561246f578160200160208202803683370190505b50905060008567ffffffffffffffff81111561248d5761248d612cdd565b6040519080825280602002602001820160405280156124b6578160200160208202803683370190505b50905060008667ffffffffffffffff8111156124d4576124d4612cdd565b6040519080825280602002602001820160405280156124fd578160200160208202803683370190505b50905060008060005b8881101561265d5760008c828151811061252257612522612cf3565b60200260200101511115612655578b818151811061254257612542612cf3565b602002602001015191508188848151811061255f5761255f612cf3565b6020908102919091018101919091526000838152600590915260409020600181015488516001600160a01b03909116908990869081106125a1576125a1612cf3565b6001600160a01b039283166020918202929092010152815488519116908890869081106125d0576125d0612cf3565b60200260200101906001600160a01b031690816001600160a01b0316815250508b828151811061260257612602612cf3565b602002602001015186858151811061261c5761261c612cf3565b6020026020010181815250508185858151811061263b5761263b612cf3565b60209081029190910101528361265081612fa9565b945050505b600101612506565b50885b8015612712578861267081613045565b99506000905084612682600184612cca565b8151811061269257612692612cf3565b6020026020010151905060068a815481106126af576126af612cf3565b9060005260206000200154600682815481106126cd576126cd612cf3565b60009182526020909120015560068054806126ea576126ea612d09565b60019003818190600052602060002001600090559055508061270b90613045565b9050612660565b506000547fd19a3d42ed383465e4058c322d9411aeac76ddb8454d22e139fc99808bd569528888888860405161274b9493929190613096565b60405180910390a25050505050505050505050565b600060405163a9059cbb60e01b6000528360045282602452602060006044600080895af13d15601f3d11600160005114161716915060006060528060405250806127dd5760405163abae3d6d60e01b81526001600160a01b038086166004830152306024830152841660448201526064810183905260840161072f565b50505050565b60408051600180825281830190925260609160208083019080368337019050509050816001600160a01b031663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612843573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612867919061302c565b8160008151811061287a5761287a612cf3565b602002602001018181525050919050565b60006128988484846128a0565b949350505050565b600080821180156128e45750826000815181106128bf576128bf612cf3565b6020026020010151846000815181106128da576128da612cf3565b6020026020010151115b15610bb357600082846000815181106128ff576128ff612cf3565b60200260200101518660008151811061291a5761291a612cf3565b602002602001015161292c9190612cca565b61293e90670de0b6b3a7640000612f70565b6129489190612f87565b7f0000000000000000000000000000000000000000000000000000000000000000111595945050505050565b508054600082559060005260206000209081019061299291906129e0565b50565b8280548282559060005260206000209081019282156129d0579160200282015b828111156129d05782518255916020019190600101906129b5565b506129dc9291506129e0565b5090565b5b808211156129dc57600081556001016129e1565b6001600160a01b038116811461299257600080fd5b600080600080600060808688031215612a2257600080fd5b8535612a2d816129f5565b94506020860135612a3d816129f5565b935060408601359250606086013567ffffffffffffffff80821115612a6157600080fd5b818801915088601f830112612a7557600080fd5b813581811115612a8457600080fd5b896020828501011115612a9657600080fd5b9699959850939650602001949392505050565b600060208284031215612abb57600080fd5b5035919050565b60008151808452602080850194506020840160005b83811015612af357815187529582019590820190600101612ad7565b509495945050505050565b6020815260006001600160a01b0380845116602084015280602085015116604084015250604083015160c06060840152612b3b60e0840182612ac2565b905060608401516080840152608084015160a084015260a084015160c08401528091505092915050565b602081526000610bb36020830184612ac2565b60a081526000612b8b60a0830188612ac2565b6020838203818501528188518084528284019150828160051b850101838b0160005b83811015612bdb57601f19878403018552612bc9838351612ac2565b94860194925090850190600101612bad565b50508681036040880152612bef818b612ac2565b9450505050508281036060840152612c078186612ac2565b90508281036080840152612c1b8185612ac2565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6020810160038310612c5f57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020808352835180602085015260005b81811015612c9357858101830151858201604001528201612c77565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115611f0d57611f0d612cb4565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b838152606060208201526000612d386060830185612ac2565b9050826040830152949350505050565b80820180821115611f0d57611f0d612cb4565b604051610100810167ffffffffffffffff81118282101715612d7f57612d7f612cdd565b60405290565b80516bffffffffffffffffffffffff81168114612da157600080fd5b919050565b8051612da1816129f5565b805163ffffffff81168114612da157600080fd5b805160068110612da157600080fd5b600082601f830112612de557600080fd5b8151602067ffffffffffffffff80831115612e0257612e02612cdd565b8260051b604051601f19603f83011681018181108482111715612e2757612e27612cdd565b6040529384526020818701810194908101925087851115612e4757600080fd5b6020870191505b84821015612e6e57612e5f82612db1565b83529183019190830190612e4e565b979650505050505050565b600060208284031215612e8b57600080fd5b815167ffffffffffffffff80821115612ea357600080fd5b908301906101008286031215612eb857600080fd5b612ec0612d5b565b612ec983612d85565b8152612ed760208401612da6565b602082015260408301516040820152612ef260608401612db1565b6060820152612f0360808401612db1565b6080820152612f1460a08401612db1565b60a0820152612f2560c08401612dc5565b60c082015260e083015182811115612f3c57600080fd5b612f4887828601612dd4565b60e08301525095945050505050565b8281526040602082015260006128986040830184612ac2565b8082028115828204841417611f0d57611f0d612cb4565b600082612fa457634e487b7160e01b600052601260045260246000fd5b500490565b600060018201612fbb57612fbb612cb4565b5060010190565b838152606060208201526000612fdb6060830185612ac2565b8281036040840152612fed8185612ac2565b9695505050505050565b6000806040838503121561300a57600080fd5b8251613015816129f5565b915061302360208401612d85565b90509250929050565b60006020828403121561303e57600080fd5b5051919050565b60008161305457613054612cb4565b506000190190565b60008151808452602080850194506020840160005b83811015612af35781516001600160a01b031687529582019590820190600101613071565b6080815260006130a96080830187612ac2565b82810360208401526130bb818761305c565b905082810360408401526130cf818661305c565b90508281036060840152612e6e8185612ac256fea26469706673582212201cbb3243bdf2246a74a754c4b24385dc52b256b192f67778a3b3a76648374a5864736f6c63430008170033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/trader_backup/vendor/valory/contracts/mech_activity/contract.py b/trader_backup/vendor/valory/contracts/mech_activity/contract.py deleted file mode 100644 index c411d06e1..000000000 --- a/trader_backup/vendor/valory/contracts/mech_activity/contract.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the class to connect to the `MechActivityContract` contract.""" - -from enum import Enum - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi - - -class MechActivityContract(Contract): - """The Service Staking contract.""" - - contract_id = PublicId.from_str("valory/mech_activity:0.1.0") - - @classmethod - def liveness_ratio( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the liveness ratio.""" - contract = cls.get_instance(ledger_api, contract_address) - liveness_ratio = contract.functions.livenessRatio().call() - return dict(data=liveness_ratio) diff --git a/trader_backup/vendor/valory/contracts/mech_activity/contract.yaml b/trader_backup/vendor/valory/contracts/mech_activity/contract.yaml deleted file mode 100644 index 1a1828d46..000000000 --- a/trader_backup/vendor/valory/contracts/mech_activity/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: mech_activity -author: valory -version: 0.1.0 -type: contract -description: Mech activity checker contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeid4hg5rx75ltdjmekmxdddwqzbvblygmvlhws5samjxfirnkp666i - build/MechActivity.json: bafybeiagrufcoljrlo2zklc7kxwh7eyrf67usos2bqnf7hss47hgm6low4 - contract.py: bafybeihgiwyy5gj5tpyz6wnjlfsywssanrbuzskqctt557f3galofewqse -fingerprint_ignore_patterns: [] -contracts: [] -class_name: MechActivityContract -contract_interface_paths: - ethereum: build/MechActivity.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - web3: - version: <7,>=6.0.0 diff --git a/trader_backup/vendor/valory/contracts/mech_marketplace/README.md b/trader_backup/vendor/valory/contracts/mech_marketplace/README.md deleted file mode 100644 index 22522064e..000000000 --- a/trader_backup/vendor/valory/contracts/mech_marketplace/README.md +++ /dev/null @@ -1 +0,0 @@ -# Agent Mech Marketplace Contract diff --git a/trader_backup/vendor/valory/contracts/mech_marketplace/__init__.py b/trader_backup/vendor/valory/contracts/mech_marketplace/__init__.py deleted file mode 100644 index bb07482ea..000000000 --- a/trader_backup/vendor/valory/contracts/mech_marketplace/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the support resources for an agent MechMarketplace.""" diff --git a/trader_backup/vendor/valory/contracts/mech_marketplace/build/mech.json b/trader_backup/vendor/valory/contracts/mech_marketplace/build/mech.json deleted file mode 100644 index dae53c607..000000000 --- a/trader_backup/vendor/valory/contracts/mech_marketplace/build/mech.json +++ /dev/null @@ -1,837 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "AgentMech", - "sourceName": "contracts/AgentMech.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_stakingFactory", - "type": "address" - }, - { - "internalType": "address", - "name": "_karmaProxy", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_minResponseTimeout", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_maxResponseTimeout", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "name": "AlreadyDelivered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "min", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "OutOfBounds", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "Overflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "current", - "type": "uint256" - } - ], - "name": "PriorityMechResponseTimeout", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrancyGuard", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "stakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceNotStaked", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "UnauthorizedAccount", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "factory", - "type": "address" - } - ], - "name": "FactoryUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "priorityMech", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "actualMech", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "requester", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "MarketplaceDeliver", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "requester", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "requestedMech", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "MarketplaceRequest", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "mech", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "status", - "type": "bool" - } - ], - "name": "MechRegistrationStatusChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "minResponseTimeout", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "maxResponseTimeout", - "type": "uint256" - } - ], - "name": "MinMaxResponseTimeoutUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "inputs": [], - "name": "DOMAIN_SEPARATOR_TYPE_HASH", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "chainId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "mech", - "type": "address" - }, - { - "internalType": "address", - "name": "mechStakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "mechServiceId", - "type": "uint256" - } - ], - "name": "checkMech", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "requester", - "type": "address" - }, - { - "internalType": "address", - "name": "requesterStakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "requesterServiceId", - "type": "uint256" - } - ], - "name": "checkRequester", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "stakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "checkStakingInstance", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "requestData", - "type": "bytes" - }, - { - "internalType": "address", - "name": "deliveryMechStakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deliveryMechServiceId", - "type": "uint256" - } - ], - "name": "deliverMarketplace", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "domainSeparator", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "getDeliveriesCount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getDomainSeparator", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "name": "getMechDeliveryInfo", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "name": "priorityMech", - "type": "address" - }, - { - "internalType": "address", - "name": "deliveryMech", - "type": "address" - }, - { - "internalType": "address", - "name": "requester", - "type": "address" - }, - { - "internalType": "uint32", - "name": "responseTimeout", - "type": "uint32" - } - ], - "internalType": "struct MechDelivery", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "mechService", - "type": "address" - } - ], - "name": "getMechServiceDeliveriesCount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - } - ], - "name": "getRequestId", - "outputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "name": "getRequestStatus", - "outputs": [ - { - "internalType": "enum MechMarketplace.RequestStatus", - "name": "status", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "getRequestsCount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "karmaProxy", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapDeliveryCounts", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapMechServiceDeliveryCounts", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapNonces", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapRequestCounts", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapRequestIdDeliveries", - "outputs": [ - { - "internalType": "address", - "name": "priorityMech", - "type": "address" - }, - { - "internalType": "address", - "name": "deliveryMech", - "type": "address" - }, - { - "internalType": "address", - "name": "requester", - "type": "address" - }, - { - "internalType": "uint32", - "name": "responseTimeout", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxResponseTimeout", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minResponseTimeout", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "numTotalRequests", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "numUndeliveredRequests", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "address", - "name": "priorityMech", - "type": "address" - }, - { - "internalType": "address", - "name": "priorityMechStakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "priorityMechServiceId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "requesterStakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "requesterServiceId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "responseTimeout", - "type": "uint256" - } - ], - "name": "request", - "outputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "stakingFactory", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x60806040525f805534801562000013575f80fd5b50604051620026cc380380620026cc833981016040819052620000369162000391565b604080516001600160a01b03851660208201528082018490528151808203830181526060909101909152839083906200006f8162000145565b5050506001600160a01b0383166200009a5760405163d92e233d60e01b815260040160405180910390fd5b6040516331a9108f60e11b8152600481018390525f906001600160a01b03851690636352211e90602401602060405180830381865afa158015620000e0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001069190620003c6565b90506001600160a01b0381166200013857604051630ede975960e01b8152600481018490526024015b60405180910390fd5b50600155506200049a9050565b6200014f620001ad565b51156200019f5760405162461bcd60e51b815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016200012f565b620001aa8162000218565b50565b6060620002136200020d604051606b60f91b6020820152602560fa1b60218201526001600160601b03193060601b166022820152600160f81b60368201525f90603701604051602081830303815290604052805190602001205f1c905090565b620002e1565b905090565b5f620002248262000339565b90505f8151602083015ff090506200028b604051606b60f91b6020820152602560fa1b60218201526001600160601b03193060601b166022820152600160f81b60368201525f90603701604051602081830303815290604052805190602001205f1c905090565b6001600160a01b0316816001600160a01b031614620002dc5760405162461bcd60e51b815260206004820152600c60248201526b15dc9a5d194819985a5b195960a21b60448201526064016200012f565b505050565b6060813b600181116200030357505060408051602081019091525f8152919050565b806200030f81620003fd565b9150506040519150601f19601f602083010116820160405280825280600160208401853c50919050565b6060815160016200034b919062000415565b826040516020016200035f92919062000431565b6040516020818303038152906040529050919050565b80516001600160a01b03811681146200038c575f80fd5b919050565b5f805f60608486031215620003a4575f80fd5b620003af8462000375565b925060208401519150604084015190509250925092565b5f60208284031215620003d7575f80fd5b620003e28262000375565b9392505050565b634e487b7160e01b5f52601160045260245ffd5b5f816200040e576200040e620003e9565b505f190190565b808201808211156200042b576200042b620003e9565b92915050565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b60058201525f600e82018190528251815b8181101562000489576020818601810151600f8684010152016200046a565b505f9201600f019182525092915050565b61222480620004a85f395ff3fe60806040526004361061017a575f3560e01c8063a035b1fe116100d1578063bdf863171161007c578063f23a6e6111610057578063f23a6e61146104d2578063f6171e4414610517578063fc0c546a14610536575f80fd5b8063bdf8631714610472578063c7dec3fc14610487578063e00b9118146104b3575f80fd5b8063b0d691fe116100ac578063b0d691fe146103d1578063b94207d314610418578063bc197c811461042b575f80fd5b8063a035b1fe1461038a578063a4f9edbf1461039f578063affed0e0146103be575f80fd5b80633a871cdd116101315780636d70f7ae1161010c5780636d70f7ae146102fb5780637af734731461032a57806391b7f5ed1461036b575f80fd5b80633a871cdd1461028557806358ce0909146102a45780635fee6085146102d0575f80fd5b8063157305fe11610161578063157305fe146102255780631626ba7e1461024457806317d70f7c14610263575f80fd5b806223de2914610185578063150b7a02146101ab575f80fd5b3661018157005b5f80fd5b348015610190575f80fd5b506101a961019f366004611943565b5050505050505050565b005b3480156101b6575f80fd5b506101ef6101c53660046119ed565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b348015610230575f80fd5b506101a961023f366004611b2f565b61054a565b34801561024f575f80fd5b506101ef61025e366004611b2f565b610771565b34801561026e575f80fd5b50610277610914565b60405190815260200161021c565b348015610290575f80fd5b5061027761029f366004611b73565b610938565b3480156102af575f80fd5b506102c36102be366004611bc2565b610974565b60405161021c9190611be2565b3480156102db575f80fd5b506102776102ea366004611c25565b60036020525f908152604090205481565b348015610306575f80fd5b5061031a610315366004611c25565b610ada565b604051901515815260200161021c565b348015610335575f80fd5b50610277610344366004611c25565b73ffffffffffffffffffffffffffffffffffffffff165f9081526003602052604090205490565b348015610376575f80fd5b506101a9610385366004611c40565b610bac565b348015610395575f80fd5b5061027760015481565b3480156103aa575f80fd5b506101a96103b9366004611c57565b610c9a565b3480156103c9575f80fd5b505f54610277565b3480156103dc575f80fd5b50730576a174d229e3cfa37253523e645a78a0c91b575b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021c565b610277610426366004611c57565b610d16565b348015610436575f80fd5b506101ef610445366004611cd2565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561047d575f80fd5b5061027760025481565b348015610492575f80fd5b506104a66104a1366004611d68565b610e63565b60405161021c9190611e45565b3480156104be575f80fd5b506102776104cd366004611e57565b610f4d565b3480156104dd575f80fd5b506101ef6104ec366004611e8e565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b348015610522575f80fd5b50610277610531366004611bc2565b610f9e565b348015610541575f80fd5b506103f3610fc0565b61055333610ada565b80610571575033730576a174d229e3cfa37253523e645a78a0c91b57145b610602576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084015b60405180910390fd5b5f828152600460205260408082208151808301928390529160029082845b8154815260200190600101908083116106205750505050509050805f6002811061064c5761064c611f05565b602002015115801561066057506020810151155b801561069557505f805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed548314155b156106cf576040517ffe239804000000000000000000000000000000000000000000000000000000008152600481018490526024016105f9565b6020818101805183515f908152600490935260408084206001908101929092558451925184528084209290925585835290822082815501819055600280549161071783611f5f565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f0cd979445339c62199996f208428d987b1cea24d18e62b79ec24d94b636e8b708484604051610764929190611f93565b60405180910390a2505050565b5f805f8061079185602081015160408201516060909201515f1a92909190565b9094509250905060ff81165f036108a757828583016020016107b282610ada565b1580156107d5575073ffffffffffffffffffffffffffffffffffffffff82163014155b1561080857507fffffffff00000000000000000000000000000000000000000000000000000000945061090e9350505050565b6040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831690631626ba7e9061085c908b908590600401611f93565b602060405180830381865afa158015610877573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061089b9190611fab565b9550505050505061090e565b6108b661031587838686610fdd565b156108e757507f1626ba7e00000000000000000000000000000000000000000000000000000000925061090e915050565b507fffffffff00000000000000000000000000000000000000000000000000000000925050505b92915050565b5f8061091e610ff9565b8060200190518101906109319190611fea565b9392505050565b5f6109416110cd565b61094b848461114c565b905061095a6040850185612016565b90505f0361096b5761096b8461124c565b610931826112ca565b6002546060905f849003610986578093505b806109918486612077565b11156109de576109a18385612077565b6040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016105f9565b8315610ad3578367ffffffffffffffff8111156109fd576109fd611a5b565b604051908082528060200260200182016040528015610a26578160200160208202803683370190505b505f80805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed549193505b84811015610a81575f828152600460205260409020600101549150610a7a8161208a565b9050610a56565b505f5b85811015610ad05781848281518110610a9f57610a9f611f05565b6020908102919091018101919091525f9283526004905260409091206001015490610ac98161208a565b9050610a84565b50505b5092915050565b5f805f610ae5610ff9565b806020019051810190610af89190611fea565b915091508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610b4e91815260200190565b602060405180830381865afa158015610b69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b8d91906120c1565b73ffffffffffffffffffffffffffffffffffffffff1614949350505050565b610bb533610ada565b80610bd3575033730576a174d229e3cfa37253523e645a78a0c91b57145b610c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b60018190556040518181527f66cbca4f3c64fecf1dcb9ce094abcf7f68c3450a1d4e3a8e917dd621edb4ebe09060200160405180910390a150565b610ca2610ff9565b5115610d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016105f9565b610d138161133e565b50565b5f600154341015610d60576001546040517fb489782800000000000000000000000000000000000000000000000000000000815234600482015260248101919091526044016105f9565b610d6a3383610f4d565b335f908152600360205260408120805492935090610d878361208a565b909155505060046020525f81815260408082207f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed80546001830181905590859055808452918320849055600280547f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec94929392909190610e068361208a565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f4bda649efe6b98b0f9c1d5e859c29e20910f45c66dabfe6fad4a4881f7faf9cc8587604051610e53929190611f93565b60405180910390a2505050919050565b6060610e6e33610ada565b80610e8c575033730576a174d229e3cfa37253523e645a78a0c91b57145b610f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b5f610f32878787878715610f2c57876114b3565b5a6114b3565b9250905080610f4357815160208301fd5b5095945050505050565b5f8282604051602001610f619291906120dc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6004602052815f5260405f208160028110610fb7575f80fd5b01549150829050565b5f80610fca610ff9565b80602001905181019061090e91906120c1565b5f805f610fec878787876115b6565b91509150610f438161169e565b60606110c86110c36040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b611850565b905090565b33730576a174d229e3cfa37253523e645a78a0c91b571461114a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016105f9565b565b5f806111a4836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018290525f90605c01604051602081830303815290604052805190602001209050919050565b90507f1626ba7e00000000000000000000000000000000000000000000000000000000611212826111d9610140880188612016565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061077192505050565b7fffffffff00000000000000000000000000000000000000000000000000000000161461124357600191505061090e565b505f9392505050565b5f80546020830135918061125f8361208a565b9190505514610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c6964206e6f6e63650000000000000000000000000000000000000060448201526064016105f9565b8015610d13576040515f9033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d805f8114611332576040519150601f19603f3d011682016040523d82523d5f602084013e611337565b606091505b5050505050565b5f611348826118a5565b90505f8151602083015ff0905061141a6040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146114ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5772697465206661696c6564000000000000000000000000000000000000000060448201526064016105f9565b505050565b5f606060018460018111156114ca576114ca61210a565b0361153e578673ffffffffffffffffffffffffffffffffffffffff1683866040516114f59190612137565b5f604051808303818686f4925050503d805f811461152e576040519150601f19603f3d011682016040523d82523d5f602084013e611533565b606091505b5090925090506115ac565b8673ffffffffffffffffffffffffffffffffffffffff168387876040516115659190612137565b5f60405180830381858888f193505050503d805f81146115a0576040519150601f19603f3d011682016040523d82523d5f602084013e6115a5565b606091505b5090925090505b9550959350505050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156115eb57505f90506003611695565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561163c573d5f803e3d5ffd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661168f575f60019250925050611695565b91505f90505b94509492505050565b5f8160048111156116b1576116b161210a565b036116b95750565b60018160048111156116cd576116cd61210a565b03611734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105f9565b60028160048111156117485761174861210a565b036117af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105f9565b60038160048111156117c3576117c361210a565b03610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105f9565b6060813b6001811161187157505060408051602081019091525f8152919050565b8061187b81611f5f565b9150506040519150601f19601f602083010116820160405280825280600160208401853c50919050565b6060815160016118b59190612077565b826040516020016118c7929190612152565b6040516020818303038152906040529050919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d13575f80fd5b5f8083601f84011261190e575f80fd5b50813567ffffffffffffffff811115611925575f80fd5b60208301915083602082850101111561193c575f80fd5b9250929050565b5f805f805f805f8060c0898b03121561195a575f80fd5b8835611965816118dd565b97506020890135611975816118dd565b96506040890135611985816118dd565b955060608901359450608089013567ffffffffffffffff808211156119a8575f80fd5b6119b48c838d016118fe565b909650945060a08b01359150808211156119cc575f80fd5b506119d98b828c016118fe565b999c989b5096995094979396929594505050565b5f805f805f60808688031215611a01575f80fd5b8535611a0c816118dd565b94506020860135611a1c816118dd565b935060408601359250606086013567ffffffffffffffff811115611a3e575f80fd5b611a4a888289016118fe565b969995985093965092949392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112611a97575f80fd5b813567ffffffffffffffff80821115611ab257611ab2611a5b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611af857611af8611a5b565b81604052838152866020858801011115611b10575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f8060408385031215611b40575f80fd5b82359150602083013567ffffffffffffffff811115611b5d575f80fd5b611b6985828601611a88565b9150509250929050565b5f805f60608486031215611b85575f80fd5b833567ffffffffffffffff811115611b9b575f80fd5b84016101608187031215611bad575f80fd5b95602085013595506040909401359392505050565b5f8060408385031215611bd3575f80fd5b50508035926020909101359150565b602080825282518282018190525f9190848201906040850190845b81811015611c1957835183529284019291840191600101611bfd565b50909695505050505050565b5f60208284031215611c35575f80fd5b8135610931816118dd565b5f60208284031215611c50575f80fd5b5035919050565b5f60208284031215611c67575f80fd5b813567ffffffffffffffff811115611c7d575f80fd5b611c8984828501611a88565b949350505050565b5f8083601f840112611ca1575f80fd5b50813567ffffffffffffffff811115611cb8575f80fd5b6020830191508360208260051b850101111561193c575f80fd5b5f805f805f805f8060a0898b031215611ce9575f80fd5b8835611cf4816118dd565b97506020890135611d04816118dd565b9650604089013567ffffffffffffffff80821115611d20575f80fd5b611d2c8c838d01611c91565b909850965060608b0135915080821115611d44575f80fd5b611d508c838d01611c91565b909650945060808b01359150808211156119cc575f80fd5b5f805f805f60a08688031215611d7c575f80fd5b8535611d87816118dd565b945060208601359350604086013567ffffffffffffffff811115611da9575f80fd5b611db588828901611a88565b935050606086013560028110611dc9575f80fd5b949793965091946080013592915050565b5f5b83811015611df4578181015183820152602001611ddc565b50505f910152565b5f8151808452611e13816020860160208601611dda565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081525f6109316020830184611dfc565b5f8060408385031215611e68575f80fd5b8235611e73816118dd565b9150602083013567ffffffffffffffff811115611b5d575f80fd5b5f805f805f8060a08789031215611ea3575f80fd5b8635611eae816118dd565b95506020870135611ebe816118dd565b94506040870135935060608701359250608087013567ffffffffffffffff811115611ee7575f80fd5b611ef389828a016118fe565b979a9699509497509295939492505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f81611f6d57611f6d611f32565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b828152604060208201525f611c896040830184611dfc565b5f60208284031215611fbb575f80fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114610931575f80fd5b5f8060408385031215611ffb575f80fd5b8251612006816118dd565b6020939093015192949293505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612049575f80fd5b83018035915067ffffffffffffffff821115612063575f80fd5b60200191503681900382131561193c575f80fd5b8082018082111561090e5761090e611f32565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036120ba576120ba611f32565b5060010190565b5f602082840312156120d1575f80fd5b8151610931816118dd565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f611c896040830184611dfc565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f8251612148818460208701611dda565b9190910192915050565b7f630000000000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008360e01b1660018201527f80600e6000396000f3000000000000000000000000000000000000000000000060058201525f600e8201525f82516121e081600f850160208701611dda565b91909101600f01939250505056fea2646970667358221220c1913351e275e1fecd00c79cd676ed135b575df5d3a88ccc57419dc3081980a264736f6c63430008150033", - "deployedBytecode": "0x60806040526004361061017a575f3560e01c8063a035b1fe116100d1578063bdf863171161007c578063f23a6e6111610057578063f23a6e61146104d2578063f6171e4414610517578063fc0c546a14610536575f80fd5b8063bdf8631714610472578063c7dec3fc14610487578063e00b9118146104b3575f80fd5b8063b0d691fe116100ac578063b0d691fe146103d1578063b94207d314610418578063bc197c811461042b575f80fd5b8063a035b1fe1461038a578063a4f9edbf1461039f578063affed0e0146103be575f80fd5b80633a871cdd116101315780636d70f7ae1161010c5780636d70f7ae146102fb5780637af734731461032a57806391b7f5ed1461036b575f80fd5b80633a871cdd1461028557806358ce0909146102a45780635fee6085146102d0575f80fd5b8063157305fe11610161578063157305fe146102255780631626ba7e1461024457806317d70f7c14610263575f80fd5b806223de2914610185578063150b7a02146101ab575f80fd5b3661018157005b5f80fd5b348015610190575f80fd5b506101a961019f366004611943565b5050505050505050565b005b3480156101b6575f80fd5b506101ef6101c53660046119ed565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b348015610230575f80fd5b506101a961023f366004611b2f565b61054a565b34801561024f575f80fd5b506101ef61025e366004611b2f565b610771565b34801561026e575f80fd5b50610277610914565b60405190815260200161021c565b348015610290575f80fd5b5061027761029f366004611b73565b610938565b3480156102af575f80fd5b506102c36102be366004611bc2565b610974565b60405161021c9190611be2565b3480156102db575f80fd5b506102776102ea366004611c25565b60036020525f908152604090205481565b348015610306575f80fd5b5061031a610315366004611c25565b610ada565b604051901515815260200161021c565b348015610335575f80fd5b50610277610344366004611c25565b73ffffffffffffffffffffffffffffffffffffffff165f9081526003602052604090205490565b348015610376575f80fd5b506101a9610385366004611c40565b610bac565b348015610395575f80fd5b5061027760015481565b3480156103aa575f80fd5b506101a96103b9366004611c57565b610c9a565b3480156103c9575f80fd5b505f54610277565b3480156103dc575f80fd5b50730576a174d229e3cfa37253523e645a78a0c91b575b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021c565b610277610426366004611c57565b610d16565b348015610436575f80fd5b506101ef610445366004611cd2565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561047d575f80fd5b5061027760025481565b348015610492575f80fd5b506104a66104a1366004611d68565b610e63565b60405161021c9190611e45565b3480156104be575f80fd5b506102776104cd366004611e57565b610f4d565b3480156104dd575f80fd5b506101ef6104ec366004611e8e565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b348015610522575f80fd5b50610277610531366004611bc2565b610f9e565b348015610541575f80fd5b506103f3610fc0565b61055333610ada565b80610571575033730576a174d229e3cfa37253523e645a78a0c91b57145b610602576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084015b60405180910390fd5b5f828152600460205260408082208151808301928390529160029082845b8154815260200190600101908083116106205750505050509050805f6002811061064c5761064c611f05565b602002015115801561066057506020810151155b801561069557505f805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed548314155b156106cf576040517ffe239804000000000000000000000000000000000000000000000000000000008152600481018490526024016105f9565b6020818101805183515f908152600490935260408084206001908101929092558451925184528084209290925585835290822082815501819055600280549161071783611f5f565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f0cd979445339c62199996f208428d987b1cea24d18e62b79ec24d94b636e8b708484604051610764929190611f93565b60405180910390a2505050565b5f805f8061079185602081015160408201516060909201515f1a92909190565b9094509250905060ff81165f036108a757828583016020016107b282610ada565b1580156107d5575073ffffffffffffffffffffffffffffffffffffffff82163014155b1561080857507fffffffff00000000000000000000000000000000000000000000000000000000945061090e9350505050565b6040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831690631626ba7e9061085c908b908590600401611f93565b602060405180830381865afa158015610877573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061089b9190611fab565b9550505050505061090e565b6108b661031587838686610fdd565b156108e757507f1626ba7e00000000000000000000000000000000000000000000000000000000925061090e915050565b507fffffffff00000000000000000000000000000000000000000000000000000000925050505b92915050565b5f8061091e610ff9565b8060200190518101906109319190611fea565b9392505050565b5f6109416110cd565b61094b848461114c565b905061095a6040850185612016565b90505f0361096b5761096b8461124c565b610931826112ca565b6002546060905f849003610986578093505b806109918486612077565b11156109de576109a18385612077565b6040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016105f9565b8315610ad3578367ffffffffffffffff8111156109fd576109fd611a5b565b604051908082528060200260200182016040528015610a26578160200160208202803683370190505b505f80805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed549193505b84811015610a81575f828152600460205260409020600101549150610a7a8161208a565b9050610a56565b505f5b85811015610ad05781848281518110610a9f57610a9f611f05565b6020908102919091018101919091525f9283526004905260409091206001015490610ac98161208a565b9050610a84565b50505b5092915050565b5f805f610ae5610ff9565b806020019051810190610af89190611fea565b915091508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610b4e91815260200190565b602060405180830381865afa158015610b69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b8d91906120c1565b73ffffffffffffffffffffffffffffffffffffffff1614949350505050565b610bb533610ada565b80610bd3575033730576a174d229e3cfa37253523e645a78a0c91b57145b610c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b60018190556040518181527f66cbca4f3c64fecf1dcb9ce094abcf7f68c3450a1d4e3a8e917dd621edb4ebe09060200160405180910390a150565b610ca2610ff9565b5115610d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016105f9565b610d138161133e565b50565b5f600154341015610d60576001546040517fb489782800000000000000000000000000000000000000000000000000000000815234600482015260248101919091526044016105f9565b610d6a3383610f4d565b335f908152600360205260408120805492935090610d878361208a565b909155505060046020525f81815260408082207f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed80546001830181905590859055808452918320849055600280547f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec94929392909190610e068361208a565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f4bda649efe6b98b0f9c1d5e859c29e20910f45c66dabfe6fad4a4881f7faf9cc8587604051610e53929190611f93565b60405180910390a2505050919050565b6060610e6e33610ada565b80610e8c575033730576a174d229e3cfa37253523e645a78a0c91b57145b610f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b5f610f32878787878715610f2c57876114b3565b5a6114b3565b9250905080610f4357815160208301fd5b5095945050505050565b5f8282604051602001610f619291906120dc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6004602052815f5260405f208160028110610fb7575f80fd5b01549150829050565b5f80610fca610ff9565b80602001905181019061090e91906120c1565b5f805f610fec878787876115b6565b91509150610f438161169e565b60606110c86110c36040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b611850565b905090565b33730576a174d229e3cfa37253523e645a78a0c91b571461114a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016105f9565b565b5f806111a4836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018290525f90605c01604051602081830303815290604052805190602001209050919050565b90507f1626ba7e00000000000000000000000000000000000000000000000000000000611212826111d9610140880188612016565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061077192505050565b7fffffffff00000000000000000000000000000000000000000000000000000000161461124357600191505061090e565b505f9392505050565b5f80546020830135918061125f8361208a565b9190505514610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c6964206e6f6e63650000000000000000000000000000000000000060448201526064016105f9565b8015610d13576040515f9033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d805f8114611332576040519150601f19603f3d011682016040523d82523d5f602084013e611337565b606091505b5050505050565b5f611348826118a5565b90505f8151602083015ff0905061141a6040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146114ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5772697465206661696c6564000000000000000000000000000000000000000060448201526064016105f9565b505050565b5f606060018460018111156114ca576114ca61210a565b0361153e578673ffffffffffffffffffffffffffffffffffffffff1683866040516114f59190612137565b5f604051808303818686f4925050503d805f811461152e576040519150601f19603f3d011682016040523d82523d5f602084013e611533565b606091505b5090925090506115ac565b8673ffffffffffffffffffffffffffffffffffffffff168387876040516115659190612137565b5f60405180830381858888f193505050503d805f81146115a0576040519150601f19603f3d011682016040523d82523d5f602084013e6115a5565b606091505b5090925090505b9550959350505050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156115eb57505f90506003611695565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561163c573d5f803e3d5ffd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661168f575f60019250925050611695565b91505f90505b94509492505050565b5f8160048111156116b1576116b161210a565b036116b95750565b60018160048111156116cd576116cd61210a565b03611734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105f9565b60028160048111156117485761174861210a565b036117af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105f9565b60038160048111156117c3576117c361210a565b03610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105f9565b6060813b6001811161187157505060408051602081019091525f8152919050565b8061187b81611f5f565b9150506040519150601f19601f602083010116820160405280825280600160208401853c50919050565b6060815160016118b59190612077565b826040516020016118c7929190612152565b6040516020818303038152906040529050919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d13575f80fd5b5f8083601f84011261190e575f80fd5b50813567ffffffffffffffff811115611925575f80fd5b60208301915083602082850101111561193c575f80fd5b9250929050565b5f805f805f805f8060c0898b03121561195a575f80fd5b8835611965816118dd565b97506020890135611975816118dd565b96506040890135611985816118dd565b955060608901359450608089013567ffffffffffffffff808211156119a8575f80fd5b6119b48c838d016118fe565b909650945060a08b01359150808211156119cc575f80fd5b506119d98b828c016118fe565b999c989b5096995094979396929594505050565b5f805f805f60808688031215611a01575f80fd5b8535611a0c816118dd565b94506020860135611a1c816118dd565b935060408601359250606086013567ffffffffffffffff811115611a3e575f80fd5b611a4a888289016118fe565b969995985093965092949392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112611a97575f80fd5b813567ffffffffffffffff80821115611ab257611ab2611a5b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611af857611af8611a5b565b81604052838152866020858801011115611b10575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f8060408385031215611b40575f80fd5b82359150602083013567ffffffffffffffff811115611b5d575f80fd5b611b6985828601611a88565b9150509250929050565b5f805f60608486031215611b85575f80fd5b833567ffffffffffffffff811115611b9b575f80fd5b84016101608187031215611bad575f80fd5b95602085013595506040909401359392505050565b5f8060408385031215611bd3575f80fd5b50508035926020909101359150565b602080825282518282018190525f9190848201906040850190845b81811015611c1957835183529284019291840191600101611bfd565b50909695505050505050565b5f60208284031215611c35575f80fd5b8135610931816118dd565b5f60208284031215611c50575f80fd5b5035919050565b5f60208284031215611c67575f80fd5b813567ffffffffffffffff811115611c7d575f80fd5b611c8984828501611a88565b949350505050565b5f8083601f840112611ca1575f80fd5b50813567ffffffffffffffff811115611cb8575f80fd5b6020830191508360208260051b850101111561193c575f80fd5b5f805f805f805f8060a0898b031215611ce9575f80fd5b8835611cf4816118dd565b97506020890135611d04816118dd565b9650604089013567ffffffffffffffff80821115611d20575f80fd5b611d2c8c838d01611c91565b909850965060608b0135915080821115611d44575f80fd5b611d508c838d01611c91565b909650945060808b01359150808211156119cc575f80fd5b5f805f805f60a08688031215611d7c575f80fd5b8535611d87816118dd565b945060208601359350604086013567ffffffffffffffff811115611da9575f80fd5b611db588828901611a88565b935050606086013560028110611dc9575f80fd5b949793965091946080013592915050565b5f5b83811015611df4578181015183820152602001611ddc565b50505f910152565b5f8151808452611e13816020860160208601611dda565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081525f6109316020830184611dfc565b5f8060408385031215611e68575f80fd5b8235611e73816118dd565b9150602083013567ffffffffffffffff811115611b5d575f80fd5b5f805f805f8060a08789031215611ea3575f80fd5b8635611eae816118dd565b95506020870135611ebe816118dd565b94506040870135935060608701359250608087013567ffffffffffffffff811115611ee7575f80fd5b611ef389828a016118fe565b979a9699509497509295939492505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f81611f6d57611f6d611f32565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b828152604060208201525f611c896040830184611dfc565b5f60208284031215611fbb575f80fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114610931575f80fd5b5f8060408385031215611ffb575f80fd5b8251612006816118dd565b6020939093015192949293505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612049575f80fd5b83018035915067ffffffffffffffff821115612063575f80fd5b60200191503681900382131561193c575f80fd5b8082018082111561090e5761090e611f32565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036120ba576120ba611f32565b5060010190565b5f602082840312156120d1575f80fd5b8151610931816118dd565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f611c896040830184611dfc565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f8251612148818460208701611dda565b9190910192915050565b7f630000000000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008360e01b1660018201527f80600e6000396000f3000000000000000000000000000000000000000000000060058201525f600e8201525f82516121e081600f850160208701611dda565b91909101600f01939250505056fea2646970667358221220c1913351e275e1fecd00c79cd676ed135b575df5d3a88ccc57419dc3081980a264736f6c63430008150033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/mech_marketplace/contract.py b/trader_backup/vendor/valory/contracts/mech_marketplace/contract.py deleted file mode 100644 index 33e5a91cc..000000000 --- a/trader_backup/vendor/valory/contracts/mech_marketplace/contract.py +++ /dev/null @@ -1,260 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the class to connect to a Mech Marketplace contract.""" - -import concurrent.futures -from typing import Any, Callable, Dict, List, cast - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi -from eth_typing import HexStr -from web3.types import BlockData, BlockIdentifier, EventData, TxReceipt - - -PUBLIC_ID = PublicId.from_str("valory/mech_marketplace:0.1.0") -FIVE_MINUTES = 300.0 - - - -class MechMarketplace(Contract): - """The Mech Marketplace contract.""" - - contract_id = PUBLIC_ID - - @staticmethod - def execute_with_timeout(func: Callable, timeout: float) -> Any: - """Execute a function with a timeout.""" - - # Create a ProcessPoolExecutor with a maximum of 1 worker (process) - with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: - # Submit the function to the executor - future = executor.submit( - func, - ) - - try: - # Wait for the result with a 5-minute timeout - data = future.result(timeout=timeout) - except TimeoutError: - # Handle the case where the execution times out - err = f"The RPC didn't respond in {timeout}." - return None, err - - # Check if an error occurred - if isinstance(data, str): - # Handle the case where the execution failed - return None, data - - return data, None - - @classmethod - def get_request_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - request_data: bytes, - priority_mech: str, - priority_mech_staking_instance: str, - priority_mech_service_id: int, - requester_staking_instance: str, - requester_service_id: int, - response_timeout: int, - **kwargs: Any - ) -> Dict[str, bytes]: - """Gets the encoded arguments for a request tx, which should only be called via the multisig. - - :param ledger_api: the ledger API object - :param contract_address: the contract's address - :param request_data: the request data - :param priority_mech: the priority mech address - :param priority_mech_staking_instance: the priority mech staking instance address - :param priority_mech_service_id: the priority mech service id - :param requester_staking_instance: the requester staking instance address - :param requester_service_id: the requester service id - :param response_timeout: the response timeout - """ - contract_address = ledger_api.api.to_checksum_address(contract_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - encoded_data = contract_instance.encodeABI( - fn_name="request", - args=( - request_data, - priority_mech, - priority_mech_staking_instance, - priority_mech_service_id, - requester_staking_instance, - requester_service_id, - response_timeout, - ) - ) - return {"data": bytes.fromhex(encoded_data[2:])} - - @classmethod - def _process_event( - cls, - ledger_api: LedgerApi, - contract: Any, - tx_hash: HexStr, - expected_logs: int, - event_name: str, - *args: Any, - **kwargs: Any - ) -> JSONLike: - """Process the logs of the given event.""" - ledger_api = cast(EthereumApi, ledger_api) - receipt: TxReceipt = ledger_api.api.eth.get_transaction_receipt(tx_hash) - event_method = getattr(contract.events, event_name) - logs: List[EventData] = list(event_method().process_receipt(receipt)) - - n_logs = len(logs) - if n_logs != expected_logs: - error = f"{expected_logs} {event_name!r} events were expected. tx {tx_hash} emitted {n_logs} instead." - return {"error": error} - - results = [] - for log in logs: - event_args = log.get("args", None) - if event_args is None or any( - expected_key not in event_args for expected_key in args - ): - return {"error": f"The emitted event's ({event_name}) logs for tx {tx_hash} do not match the expected format: {log}"} - results.append({arg_name: event_args[arg_name] for arg_name in args}) - - return dict(results=results) - - @classmethod - def process_request_event( - cls, - ledger_api: LedgerApi, - contract_address: str, - tx_hash: HexStr, - expected_logs: int = 1, - **kwargs: Any - ) -> JSONLike: - """ - Process the request receipt to get the requestId and the given data from the `Request` event's logs. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param tx_hash: the hash of a request tx to be processed. - :param expected_logs: the number of logs expected. - :return: a dictionary with a key named `results` - which contains a list of dictionaries (as many as the expected logs) containing the request id and the data. - """ - contract_address = ledger_api.api.to_checksum_address(contract_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - res = cls._process_event( - ledger_api, contract_instance, tx_hash, expected_logs, "MarketplaceRequest", "requestId", "data" - ) - - return res - - @classmethod - def process_deliver_event( - cls, - ledger_api: LedgerApi, - contract_address: str, - tx_hash: HexStr, - expected_logs: int = 1, - **kwargs: Any - ) -> JSONLike: - """ - Process the request receipt to get the requestId and the delivered data if the `MarketplaceDeliver` event has been emitted. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param tx_hash: the hash of a request tx to be processed. - :param expected_logs: the number of logs expected. - :return: a dictionary with the request id and the data. - """ - contract_address = ledger_api.api.to_checksum_address(contract_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - res = cls._process_event( - ledger_api, contract_instance, tx_hash, expected_logs, "MarketplaceDeliver", "requestId", "data" - ) - - return res - - @classmethod - def get_block_number( - cls, - ledger_api: EthereumApi, - contract_address: str, - tx_hash: HexStr, - **kwargs: Any - ) -> JSONLike: - """Get the number of the block in which the tx of the given hash was settled.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - receipt: TxReceipt = ledger_api.api.eth.get_transaction_receipt(tx_hash) - block: BlockData = ledger_api.api.eth.get_block(receipt["blockNumber"]) - return dict(number=block["number"]) - - @classmethod - def get_response( - cls, - ledger_api: LedgerApi, - contract_address: str, - request_id: int, - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - timeout: float = FIVE_MINUTES, - **kwargs: Any - ) -> JSONLike: - """Filter the `MarketplaceDeliver` events emitted by the contract and get the data of the given `request_id`.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - ledger_api = cast(EthereumApi, ledger_api) - - def get_responses() -> Any: - """Get the responses from the contract.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - deliver_filter = contract_instance.events.MarketplaceDeliver.build_filter() - deliver_filter.fromBlock = from_block - deliver_filter.toBlock = to_block - deliver_filter.args.requestId.match_single(request_id) - delivered = list(deliver_filter.deploy(ledger_api.api).get_all_entries()) - n_delivered = len(delivered) - - if n_delivered == 0: - info = f"The mech ({contract_address}) has not delivered a response yet for request with id {request_id}." - return {"info": info} - - if n_delivered != 1: - error = ( - f"A single response was expected by the mech ({contract_address}) for request with id {request_id}. " - f"Received {n_delivered} responses: {delivered}." - ) - return error - - delivered_event = delivered.pop() - deliver_args = delivered_event.get("args", None) - if deliver_args is None or "data" not in deliver_args: - error = f"The mech's response does not match the expected format: {delivered_event}" - return error - - return dict(data=deliver_args["data"]) - - data, err = cls.execute_with_timeout(get_responses, timeout=timeout) - if err is not None: - return {"error": err} - - return data diff --git a/trader_backup/vendor/valory/contracts/mech_marketplace/contract.yaml b/trader_backup/vendor/valory/contracts/mech_marketplace/contract.yaml deleted file mode 100644 index d41799bd0..000000000 --- a/trader_backup/vendor/valory/contracts/mech_marketplace/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: mech_marketplace -author: valory -version: 0.1.0 -type: contract -description: Agent mech marketplace contract. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeihygfmkbo4cegrqnz5ws6bbjaifubvk7r2uyvuanxpqy24l634tba - __init__.py: bafybeie6625ddrcph7pcxef4fbfcuhyd6yuzdyyqcoqpc5xdjb4rttw7my - build/mech.json: bafybeif2doizav5rs5hig6bruaoz2bedlyesyh23s735llblh64vazespi - contract.py: bafybeiawzcqvkx7tip7tck2czf47d5rnolebmet3fbmv5p4hzpv3fmarwq -fingerprint_ignore_patterns: [] -contracts: [] -class_name: MechMarketplace -contract_interface_paths: - ethereum: build/mech.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - web3: - version: <7,>=6.0.0 - eth_typing: {} diff --git a/trader_backup/vendor/valory/contracts/multisend/README.md b/trader_backup/vendor/valory/contracts/multisend/README.md deleted file mode 100644 index 6570c37f7..000000000 --- a/trader_backup/vendor/valory/contracts/multisend/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# `Multisend` contract - -## Description - -## Functions - diff --git a/trader_backup/vendor/valory/contracts/multisend/__init__.py b/trader_backup/vendor/valory/contracts/multisend/__init__.py deleted file mode 100644 index 218a7d8df..000000000 --- a/trader_backup/vendor/valory/contracts/multisend/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the support resources for the multisend (MultiSend) contract.""" diff --git a/trader_backup/vendor/valory/contracts/multisend/build/MultiSend.json b/trader_backup/vendor/valory/contracts/multisend/build/MultiSend.json deleted file mode 100644 index aa4031f87..000000000 --- a/trader_backup/vendor/valory/contracts/multisend/build/MultiSend.json +++ /dev/null @@ -1,358 +0,0 @@ -{ - "contractName": "MultiSend", - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "transactions", - "type": "bytes" - } - ], - "name": "multiSend", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b506101a3806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80638d80ff0a14610030575b600080fd5b6100e96004803603602081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184600183028401116401000000008311171561009757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100eb565b005b805160205b81811015610172578083015160f81c6001820184015160601c601583018501516035840186015160558501870160008560008114610135576001811461014557610150565b6000808585888a5af19150610150565b6000808585895af491505b50600081141561015f57600080fd5b82605501870196505050505050506100f0565b50505056fea165627a7a72305820006744fee21c3396bfcae6ec5f76f06721713e70e465c0041ecbe4c6435633550029", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80638d80ff0a14610030575b600080fd5b6100e96004803603602081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184600183028401116401000000008311171561009757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100eb565b005b805160205b81811015610172578083015160f81c6001820184015160601c601583018501516035840186015160558501870160008560008114610135576001811461014557610150565b6000808585888a5af19150610150565b6000808585895af491505b50600081141561015f57600080fd5b82605501870196505050505050506100f0565b50505056fea165627a7a72305820006744fee21c3396bfcae6ec5f76f06721713e70e465c0041ecbe4c6435633550029", - "sourceMap": "304:2438:18:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;304:2438:18;;;;;;;", - "deployedSourceMap": "304:2438:18:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;304:2438:18;;;;;;;;;;;;;;;;;;;925:1815;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;925:1815:18;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;925:1815:18;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;925:1815:18;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;925:1815:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;925:1815:18;;;;;;;;;;;;;;;:::i;:::-;;;1107:12;1101:19;1142:4;1159:1565;1173:6;1170:1;1167:13;1159:1565;;;1494:1;1480:12;1476:20;1470:27;1464:4;1460:38;1768:4;1765:1;1761:12;1747;1743:31;1737:38;1731:4;1727:49;1930:4;1927:1;1923:12;1909;1905:31;1899:38;2113:4;2110:1;2106:12;2092;2088:31;2082:38;2307:4;2304:1;2300:12;2286;2282:31;2345:1;2370:9;2401:1;2396:66;;;;2484:1;2479:67;;;;2363:183;;2396:66;2458:1;2455;2443:10;2437:4;2430:5;2426:2;2421:3;2416:44;2405:55;;2396:66;;2479:67;2542:1;2539;2527:10;2521:4;2517:2;2512:3;2499:45;2488:56;;2363:183;;2578:1;2569:7;2566:14;2563:2;;;2593:1;2590;2583:12;2563:2;2698:10;2692:4;2688:21;2685:1;2681:29;2676:34;;1185:1539;;;;;;1159:1565;;;1073:1661;;;:::o", - "source": "pragma solidity ^0.5.0;\n\n\n/// @title Multi Send - Allows to batch multiple transactions into one.\n/// @author Nick Dodson - \n/// @author Gonçalo Sá - \n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract MultiSend {\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions)\n public\n {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes]) to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas, to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas, to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n}\n", - "sourcePath": "/home/uxio/gnosis/dev/safe-contracts/contracts/libraries/MultiSend.sol", - "ast": { - "absolutePath": "/home/uxio/gnosis/dev/safe-contracts/contracts/libraries/MultiSend.sol", - "exportedSymbols": { - "MultiSend": [ - 2276 - ] - }, - "id": 2277, - "nodeType": "SourceUnit", - "nodes": [ - { - "id": 2268, - "literals": [ - "solidity", - "^", - "0.5", - ".0" - ], - "nodeType": "PragmaDirective", - "src": "0:23:18" - }, - { - "baseContracts": [], - "contractDependencies": [], - "contractKind": "contract", - "documentation": "@title Multi Send - Allows to batch multiple transactions into one.\n @author Nick Dodson - \n @author Gonçalo Sá - \n @author Stefan George - \n @author Richard Meissner - ", - "fullyImplemented": true, - "id": 2276, - "linearizedBaseContracts": [ - 2276 - ], - "name": "MultiSend", - "nodeType": "ContractDefinition", - "nodes": [ - { - "body": { - "id": 2274, - "nodeType": "Block", - "src": "990:1750:18", - "statements": [ - { - "externalReferences": [ - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1107:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1480:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1747:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1909:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "2092:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "2286:12:18", - "valueSize": 1 - } - } - ], - "id": 2273, - "nodeType": "InlineAssembly", - "operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let operation := shr(0xf8, mload(add(transactions, i)))\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n let value := mload(add(transactions, add(i, 0x15)))\n let dataLength := mload(add(transactions, add(i, 0x35)))\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n case 1 {\n success := delegatecall(gas(), to, data, dataLength, 0, 0)\n }\n if eq(success, 0)\n {\n revert(0, 0)\n }\n i := add(i, add(0x55, dataLength))\n }\n}", - "src": "1064:1676:18" - } - ] - }, - "documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n to as a address (=> 20 bytes),\n value as a uint256 (=> 32 bytes),\n data length as a uint256 (=> 32 bytes),\n data as bytes.\n see abi.encodePacked for more information on packed encoding", - "id": 2275, - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "multiSend", - "nodeType": "FunctionDefinition", - "parameters": { - "id": 2271, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2270, - "name": "transactions", - "nodeType": "VariableDeclaration", - "scope": 2275, - "src": "944:25:18", - "stateVariable": false, - "storageLocation": "memory", - "typeDescriptions": { - "typeIdentifier": "t_bytes_memory_ptr", - "typeString": "bytes" - }, - "typeName": { - "id": 2269, - "name": "bytes", - "nodeType": "ElementaryTypeName", - "src": "944:5:18", - "typeDescriptions": { - "typeIdentifier": "t_bytes_storage_ptr", - "typeString": "bytes" - } - }, - "value": null, - "visibility": "internal" - } - ], - "src": "943:27:18" - }, - "returnParameters": { - "id": 2272, - "nodeType": "ParameterList", - "parameters": [], - "src": "990:0:18" - }, - "scope": 2276, - "src": "925:1815:18", - "stateMutability": "nonpayable", - "superFunction": null, - "visibility": "public" - } - ], - "scope": 2277, - "src": "304:2438:18" - } - ], - "src": "0:2743:18" - }, - "legacyAST": { - "absolutePath": "/home/uxio/gnosis/dev/safe-contracts/contracts/libraries/MultiSend.sol", - "exportedSymbols": { - "MultiSend": [ - 2276 - ] - }, - "id": 2277, - "nodeType": "SourceUnit", - "nodes": [ - { - "id": 2268, - "literals": [ - "solidity", - "^", - "0.5", - ".0" - ], - "nodeType": "PragmaDirective", - "src": "0:23:18" - }, - { - "baseContracts": [], - "contractDependencies": [], - "contractKind": "contract", - "documentation": "@title Multi Send - Allows to batch multiple transactions into one.\n @author Nick Dodson - \n @author Gonçalo Sá - \n @author Stefan George - \n @author Richard Meissner - ", - "fullyImplemented": true, - "id": 2276, - "linearizedBaseContracts": [ - 2276 - ], - "name": "MultiSend", - "nodeType": "ContractDefinition", - "nodes": [ - { - "body": { - "id": 2274, - "nodeType": "Block", - "src": "990:1750:18", - "statements": [ - { - "externalReferences": [ - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1107:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1480:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1747:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1909:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "2092:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "2286:12:18", - "valueSize": 1 - } - } - ], - "id": 2273, - "nodeType": "InlineAssembly", - "operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let operation := shr(0xf8, mload(add(transactions, i)))\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n let value := mload(add(transactions, add(i, 0x15)))\n let dataLength := mload(add(transactions, add(i, 0x35)))\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n case 1 {\n success := delegatecall(gas(), to, data, dataLength, 0, 0)\n }\n if eq(success, 0)\n {\n revert(0, 0)\n }\n i := add(i, add(0x55, dataLength))\n }\n}", - "src": "1064:1676:18" - } - ] - }, - "documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n to as a address (=> 20 bytes),\n value as a uint256 (=> 32 bytes),\n data length as a uint256 (=> 32 bytes),\n data as bytes.\n see abi.encodePacked for more information on packed encoding", - "id": 2275, - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "multiSend", - "nodeType": "FunctionDefinition", - "parameters": { - "id": 2271, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2270, - "name": "transactions", - "nodeType": "VariableDeclaration", - "scope": 2275, - "src": "944:25:18", - "stateVariable": false, - "storageLocation": "memory", - "typeDescriptions": { - "typeIdentifier": "t_bytes_memory_ptr", - "typeString": "bytes" - }, - "typeName": { - "id": 2269, - "name": "bytes", - "nodeType": "ElementaryTypeName", - "src": "944:5:18", - "typeDescriptions": { - "typeIdentifier": "t_bytes_storage_ptr", - "typeString": "bytes" - } - }, - "value": null, - "visibility": "internal" - } - ], - "src": "943:27:18" - }, - "returnParameters": { - "id": 2272, - "nodeType": "ParameterList", - "parameters": [], - "src": "990:0:18" - }, - "scope": 2276, - "src": "925:1815:18", - "stateMutability": "nonpayable", - "superFunction": null, - "visibility": "public" - } - ], - "scope": 2277, - "src": "304:2438:18" - } - ], - "src": "0:2743:18" - }, - "compiler": { - "name": "solc", - "version": "0.5.7+commit.6da8b019.Emscripten.clang" - }, - "networks": {}, - "schemaVersion": "2.0.2", - "updatedAt": "2019-07-22T10:39:57.431Z" -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/multisend/contract.py b/trader_backup/vendor/valory/contracts/multisend/contract.py deleted file mode 100644 index 0082a6e61..000000000 --- a/trader_backup/vendor/valory/contracts/multisend/contract.py +++ /dev/null @@ -1,191 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the class to connect to an Gnosis Safe contract.""" -# heavily borrows from https://github.com/gnosis/gnosis-py/blob/51b41f5a8577a96e296b9b7e037491632cda9d8c/gnosis/safe/multi_send.py -import logging -from enum import Enum -from typing import Any, Dict, List, Optional, Tuple, cast - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from hexbytes import HexBytes -from web3 import Web3 - - -PUBLIC_ID = PublicId.from_str("valory/multisend:0.1.0") -MIN_GAS = MIN_GASPRICE = 1 - -_logger = logging.getLogger( - f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" -) - - -class MultiSendOperation(Enum): - """Operation types.""" - - CALL = 0 - DELEGATE_CALL = 1 - - -def encode_data(tx: Dict) -> bytes: - """Encodes multisend transaction.""" - operation = HexBytes( - "{:0>2x}".format(cast(MultiSendOperation, tx.get("operation")).value) - ) # Operation 1 byte - to = HexBytes( - "{:0>40x}".format(int(cast(str, tx.get("to")), 16)) - ) # Address 20 bytes - value = HexBytes("{:0>64x}".format(cast(int, tx.get("value")))) # Value 32 bytes - data = cast(bytes, tx.get("data", b"")) - data_ = HexBytes(data) - data_length = HexBytes("{:0>64x}".format(len(data_))) # Data length 32 bytes - return operation + to + value + data_length + data_ - - -def decode_data(encoded_tx: bytes) -> Tuple[Dict, int]: - """Decodes multisend transaction.""" - encoded_tx = HexBytes(encoded_tx) - operation = MultiSendOperation(encoded_tx[0]) - to = Web3.to_checksum_address(encoded_tx[1 : 1 + 20]) - value = int.from_bytes(encoded_tx[21 : 21 + 32], byteorder="big") - data_length = int.from_bytes(encoded_tx[21 + 32 : 21 + 32 * 2], byteorder="big") - data = encoded_tx[21 + 32 * 2 : 21 + 32 * 2 + data_length] - len_data = len(data) - if len_data != data_length: # pragma: nocover - raise ValueError( - f"Data length {data_length} is different from len(data) {len_data}" - ) - total_length = 21 + 32 * 2 + data_length - return ( - {"operation": operation, "to": to, "value": value, "data": data}, - total_length, - ) - - -def to_bytes(multi_send_txs: List[Dict]) -> bytes: - """Multi send tx list to bytes.""" - return b"".join([encode_data(tx) for tx in multi_send_txs]) - - -def from_bytes(encoded_multisend_txs: bytes) -> List[Dict]: - """Encoded multi send tx to list.""" - encoded_multisend_txs = HexBytes(encoded_multisend_txs) - next_data_position = 0 - txs = [] - while len(encoded_multisend_txs[next_data_position:]) > 0: - tx, total_length = decode_data(encoded_multisend_txs[next_data_position:]) - next_data_position += total_length - txs.append(tx) - return txs - - -class MultiSendContract(Contract): - """The MultiSend contract.""" - - contract_id = PUBLIC_ID - - @classmethod - def get_raw_transaction( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get the Safe transaction.""" - raise NotImplementedError - - @classmethod - def get_raw_message( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[bytes]: - """Get raw message.""" - raise NotImplementedError - - @classmethod - def get_state( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get state.""" - raise NotImplementedError - - @classmethod - def get_deploy_transaction( - cls, ledger_api: LedgerApi, deployer_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get deploy transaction.""" - raise NotImplementedError - - @classmethod - def get_tx_data( - cls, ledger_api: LedgerApi, contract_address: str, multi_send_txs: List[Dict] - ) -> Optional[JSONLike]: - """ - Get a multisend transaction data from list. - - :param ledger_api: ledger API object. - :param contract_address: the contract address. - :param multi_send_txs: the multisend transaction list. - :return: an optional JSON-like object. - """ - multisend_contract = cls.get_instance(ledger_api, contract_address) - encoded_multisend_data = to_bytes(multi_send_txs) - return { - "data": multisend_contract.functions.multiSend( - encoded_multisend_data - ).build_transaction({"gas": MIN_GAS, "gasPrice": MIN_GASPRICE})["data"] - } - - @classmethod - def get_multisend_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - txs: List[Dict], - ) -> Optional[JSONLike]: - """ - Get a multisend transaction data from list. - - :param ledger_api: ledger API object. - :param contract_address: the contract address. - :param txs: the multisend transaction list. - :return: an optional JSON-like object. - """ - multisend_contract = cls.get_instance(ledger_api, contract_address) - encoded_multisend_data = to_bytes(txs) - return multisend_contract.functions.multiSend( - encoded_multisend_data - ).build_transaction({"gas": MIN_GAS, "gasPrice": MIN_GASPRICE}) - - @classmethod - def get_tx_list( - cls, ledger_api: LedgerApi, contract_address: str, multi_send_data: str - ) -> Optional[JSONLike]: - """ - Get a multisend transaction list from encoded data. - - :param ledger_api: ledger API object. - :param contract_address: the contract address. - :param multi_send_data: the multisend transaction data. - :return: an optional JSON-like object. - """ - multisend_contract = cls.get_instance(ledger_api, contract_address) - _, encoded_multisend_data = multisend_contract.decode_function_input( - multi_send_data - ) - return {"tx_list": from_bytes(encoded_multisend_data["transactions"])} diff --git a/trader_backup/vendor/valory/contracts/multisend/contract.yaml b/trader_backup/vendor/valory/contracts/multisend/contract.yaml deleted file mode 100644 index 9128ba6ad..000000000 --- a/trader_backup/vendor/valory/contracts/multisend/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: multisend -author: valory -version: 0.1.0 -type: contract -description: MultiSend contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeidavn55z6uoz3hdjxs4ukvykl2tkvbntnl22uexfyk7unpnfqjflq - __init__.py: bafybeigzxw44dlgdb4qxhm6zul426uyxnqtlhe3oajivdyo3ue7kb45pai - build/MultiSend.json: bafybeicamzvsaaxtboijwfnv24ctrgv5v7gn5irnydnuf62y57o7fmx2jm - contract.py: bafybeid5h5sro6nt7jmr52ntqdwo4ajhdyxy5estq625gzvo3dbkjuzxia - tests/__init__.py: bafybeifd5zc6x3oxef7uy6mhjnt6oybna6ux7ycareqoqo52czkfxaeawm - tests/test_contract.py: bafybeid72mml6mvtv6qqr7r6a2nfbgbwpkhyitx5mmdtzcejt5zo7wcmje -fingerprint_ignore_patterns: [] -contracts: [] -class_name: MultiSendContract -contract_interface_paths: - ethereum: build/MultiSend.json -dependencies: - hexbytes: {} - web3: - version: <7,>=6.0.0 diff --git a/trader_backup/vendor/valory/contracts/multisend/tests/__init__.py b/trader_backup/vendor/valory/contracts/multisend/tests/__init__.py deleted file mode 100644 index 93954cfc8..000000000 --- a/trader_backup/vendor/valory/contracts/multisend/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/multisend contract.""" diff --git a/trader_backup/vendor/valory/contracts/multisend/tests/test_contract.py b/trader_backup/vendor/valory/contracts/multisend/tests/test_contract.py deleted file mode 100644 index a854239cf..000000000 --- a/trader_backup/vendor/valory/contracts/multisend/tests/test_contract.py +++ /dev/null @@ -1,125 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/gnosis contract.""" - -from pathlib import Path -from typing import Dict -from unittest import mock - -import pytest -from aea.contracts.base import Contract -from aea.crypto.base import Crypto, LedgerApi -from aea.crypto.registries import crypto_registry -from aea.test_tools.test_contract import BaseContractTestCase -from aea_ledger_ethereum import EthereumCrypto -from hexbytes import HexBytes - -from packages.valory.contracts.multisend.contract import ( - MultiSendContract, - MultiSendOperation, -) - - -PACKAGE_DIR = Path(__file__).parent.parent -CONTRACT_ADDRESS = "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2" -CHAIN_ID = 1 - - -class TestMultisendContract(BaseContractTestCase): - """Base test case for GnosisSafeContract""" - - path_to_contract = PACKAGE_DIR - ledger_identifier = EthereumCrypto.identifier - contract: MultiSendContract - tx_list = [ - { - "operation": MultiSendOperation.CALL, - "to": crypto_registry.make(EthereumCrypto.identifier).address, - "value": 1, - "data": HexBytes("0x123456789a"), - }, - { - "operation": MultiSendOperation.DELEGATE_CALL, - "to": crypto_registry.make(EthereumCrypto.identifier).address, - "value": 796, - "data": HexBytes("0x123456789a"), - }, - ] - - @classmethod - def finish_contract_deployment(cls) -> str: - """Finish the contract deployment.""" - contract_address = CONTRACT_ADDRESS - return contract_address - - @classmethod - def _deploy_contract( - cls, - contract: Contract, - ledger_api: LedgerApi, - deployer_crypto: Crypto, - gas: int, - ) -> Dict: - """Deploy contract.""" - return {} - - def test_non_implemented_methods( - self, - ) -> None: - """Test not implemented methods.""" - with pytest.raises(NotImplementedError): - self.contract.get_raw_transaction(self.ledger_api, "") - - with pytest.raises(NotImplementedError): - self.contract.get_raw_message(self.ledger_api, "") - - with pytest.raises(NotImplementedError): - self.contract.get_state(self.ledger_api, "") - - with pytest.raises(NotImplementedError): - self.contract.get_deploy_transaction(self.ledger_api, "") - - def test_get_tx_data_get_tx_list(self) -> None: - """Run end-to-end data conversion test.""" - assert self.contract_address is not None - with mock.patch.object( - self.ledger_api.api.manager, "request_blocking", return_value=CHAIN_ID - ): - result = self.contract.get_tx_data( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - multi_send_txs=self.tx_list, - ) - assert isinstance(result, dict) - assert "data" in result - data = result["data"] - assert isinstance(data, str) - assert len(data) > 0, "No data." - with mock.patch.object( - self.ledger_api.api.manager, "request_blocking", return_value=CHAIN_ID - ): - result = self.contract.get_tx_list( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - multi_send_data=data, - ) - assert isinstance(result, dict) - assert "tx_list" in result - assert self.tx_list == result["tx_list"], "Not same." diff --git a/trader_backup/vendor/valory/contracts/realitio/__init__.py b/trader_backup/vendor/valory/contracts/realitio/__init__.py deleted file mode 100644 index ff1cf563e..000000000 --- a/trader_backup/vendor/valory/contracts/realitio/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for the Realitio_v2_1 contract.""" diff --git a/trader_backup/vendor/valory/contracts/realitio/build/Realitio.json b/trader_backup/vendor/valory/contracts/realitio/build/Realitio.json deleted file mode 100644 index 79eb60ca4..000000000 --- a/trader_backup/vendor/valory/contracts/realitio/build/Realitio.json +++ /dev/null @@ -1,1069 +0,0 @@ -{ - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "history_hashes", - "type": "bytes32[]" - }, - { - "name": "addrs", - "type": "address[]" - }, - { - "name": "bonds", - "type": "uint256[]" - }, - { - "name": "answers", - "type": "bytes32[]" - } - ], - "name": "claimWinnings", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "content_hash", - "type": "bytes32" - }, - { - "name": "arbitrator", - "type": "address" - }, - { - "name": "min_timeout", - "type": "uint32" - }, - { - "name": "min_bond", - "type": "uint256" - } - ], - "name": "getFinalAnswerIfMatches", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getBounty", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getArbitrator", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getBond", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_ids", - "type": "bytes32[]" - }, - { - "name": "lengths", - "type": "uint256[]" - }, - { - "name": "hist_hashes", - "type": "bytes32[]" - }, - { - "name": "addrs", - "type": "address[]" - }, - { - "name": "bonds", - "type": "uint256[]" - }, - { - "name": "answers", - "type": "bytes32[]" - } - ], - "name": "claimMultipleAndWithdrawBalance", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "withdraw", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "answer", - "type": "bytes32" - }, - { - "name": "nonce", - "type": "uint256" - }, - { - "name": "bond", - "type": "uint256" - } - ], - "name": "submitAnswerReveal", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "fee", - "type": "uint256" - } - ], - "name": "setQuestionFee", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "template_hashes", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getContentHash", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "question_claims", - "outputs": [ - { - "name": "payee", - "type": "address" - }, - { - "name": "last_bond", - "type": "uint256" - }, - { - "name": "queued_funds", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "fundAnswerBounty", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "arbitrator_question_fees", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "template_id", - "type": "uint256" - }, - { - "name": "question", - "type": "string" - }, - { - "name": "arbitrator", - "type": "address" - }, - { - "name": "timeout", - "type": "uint32" - }, - { - "name": "opening_ts", - "type": "uint32" - }, - { - "name": "nonce", - "type": "uint256" - } - ], - "name": "askQuestion", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "answer", - "type": "bytes32" - }, - { - "name": "max_previous", - "type": "uint256" - } - ], - "name": "submitAnswer", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "isFinalized", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getHistoryHash", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "commitments", - "outputs": [ - { - "name": "reveal_ts", - "type": "uint32" - }, - { - "name": "is_revealed", - "type": "bool" - }, - { - "name": "revealed_answer", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "content", - "type": "string" - } - ], - "name": "createTemplate", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getBestAnswer", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "isPendingArbitration", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "questions", - "outputs": [ - { - "name": "content_hash", - "type": "bytes32" - }, - { - "name": "arbitrator", - "type": "address" - }, - { - "name": "opening_ts", - "type": "uint32" - }, - { - "name": "timeout", - "type": "uint32" - }, - { - "name": "finalize_ts", - "type": "uint32" - }, - { - "name": "is_pending_arbitration", - "type": "bool" - }, - { - "name": "bounty", - "type": "uint256" - }, - { - "name": "best_answer", - "type": "bytes32" - }, - { - "name": "history_hash", - "type": "bytes32" - }, - { - "name": "bond", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getOpeningTS", - "outputs": [ - { - "name": "", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getTimeout", - "outputs": [ - { - "name": "", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "content", - "type": "string" - }, - { - "name": "question", - "type": "string" - }, - { - "name": "arbitrator", - "type": "address" - }, - { - "name": "timeout", - "type": "uint32" - }, - { - "name": "opening_ts", - "type": "uint32" - }, - { - "name": "nonce", - "type": "uint256" - } - ], - "name": "createTemplateAndAskQuestion", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getFinalAnswer", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getFinalizeTS", - "outputs": [ - { - "name": "", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "templates", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "resultFor", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "answer_hash", - "type": "bytes32" - }, - { - "name": "max_previous", - "type": "uint256" - }, - { - "name": "_answerer", - "type": "address" - } - ], - "name": "submitAnswerCommitment", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "requester", - "type": "address" - }, - { - "name": "max_previous", - "type": "uint256" - } - ], - "name": "notifyOfArbitrationRequest", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "answer", - "type": "bytes32" - }, - { - "name": "answerer", - "type": "address" - } - ], - "name": "submitAnswerByArbitrator", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "arbitrator", - "type": "address" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "LogSetQuestionFee", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "template_id", - "type": "uint256" - }, - { - "indexed": true, - "name": "user", - "type": "address" - }, - { - "indexed": false, - "name": "question_text", - "type": "string" - } - ], - "name": "LogNewTemplate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": true, - "name": "user", - "type": "address" - }, - { - "indexed": false, - "name": "template_id", - "type": "uint256" - }, - { - "indexed": false, - "name": "question", - "type": "string" - }, - { - "indexed": true, - "name": "content_hash", - "type": "bytes32" - }, - { - "indexed": false, - "name": "arbitrator", - "type": "address" - }, - { - "indexed": false, - "name": "timeout", - "type": "uint32" - }, - { - "indexed": false, - "name": "opening_ts", - "type": "uint32" - }, - { - "indexed": false, - "name": "nonce", - "type": "uint256" - }, - { - "indexed": false, - "name": "created", - "type": "uint256" - } - ], - "name": "LogNewQuestion", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": false, - "name": "bounty_added", - "type": "uint256" - }, - { - "indexed": false, - "name": "bounty", - "type": "uint256" - }, - { - "indexed": true, - "name": "user", - "type": "address" - } - ], - "name": "LogFundAnswerBounty", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "answer", - "type": "bytes32" - }, - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": false, - "name": "history_hash", - "type": "bytes32" - }, - { - "indexed": true, - "name": "user", - "type": "address" - }, - { - "indexed": false, - "name": "bond", - "type": "uint256" - }, - { - "indexed": false, - "name": "ts", - "type": "uint256" - }, - { - "indexed": false, - "name": "is_commitment", - "type": "bool" - } - ], - "name": "LogNewAnswer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": true, - "name": "user", - "type": "address" - }, - { - "indexed": true, - "name": "answer_hash", - "type": "bytes32" - }, - { - "indexed": false, - "name": "answer", - "type": "bytes32" - }, - { - "indexed": false, - "name": "nonce", - "type": "uint256" - }, - { - "indexed": false, - "name": "bond", - "type": "uint256" - } - ], - "name": "LogAnswerReveal", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": true, - "name": "user", - "type": "address" - } - ], - "name": "LogNotifyOfArbitrationRequest", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": true, - "name": "answer", - "type": "bytes32" - } - ], - "name": "LogFinalize", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": true, - "name": "user", - "type": "address" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "LogClaim", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "user", - "type": "address" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "LogWithdraw", - "type": "event" - } - ], - "bytecode": "608060405260006001553480156200001657600080fd5b506200008d606060405190810160405280603f81526020017f7b227469746c65223a20222573222c202274797065223a2022626f6f6c222c2081526020017f2263617465676f7279223a20222573222c20226c616e67223a20222573227d0081525062000308640100000000026401000000009004565b506200012a608060405190810160405280604f81526020017f7b227469746c65223a20222573222c202274797065223a202275696e74222c2081526020017f22646563696d616c73223a2031382c202263617465676f7279223a202225732281526020017f2c20226c616e67223a20222573227d000000000000000000000000000000000081525062000308640100000000026401000000009004565b50620001c7608060405190810160405280605a81526020017f7b227469746c65223a20222573222c202274797065223a202273696e676c652d81526020017f73656c656374222c20226f7574636f6d6573223a205b25735d2c20226361746581526020017f676f7279223a20222573222c20226c616e67223a20222573227d00000000000081525062000308640100000000026401000000009004565b5062000264608060405190810160405280605c81526020017f7b227469746c65223a20222573222c202274797065223a20226d756c7469706c81526020017f652d73656c656374222c20226f7574636f6d6573223a205b25735d2c2022636181526020017f7465676f7279223a20222573222c20226c616e67223a20222573227d0000000081525062000308640100000000026401000000009004565b5062000301608060405190810160405280604381526020017f7b227469746c65223a20222573222c202274797065223a20226461746574696d81526020017f65222c202263617465676f7279223a20222573222c20226c616e67223a20222581526020017f73227d000000000000000000000000000000000000000000000000000000000081525062000308640100000000026401000000009004565b50620004ca565b60015460008181526002602090815260408083204390555184519293928592918201918291908401908083835b60208310620003565780518252601f19909201916020918201910162000335565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310620003bb5780518252601f1990920191602091820191016200039a565b51815160209384036101000a6000190180199092169116179052604080519290940182900382206000888152600383528581209190915581835289518383015289513397508896507fb87fb721c0a557bb8dff89a86796466931d82ba530a66a239263eb8735ade2e4958b955084939084019290860191908190849084905b83811015620004545781810151838201526020016200043a565b50505050905090810190601f168015620004825780820380516001836020036101000a031916815260200191505b509250505060405180910390a3620004aa8160016401000000006200314a620004b382021704565b60015592915050565b600082820183811015620004c357fe5b9392505050565b6139a680620004da6000396000f3006080604052600436106101925763ffffffff60e060020a6000350416631101a0fd811461019757806312a203c31461029e5780632417395c146102e35780632518904c146102fb57806326d6c97b1461032f57806328828b1e146103475780633ccfd60b146104b95780634dc266b4146104ce5780634df6ca2a146104ef5780634e60f8831461050757806351577ea91461051f578063590158a71461053757806359245ff3146105775780636fa427421461058257806370a08231146105a3578063762c38fd146105c457806377f325df1461063a5780637f8d429e1461064b57806382ffa9f714610677578063839df9451461068f57806383bf4609146106cc5780638d552d4614610725578063924532fb1461073d57806395addb90146107555780639e63fa6a146107d15780639f1025c614610802578063a1130d041461081a578063a462fb7b146108c9578063acae8f4e146108e1578063bc525652146108f9578063d09cc57e146108c9578063d7cff98614610911578063f6a94ecb1461092e578063fe92049d14610955575b600080fd5b3480156101a357600080fd5b5060408051602060046024803582810135848102808701860190975280865261029c96843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375094975061097c9650505050505050565b005b3480156102aa57600080fd5b506102d1600435602435600160a060020a036044351663ffffffff60643516608435610cac565b60408051918252519081900360200190f35b3480156102ef57600080fd5b506102d1600435610ee9565b34801561030757600080fd5b50610313600435610efe565b60408051600160a060020a039092168252519081900360200190f35b34801561033b57600080fd5b506102d1600435610f1c565b34801561035357600080fd5b506040805160206004803580820135838102808601850190965280855261029c95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610f319650505050505050565b3480156104c557600080fd5b5061029c611145565b3480156104da57600080fd5b5061029c6004356024356044356064356111c0565b3480156104fb57600080fd5b5061029c600435611660565b34801561051357600080fd5b506102d16004356116af565b34801561052b57600080fd5b506102d16004356116c1565b34801561054357600080fd5b5061054f6004356116d3565b60408051600160a060020a039094168452602084019290925282820152519081900360600190f35b61029c6004356116fe565b34801561058e57600080fd5b506102d1600160a060020a036004351661195b565b3480156105af57600080fd5b506102d1600160a060020a036004351661196d565b60408051602060046024803582810135601f81018590048502860185019096528585526102d195833595369560449491939091019190819084018382808284375094975050508335600160a060020a03169450505050602081013563ffffffff908116916040810135909116906060013561197f565b61029c600435602435604435611ca3565b34801561065757600080fd5b50610663600435612037565b604080519115158252519081900360200190f35b34801561068357600080fd5b506102d1600435612094565b34801561069b57600080fd5b506106a76004356120a9565b6040805163ffffffff9094168452911515602084015282820152519081900360600190f35b3480156106d857600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102d19436949293602493928401919081908401838280828437509497506120d69650505050505050565b34801561073157600080fd5b506102d1600435612270565b34801561074957600080fd5b50610663600435612286565b34801561076157600080fd5b5061076d60043561229e565b604080519a8b52600160a060020a0390991660208b015263ffffffff9788168a8a015295871660608a015293909516608088015290151560a087015260c086015260e085019290925261010084019190915261012083015251908190036101400190f35b3480156107dd57600080fd5b506107e9600435612309565b6040805163ffffffff9092168252519081900360200190f35b34801561080e57600080fd5b506107e960043561232b565b6040805160206004803580820135601f81018490048402850184019095528484526102d194369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375094975050508335600160a060020a03169450505050602081013563ffffffff908116916040810135909116906060013561234d565b3480156108d557600080fd5b506102d1600435612375565b3480156108ed57600080fd5b506107e96004356123ef565b34801561090557600080fd5b506102d1600435612411565b61029c600435602435604435600160a060020a0360643516612423565b34801561093a57600080fd5b5061029c600435600160a060020a036024351660443561293a565b34801561096157600080fd5b5061029c600435602435600160a060020a0360443516612d10565b60008060008060008060008b61099181612037565b15156109e7576040805160e560020a62461bcd02815260206004820152601a60248201527f7175657374696f6e206d7573742062652066696e616c697a6564000000000000604482015290519081900360640190fd5b8b51600010610a66576040805160e560020a62461bcd02815260206004820152603060248201527f6174206c65617374206f6e6520686973746f7279206861736820656e7472792060448201527f6d7573742062652070726f766964656400000000000000000000000000000000606482015290519081900360840190fd5b60008d815260056020818152604080842080546001820154600290920154600494859052928620948501549490930154600160a060020a039093169c509a509850909650945092505b8b51831015610bcf57610b21858d85815181101515610aca57fe5b906020019060200201518b86815181101515610ae257fe5b906020019060200201518d87815181101515610afa57fe5b906020019060200201518f88815181101515610b1257fe5b90602001906020020151612f34565b9150610b33868863ffffffff61314a16565b9550610b8a8d85888b8f88815181101515610b4a57fe5b906020019060200201518f89815181101515610b6257fe5b906020019060200201518f8a815181101515610b7a57fe5b9060200190602002015189613164565b8b519099509096508a9084908110610b9e57fe5b9060200190602002015196508b83815181101515610bb857fe5b602090810290910101519450600190920191610aaf565b8415610c3a57600160a060020a03881615610bf457610bef8d8988613294565b600095505b60008d8152600560205260409020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038a1617815560018101889055600201869055610c89565b610c548d89610c4f898b63ffffffff61314a16565b613294565b60008d8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff1916815560018101829055600201555b5050506000998a5250600460205260409098206005019790975550505050505050565b600085610cb881612037565b1515610d0e576040805160e560020a62461bcd02815260206004820152601a60248201527f7175657374696f6e206d7573742062652066696e616c697a6564000000000000604482015290519081900360640190fd5b6000878152600460205260409020548614610d73576040805160e560020a62461bcd02815260206004820152601760248201527f636f6e74656e742068617368206d757374206d61746368000000000000000000604482015290519081900360640190fd5b600087815260046020526040902060010154600160a060020a03868116911614610de7576040805160e560020a62461bcd02815260206004820152601560248201527f61726269747261746f72206d757374206d617463680000000000000000000000604482015290519081900360640190fd5b60008781526004602052604090206001015463ffffffff60c060020a90910481169085161115610e61576040805160e560020a62461bcd02815260206004820152601b60248201527f74696d656f7574206d757374206265206c6f6e6720656e6f7567680000000000604482015290519081900360640190fd5b600087815260046020526040902060060154831115610eca576040805160e560020a62461bcd02815260206004820152601860248201527f626f6e64206d757374206265206869676820656e6f7567680000000000000000604482015290519081900360640190fd5b6000878152600460208190526040909120015491505095945050505050565b60009081526004602052604090206003015490565b600090815260046020526040902060010154600160a060020a031690565b60009081526004602052604090206006015490565b60008080806060808080845b8e5189101561112c578e89815181101515610f5457fe5b9060200190602002015196508d89815181101515610f6e57fe5b90602001906020020151955085604051908082528060200260200182016040528015610fa4578160200160208202803883390190505b50945085604051908082528060200260200182016040528015610fd1578160200160208202803883390190505b50935085604051908082528060200260200182016040528015610ffe578160200160208202803883390190505b5092508560405190808252806020026020018201604052801561102b578160200160208202803883390190505b509150600090505b85811015611114578c8881518110151561104957fe5b90602001906020020151858281518110151561106157fe5b602090810290910101528b518c908990811061107957fe5b90602001906020020151848281518110151561109157fe5b600160a060020a039092166020928302909101909101528a518b90899081106110b657fe5b9060200190602002015183828151811015156110ce57fe5b6020908102909101015289518a90899081106110e657fe5b9060200190602002015182828151811015156110fe57fe5b6020908102909101015260019788019701611033565b611121878686868661097c565b600190980197610f3d565b611134611145565b505050505050505050505050505050565b33600081815260208190526040808220805490839055905190929183156108fc02918491818181858888f19350505050158015611186573d6000803e3d6000fd5b5060408051828152905133917f4ce7033d118120e254016dccf195288400b28fc8936425acd5f17ce2df3ab708919081900360200190a250565b600084815260046020526040812060010154819086908290819060c060020a900463ffffffff16811061122b576040805160e560020a62461bcd02815260206004820152601360248201526000805160206138bb833981519152604482015290519081900360640190fd5b60008381526004602052604090206001015460e060020a900463ffffffff16915081158061126457504263ffffffff168263ffffffff16115b15156112e0576040805160e560020a62461bcd02815260206004820152602960248201527f66696e616c697a6174696f6e206465616c696e65206d757374206e6f7420686160448201527f7665207061737365640000000000000000000000000000000000000000000000606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff1680158061131957504263ffffffff168163ffffffff1611155b151561135d576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061393b833981519152604482015290519081900360640190fd5b6040805160208082018b90528183018a9052825180830384018152606090920192839052815191929182918401908083835b602083106113ae5780518252601f19909201916020918201910161138f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209450888587604051602001808460001916600019168152602001836000191660001916815260200182815260200193505050506040516020818303038152906040526040518082805190602001908083835b6020831061144c5780518252601f19909201916020918201910161142d565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120600081815260069092529290205491975050640100000000900460ff161591506115109050576040805160e560020a62461bcd02815260206004820152602a60248201527f636f6d6d69746d656e74206d757374206e6f742068617665206265656e20726560448201527f7665616c65642079657400000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008481526006602052604090205463ffffffff4281169116116115a3576040805160e560020a62461bcd028152602060048201526024808201527f72657665616c20646561646c696e65206d757374206e6f74206861766520706160448201527f7373656400000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6000848152600660208181526040808420600181018d9055805464ff0000000019166401000000001790558c84526004909152909120015486141561160e5760008981526004602052604090206001015461160e908a908a9060c060020a900463ffffffff16613315565b60408051898152602081018990528082018890529051869133918c917fa7b2d313bc7a062e30b2c3b811aa4c9faf09755a6b4ea3bf42deff920944332f919081900360600190a4505050505050505050565b336000818152600760209081526040918290208490558151928352820183905280517fdca703d022171824d3d639b33c1525fd2338120b4cfb89507c0b59596893acda9281900390910190a150565b60036020526000908152604090205481565b60009081526004602052604090205490565b600560205260009081526040902080546001820154600290920154600160a060020a03909116919083565b600081815260046020526040812060010154829190819060c060020a900463ffffffff168110611766576040805160e560020a62461bcd02815260206004820152601360248201526000805160206138bb833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff16156117d2576040805160e560020a62461bcd02815260206004820152602860248201526000805160206138fb83398151915260448201526000805160206138db833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff16915081158061180b57504263ffffffff168263ffffffff16115b1515611863576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061391b833981519152604482015260008051602061395b833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff1680158061189c57504263ffffffff168163ffffffff1611155b15156118e0576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061393b833981519152604482015290519081900360640190fd5b600084815260046020526040902060030154611902903463ffffffff61314a16565b6000858152600460209081526040918290206003018390558151348152908101929092528051339287927f54d68405b79f2aa4fd4e8db7b67844ad254cf8f208aac476c2894134a9deab6692918290030190a350505050565b60076020526000908152604090205481565b60006020819052908152604090205481565b6000868152600260205260408120548190819081106119e8576040805160e560020a62461bcd02815260206004820152601360248201527f74656d706c617465206d75737420657869737400000000000000000000000000604482015290519081900360640190fd5b888589604051602001808481526020018363ffffffff1663ffffffff1660e060020a02815260040182805190602001908083835b60208310611a3b5780518252601f199092019160209182019101611a1c565b6001836020036101000a03801982511681845116808217855250505050505090500193505050506040516020818303038152906040526040518082805190602001908083835b60208310611aa05780518252601f199092019160209182019101611a81565b51815160209384036101000a600019018019909216911617905260408051929094018290038220828201819052600160a060020a038e166c010000000000000000000000009081028487015263ffffffff8e1660e060020a02605485015233026058840152606c8084018c905285518085039091018152608c9093019485905282519098509195509293508392850191508083835b60208310611b545780518252601f199092019160209182019101611b35565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209050611b90818389898961338c565b816000191633600160a060020a031682600019167ffe2dac156a3890636ce13f65f4fdf41dcaee11526e4a5374531572d92194796c8c8c8c8c8c8c42604051808881526020018060200187600160a060020a0316600160a060020a031681526020018663ffffffff1663ffffffff1681526020018563ffffffff1663ffffffff168152602001848152602001838152602001828103825288818151815260200191508051906020019080838360005b83811015611c57578181015183820152602001611c3f565b50505050905090810190601f168015611c845780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a498975050505050505050565b600083815260046020526040812060010154849190819060c060020a900463ffffffff168110611d0b576040805160e560020a62461bcd02815260206004820152601360248201526000805160206138bb833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff1615611d77576040805160e560020a62461bcd02815260206004820152602860248201526000805160206138fb83398151915260448201526000805160206138db833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff169150811580611db057504263ffffffff168263ffffffff16115b1515611e08576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061391b833981519152604482015260008051602061395b833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff16801580611e4157504263ffffffff168163ffffffff1611155b1515611e85576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061393b833981519152604482015290519081900360640190fd5b8560003411611ede576040805160e560020a62461bcd02815260206004820152601560248201527f626f6e64206d75737420626520706f7369746976650000000000000000000000604482015290519081900360640190fd5b600081815260046020526040902060060154611f0190600263ffffffff6136ed16565b341015611f7e576040805160e560020a62461bcd02815260206004820152602a60248201527f626f6e64206d75737420626520646f75626c65206174206c656173742070726560448201527f76696f757320626f6e6400000000000000000000000000000000000000000000606482015290519081900360840190fd5b86856000811115611ff257600082815260046020526040902060060154811015611ff2576040805160e560020a62461bcd02815260206004820152601d60248201527f626f6e64206d75737420657863656564206d61785f70726576696f7573000000604482015290519081900360640190fd5b612000898933346000613718565b60008981526004602052604090206001015461202c908a908a9060c060020a900463ffffffff16613315565b505050505050505050565b6000818152600460205260408120600181015460029091015460e060020a90910463ffffffff169060ff161580156120755750600063ffffffff8216115b801561208d57504263ffffffff168163ffffffff1611155b9392505050565b60009081526004602052604090206005015490565b6006602052600090815260409020805460019091015463ffffffff821691640100000000900460ff169083565b60015460008181526002602090815260408083204390555184519293928592918201918291908401908083835b602083106121225780518252601f199092019160209182019101612103565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b602083106121855780518252601f199092019160209182019101612166565b51815160209384036101000a6000190180199092169116179052604080519290940182900382206000888152600383528581209190915581835289518383015289513397508896507fb87fb721c0a557bb8dff89a86796466931d82ba530a66a239263eb8735ade2e4958b955084939084019290860191908190849084905b8381101561221c578181015183820152602001612204565b50505050905090810190601f1680156122495780820380516001836020036101000a031916815260200191505b509250505060405180910390a361226781600163ffffffff61314a16565b60015592915050565b6000908152600460208190526040909120015490565b60009081526004602052604090206002015460ff1690565b600460208190526000918252604090912080546001820154600283015460038401549484015460058501546006909501549395600160a060020a0384169563ffffffff60a060020a860481169660c060020a870482169660e060020a90049091169460ff169391908a565b60009081526004602052604090206001015460a060020a900463ffffffff1690565b60009081526004602052604090206001015460c060020a900463ffffffff1690565b600080612359886120d6565b905061236981888888888861197f565b98975050505050505050565b60008161238181612037565b15156123d7576040805160e560020a62461bcd02815260206004820152601a60248201527f7175657374696f6e206d7573742062652066696e616c697a6564000000000000604482015290519081900360640190fd5b50506000908152600460208190526040909120015490565b60009081526004602052604090206001015460e060020a900463ffffffff1690565b60026020526000908152604090205481565b6000848152600460205260408120600101548190819087908290819060c060020a900463ffffffff168110612490576040805160e560020a62461bcd02815260206004820152601360248201526000805160206138bb833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff16156124fc576040805160e560020a62461bcd02815260206004820152602860248201526000805160206138fb83398151915260448201526000805160206138db833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff16915081158061253557504263ffffffff168263ffffffff16115b151561258d576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061391b833981519152604482015260008051602061395b833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff168015806125c657504263ffffffff168163ffffffff1611155b151561260a576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061393b833981519152604482015290519081900360640190fd5b8960003411612663576040805160e560020a62461bcd02815260206004820152601560248201527f626f6e64206d75737420626520706f7369746976650000000000000000000000604482015290519081900360640190fd5b60008181526004602052604090206006015461268690600263ffffffff6136ed16565b341015612703576040805160e560020a62461bcd02815260206004820152602a60248201527f626f6e64206d75737420626520646f75626c65206174206c656173742070726560448201527f76696f757320626f6e6400000000000000000000000000000000000000000000606482015290519081900360840190fd5b8a89600081111561277757600082815260046020526040902060060154811015612777576040805160e560020a62461bcd02815260206004820152601d60248201527f626f6e64206d75737420657863656564206d61785f70726576696f7573000000604482015290519081900360640190fd5b8c8c34604051602001808460001916600019168152602001836000191660001916815260200182815260200193505050506040516020818303038152906040526040518082805190602001908083835b602083106127e65780518252601f1990920191602091820191016127c7565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209b50505050600160a060020a038a1615612829578961282b565b335b60008a81526006602052604090205490985063ffffffff16156128be576040805160e560020a62461bcd02815260206004820152602160248201527f636f6d6d69746d656e74206d757374206e6f7420616c7265616479206578697360448201527f7400000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008d81526004602052604090206001015460089060c060020a900463ffffffff160496506128f763ffffffff42811690899061389016565b60008a8152600660205260409020805463ffffffff191663ffffffff9290921691909117905561292b8d8a8a346001613718565b50505050505050505050505050565b6000838152600460205260409020600101548390600160a060020a031633146129ad576040805160e560020a62461bcd02815260206004820152601d60248201527f6d73672e73656e646572206d7573742062652061726269747261746f72000000604482015290519081900360640190fd5b600084815260046020526040812060010154859190819060c060020a900463ffffffff168110612a15576040805160e560020a62461bcd02815260206004820152601360248201526000805160206138bb833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff1615612a81576040805160e560020a62461bcd02815260206004820152602860248201526000805160206138fb83398151915260448201526000805160206138db833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff169150811580612aba57504263ffffffff168263ffffffff16115b1515612b12576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061391b833981519152604482015260008051602061395b833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff16801580612b4b57504263ffffffff168163ffffffff1611155b1515612b8f576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061393b833981519152604482015290519081900360640190fd5b86856000811115612c0357600082815260046020526040902060060154811015612c03576040805160e560020a62461bcd02815260206004820152601d60248201527f626f6e64206d75737420657863656564206d61785f70726576696f7573000000604482015290519081900360640190fd5b60008981526004602052604081206006015411612cb6576040805160e560020a62461bcd02815260206004820152604260248201527f5175657374696f6e206d75737420616c7265616479206861766520616e20616e60448201527f73776572207768656e206172626974726174696f6e206973207265717565737460648201527f6564000000000000000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b600089815260046020526040808220600201805460ff1916600117905551600160a060020a038a16918b917f75d7939999bc902187c4aed400872883e445145f1983539166f783fa040b47629190a3505050505050505050565b6000838152600460205260409020600101548390600160a060020a03163314612d83576040805160e560020a62461bcd02815260206004820152601d60248201527f6d73672e73656e646572206d7573742062652061726269747261746f72000000604482015290519081900360640190fd5b600084815260046020526040902060020154849060ff161515612e15576040805160e560020a62461bcd028152602060048201526024808201527f7175657374696f6e206d7573742062652070656e64696e67206172626974726160448201527f74696f6e00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b3415612e6b576040805160e560020a62461bcd02815260206004820152601160248201527f626f6e64206d757374206265207a65726f000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0383161515612ecb576040805160e560020a62461bcd02815260206004820152601960248201527f616e737765726572206d7573742062652070726f766964656400000000000000604482015290519081900360640190fd5b604051849086907f18d760beffe3717270cd90d9d920ec1a48c194e9ad7bba23eb1c92d3eb974f9790600090a36000858152600460205260408120600201805460ff19169055612f219086908690869080613718565b612f2d85856000613315565b5050505050565b604080516020808201879052818301869052606082018590526c01000000000000000000000000600160a060020a0385160260808301527f01000000000000000000000000000000000000000000000000000000000000006094830152825160758184030181526095909201928390528151600093918291908401908083835b60208310612fd35780518252601f199092019160209182019101612fb4565b5181516020939093036101000a60001901801990911692169190911790526040519201829003909120891415925061301091505057506001613141565b604080516020808201889052818301879052606082018690526c01000000000000000000000000600160a060020a0386160260808301526000609483015282516075818403018152609590920192839052815191929182918401908083835b6020831061308e5780518252601f19909201916020918201910161306f565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912089141592506130cb91505057506000613141565b6040805160e560020a62461bcd02815260206004820152603660248201527f486973746f727920696e7075742070726f766964656420646964206e6f74206d60448201527f6174636820746865206578706563746564206861736800000000000000000000606482015290519081900360840190fd5b95945050505050565b60008282018381101561315957fe5b8091505b5092915050565b60008060008084156131e457600086815260066020526040902054869250640100000000900460ff1615156131bc576000828152600660205260408120805464ffffffffff1916815560010155899350889250613285565b6000828152600660205260408120600181018054825464ffffffffff19169092559190915595505b858b141561327e57600160a060020a038916151561323d5760008c8152600460205260409020600301549798508897613224908b9063ffffffff61314a16565b60008d815260046020526040812060030155995061327e565b600160a060020a03888116908a161461327e57868a101561325e5789613260565b865b90506132778c8a610c4f8d8563ffffffff6138a816565b8798508099505b8989935093505b50509850989650505050505050565b600160a060020a0382166000908152602081905260409020546132bd908263ffffffff61314a16565b600160a060020a038316600081815260208181526040918290209390935580518481529051919286927f9c121aff33b50c1a53fef034ebec5f83da2d5a5187048f9c76c397ba27c1a1a69281900390910190a3505050565b60008381526004602081905260409091200182905561333e63ffffffff42811690839061389016565b600093845260046020526040909320600101805463ffffffff9490941660e060020a027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909416939093179092555050565b6000858152600460205260408120600101548190879060c060020a900463ffffffff1615613404576040805160e560020a62461bcd02815260206004820152601760248201527f7175657374696f6e206d757374206e6f74206578697374000000000000000000604482015290519081900360640190fd5b600063ffffffff861611613462576040805160e560020a62461bcd02815260206004820152601860248201527f74696d656f7574206d75737420626520706f7369746976650000000000000000604482015290519081900360640190fd5b6301e1338063ffffffff8616106134e9576040805160e560020a62461bcd02815260206004820152602260248201527f74696d656f7574206d757374206265206c657373207468616e2033363520646160448201527f7973000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0386161515613549576040805160e560020a62461bcd02815260206004820152601660248201527f61726269747261746f72206d7573742062652073657400000000000000000000604482015290519081900360640190fd5b34925033600160a060020a0387161461364a57600160a060020a0386166000908152600760205260409020549150818310156135f4576040805160e560020a62461bcd028152602060048201526024808201527f4554482070726f7669646564206d75737420636f766572207175657374696f6e60448201527f2066656500000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b613604838363ffffffff6138a816565b600160a060020a038716600090815260208190526040902054909350613630908363ffffffff61314a16565b600160a060020a0387166000908152602081905260409020555b505060009586526004602052604090952093845560018401805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03949094169390931777ffffffff0000000000000000000000000000000000000000191660a060020a63ffffffff92831602177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1660c060020a929091169190910217905560030155565b600080831515613700576000915061315d565b5082820282848281151561371057fe5b041461315957fe5b600085815260046020908152604080832060050154815180840191909152808201889052606081018690526c01000000000000000000000000600160a060020a0388160260808201527f010000000000000000000000000000000000000000000000000000000000000085151502609482015281516075818303018152609590910191829052805190928291908401908083835b602083106137cb5780518252601f1990920191602091820191016137ac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905060008311156138185760008681526004602052604090206006018390555b600086815260046020908152604091829020600501839055815187815290810183905280820185905242606082015283151560808201529051600160a060020a0386169188917fe47ca4ebbbc2990134d1168821f38c5e177f3d5ee564bffeadeaa351905e62219181900360a00190a3505050505050565b600082820163ffffffff808516908216101561315957fe5b6000828211156138b457fe5b5090039056007175657374696f6e206d757374206578697374000000000000000000000000006974726174696f6e0000000000000000000000000000000000000000000000007175657374696f6e206d757374206e6f742062652070656e64696e672061726266696e616c697a6174696f6e20646561646c696e65206d757374206e6f7420686f70656e696e672064617465206d7573742068617665207061737365640000006176652070617373656400000000000000000000000000000000000000000000a165627a7a72305820e7af9378240e218241c6138a31e3e3b63a25874b9949b4e903f6f855bfc899100029" -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/realitio/contract.py b/trader_backup/vendor/valory/contracts/realitio/contract.py deleted file mode 100644 index b04dca8fd..000000000 --- a/trader_backup/vendor/valory/contracts/realitio/contract.py +++ /dev/null @@ -1,428 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the Realitio_v2_1 contract definition.""" -import concurrent.futures -import logging -from typing import List, Tuple, Union, Dict, Callable, Any - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from eth_typing import ChecksumAddress -from requests.exceptions import ReadTimeout as RequestsReadTimeoutError -from urllib3.exceptions import ReadTimeoutError as Urllib3ReadTimeoutError -from web3.exceptions import ContractLogicError -from web3.types import BlockIdentifier - - -ClaimParamsType = Tuple[ - List[bytes], List[ChecksumAddress], List[int], List[bytes] -] - -FIVE_MINUTES = 300.0 - -PUBLIC_ID = PublicId.from_str("valory/realitio:0.1.0") -_logger = logging.getLogger( - f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" -) - -MARKET_FEE = 2.0 -UNIT_SEPARATOR = chr(9247) - - -def format_answers(answers: List[str]) -> str: - """Format answers.""" - return ",".join(map(lambda x: '"' + x + '"', answers)) - - -def build_question(question_data: Dict) -> str: - """Build question.""" - return UNIT_SEPARATOR.join( - [ - question_data["question"], - format_answers(question_data["answers"]), - question_data["topic"], - question_data["language"], - ] - ) - - -class RealitioContract(Contract): - """The Realitio_v2_1 smart contract.""" - - contract_id = PUBLIC_ID - - @staticmethod - def execute_with_timeout(func: Callable, timeout: float) -> Any: - """Execute a function with a timeout.""" - - # Create a ProcessPoolExecutor with a maximum of 1 worker (process) - with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: - # Submit the function to the executor - future = executor.submit( - func, - ) - - try: - # Wait for the result with a 5-minute timeout - data = future.result(timeout=timeout) - except TimeoutError: - # Handle the case where the execution times out - err = f"The RPC didn't respond in {timeout}." - return None, err - - # Check if an error occurred - if isinstance(data, str): - # Handle the case where the execution failed - return None, data - - return data, None - - @classmethod - def check_finalized( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: bytes, - ) -> JSONLike: - """Check whether a market has been finalized.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - is_finalized = contract_instance.functions.isFinalized(question_id).call() - return dict(finalized=is_finalized) - - @classmethod - def get_claim_params( - cls, - ledger_api: LedgerApi, - contract_address: str, - from_block: int, - to_block: int, - question_id: bytes, - timeout: float = FIVE_MINUTES, - ) -> Dict[str, Union[str, list]]: - """Filters the `LogNewAnswer` event by question id to calculate the history hashes.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - - def get_claim_params() -> Any: - """Get claim params.""" - try: - answer_filter = contract_instance.events.LogNewAnswer.build_filter() - answer_filter.fromBlock = from_block - answer_filter.toBlock = to_block - answer_filter.args.question_id.match_single(question_id) - answered = list(answer_filter.deploy(ledger_api.api).get_all_entries()) - return answered - except (Urllib3ReadTimeoutError, RequestsReadTimeoutError): - msg = ( - "The RPC timed out! This usually happens if the filtering is too wide. " - f"The service tried to filter from block {from_block} to {to_block}. " - f"If this issue persists, please try lowering the `EVENT_FILTERING_BATCH_SIZE`!" - ) - return msg - - answered, err = cls.execute_with_timeout(get_claim_params, timeout=timeout) - if err is not None: - return dict(error=err) - - msg = ( - f"Found {len(answered)} answer(s) for question with id {question_id.hex()} " - f"between blocks {from_block} and {to_block}." - ) - return dict(info=msg, answered=answered) - - @classmethod - def build_claim_winnings( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: bytes, - claim_params: ClaimParamsType, - ) -> JSONLike: - """Build `claimWinnings` transaction.""" - contract = cls.get_instance(ledger_api, contract_address) - data = contract.encodeABI( - fn_name="claimWinnings", - args=(question_id, *claim_params), - ) - return dict(data=data) - - @classmethod - def simulate_claim_winnings( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: bytes, - claim_params: ClaimParamsType, - sender_address: str, - ) -> JSONLike: - """Simulate `claimWinnings` transaction.""" - data = cls.build_claim_winnings(ledger_api, contract_address, question_id, claim_params)["data"] - try: - ledger_api.api.eth.call( - { - "from": ledger_api.api.to_checksum_address(sender_address), - "to": ledger_api.api.to_checksum_address(contract_address), - "data": data[2:], - } - ) - simulation_ok = True - except (ValueError, ContractLogicError) as e: - _logger.info(f"Simulation failed: {str(e)}") - simulation_ok = False - return dict(data=simulation_ok) - - @classmethod - def get_history_hash( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: bytes, - ) -> JSONLike: - """Get history hash for a question""" - contract = cls.get_instance(ledger_api, contract_address) - data = contract.functions.getHistoryHash(question_id).call() - return dict(data=data) - - @classmethod - def get_raw_transaction( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> JSONLike: - """ - Handler method for the 'GET_RAW_TRANSACTION' requests. - - Implement this method in the sub class if you want - to handle the contract requests manually. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param kwargs: the keyword arguments. - :return: the tx # noqa: DAR202 - """ - raise NotImplementedError - - @classmethod - def get_raw_message( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> bytes: - """ - Handler method for the 'GET_RAW_MESSAGE' requests. - - Implement this method in the sub class if you want - to handle the contract requests manually. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param kwargs: the keyword arguments. - :return: the tx # noqa: DAR202 - """ - raise NotImplementedError - - @classmethod - def get_state( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> JSONLike: - """ - Handler method for the 'GET_STATE' requests. - - Implement this method in the sub class if you want - to handle the contract requests manually. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param kwargs: the keyword arguments. - :return: the tx # noqa: DAR202 - """ - raise NotImplementedError - - @classmethod - def get_ask_question_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_data: Dict, - opening_timestamp: int, - timeout: int, - arbitrator_contract: str, - template_id: int = 2, - question_nonce: int = 0, - ) -> JSONLike: - """Get ask question transaction.""" - question = build_question(question_data=question_data) - kwargs = { - "template_id": template_id, - "question": question, - "arbitrator": ledger_api.api.to_checksum_address(arbitrator_contract), - "timeout": timeout, - "opening_ts": opening_timestamp, - "nonce": question_nonce, - } - return ledger_api.build_transaction( - contract_instance=cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ), - method_name="askQuestion", - method_args=kwargs, - ) - - @classmethod - def get_ask_question_tx_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_data: Dict, - opening_timestamp: int, - timeout: int, - arbitrator_contract: str, - template_id: int = 2, - question_nonce: int = 0, - ) -> JSONLike: - """Get ask question transaction.""" - question = build_question(question_data=question_data) - kwargs = { - "template_id": template_id, - "question": question, - "arbitrator": ledger_api.api.to_checksum_address(arbitrator_contract), - "timeout": timeout, - "opening_ts": opening_timestamp, - "nonce": question_nonce, - } - contract_instance = cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - data = contract_instance.encodeABI(fn_name="askQuestion", kwargs=kwargs) - return {"data": bytes.fromhex(data[2:])} # type: ignore - - @classmethod - def calculate_question_id( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_data: Dict, - opening_timestamp: int, - timeout: int, - arbitrator_contract: str, - sender: str, - template_id: int = 2, - question_nonce: int = 0, - ) -> JSONLike: - """Get ask question transaction.""" - question = build_question(question_data=question_data) - content_hash = ledger_api.api.solidity_keccak( - ["uint256", "uint32", "string"], - [template_id, opening_timestamp, question], - ) - question_id = ledger_api.api.solidity_keccak( - ["bytes32", "address", "uint32", "address", "uint256"], - [ - content_hash, - ledger_api.api.to_checksum_address(arbitrator_contract), - timeout, - ledger_api.api.to_checksum_address(sender), - question_nonce, - ], - ) - return {"question_id": question_id.hex()} - - @classmethod - def get_question_events( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_ids: List[bytes], - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - ) -> JSONLike: - """Get questions.""" - # TODO: consider using multicall2 or constructor trick instead of filters - contract = cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - entries = contract.events.LogNewQuestion.create_filter( - fromBlock=from_block, - toBlock=to_block, - argument_filters=dict(question_id=question_ids), - ).get_all_entries() - events = list( - dict( - tx_hash=entry.transactionHash.hex(), - block_number=entry.blockNumber, - question_id=entry["args"]["question_id"], - user=entry["args"]["user"], - template_id=entry["args"]["template_id"], - question=entry["args"]["question"], - content_hash=entry["args"]["content_hash"], - arbitrator=entry["args"]["arbitrator"], - timeout=entry["args"]["timeout"], - opening_ts=entry["args"]["opening_ts"], - nonce=entry["args"]["nonce"], - created=entry["args"]["created"], - ) - for entry in entries - ) - return dict(data=events) - - @classmethod - def get_submit_answer_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: bytes, - answer: bytes, - max_previous: int, - ) -> JSONLike: - """Get submit answer transaction.""" - contract = cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - data = contract.encodeABI( - fn_name="submitAnswer", - args=[ - question_id, - answer, - max_previous, - ], - ) - return dict(data=data) - - @classmethod - def balance_of( - cls, - ledger_api: LedgerApi, - contract_address: str, - address: str, - ) -> JSONLike: - """Get balance for an address""" - contract = cls.get_instance(ledger_api, contract_address) - data = contract.functions.balanceOf(address).call() - return dict(data=data) - - @classmethod - def build_withdraw_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Build `withdraw` transaction.""" - contract = cls.get_instance(ledger_api, contract_address) - data = contract.encodeABI( - fn_name="withdraw", - ) - return dict(data=data) diff --git a/trader_backup/vendor/valory/contracts/realitio/contract.yaml b/trader_backup/vendor/valory/contracts/realitio/contract.yaml deleted file mode 100644 index beb6290ca..000000000 --- a/trader_backup/vendor/valory/contracts/realitio/contract.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: realitio -author: valory -version: 0.1.0 -type: contract -description: Realitio_v2_1 contract. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeictahkgfmlqv5kksvj6klmxtmjdpeq4sp3x7dp2yr5x4kmzbcihse - build/Realitio.json: bafybeiagi7zoeoy5s7duhg4oeuekj2s6z5mad2z6g2pn3n5elsvze25qiu - contract.py: bafybeih7u7cpfqn3htwribajjfhka6ilhww7lx4w5qqls6b3gxevaevfoa -fingerprint_ignore_patterns: [] -class_name: RealitioContract -contract_interface_paths: - ethereum: build/Realitio.json -dependencies: - eth_typing: {} - hexbytes: {} - web3: - version: <7,>=6.0.0 - requests: - version: ==2.28.1 - urllib3: - version: ==1.26.16 -contracts: [] diff --git a/trader_backup/vendor/valory/contracts/realitio_proxy/__init__.py b/trader_backup/vendor/valory/contracts/realitio_proxy/__init__.py deleted file mode 100644 index 7b0d92450..000000000 --- a/trader_backup/vendor/valory/contracts/realitio_proxy/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for the RealitioProxy contract.""" diff --git a/trader_backup/vendor/valory/contracts/realitio_proxy/build/Realitio.json b/trader_backup/vendor/valory/contracts/realitio_proxy/build/Realitio.json deleted file mode 100644 index 66c972926..000000000 --- a/trader_backup/vendor/valory/contracts/realitio_proxy/build/Realitio.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "contract IConditionalTokens", - "name": "_conditionalTokens", - "type": "address" - }, - { - "internalType": "contract IRealitio", - "name": "_realitio", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nuancedBinaryTemplateId", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "constant": true, - "inputs": [], - "name": "conditionalTokens", - "outputs": [ - { - "internalType": "contract IConditionalTokens", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "nuancedBinaryTemplateId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "realitio", - "outputs": [ - { - "internalType": "contract IRealitio", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "bytes32", - "name": "questionId", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "templateId", - "type": "uint256" - }, - { - "internalType": "string", - "name": "question", - "type": "string" - }, - { - "internalType": "uint256", - "name": "numOutcomes", - "type": "uint256" - } - ], - "name": "resolve", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "608060405234801561001057600080fd5b50604051610b3a380380610b3a8339818101604052606081101561003357600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600281905550505050610a48806100f26000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80635bd9e29914610051578063bc8802a21461009b578063d41f2556146100e5578063dbc0e6351461017c575b600080fd5b61005961019a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100a36101bf565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61017a600480360360808110156100fb57600080fd5b8101908080359060200190929190803590602001909291908035906020019064010000000081111561012c57600080fd5b82018360208201111561013e57600080fd5b8035906020019184600183028401116401000000008311171561016057600080fd5b9091929391929390803590602001909291905050506101e5565b005b610184610596565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600084600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639e63fa6a886040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561025b57600080fd5b505afa15801561026f573d6000803e3d6000fd5b505050506040513d602081101561028557600080fd5b81019080805190602001909291905050508585604051602001808581526020018463ffffffff1663ffffffff1660e01b815260040183838082843780830192505050945050505050604051602081830303815290604052805190602001209050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166351577ea9876040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561035857600080fd5b505afa15801561036c573d6000803e3d6000fd5b505050506040513d602081101561038257600080fd5b81019080805190602001909291905050508114610407576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f436f6e74656e742068617368206d69736d61746368000000000000000000000081525060200191505060405180910390fd5b606060008614806104185750600286145b1561042e57610427878461059c565b90506104b8565b600254861415610449576104428784610767565b90506104b7565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f556e6b6e6f776e2074656d706c6174654964000000000000000000000000000081525060200191505060405180910390fd5b5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c49298ac88836040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019060200280838360005b8381101561054f578082015181840152602081019050610534565b505050509050019350505050600060405180830381600087803b15801561057557600080fd5b505af1158015610589573d6000803e3d6000fd5b5050505050505050505050565b60025481565b606080826040519080825280602002602001820160405280156105ce5781602001602082028038833980820191505090505b5090506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d09cc57e866040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561064657600080fd5b505afa15801561065a573d6000803e3d6000fd5b505050506040513d602081101561067057600080fd5b810190808051906020019092919050505060001c90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114156106e95760008090505b848110156106e35760018382815181106106ca57fe5b60200260200101818152505080806001019150506106b4565b5061075c565b838110610741576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806109ec6028913960400191505060405180910390fd5b600182828151811061074f57fe5b6020026020010181815250505b819250505092915050565b6060600282146107c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806109c96023913960400191505060405180910390fd5b606060026040519080825280602002602001820160405280156107f45781602001602082028038833980820191505090505b5090506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d09cc57e866040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561086c57600080fd5b505afa158015610880573d6000803e3d6000fd5b505050506040513d602081101561089657600080fd5b810190808051906020019092919050505060001c90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81141561090f576001826000815181106108e357fe5b6020026020010181815250506001826001815181106108fe57fe5b6020026020010181815250506109bd565b60058110610985576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f416e73776572206d757374206265206265747765656e203020616e642034000081525060200191505060405180910390fd5b806004038260008151811061099657fe5b60200260200101818152505080826001815181106109b057fe5b6020026020010181815250505b81925050509291505056fe4e756d626572206f66206f7574636f6d657320657870656374656420746f2062652032416e73776572206d757374206265206265747765656e203020616e64206e756d4f7574636f6d6573a265627a7a72315820abd52a8d5d3ccb67c384524197507ac525c640d009250c3a5e4721fd1a7b6ef864736f6c634300050c0032000000000000000000000000ceafdd6bc0bef976fdcd1112955828e00543c0ce00000000000000000000000079e32ae03fb27b07c89c0c568f80287c01ca2e570000000000000000000000000000000000000000000000000000000000000005" -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/realitio_proxy/contract.py b/trader_backup/vendor/valory/contracts/realitio_proxy/contract.py deleted file mode 100644 index c7f40aec9..000000000 --- a/trader_backup/vendor/valory/contracts/realitio_proxy/contract.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- 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 the realitio proxy contract definition.""" - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi - - -class RealitioProxyContract(Contract): - """The RealitioProxy smart contract.""" - - contract_id = PublicId.from_str("valory/realitio_proxy:0.1.0") - - @classmethod - def build_resolve_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: bytes, - template_id: int, - question: str, - num_outcomes: int, - ) -> JSONLike: - """Build a `resolve` tx.""" - contract = cls.get_instance(ledger_api, contract_address) - data = contract.encodeABI( - fn_name="resolve", - args=[ - question_id, - template_id, - question, - num_outcomes, - ], - ) - return dict(data=data) diff --git a/trader_backup/vendor/valory/contracts/realitio_proxy/contract.yaml b/trader_backup/vendor/valory/contracts/realitio_proxy/contract.yaml deleted file mode 100644 index 3adbb2eea..000000000 --- a/trader_backup/vendor/valory/contracts/realitio_proxy/contract.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: realitio_proxy -author: valory -version: 0.1.0 -type: contract -description: RealitioProxy contract. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeickfnpykdx2ffgrrza6yhn7gfr2plis354oohzljhlnpwnp4kpe2u - build/Realitio.json: bafybeiaqw4aid7mitc4vfzhlcxhbncei4hd3ywok2ugzs3zkhcx3pliatm - contract.py: bafybeidcouc7xpdcntmzi5dgv5qwnp23dmctdzvof7kwsmzsk27iguaa2e -fingerprint_ignore_patterns: [] -class_name: RealitioProxyContract -contract_interface_paths: - ethereum: build/Realitio.json -dependencies: - web3: - version: <7,>=6.0.0 -contracts: [] diff --git a/trader_backup/vendor/valory/contracts/service_registry/__init__.py b/trader_backup/vendor/valory/contracts/service_registry/__init__.py deleted file mode 100644 index d616d9211..000000000 --- a/trader_backup/vendor/valory/contracts/service_registry/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 the support resources for the service registry contract.""" diff --git a/trader_backup/vendor/valory/contracts/service_registry/build/ServiceRegistry.json b/trader_backup/vendor/valory/contracts/service_registry/build/ServiceRegistry.json deleted file mode 100644 index cfb4e9391..000000000 --- a/trader_backup/vendor/valory/contracts/service_registry/build/ServiceRegistry.json +++ /dev/null @@ -1,1988 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ServiceRegistry", - "sourceName": "contracts/ServiceRegistry.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - }, - { - "internalType": "string", - "name": "_baseURI", - "type": "string" - }, - { - "internalType": "address", - "name": "_agentRegistry", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "AgentInstanceRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentInstancesSlotsFilled", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "AgentNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentNotInService", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "componentId", - "type": "uint256" - } - ], - "name": "ComponentNotFound", - "type": "error" - }, - { - "inputs": [], - "name": "HashExists", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectAgentBondingValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectRegistrationDepositValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "provided", - "type": "address" - }, - { - "internalType": "address", - "name": "expected", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OnlyOwnServiceMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorHasNoInstances", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "Overflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerOnly", - "type": "error" - }, - { - "inputs": [], - "name": "Paused", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrancyGuard", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceMustBeInactive", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "TransferFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "UnauthorizedMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "WrongAgentId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "numValues1", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numValues2", - "type": "uint256" - } - ], - "name": "WrongArrayLength", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongOperator", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "state", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceState", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "currentThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxThreshold", - "type": "uint256" - } - ], - "name": "WrongThreshold", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ActivateRegistration", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "string", - "name": "baseURI", - "type": "string" - } - ], - "name": "BaseURIChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "CreateMultisigWithAgents", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "CreateService", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "DeployService", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "drainer", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Drain", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "drainer", - "type": "address" - } - ], - "name": "DrainerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorSlashed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorUnbond", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "receiver", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Refund", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "agentInstance", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "RegisterInstance", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "TerminateService", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - } - ], - "name": "UpdateService", - "type": "event" - }, - { - "inputs": [], - "name": "CID_PREFIX", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "activateRegistration", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "agentRegistry", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newDrainer", - "type": "address" - } - ], - "name": "changeDrainer", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newManager", - "type": "address" - } - ], - "name": "changeManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "bool", - "name": "permission", - "type": "bool" - } - ], - "name": "changeMultisigPermission", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "changeOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "internalType": "struct AgentParams[]", - "name": "agentParams", - "type": "tuple[]" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - } - ], - "name": "create", - "outputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "multisigImplementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "deploy", - "outputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "drain", - "outputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "drainer", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "name": "exists", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getAgentInstances", - "outputs": [ - { - "internalType": "uint256", - "name": "numAgentInstances", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getAgentParams", - "outputs": [ - { - "internalType": "uint256", - "name": "numAgentIds", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "internalType": "struct AgentParams[]", - "name": "agentParams", - "type": "tuple[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "getInstancesForAgentId", - "outputs": [ - { - "internalType": "uint256", - "name": "numAgentInstances", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getOperatorBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getPreviousHashes", - "outputs": [ - { - "internalType": "uint256", - "name": "numHashes", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "configHashes", - "type": "bytes32[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getService", - "outputs": [ - { - "components": [ - { - "internalType": "uint96", - "name": "securityDeposit", - "type": "uint96" - }, - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "maxNumAgentInstances", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "numAgentInstances", - "type": "uint32" - }, - { - "internalType": "enum ServiceRegistry.ServiceState", - "name": "state", - "type": "uint8" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - } - ], - "internalType": "struct ServiceRegistry.Service", - "name": "service", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "enum IRegistry.UnitType", - "name": "unitType", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getUnitIdsOfService", - "outputs": [ - { - "internalType": "uint256", - "name": "numUnitIds", - "type": "uint256" - }, - { - "internalType": "uint32[]", - "name": "unitIds", - "type": "uint32[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "manager", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapAgentInstanceOperators", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapConfigHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapMultisigs", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapOperatorAndServiceIdAgentInstances", - "outputs": [ - { - "internalType": "address", - "name": "instance", - "type": "address" - }, - { - "internalType": "uint32", - "name": "agentId", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapOperatorAndServiceIdOperatorBalances", - "outputs": [ - { - "internalType": "uint96", - "name": "", - "type": "uint96" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceAndAgentIdAgentInstances", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceAndAgentIdAgentParams", - "outputs": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceIdSetAgentIds", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceIdSetComponentIds", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServices", - "outputs": [ - { - "internalType": "uint96", - "name": "securityDeposit", - "type": "uint96" - }, - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "maxNumAgentInstances", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "numAgentInstances", - "type": "uint32" - }, - { - "internalType": "enum ServiceRegistry.ServiceState", - "name": "state", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - } - ], - "name": "registerAgents", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "bURI", - "type": "string" - } - ], - "name": "setBaseURI", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - }, - { - "internalType": "uint96[]", - "name": "amounts", - "type": "uint96[]" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "slash", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "slashedFunds", - "outputs": [ - { - "internalType": "uint96", - "name": "", - "type": "uint96" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "terminate", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "refund", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "tokenByIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "unbond", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "refund", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "internalType": "struct AgentParams[]", - "name": "agentParams", - "type": "tuple[]" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "update", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x60a06040526001600a553480156200001657600080fd5b506040516200636638038062006366833981016040819052620000399162000160565b83836000620000498382620002a2565b506001620000588282620002a2565b50600891506200006b90508382620002a2565b506001600160a01b03166080525050600680546001600160a01b03191633179055506200036e565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000bb57600080fd5b81516001600160401b0380821115620000d857620000d862000093565b604051601f8301601f19908116603f0116810190828211818310171562000103576200010362000093565b816040528381526020925086838588010111156200012057600080fd5b600091505b8382101562000144578582018301518183018401529082019062000125565b83821115620001565760008385830101525b9695505050505050565b600080600080608085870312156200017757600080fd5b84516001600160401b03808211156200018f57600080fd5b6200019d88838901620000a9565b95506020870151915080821115620001b457600080fd5b620001c288838901620000a9565b94506040870151915080821115620001d957600080fd5b50620001e887828801620000a9565b606087015190935090506001600160a01b03811681146200020857600080fd5b939692955090935050565b600181811c908216806200022857607f821691505b6020821081036200024957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029d57600081815260208120601f850160051c81016020861015620002785750805b601f850160051c820191505b81811015620002995782815560010162000284565b5050505b505050565b81516001600160401b03811115620002be57620002be62000093565b620002d681620002cf845462000213565b846200024f565b602080601f8311600181146200030e5760008415620002f55750858301515b600019600386901b1c1916600185901b17855562000299565b600085815260208120601f198616915b828110156200033f578886015182559484019460019091019084016200031e565b50858210156200035e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051615fce620003986000396000818161043e01528181613e9e01526146600152615fce6000f3fe6080604052600436106103605760003560e01c80636f99f15c116101c6578063a5d059ca116100f7578063dff7672411610095578063ef0e239b1161006f578063ef0e239b14610bda578063f908bc7714610c07578063fbdeb3d714610c27578063ffa1ad7414610c4757600080fd5b8063dff7672414610b79578063e23f6fb414610b8c578063e985e9c514610b9f57600080fd5b8063b88d4fde116100d1578063b88d4fde14610af9578063c87b56dd14610b19578063cbf994f814610b39578063ccc9305d14610b5957600080fd5b8063a5d059ca14610a74578063a60e4c3c14610aab578063a6f9dae114610ad957600080fd5b80638a2bd86f1161016457806395d89b411161013e57806395d89b4114610a0a5780639890220b14610a1f578063a22cb46514610a34578063a3fbbaae14610a5457600080fd5b80638a2bd86f146109775780638da5cb5b146109bc57806392080b23146109dc57600080fd5b806373b8b6a2116101a057806373b8b6a2146108e25780637c5e63e01461090257806382694b1d1461093757806386a2bdd41461095757600080fd5b80636f99f15c1461085e57806370a082311461087e578063718934d81461089e57600080fd5b806342144854116102a05780634f6ccce71161023e5780635e4507fa116102185780635e4507fa1461079f5780636352211e146107bf57806363dd7615146107df5780636c0360eb1461084957600080fd5b80634f6ccce71461073857806355f804b31461075857806357838e851461077857600080fd5b8063481c6a751161027a578063481c6a75146106a25780634d486f85146106c25780634eb780da146106e25780634f558e791461071857600080fd5b806342144854146105a55780634236aff8146105f357806342842e0e1461068257600080fd5b806317351f7e1161030d57806321e4f7bb116102e757806321e4f7bb1461050257806323b872dd14610530578063323e010714610550578063406f14ad1461058557600080fd5b806317351f7e1461048057806318160ddd146104b05780631de286ba146104d457600080fd5b8063095ea7b31161033e578063095ea7b31461040a5780630d1cfcae1461042c57806310c6aa191461046057600080fd5b806301ffc9a71461036557806306fdde031461039a578063081812fc146103bc575b600080fd5b34801561037157600080fd5b50610385610380366004614e43565b610c78565b60405190151581526020015b60405180910390f35b3480156103a657600080fd5b506103af610cca565b6040516103919190614ec3565b3480156103c857600080fd5b506103f26103d7366004614ed6565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610391565b34801561041657600080fd5b5061042a610425366004614f04565b610d58565b005b34801561043857600080fd5b506103f27f000000000000000000000000000000000000000000000000000000000000000081565b34801561046c57600080fd5b5061042a61047b366004614f30565b610e3f565b34801561048c57600080fd5b5061038561049b366004614f30565b60146020526000908152604090205460ff1681565b3480156104bc57600080fd5b506104c660095481565b604051908152602001610391565b3480156104e057600080fd5b506104f46104ef366004614ed6565b610ef8565b604051610391929190614f4d565b34801561050e57600080fd5b5061052261051d366004614fb4565b61114e565b60405161039192919061501a565b34801561053c57600080fd5b5061042a61054b36600461503b565b61123c565b34801561055c57600080fd5b5061057061056b366004614fb4565b611416565b60405163ffffffff9091168152602001610391565b34801561059157600080fd5b506105706105a0366004614fb4565b61145f565b3480156105b157600080fd5b506105db6105c0366004614ed6565b6010602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610391565b3480156105ff57600080fd5b5061066f61060e366004614ed6565b6015602052600090815260409020805460018201546002909201546001600160601b03821692600160601b928390046001600160a01b031692909163ffffffff808216926401000000008304821692600160401b8104909216910460ff1687565b60405161039197969594939291906150b4565b34801561068e57600080fd5b5061042a61069d36600461503b565b61147b565b3480156106ae57600080fd5b506007546103f2906001600160a01b031681565b3480156106ce57600080fd5b506105226106dd366004614ed6565b611570565b3480156106ee57600080fd5b506103f26106fd366004614f30565b6011602052600090815260409020546001600160a01b031681565b34801561072457600080fd5b50610385610733366004614ed6565b6116c2565b34801561074457600080fd5b506104c6610753366004614ed6565b6116e4565b34801561076457600080fd5b5061042a6107733660046151d7565b611729565b34801561078457600080fd5b50600b546103f290600160601b90046001600160a01b031681565b3480156107ab57600080fd5b506103f26107ba366004614fb4565b6117d2565b3480156107cb57600080fd5b506103f26107da366004614ed6565b61180a565b3480156107eb57600080fd5b506108256107fa366004614ed6565b600e6020526000908152604090205463ffffffff81169064010000000090046001600160601b031682565b6040805163ffffffff90931683526001600160601b03909116602083015201610391565b34801561085557600080fd5b506103af61186f565b34801561086a57600080fd5b50600b546105db906001600160601b031681565b34801561088a57600080fd5b506104c6610899366004614f30565b61187c565b3480156108aa57600080fd5b506108be6108b9366004614fb4565b6118f0565b604080516001600160a01b03909316835263ffffffff909116602083015201610391565b3480156108ee57600080fd5b506103856108fd3660046152cf565b611936565b34801561090e57600080fd5b506103af6040518060400160405280600981526020016806630313730313232360bc1b81525081565b34801561094357600080fd5b50610385610952366004615399565b611d8b565b34801561096357600080fd5b506104c6610972366004614fb4565b611e24565b34801561098357600080fd5b506104c6610992366004614f04565b60a01b6001600160a01b03909116176000908152601060205260409020546001600160601b031690565b3480156109c857600080fd5b506006546103f2906001600160a01b031681565b3480156109e857600080fd5b506109fc6109f73660046153d7565b611e55565b60405161039192919061542f565b348015610a1657600080fd5b506103af611f90565b348015610a2b57600080fd5b506104c6611f9d565b348015610a4057600080fd5b5061042a610a4f366004615399565b6120fb565b348015610a6057600080fd5b5061042a610a6f366004614f30565b612167565b348015610a8057600080fd5b50610a94610a8f366004614f04565b612218565b604080519215158352602083019190915201610391565b348015610ab757600080fd5b50610acb610ac6366004614ed6565b6126b4565b604051610391929190615448565b348015610ae557600080fd5b5061042a610af4366004614f30565b612718565b348015610b0557600080fd5b5061042a610b14366004615496565b6127c9565b348015610b2557600080fd5b506103af610b34366004614ed6565b6128ae565b348015610b4557600080fd5b50610385610b5436600461563a565b612928565b348015610b6557600080fd5b50610a94610b74366004614f04565b612eb6565b610385610b873660046156d7565b613246565b610385610b9a366004614f04565b613841565b348015610bab57600080fd5b50610385610bba366004615757565b600560209081526000928352604080842090915290825290205460ff1681565b348015610be657600080fd5b50610bfa610bf5366004614ed6565b6139c0565b6040516103919190615785565b348015610c1357600080fd5b506103f2610c22366004615821565b613b40565b348015610c3357600080fd5b506104c6610c42366004615895565b613fe6565b348015610c5357600080fd5b506103af604051806040016040528060058152602001640312e302e360dc1b81525081565b60006301ffc9a760e01b6001600160e01b031983161480610ca957506380ac58cd60e01b6001600160e01b03198316145b80610cc45750635b5e139f60e01b6001600160e01b03198316145b92915050565b60008054610cd79061592a565b80601f0160208091040260200160405190810160405280929190818152602001828054610d039061592a565b8015610d505780601f10610d2557610100808354040283529160200191610d50565b820191906000526020600020905b815481529060010190602001808311610d3357829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b031633811480610da157506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b610de35760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6006546001600160a01b03163314610e7f5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b038116610ea65760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160601b0316600160601b6001600160a01b038416908102919091179091556040517f8d1e8547016120917daad7f81c42b48f7fee379badc48f1889f0f43bb619472590600090a250565b600081815260156020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff9104166005811115610f9957610f9961507c565b6005811115610faa57610faa61507c565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561102957602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411610fec5790505b50505050508152505090508060e001515192508267ffffffffffffffff8111156110555761105561510f565b60405190808252806020026020018201604052801561109a57816020015b60408051808201909152600080825260208201528152602001906001900390816110735790505b50915060005b8381101561114757600085905060208360e0015183815181106110c5576110c5615964565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260409081902081518083019092525492831681526401000000009092046001600160601b031692820192909252845185908490811061112a5761112a615964565b6020026020010181905250508061114090615990565b90506110a0565b5050915091565b602081811b83176000818152600f909252604090912054906060908267ffffffffffffffff8111156111825761118261510f565b6040519080825280602002602001820160405280156111ab578160200160208202803683370190505b50915060005b83811015611233576000828152600f602052604090208054829081106111d9576111d9615964565b9060005260206000200160009054906101000a90046001600160a01b031683828151811061120957611209615964565b6001600160a01b03909216602092830291909101909101528061122b81615990565b9150506111b1565b50509250929050565b6000818152600260205260409020546001600160a01b038481169116146112a55760405162461bcd60e51b815260206004820152600a60248201527f57524f4e475f46524f4d000000000000000000000000000000000000000000006044820152606401610dda565b6001600160a01b0382166112ef5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610dda565b336001600160a01b038416148061132957506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061134a57506000818152600460205260409020546001600160a01b031633145b6113875760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610dda565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6012602052816000526040600020818154811061143257600080fd5b9060005260206000209060089182820401919006600402915091509054906101000a900463ffffffff1681565b6013602052816000526040600020818154811061143257600080fd5b61148683838361123c565b6001600160a01b0382163b1561156b57604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af11580156114fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152191906159a9565b6001600160e01b0319161461156b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610dda565b505050565b600081815260156020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff91041660058111156116115761161161507c565b60058111156116225761162261507c565b8152602001600382018054806020026020016040519081016040528092919081815260200182805480156116a157602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116116645790505b50505050508152505090506116b681856142de565b91508151925050915091565b60008082118015610cc457506009546116dc9060016159c6565b821092915050565b60006116f18260016159c6565b905060095481111561172457600954604051637ae5968560e01b8152610dda918391600401918252602082015260400190565b919050565b6006546001600160a01b031633146117695760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b805160000361178b57604051637c946ed760e01b815260040160405180910390fd5b60086117978282615a24565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf6816040516117c79190614ec3565b60405180910390a150565b600f60205281600052604060002081815481106117ee57600080fd5b6000918252602090912001546001600160a01b03169150829050565b6000818152600260205260409020546001600160a01b0316806117245760405162461bcd60e51b815260206004820152600a60248201527f4e4f545f4d494e544544000000000000000000000000000000000000000000006044820152606401610dda565b60088054610cd79061592a565b60006001600160a01b0382166118d45760405162461bcd60e51b815260206004820152600c60248201527f5a45524f5f4144445245535300000000000000000000000000000000000000006044820152606401610dda565b506001600160a01b031660009081526003602052604090205490565b600d602052816000526040600020818154811061190c57600080fd5b6000918252602090912001546001600160a01b0381169250600160a01b900463ffffffff16905082565b600081815260156020908152604080832081516101008101835281546001600160601b0381168252600160601b908190046001600160a01b031694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a0840152849360c08401910460ff1660058111156119cd576119cd61507c565b60058111156119de576119de61507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015611a5d57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611a205790505b505050505081525050905060046005811115611a7b57611a7b61507c565b8160c001516005811115611a9157611a9161507c565b14611ad0578060c001516005811115611aac57611aac61507c565b604051633c053f9d60e21b8152600481019190915260248101849052604401610dda565b8351855114611aff57845184516040516308151c1160e41b815260048101929092526024820152604401610dda565b80602001516001600160a01b0316336001600160a01b031614611b535760208101516040516379f91cd360e01b81523360048201526001600160a01b03909116602482015260448101849052606401610dda565b845160005b81811015611d7e57600060116000898481518110611b7857611b78615964565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081205490931660a08a901b81178085526010909252919092205489519193506001600160601b03169081908a9086908110611bdd57611bdd615964565b60200260200101516001611bf19190615ae4565b6001600160601b03161115611c4b57600b8054829190600090611c1e9084906001600160601b0316615ae4565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060009050611ccf565b888481518110611c5d57611c5d615964565b6020908102919091010151600b8054600090611c839084906001600160601b0316615ae4565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550888481518110611cb957611cb9615964565b602002602001015181611ccc9190615b0f565b90505b600082815260106020526040902080546bffffffffffffffffffffffff19166001600160601b038316179055885188906001600160a01b038516907fa2e524bd0f71903485fbb3d6d50cb305f61005ceea2047c3ac92aa7e0d104306908c9088908110611d3e57611d3e615964565b6020026020010151604051611d6291906001600160601b0391909116815260200190565b60405180910390a350505080611d7790615990565b9050611b58565b5060019695505050505050565b6006546000906001600160a01b03163314611dce5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b038316611df55760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b03919091166000908152601460205260409020805460ff1916911515919091179055600190565b600c6020528160005260406000208181548110611e4057600080fd5b90600052602060002001600091509150505481565b6000606081846001811115611e6c57611e6c61507c565b03611efd5760008381526012602090815260409182902080548351818402810184019094528084529091830182828015611ef157602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611eb45790505b50505050509050611f85565b60008381526013602090815260409182902080548351818402810184019094528084529091830182828015611f7d57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611f405790505b505050505090505b805191509250929050565b60018054610cd79061592a565b60006001600a541115611fc3576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a55600b54600160601b90046001600160a01b0316331461201557600b5460405163312d21ff60e11b8152336004820152600160601b9091046001600160a01b03166024820152604401610dda565b50600b546001600160601b031680156120f357600b80546bffffffffffffffffffffffff19169055604051600090339083908381818185875af1925050503d806000811461207f576040519150601f19603f3d011682016040523d82523d6000602084013e612084565b606091505b50509050806120bc5760405163cd3f165960e01b81526000600482015230602482015233604482015260648101839052608401610dda565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2505b6001600a5590565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6006546001600160a01b031633146121a75760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b0381166121ce5760405163d92e233d60e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f2c1c11af44aa5608f1dca38c00275c30ea091e02417d36e70e9a1538689c433d90600090a250565b6000806001600a54111561223f576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146122845760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b0384166122ab5760405163d92e233d60e01b815260040160405180910390fd5b600083815260156020526040902060056002820154600160601b900460ff1660058111156122db576122db61507c565b14612324576002810154600160601b900460ff1660058111156123005761230061507c565b604051633c053f9d60e21b8152600481019190915260248101859052604401610dda565b60a084901b6001600160a01b038616176000818152600d6020908152604080832080548251818502810185019093528083529192909190849084015b828210156123ac57600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900463ffffffff1681830152825260019092019101612360565b50508251929350505060008190036123e95760405163df2ddd7360e01b81526001600160a01b038916600482015260248101889052604401610dda565b808460020160088282829054906101000a900463ffffffff1661240c9190615b37565b92506101000a81548163ffffffff021916908363ffffffff1602179055508360020160089054906101000a900463ffffffff1663ffffffff166000036124625760028401805460ff60601b1916600160601b1790555b60005b8181101561252a576000889050602084838151811061248657612486615964565b60209081029190910181015181015163ffffffff1690911b919091176000818152600e9092526040909120546124cd9064010000000090046001600160601b0316886159c6565b9650601160008584815181106124e5576124e5615964565b602090810291909101810151516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055508061252281615990565b915050612465565b506000838152600d6020526040812061254291614c87565b6000838152601060205260409020546001600160601b03168086111561256f57806001600160601b031695505b85156126685760008481526010602052604080822080546bffffffffffffffffffffffff19169055516001600160a01b038b169088908381818185875af1925050503d80600081146125dd576040519150601f19603f3d011682016040523d82523d6000602084013e6125e2565b606091505b50509050806126235760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038b16604482015260648101889052608401610dda565b896001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d8860405161265e91815260200190565b60405180910390a2505b60405188906001600160a01b038b16907f5ebf7fe30be09f0f03b9195632508d95c8b67bf010c93abda67f70d5d9599d1e90600090a350506001600a8190559793965092945050505050565b6000818152600c60209081526040808320805482518185028101850190935280835260609383018282801561270857602002820191906000526020600020905b8154815260200190600101908083116126f4575b5050505050905080519150915091565b6006546001600160a01b031633146127585760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b03811661277f5760405163d92e233d60e01b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b90600090a250565b6127d485858561123c565b6001600160a01b0384163b156128a757604051630a85bd0160e11b808252906001600160a01b0386169063150b7a029061281a9033908a90899089908990600401615b54565b6020604051808303816000875af1158015612839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285d91906159a9565b6001600160e01b031916146128a75760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610dda565b5050505050565b6000818152601560205260408120600101546060915060086040518060400160405280600981526020016806630313730313232360bc1b8152506128f18361442f565b6128fe608085901b61442f565b6040516020016129119493929190615ba8565b604051602081830303815290604052915050919050565b6007546000906001600160a01b0316331461296b5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b60006129768361180a565b9050876001600160a01b0316816001600160a01b0316146129bd5760405163521eb56d60e11b81526001600160a01b03808a16600483015282166024820152604401610dda565b600083815260156020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a08401529192909160c084019160ff9104166005811115612a5757612a5761507c565b6005811115612a6857612a6861507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015612ae757602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612aaa5790505b505050505081525050905060016005811115612b0557612b0561507c565b8160c001516005811115612b1b57612b1b61507c565b14612b36578060c0015160058111156123005761230061507c565b612b418888886145ff565b63ffffffff85166060820152600060808201819052875167ffffffffffffffff811115612b7057612b7061510f565b604051908082528060200260200182016040528015612b99578160200160208202803683370190505b5090506000885167ffffffffffffffff811115612bb857612bb861510f565b604051908082528060200260200182016040528015612bfd57816020015b6040805180820190915260008082526020820152815260200190600190039081612bd65790505b5090506000805b8a51811015612d3257898181518110612c1f57612c1f615964565b60200260200101516000015163ffffffff16600003612c9457600088905060208c8381518110612c5157612c51615964565b60209081029190910181015163ffffffff1690911b919091176000908152600e9091526040902080546fffffffffffffffffffffffffffffffff19169055612d20565b8a8181518110612ca657612ca6615964565b6020026020010151848381518110612cc057612cc0615964565b602002602001019063ffffffff16908163ffffffff1681525050898181518110612cec57612cec615964565b6020026020010151838381518110612d0657612d06615964565b60200260200101819052508180612d1c90615990565b9250505b80612d2a81615990565b915050612c04565b5060408401518b8114612d69576000888152600c602090815260408083208054600181018255908452919092200182905585018c90525b612d76858585858c6147c6565b6000888152601560209081526040918290208751918801516001600160a01b0316600160601b9081026001600160601b03909316929092178155918701516001830155606087015160028301805460808a015160a08b015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c08a01518a9594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115612e4b57612e4b61507c565b021790555060e08201518051612e6b916003840191602090910190614ca8565b50506040518d81528991507fff312ce131c4d73ac90ece91266be7090486c5e15f78b7ea2b108c36dfd475299060200160405180910390a25060019c9b505050505050505050505050565b6000806001600a541115612edd576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314612f225760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6000612f2d8461180a565b9050846001600160a01b0316816001600160a01b031614612f745760405163521eb56d60e11b81526001600160a01b03808716600483015282166024820152604401610dda565b600084815260156020526040902060016002820154600160601b900460ff166005811115612fa457612fa461507c565b1480612fcf575060056002820154600160601b900460ff166005811115612fcd57612fcd61507c565b145b15613018576002810154600160601b900460ff166005811115612ff457612ff461507c565b604051633c053f9d60e21b8152600481019190915260248101869052604401610dda565b6002810154600160401b900463ffffffff16156130525760028101805460ff60601b19166c05000000000000000000000000179055613068565b60028101805460ff60601b1916600160601b1790555b600085815260126020526040812061307f91614d57565b600085815260136020526040812061309691614d57565b60005b600382015481101561312357600086905060208360030183815481106130c1576130c1615964565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff16901b81179050600f600082815260200190815260200160002060006131129190614d7c565b5061311c81615990565b9050613099565b5080546040516001600160601b0390911693506000906001600160a01b0388169085908381818185875af1925050503d806000811461317e576040519150601f19603f3d011682016040523d82523d6000602084013e613183565b606091505b50509050806131c45760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038816604482015260648101859052608401610dda565b866001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d856040516131ff91815260200190565b60405180910390a260405186907fe45f5b9540df4f71b7e044809fa318806328c1ea2388a70c7373d97ccf8a0faa90600090a250506001600a819055959194509092505050565b6007546000906001600160a01b031633146132895760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b81518351146132b857825182516040516308151c1160e41b815260048101929092526024820152604401610dda565b6000848152601560205260409020600280820154600160601b900460ff1660058111156132e7576132e761507c565b1461330c576002810154600160601b900460ff166005811115612ff457612ff461507c565b83516000805b82811015613401576000889050602087838151811061333357613333615964565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260408082208151808301909252549384168082526401000000009094046001600160601b03169481019490945290929190036133d45787838151811061339f5761339f615964565b60200260200101518a6040516332832be560e21b8152600401610dda92919063ffffffff929092168252602082015260400190565b60208101516133ec906001600160601b0316856159c6565b93505050806133fa90615990565b9050613312565b5080341461343257604051637ebbcab960e11b81523460048201526024810182905260448101889052606401610dda565b6001600160a01b03888116600090815260116020526040902054161561346e576040516322ddebd960e21b815260048101889052602401610dda565b60a087901b6001600160a01b0389161760005b8381101561376257600088828151811061349d5761349d615964565b6020026020010151905060008883815181106134bb576134bb615964565b60200260200101519050816001600160a01b03168c6001600160a01b0316036134fa576040516322ddebd960e21b8152600481018c9052602401610dda565b6001600160a01b038281166000908152601160205260409020541615613551576001600160a01b038281166000908152601160205260409081902054905163631695bd60e01b815291166004820152602401610dda565b60008b905060208a858151811061356a5761356a615964565b60209081029190910181015163ffffffff90811690921b929092176000818152600e8452604080822054600f909552902054909290911690036135c3576040516304ad100760e21b8152600481018d9052602401610dda565b6000818152600f602090815260408083208054600181810183559185528385200180546001600160a01b03808a166001600160a01b031990921682179092558a8652600d8552838620845180860190955290845263ffffffff8089168587019081528254948501835591875294909520925192909101805494518416600160a01b0277ffffffffffffffffffffffffffffffffffffffffffffffff19909516929091169190911792909217909155600289018054600160401b900490911690600861368d83615c3a565b91906101000a81548163ffffffff021916908363ffffffff160217905550508c60116000856001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001600160a01b03168c8e6001600160a01b03167f6835389a6da5341647f18cbe0a89c56f473f4c17bfaee6e6d07d61f1928e0b7c85604051613746919063ffffffff91909116815260200190565b60405180910390a45050508061375b90615990565b9050613481565b50600284015463ffffffff64010000000082048116600160401b90920416036137a45760028401805460ff60601b19166c030000000000000000000000001790555b600081815260106020526040812080543492906137cb9084906001600160601b0316615ae4565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550886001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161382a91815260200190565b60405180910390a250600198975050505050505050565b6007546000906001600160a01b031633146138845760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b600061388f8361180a565b9050836001600160a01b0316816001600160a01b0316146138d65760405163521eb56d60e11b81526001600160a01b03808616600483015282166024820152604401610dda565b600083815260156020526040902060016002820154600160601b900460ff1660058111156139065761390661507c565b1461392757604051635960d22f60e11b815260048101859052602401610dda565b80546001600160601b0316341461396c578054604051631c30abbb60e31b81523460048201526001600160601b03909116602482015260448101859052606401610dda565b60028101805460ff60601b19166c0200000000000000000000000017905560405184907fa48b531f972c0e4aca57afcc5c099c52a7bd21bc5e2a1b733eec3be9e88da97a90600090a2506001949350505050565b613a086040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b60008281526015602090815260409182902082516101008101845281546001600160601b0381168252600160601b908190046001600160a01b031693820193909352600182015493810193909352600281015463ffffffff8082166060860152640100000000820481166080860152600160401b82041660a0850152909160c08401910460ff166005811115613aa057613aa061507c565b6005811115613ab157613ab161507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613b3057602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613af35790505b5050505050815250509050919050565b60006001600a541115613b66576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314613bab5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6000613bb68561180a565b9050856001600160a01b0316816001600160a01b031614613bfd5760405163521eb56d60e11b81526001600160a01b03808816600483015282166024820152604401610dda565b6001600160a01b03841660009081526014602052604090205460ff16613c405760405162a2307960e51b81526001600160a01b0385166004820152602401610dda565b600085815260156020526040902060036002820154600160601b900460ff166005811115613c7057613c7061507c565b14613cb9576002810154600160601b900460ff166005811115613c9557613c9561507c565b604051633c053f9d60e21b8152600481019190915260248101879052604401610dda565b604080516101008101825282546001600160601b0381168252600160601b908190046001600160a01b03166020830152600184015492820192909252600283015463ffffffff8082166060840152640100000000820481166080840152600160401b82041660a0830152600092613de69291859160c08401910460ff166005811115613d4757613d4761507c565b6005811115613d5857613d5861507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613dd757602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613d9a5790505b505050505081525050886142de565b6002830154604051631e731b7560e31b81529192506001600160a01b0388169163f398dba891613e2391859163ffffffff16908a90600401615c5d565b6020604051808303816000875af1158015613e42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e669190615c98565b6000888152601360205260409020600384018054929650613e8692614d9a565b506040516304d9dc3f60e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906309b3b87e90613ed6906003860190600401615cb5565b600060405180830381865afa158015613ef3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613f1b9190810190615e3d565b60008881526012602090815260409091208251613f3e9391929190910190614ca8565b5081546001600160601b0316600160601b6001600160a01b03861690810291909117835560028301805460ff60601b19166c0400000000000000000000000017905560405188907f2d53f895cd5faf3cddba94a25c2ced2105885b5b37450ff430ffa3cbdf332c7490600090a360405187907fa133ed72c03a7d008deaae618a61613c4fd41c67bba1cad1a6bc0a1c5a9c156e90600090a250506001600a5550949350505050565b60006001600a54111561400c576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146140515760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b0386166140785760405163d92e233d60e01b815260040160405180910390fd5b6140838585856145ff565b60005b8451811015614117578381815181106140a1576140a1615964565b60200260200101516000015163ffffffff16600014806140e757508381815181106140ce576140ce615964565b6020026020010151602001516001600160601b03166000145b1561410557604051637c946ed760e01b815260040160405180910390fd5b8061410f81615990565b915050614086565b50506009548061412681615990565b9150506141716040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b63ffffffff8316606082015260408101869052600160c08201818152505061419d8186868851866147c6565b6000828152601560209081526040918290208351918401516001600160a01b0316600160601b9081026001600160601b039093169290921781559183015160018301556060830151600283018054608086015160a087015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c0860151869594909360ff60601b19166cffffffffff00000000000000001990921691909117908360058111156142725761427261507c565b021790555060e08201518051614292916003840191602090910190614ca8565b50505060098290556142a48783614a7d565b60405182907f9169d45eacd63571e315a0504da919b7c89de505493e7b34051802dd0816a06990600090a2506001600a5595945050505050565b60608260a0015163ffffffff1667ffffffffffffffff8111156143035761430361510f565b60405190808252806020026020018201604052801561432c578160200160208202803683370190505b5090506000805b8460e001515181101561442757600084905060208660e00151838151811061435d5761435d615964565b602002602001015163ffffffff16901b8117905060005b6000828152600f6020526040902054811015614412576000828152600f602052604090208054829081106143aa576143aa615964565b9060005260206000200160009054906101000a90046001600160a01b03168585815181106143da576143da615964565b6001600160a01b0390921660209283029190910190910152836143fc81615990565b945050808061440a90615990565b915050614374565b5050808061441f90615990565b915050614333565b505092915050565b7aff00000000000000ff00000000000000ff00000000000000ff00006bffffffff0000000000000000604083901c9081167bffffffff00000000000000000000000000000000000000000000000084161760201c6fffffffff000000000000000000000000919091166001600160e01b031984161717601081901c9182167eff00000000000000ff00000000000000ff00000000000000ff000000000000821617600890811c7bff00000000000000ff00000000000000ff00000000000000ff000000939093167fff00000000000000ff00000000000000ff00000000000000ff000000000000009290921691909117919091179081901c7e0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f167f0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f00600492831c16179061459b827f06060606060606060606060606060606060606060606060606060606060606066159c6565b901c7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f1660276145cb9190615ed7565b6145f5827f30303030303030303030303030303030303030303030303030303030303030306159c6565b610cc491906159c6565b600083900361462157604051637c946ed760e01b815260040160405180910390fd5b8151158061463157508051825114155b1561465c57815181516040516308151c1160e41b815260048101929092526024820152604401610dda565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156146bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146e09190615ef6565b90506000805b84518110156147be576146fa8260016159c6565b85828151811061470c5761470c615964565b602002602001015163ffffffff16108061474457508285828151811061473457614734615964565b602002602001015163ffffffff16115b156147895784818151811061475b5761475b615964565b6020026020010151604051632ab10b0b60e21b8152600401610dda919063ffffffff91909116815260200190565b84818151811061479b5761479b615964565b602002602001015163ffffffff16915080806147b690615990565b9150506146e6565b505050505050565b60008267ffffffffffffffff8111156147e1576147e161510f565b60405190808252806020026020018201604052801561480a578160200160208202803683370190505b5060e087015260005b8381101561499a5785818151811061482d5761482d615964565b60200260200101518760e00151828151811061484b5761484b615964565b63ffffffff909216602092830291909101820152865184919088908490811061487657614876615964565b602002602001015163ffffffff16901b8117905085828151811061489c5761489c615964565b6020908102919091018101516000838152600e8352604090208151815492909301516001600160601b0316640100000000026fffffffffffffffffffffffffffffffff1990921663ffffffff90931692909217179055855186908390811061490657614906615964565b602002602001015160000151886080018181516149239190615f0f565b63ffffffff1690525085516001600160601b0384169087908490811061494b5761494b615964565b6020026020010151602001516001600160601b031611156149875785828151811061497857614978615964565b60200260200101516020015192505b508061499281615990565b915050614813565b506001600160601b038116865260808601516000906149ba906002615f2e565b6149c5906001615f0f565b63ffffffff1690506149d8600382615f70565b6000036149f1576149ea600382615f84565b9050614a0a565b6149fc600382615f84565b614a079060016159c6565b90505b80876060015163ffffffff161080614a355750866080015163ffffffff16876060015163ffffffff16115b15614a74576060870151608088015160405163eb3a8ba360e01b815263ffffffff92831660048201526024810184905291166044820152606401610dda565b50505050505050565b614a878282614b6d565b6001600160a01b0382163b15614b6957604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af1158015614afb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b1f91906159a9565b6001600160e01b03191614614b695760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610dda565b5050565b6001600160a01b038216614bb75760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610dda565b6000818152600260205260409020546001600160a01b031615614c1c5760405162461bcd60e51b815260206004820152600e60248201527f414c52454144595f4d494e5445440000000000000000000000000000000000006044820152606401610dda565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b5080546000825590600052602060002090810190614ca59190614de8565b50565b82805482825590600052602060002090600701600890048101928215614d475791602002820160005b83821115614d1557835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614cd1565b8015614d455782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614d15565b505b50614d53929150614e18565b5090565b508054600082556007016008900490600052602060002090810190614ca59190614e18565b5080546000825590600052602060002090810190614ca59190614e18565b82805482825590600052602060002090600701600890048101928215614d47576000526020600020916007016008900482015b82811115614d47578254825591600101919060010190614dcd565b5b80821115614d5357805477ffffffffffffffffffffffffffffffffffffffffffffffff19168155600101614de9565b5b80821115614d535760008155600101614e19565b6001600160e01b031981168114614ca557600080fd5b600060208284031215614e5557600080fd5b8135614e6081614e2d565b9392505050565b60005b83811015614e82578181015183820152602001614e6a565b83811115614e91576000848401525b50505050565b60008151808452614eaf816020860160208601614e67565b601f01601f19169290920160200192915050565b602081526000614e606020830184614e97565b600060208284031215614ee857600080fd5b5035919050565b6001600160a01b0381168114614ca557600080fd5b60008060408385031215614f1757600080fd5b8235614f2281614eef565b946020939093013593505050565b600060208284031215614f4257600080fd5b8135614e6081614eef565b6000604080830185845260208281860152818651808452606087019150828801935060005b81811015614fa6578451805163ffffffff1684528401516001600160601b0316848401529383019391850191600101614f72565b509098975050505050505050565b60008060408385031215614fc757600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b8381101561500f5781516001600160a01b031687529582019590820190600101614fea565b509495945050505050565b8281526040602082015260006150336040830184614fd6565b949350505050565b60008060006060848603121561505057600080fd5b833561505b81614eef565b9250602084013561506b81614eef565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b600681106150b057634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03881681526001600160a01b03871660208201526040810186905263ffffffff85811660608301528481166080830152831660a082015260e0810161510360c0830184615092565b98975050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156151485761514861510f565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156151775761517761510f565b604052919050565b600067ffffffffffffffff8311156151995761519961510f565b6151ac601f8401601f191660200161514e565b90508281528383830111156151c057600080fd5b828260208301376000602084830101529392505050565b6000602082840312156151e957600080fd5b813567ffffffffffffffff81111561520057600080fd5b8201601f8101841361521157600080fd5b6150338482356020840161517f565b600067ffffffffffffffff82111561523a5761523a61510f565b5060051b60200190565b600082601f83011261525557600080fd5b8135602061526a61526583615220565b61514e565b82815260059290921b8401810191818101908684111561528957600080fd5b8286015b848110156152ad5780356152a081614eef565b835291830191830161528d565b509695505050505050565b80356001600160601b038116811461172457600080fd5b6000806000606084860312156152e457600080fd5b833567ffffffffffffffff808211156152fc57600080fd5b61530887838801615244565b945060209150818601358181111561531f57600080fd5b86019050601f8101871361533257600080fd5b803561534061526582615220565b81815260059190911b8201830190838101908983111561535f57600080fd5b928401925b8284101561538457615375846152b8565b82529284019290840190615364565b96999698505050506040949094013593505050565b600080604083850312156153ac57600080fd5b82356153b781614eef565b9150602083013580151581146153cc57600080fd5b809150509250929050565b600080604083850312156153ea57600080fd5b823560028110614f2257600080fd5b600081518084526020808501945080840160005b8381101561500f57815163ffffffff168752958201959082019060010161540d565b82815260406020820152600061503360408301846153f9565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156154895784518352938301939183019160010161546d565b5090979650505050505050565b6000806000806000608086880312156154ae57600080fd5b85356154b981614eef565b945060208601356154c981614eef565b935060408601359250606086013567ffffffffffffffff808211156154ed57600080fd5b818801915088601f83011261550157600080fd5b81358181111561551057600080fd5b89602082850101111561552257600080fd5b9699959850939650602001949392505050565b63ffffffff81168114614ca557600080fd5b600082601f83011261555857600080fd5b8135602061556861526583615220565b82815260059290921b8401810191818101908684111561558757600080fd5b8286015b848110156152ad57803561559e81615535565b835291830191830161558b565b600082601f8301126155bc57600080fd5b813560206155cc61526583615220565b82815260069290921b840181019181810190868411156155eb57600080fd5b8286015b848110156152ad57604081890312156156085760008081fd5b615610615125565b813561561b81615535565b81526156288286016152b8565b818601528352918301916040016155ef565b60008060008060008060c0878903121561565357600080fd5b863561565e81614eef565b955060208701359450604087013567ffffffffffffffff8082111561568257600080fd5b61568e8a838b01615547565b955060608901359150808211156156a457600080fd5b506156b189828a016155ab565b93505060808701356156c281615535565b8092505060a087013590509295509295509295565b600080600080608085870312156156ed57600080fd5b84356156f881614eef565b935060208501359250604085013567ffffffffffffffff8082111561571c57600080fd5b61572888838901615244565b9350606087013591508082111561573e57600080fd5b5061574b87828801615547565b91505092959194509250565b6000806040838503121561576a57600080fd5b823561577581614eef565b915060208301356153cc81614eef565b602081526001600160601b0382511660208201526001600160a01b03602083015116604082015260408201516060820152600060608301516157cf608084018263ffffffff169052565b50608083015163ffffffff811660a08401525060a083015163ffffffff811660c08401525060c083015161580660e0840182615092565b5060e0830151610100838101526150336101208401826153f9565b6000806000806080858703121561583757600080fd5b843561584281614eef565b935060208501359250604085013561585981614eef565b9150606085013567ffffffffffffffff81111561587557600080fd5b8501601f8101871361588657600080fd5b61574b8782356020840161517f565b600080600080600060a086880312156158ad57600080fd5b85356158b881614eef565b945060208601359350604086013567ffffffffffffffff808211156158dc57600080fd5b6158e889838a01615547565b945060608801359150808211156158fe57600080fd5b5061590b888289016155ab565b925050608086013561591c81615535565b809150509295509295909350565b600181811c9082168061593e57607f821691505b60208210810361595e57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016159a2576159a261597a565b5060010190565b6000602082840312156159bb57600080fd5b8151614e6081614e2d565b600082198211156159d9576159d961597a565b500190565b601f82111561156b57600081815260208120601f850160051c81016020861015615a055750805b601f850160051c820191505b818110156147be57828155600101615a11565b815167ffffffffffffffff811115615a3e57615a3e61510f565b615a5281615a4c845461592a565b846159de565b602080601f831160018114615a875760008415615a6f5750858301515b600019600386901b1c1916600185901b1785556147be565b600085815260208120601f198616915b82811015615ab657888601518255948401946001909101908401615a97565b5085821015615ad45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006001600160601b03808316818516808303821115615b0657615b0661597a565b01949350505050565b60006001600160601b0383811690831681811015615b2f57615b2f61597a565b039392505050565b600063ffffffff83811690831681811015615b2f57615b2f61597a565b60006001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b6000808654615bb68161592a565b60018281168015615bce5760018114615be357615c12565b60ff1984168752821515830287019450615c12565b8a60005260208060002060005b85811015615c095781548a820152908401908201615bf0565b50505082870194505b505050508551615c26818360208a01614e67565b019384525050602082015260400192915050565b600063ffffffff808316818103615c5357615c5361597a565b6001019392505050565b606081526000615c706060830186614fd6565b63ffffffff851660208401528281036040840152615c8e8185614e97565b9695505050505050565b600060208284031215615caa57600080fd5b8151614e6081614eef565b60006020808301818452808554615cd0818490815260200190565b60008881526020812094509092505b81600782011015615d5557835463ffffffff808216855281871c811687860152604082811c821690860152606082811c821690860152608082811c82169086015260a082811c82169086015260c082811c9091169085015260e090811c9084015260019093019261010090920191600801615cdf565b92549281811015615d715763ffffffff84168352918401916001015b81811015615d8c5783851c63ffffffff168352918401916001015b81811015615da957604084901c63ffffffff168352918401916001015b81811015615dc657606084901c63ffffffff168352918401916001015b81811015615de357608084901c63ffffffff168352918401916001015b81811015615e005760a084901c63ffffffff168352918401916001015b81811015615e1d5760c084901c63ffffffff168352918401916001015b81811015615e315760e084901c8352918401915b50909695505050505050565b60006020808385031215615e5057600080fd5b825167ffffffffffffffff811115615e6757600080fd5b8301601f81018513615e7857600080fd5b8051615e8661526582615220565b81815260059190911b82018301908381019087831115615ea557600080fd5b928401925b82841015615ecc578351615ebd81615535565b82529284019290840190615eaa565b979650505050505050565b6000816000190483118215151615615ef157615ef161597a565b500290565b600060208284031215615f0857600080fd5b5051919050565b600063ffffffff808316818516808303821115615b0657615b0661597a565b600063ffffffff80831681851681830481118215151615615f5157615f5161597a565b02949350505050565b634e487b7160e01b600052601260045260246000fd5b600082615f7f57615f7f615f5a565b500690565b600082615f9357615f93615f5a565b50049056fea2646970667358221220c6f47c49865f99357fc7f3a83dfde648490b39975e4ec4242e3bcab08caabf3664736f6c634300080f0033", - "deployedBytecode": "0x6080604052600436106103605760003560e01c80636f99f15c116101c6578063a5d059ca116100f7578063dff7672411610095578063ef0e239b1161006f578063ef0e239b14610bda578063f908bc7714610c07578063fbdeb3d714610c27578063ffa1ad7414610c4757600080fd5b8063dff7672414610b79578063e23f6fb414610b8c578063e985e9c514610b9f57600080fd5b8063b88d4fde116100d1578063b88d4fde14610af9578063c87b56dd14610b19578063cbf994f814610b39578063ccc9305d14610b5957600080fd5b8063a5d059ca14610a74578063a60e4c3c14610aab578063a6f9dae114610ad957600080fd5b80638a2bd86f1161016457806395d89b411161013e57806395d89b4114610a0a5780639890220b14610a1f578063a22cb46514610a34578063a3fbbaae14610a5457600080fd5b80638a2bd86f146109775780638da5cb5b146109bc57806392080b23146109dc57600080fd5b806373b8b6a2116101a057806373b8b6a2146108e25780637c5e63e01461090257806382694b1d1461093757806386a2bdd41461095757600080fd5b80636f99f15c1461085e57806370a082311461087e578063718934d81461089e57600080fd5b806342144854116102a05780634f6ccce71161023e5780635e4507fa116102185780635e4507fa1461079f5780636352211e146107bf57806363dd7615146107df5780636c0360eb1461084957600080fd5b80634f6ccce71461073857806355f804b31461075857806357838e851461077857600080fd5b8063481c6a751161027a578063481c6a75146106a25780634d486f85146106c25780634eb780da146106e25780634f558e791461071857600080fd5b806342144854146105a55780634236aff8146105f357806342842e0e1461068257600080fd5b806317351f7e1161030d57806321e4f7bb116102e757806321e4f7bb1461050257806323b872dd14610530578063323e010714610550578063406f14ad1461058557600080fd5b806317351f7e1461048057806318160ddd146104b05780631de286ba146104d457600080fd5b8063095ea7b31161033e578063095ea7b31461040a5780630d1cfcae1461042c57806310c6aa191461046057600080fd5b806301ffc9a71461036557806306fdde031461039a578063081812fc146103bc575b600080fd5b34801561037157600080fd5b50610385610380366004614e43565b610c78565b60405190151581526020015b60405180910390f35b3480156103a657600080fd5b506103af610cca565b6040516103919190614ec3565b3480156103c857600080fd5b506103f26103d7366004614ed6565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610391565b34801561041657600080fd5b5061042a610425366004614f04565b610d58565b005b34801561043857600080fd5b506103f27f000000000000000000000000000000000000000000000000000000000000000081565b34801561046c57600080fd5b5061042a61047b366004614f30565b610e3f565b34801561048c57600080fd5b5061038561049b366004614f30565b60146020526000908152604090205460ff1681565b3480156104bc57600080fd5b506104c660095481565b604051908152602001610391565b3480156104e057600080fd5b506104f46104ef366004614ed6565b610ef8565b604051610391929190614f4d565b34801561050e57600080fd5b5061052261051d366004614fb4565b61114e565b60405161039192919061501a565b34801561053c57600080fd5b5061042a61054b36600461503b565b61123c565b34801561055c57600080fd5b5061057061056b366004614fb4565b611416565b60405163ffffffff9091168152602001610391565b34801561059157600080fd5b506105706105a0366004614fb4565b61145f565b3480156105b157600080fd5b506105db6105c0366004614ed6565b6010602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610391565b3480156105ff57600080fd5b5061066f61060e366004614ed6565b6015602052600090815260409020805460018201546002909201546001600160601b03821692600160601b928390046001600160a01b031692909163ffffffff808216926401000000008304821692600160401b8104909216910460ff1687565b60405161039197969594939291906150b4565b34801561068e57600080fd5b5061042a61069d36600461503b565b61147b565b3480156106ae57600080fd5b506007546103f2906001600160a01b031681565b3480156106ce57600080fd5b506105226106dd366004614ed6565b611570565b3480156106ee57600080fd5b506103f26106fd366004614f30565b6011602052600090815260409020546001600160a01b031681565b34801561072457600080fd5b50610385610733366004614ed6565b6116c2565b34801561074457600080fd5b506104c6610753366004614ed6565b6116e4565b34801561076457600080fd5b5061042a6107733660046151d7565b611729565b34801561078457600080fd5b50600b546103f290600160601b90046001600160a01b031681565b3480156107ab57600080fd5b506103f26107ba366004614fb4565b6117d2565b3480156107cb57600080fd5b506103f26107da366004614ed6565b61180a565b3480156107eb57600080fd5b506108256107fa366004614ed6565b600e6020526000908152604090205463ffffffff81169064010000000090046001600160601b031682565b6040805163ffffffff90931683526001600160601b03909116602083015201610391565b34801561085557600080fd5b506103af61186f565b34801561086a57600080fd5b50600b546105db906001600160601b031681565b34801561088a57600080fd5b506104c6610899366004614f30565b61187c565b3480156108aa57600080fd5b506108be6108b9366004614fb4565b6118f0565b604080516001600160a01b03909316835263ffffffff909116602083015201610391565b3480156108ee57600080fd5b506103856108fd3660046152cf565b611936565b34801561090e57600080fd5b506103af6040518060400160405280600981526020016806630313730313232360bc1b81525081565b34801561094357600080fd5b50610385610952366004615399565b611d8b565b34801561096357600080fd5b506104c6610972366004614fb4565b611e24565b34801561098357600080fd5b506104c6610992366004614f04565b60a01b6001600160a01b03909116176000908152601060205260409020546001600160601b031690565b3480156109c857600080fd5b506006546103f2906001600160a01b031681565b3480156109e857600080fd5b506109fc6109f73660046153d7565b611e55565b60405161039192919061542f565b348015610a1657600080fd5b506103af611f90565b348015610a2b57600080fd5b506104c6611f9d565b348015610a4057600080fd5b5061042a610a4f366004615399565b6120fb565b348015610a6057600080fd5b5061042a610a6f366004614f30565b612167565b348015610a8057600080fd5b50610a94610a8f366004614f04565b612218565b604080519215158352602083019190915201610391565b348015610ab757600080fd5b50610acb610ac6366004614ed6565b6126b4565b604051610391929190615448565b348015610ae557600080fd5b5061042a610af4366004614f30565b612718565b348015610b0557600080fd5b5061042a610b14366004615496565b6127c9565b348015610b2557600080fd5b506103af610b34366004614ed6565b6128ae565b348015610b4557600080fd5b50610385610b5436600461563a565b612928565b348015610b6557600080fd5b50610a94610b74366004614f04565b612eb6565b610385610b873660046156d7565b613246565b610385610b9a366004614f04565b613841565b348015610bab57600080fd5b50610385610bba366004615757565b600560209081526000928352604080842090915290825290205460ff1681565b348015610be657600080fd5b50610bfa610bf5366004614ed6565b6139c0565b6040516103919190615785565b348015610c1357600080fd5b506103f2610c22366004615821565b613b40565b348015610c3357600080fd5b506104c6610c42366004615895565b613fe6565b348015610c5357600080fd5b506103af604051806040016040528060058152602001640312e302e360dc1b81525081565b60006301ffc9a760e01b6001600160e01b031983161480610ca957506380ac58cd60e01b6001600160e01b03198316145b80610cc45750635b5e139f60e01b6001600160e01b03198316145b92915050565b60008054610cd79061592a565b80601f0160208091040260200160405190810160405280929190818152602001828054610d039061592a565b8015610d505780601f10610d2557610100808354040283529160200191610d50565b820191906000526020600020905b815481529060010190602001808311610d3357829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b031633811480610da157506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b610de35760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6006546001600160a01b03163314610e7f5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b038116610ea65760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160601b0316600160601b6001600160a01b038416908102919091179091556040517f8d1e8547016120917daad7f81c42b48f7fee379badc48f1889f0f43bb619472590600090a250565b600081815260156020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff9104166005811115610f9957610f9961507c565b6005811115610faa57610faa61507c565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561102957602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411610fec5790505b50505050508152505090508060e001515192508267ffffffffffffffff8111156110555761105561510f565b60405190808252806020026020018201604052801561109a57816020015b60408051808201909152600080825260208201528152602001906001900390816110735790505b50915060005b8381101561114757600085905060208360e0015183815181106110c5576110c5615964565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260409081902081518083019092525492831681526401000000009092046001600160601b031692820192909252845185908490811061112a5761112a615964565b6020026020010181905250508061114090615990565b90506110a0565b5050915091565b602081811b83176000818152600f909252604090912054906060908267ffffffffffffffff8111156111825761118261510f565b6040519080825280602002602001820160405280156111ab578160200160208202803683370190505b50915060005b83811015611233576000828152600f602052604090208054829081106111d9576111d9615964565b9060005260206000200160009054906101000a90046001600160a01b031683828151811061120957611209615964565b6001600160a01b03909216602092830291909101909101528061122b81615990565b9150506111b1565b50509250929050565b6000818152600260205260409020546001600160a01b038481169116146112a55760405162461bcd60e51b815260206004820152600a60248201527f57524f4e475f46524f4d000000000000000000000000000000000000000000006044820152606401610dda565b6001600160a01b0382166112ef5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610dda565b336001600160a01b038416148061132957506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061134a57506000818152600460205260409020546001600160a01b031633145b6113875760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610dda565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6012602052816000526040600020818154811061143257600080fd5b9060005260206000209060089182820401919006600402915091509054906101000a900463ffffffff1681565b6013602052816000526040600020818154811061143257600080fd5b61148683838361123c565b6001600160a01b0382163b1561156b57604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af11580156114fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152191906159a9565b6001600160e01b0319161461156b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610dda565b505050565b600081815260156020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff91041660058111156116115761161161507c565b60058111156116225761162261507c565b8152602001600382018054806020026020016040519081016040528092919081815260200182805480156116a157602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116116645790505b50505050508152505090506116b681856142de565b91508151925050915091565b60008082118015610cc457506009546116dc9060016159c6565b821092915050565b60006116f18260016159c6565b905060095481111561172457600954604051637ae5968560e01b8152610dda918391600401918252602082015260400190565b919050565b6006546001600160a01b031633146117695760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b805160000361178b57604051637c946ed760e01b815260040160405180910390fd5b60086117978282615a24565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf6816040516117c79190614ec3565b60405180910390a150565b600f60205281600052604060002081815481106117ee57600080fd5b6000918252602090912001546001600160a01b03169150829050565b6000818152600260205260409020546001600160a01b0316806117245760405162461bcd60e51b815260206004820152600a60248201527f4e4f545f4d494e544544000000000000000000000000000000000000000000006044820152606401610dda565b60088054610cd79061592a565b60006001600160a01b0382166118d45760405162461bcd60e51b815260206004820152600c60248201527f5a45524f5f4144445245535300000000000000000000000000000000000000006044820152606401610dda565b506001600160a01b031660009081526003602052604090205490565b600d602052816000526040600020818154811061190c57600080fd5b6000918252602090912001546001600160a01b0381169250600160a01b900463ffffffff16905082565b600081815260156020908152604080832081516101008101835281546001600160601b0381168252600160601b908190046001600160a01b031694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a0840152849360c08401910460ff1660058111156119cd576119cd61507c565b60058111156119de576119de61507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015611a5d57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611a205790505b505050505081525050905060046005811115611a7b57611a7b61507c565b8160c001516005811115611a9157611a9161507c565b14611ad0578060c001516005811115611aac57611aac61507c565b604051633c053f9d60e21b8152600481019190915260248101849052604401610dda565b8351855114611aff57845184516040516308151c1160e41b815260048101929092526024820152604401610dda565b80602001516001600160a01b0316336001600160a01b031614611b535760208101516040516379f91cd360e01b81523360048201526001600160a01b03909116602482015260448101849052606401610dda565b845160005b81811015611d7e57600060116000898481518110611b7857611b78615964565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081205490931660a08a901b81178085526010909252919092205489519193506001600160601b03169081908a9086908110611bdd57611bdd615964565b60200260200101516001611bf19190615ae4565b6001600160601b03161115611c4b57600b8054829190600090611c1e9084906001600160601b0316615ae4565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060009050611ccf565b888481518110611c5d57611c5d615964565b6020908102919091010151600b8054600090611c839084906001600160601b0316615ae4565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550888481518110611cb957611cb9615964565b602002602001015181611ccc9190615b0f565b90505b600082815260106020526040902080546bffffffffffffffffffffffff19166001600160601b038316179055885188906001600160a01b038516907fa2e524bd0f71903485fbb3d6d50cb305f61005ceea2047c3ac92aa7e0d104306908c9088908110611d3e57611d3e615964565b6020026020010151604051611d6291906001600160601b0391909116815260200190565b60405180910390a350505080611d7790615990565b9050611b58565b5060019695505050505050565b6006546000906001600160a01b03163314611dce5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b038316611df55760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b03919091166000908152601460205260409020805460ff1916911515919091179055600190565b600c6020528160005260406000208181548110611e4057600080fd5b90600052602060002001600091509150505481565b6000606081846001811115611e6c57611e6c61507c565b03611efd5760008381526012602090815260409182902080548351818402810184019094528084529091830182828015611ef157602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611eb45790505b50505050509050611f85565b60008381526013602090815260409182902080548351818402810184019094528084529091830182828015611f7d57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611f405790505b505050505090505b805191509250929050565b60018054610cd79061592a565b60006001600a541115611fc3576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a55600b54600160601b90046001600160a01b0316331461201557600b5460405163312d21ff60e11b8152336004820152600160601b9091046001600160a01b03166024820152604401610dda565b50600b546001600160601b031680156120f357600b80546bffffffffffffffffffffffff19169055604051600090339083908381818185875af1925050503d806000811461207f576040519150601f19603f3d011682016040523d82523d6000602084013e612084565b606091505b50509050806120bc5760405163cd3f165960e01b81526000600482015230602482015233604482015260648101839052608401610dda565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2505b6001600a5590565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6006546001600160a01b031633146121a75760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b0381166121ce5760405163d92e233d60e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f2c1c11af44aa5608f1dca38c00275c30ea091e02417d36e70e9a1538689c433d90600090a250565b6000806001600a54111561223f576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146122845760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b0384166122ab5760405163d92e233d60e01b815260040160405180910390fd5b600083815260156020526040902060056002820154600160601b900460ff1660058111156122db576122db61507c565b14612324576002810154600160601b900460ff1660058111156123005761230061507c565b604051633c053f9d60e21b8152600481019190915260248101859052604401610dda565b60a084901b6001600160a01b038616176000818152600d6020908152604080832080548251818502810185019093528083529192909190849084015b828210156123ac57600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900463ffffffff1681830152825260019092019101612360565b50508251929350505060008190036123e95760405163df2ddd7360e01b81526001600160a01b038916600482015260248101889052604401610dda565b808460020160088282829054906101000a900463ffffffff1661240c9190615b37565b92506101000a81548163ffffffff021916908363ffffffff1602179055508360020160089054906101000a900463ffffffff1663ffffffff166000036124625760028401805460ff60601b1916600160601b1790555b60005b8181101561252a576000889050602084838151811061248657612486615964565b60209081029190910181015181015163ffffffff1690911b919091176000818152600e9092526040909120546124cd9064010000000090046001600160601b0316886159c6565b9650601160008584815181106124e5576124e5615964565b602090810291909101810151516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055508061252281615990565b915050612465565b506000838152600d6020526040812061254291614c87565b6000838152601060205260409020546001600160601b03168086111561256f57806001600160601b031695505b85156126685760008481526010602052604080822080546bffffffffffffffffffffffff19169055516001600160a01b038b169088908381818185875af1925050503d80600081146125dd576040519150601f19603f3d011682016040523d82523d6000602084013e6125e2565b606091505b50509050806126235760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038b16604482015260648101889052608401610dda565b896001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d8860405161265e91815260200190565b60405180910390a2505b60405188906001600160a01b038b16907f5ebf7fe30be09f0f03b9195632508d95c8b67bf010c93abda67f70d5d9599d1e90600090a350506001600a8190559793965092945050505050565b6000818152600c60209081526040808320805482518185028101850190935280835260609383018282801561270857602002820191906000526020600020905b8154815260200190600101908083116126f4575b5050505050905080519150915091565b6006546001600160a01b031633146127585760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b03811661277f5760405163d92e233d60e01b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b90600090a250565b6127d485858561123c565b6001600160a01b0384163b156128a757604051630a85bd0160e11b808252906001600160a01b0386169063150b7a029061281a9033908a90899089908990600401615b54565b6020604051808303816000875af1158015612839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285d91906159a9565b6001600160e01b031916146128a75760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610dda565b5050505050565b6000818152601560205260408120600101546060915060086040518060400160405280600981526020016806630313730313232360bc1b8152506128f18361442f565b6128fe608085901b61442f565b6040516020016129119493929190615ba8565b604051602081830303815290604052915050919050565b6007546000906001600160a01b0316331461296b5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b60006129768361180a565b9050876001600160a01b0316816001600160a01b0316146129bd5760405163521eb56d60e11b81526001600160a01b03808a16600483015282166024820152604401610dda565b600083815260156020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a08401529192909160c084019160ff9104166005811115612a5757612a5761507c565b6005811115612a6857612a6861507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015612ae757602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612aaa5790505b505050505081525050905060016005811115612b0557612b0561507c565b8160c001516005811115612b1b57612b1b61507c565b14612b36578060c0015160058111156123005761230061507c565b612b418888886145ff565b63ffffffff85166060820152600060808201819052875167ffffffffffffffff811115612b7057612b7061510f565b604051908082528060200260200182016040528015612b99578160200160208202803683370190505b5090506000885167ffffffffffffffff811115612bb857612bb861510f565b604051908082528060200260200182016040528015612bfd57816020015b6040805180820190915260008082526020820152815260200190600190039081612bd65790505b5090506000805b8a51811015612d3257898181518110612c1f57612c1f615964565b60200260200101516000015163ffffffff16600003612c9457600088905060208c8381518110612c5157612c51615964565b60209081029190910181015163ffffffff1690911b919091176000908152600e9091526040902080546fffffffffffffffffffffffffffffffff19169055612d20565b8a8181518110612ca657612ca6615964565b6020026020010151848381518110612cc057612cc0615964565b602002602001019063ffffffff16908163ffffffff1681525050898181518110612cec57612cec615964565b6020026020010151838381518110612d0657612d06615964565b60200260200101819052508180612d1c90615990565b9250505b80612d2a81615990565b915050612c04565b5060408401518b8114612d69576000888152600c602090815260408083208054600181018255908452919092200182905585018c90525b612d76858585858c6147c6565b6000888152601560209081526040918290208751918801516001600160a01b0316600160601b9081026001600160601b03909316929092178155918701516001830155606087015160028301805460808a015160a08b015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c08a01518a9594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115612e4b57612e4b61507c565b021790555060e08201518051612e6b916003840191602090910190614ca8565b50506040518d81528991507fff312ce131c4d73ac90ece91266be7090486c5e15f78b7ea2b108c36dfd475299060200160405180910390a25060019c9b505050505050505050505050565b6000806001600a541115612edd576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314612f225760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6000612f2d8461180a565b9050846001600160a01b0316816001600160a01b031614612f745760405163521eb56d60e11b81526001600160a01b03808716600483015282166024820152604401610dda565b600084815260156020526040902060016002820154600160601b900460ff166005811115612fa457612fa461507c565b1480612fcf575060056002820154600160601b900460ff166005811115612fcd57612fcd61507c565b145b15613018576002810154600160601b900460ff166005811115612ff457612ff461507c565b604051633c053f9d60e21b8152600481019190915260248101869052604401610dda565b6002810154600160401b900463ffffffff16156130525760028101805460ff60601b19166c05000000000000000000000000179055613068565b60028101805460ff60601b1916600160601b1790555b600085815260126020526040812061307f91614d57565b600085815260136020526040812061309691614d57565b60005b600382015481101561312357600086905060208360030183815481106130c1576130c1615964565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff16901b81179050600f600082815260200190815260200160002060006131129190614d7c565b5061311c81615990565b9050613099565b5080546040516001600160601b0390911693506000906001600160a01b0388169085908381818185875af1925050503d806000811461317e576040519150601f19603f3d011682016040523d82523d6000602084013e613183565b606091505b50509050806131c45760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038816604482015260648101859052608401610dda565b866001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d856040516131ff91815260200190565b60405180910390a260405186907fe45f5b9540df4f71b7e044809fa318806328c1ea2388a70c7373d97ccf8a0faa90600090a250506001600a819055959194509092505050565b6007546000906001600160a01b031633146132895760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b81518351146132b857825182516040516308151c1160e41b815260048101929092526024820152604401610dda565b6000848152601560205260409020600280820154600160601b900460ff1660058111156132e7576132e761507c565b1461330c576002810154600160601b900460ff166005811115612ff457612ff461507c565b83516000805b82811015613401576000889050602087838151811061333357613333615964565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260408082208151808301909252549384168082526401000000009094046001600160601b03169481019490945290929190036133d45787838151811061339f5761339f615964565b60200260200101518a6040516332832be560e21b8152600401610dda92919063ffffffff929092168252602082015260400190565b60208101516133ec906001600160601b0316856159c6565b93505050806133fa90615990565b9050613312565b5080341461343257604051637ebbcab960e11b81523460048201526024810182905260448101889052606401610dda565b6001600160a01b03888116600090815260116020526040902054161561346e576040516322ddebd960e21b815260048101889052602401610dda565b60a087901b6001600160a01b0389161760005b8381101561376257600088828151811061349d5761349d615964565b6020026020010151905060008883815181106134bb576134bb615964565b60200260200101519050816001600160a01b03168c6001600160a01b0316036134fa576040516322ddebd960e21b8152600481018c9052602401610dda565b6001600160a01b038281166000908152601160205260409020541615613551576001600160a01b038281166000908152601160205260409081902054905163631695bd60e01b815291166004820152602401610dda565b60008b905060208a858151811061356a5761356a615964565b60209081029190910181015163ffffffff90811690921b929092176000818152600e8452604080822054600f909552902054909290911690036135c3576040516304ad100760e21b8152600481018d9052602401610dda565b6000818152600f602090815260408083208054600181810183559185528385200180546001600160a01b03808a166001600160a01b031990921682179092558a8652600d8552838620845180860190955290845263ffffffff8089168587019081528254948501835591875294909520925192909101805494518416600160a01b0277ffffffffffffffffffffffffffffffffffffffffffffffff19909516929091169190911792909217909155600289018054600160401b900490911690600861368d83615c3a565b91906101000a81548163ffffffff021916908363ffffffff160217905550508c60116000856001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001600160a01b03168c8e6001600160a01b03167f6835389a6da5341647f18cbe0a89c56f473f4c17bfaee6e6d07d61f1928e0b7c85604051613746919063ffffffff91909116815260200190565b60405180910390a45050508061375b90615990565b9050613481565b50600284015463ffffffff64010000000082048116600160401b90920416036137a45760028401805460ff60601b19166c030000000000000000000000001790555b600081815260106020526040812080543492906137cb9084906001600160601b0316615ae4565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550886001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161382a91815260200190565b60405180910390a250600198975050505050505050565b6007546000906001600160a01b031633146138845760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b600061388f8361180a565b9050836001600160a01b0316816001600160a01b0316146138d65760405163521eb56d60e11b81526001600160a01b03808616600483015282166024820152604401610dda565b600083815260156020526040902060016002820154600160601b900460ff1660058111156139065761390661507c565b1461392757604051635960d22f60e11b815260048101859052602401610dda565b80546001600160601b0316341461396c578054604051631c30abbb60e31b81523460048201526001600160601b03909116602482015260448101859052606401610dda565b60028101805460ff60601b19166c0200000000000000000000000017905560405184907fa48b531f972c0e4aca57afcc5c099c52a7bd21bc5e2a1b733eec3be9e88da97a90600090a2506001949350505050565b613a086040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b60008281526015602090815260409182902082516101008101845281546001600160601b0381168252600160601b908190046001600160a01b031693820193909352600182015493810193909352600281015463ffffffff8082166060860152640100000000820481166080860152600160401b82041660a0850152909160c08401910460ff166005811115613aa057613aa061507c565b6005811115613ab157613ab161507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613b3057602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613af35790505b5050505050815250509050919050565b60006001600a541115613b66576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314613bab5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6000613bb68561180a565b9050856001600160a01b0316816001600160a01b031614613bfd5760405163521eb56d60e11b81526001600160a01b03808816600483015282166024820152604401610dda565b6001600160a01b03841660009081526014602052604090205460ff16613c405760405162a2307960e51b81526001600160a01b0385166004820152602401610dda565b600085815260156020526040902060036002820154600160601b900460ff166005811115613c7057613c7061507c565b14613cb9576002810154600160601b900460ff166005811115613c9557613c9561507c565b604051633c053f9d60e21b8152600481019190915260248101879052604401610dda565b604080516101008101825282546001600160601b0381168252600160601b908190046001600160a01b03166020830152600184015492820192909252600283015463ffffffff8082166060840152640100000000820481166080840152600160401b82041660a0830152600092613de69291859160c08401910460ff166005811115613d4757613d4761507c565b6005811115613d5857613d5861507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613dd757602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613d9a5790505b505050505081525050886142de565b6002830154604051631e731b7560e31b81529192506001600160a01b0388169163f398dba891613e2391859163ffffffff16908a90600401615c5d565b6020604051808303816000875af1158015613e42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e669190615c98565b6000888152601360205260409020600384018054929650613e8692614d9a565b506040516304d9dc3f60e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906309b3b87e90613ed6906003860190600401615cb5565b600060405180830381865afa158015613ef3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613f1b9190810190615e3d565b60008881526012602090815260409091208251613f3e9391929190910190614ca8565b5081546001600160601b0316600160601b6001600160a01b03861690810291909117835560028301805460ff60601b19166c0400000000000000000000000017905560405188907f2d53f895cd5faf3cddba94a25c2ced2105885b5b37450ff430ffa3cbdf332c7490600090a360405187907fa133ed72c03a7d008deaae618a61613c4fd41c67bba1cad1a6bc0a1c5a9c156e90600090a250506001600a5550949350505050565b60006001600a54111561400c576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146140515760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b0386166140785760405163d92e233d60e01b815260040160405180910390fd5b6140838585856145ff565b60005b8451811015614117578381815181106140a1576140a1615964565b60200260200101516000015163ffffffff16600014806140e757508381815181106140ce576140ce615964565b6020026020010151602001516001600160601b03166000145b1561410557604051637c946ed760e01b815260040160405180910390fd5b8061410f81615990565b915050614086565b50506009548061412681615990565b9150506141716040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b63ffffffff8316606082015260408101869052600160c08201818152505061419d8186868851866147c6565b6000828152601560209081526040918290208351918401516001600160a01b0316600160601b9081026001600160601b039093169290921781559183015160018301556060830151600283018054608086015160a087015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c0860151869594909360ff60601b19166cffffffffff00000000000000001990921691909117908360058111156142725761427261507c565b021790555060e08201518051614292916003840191602090910190614ca8565b50505060098290556142a48783614a7d565b60405182907f9169d45eacd63571e315a0504da919b7c89de505493e7b34051802dd0816a06990600090a2506001600a5595945050505050565b60608260a0015163ffffffff1667ffffffffffffffff8111156143035761430361510f565b60405190808252806020026020018201604052801561432c578160200160208202803683370190505b5090506000805b8460e001515181101561442757600084905060208660e00151838151811061435d5761435d615964565b602002602001015163ffffffff16901b8117905060005b6000828152600f6020526040902054811015614412576000828152600f602052604090208054829081106143aa576143aa615964565b9060005260206000200160009054906101000a90046001600160a01b03168585815181106143da576143da615964565b6001600160a01b0390921660209283029190910190910152836143fc81615990565b945050808061440a90615990565b915050614374565b5050808061441f90615990565b915050614333565b505092915050565b7aff00000000000000ff00000000000000ff00000000000000ff00006bffffffff0000000000000000604083901c9081167bffffffff00000000000000000000000000000000000000000000000084161760201c6fffffffff000000000000000000000000919091166001600160e01b031984161717601081901c9182167eff00000000000000ff00000000000000ff00000000000000ff000000000000821617600890811c7bff00000000000000ff00000000000000ff00000000000000ff000000939093167fff00000000000000ff00000000000000ff00000000000000ff000000000000009290921691909117919091179081901c7e0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f167f0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f00600492831c16179061459b827f06060606060606060606060606060606060606060606060606060606060606066159c6565b901c7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f1660276145cb9190615ed7565b6145f5827f30303030303030303030303030303030303030303030303030303030303030306159c6565b610cc491906159c6565b600083900361462157604051637c946ed760e01b815260040160405180910390fd5b8151158061463157508051825114155b1561465c57815181516040516308151c1160e41b815260048101929092526024820152604401610dda565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156146bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146e09190615ef6565b90506000805b84518110156147be576146fa8260016159c6565b85828151811061470c5761470c615964565b602002602001015163ffffffff16108061474457508285828151811061473457614734615964565b602002602001015163ffffffff16115b156147895784818151811061475b5761475b615964565b6020026020010151604051632ab10b0b60e21b8152600401610dda919063ffffffff91909116815260200190565b84818151811061479b5761479b615964565b602002602001015163ffffffff16915080806147b690615990565b9150506146e6565b505050505050565b60008267ffffffffffffffff8111156147e1576147e161510f565b60405190808252806020026020018201604052801561480a578160200160208202803683370190505b5060e087015260005b8381101561499a5785818151811061482d5761482d615964565b60200260200101518760e00151828151811061484b5761484b615964565b63ffffffff909216602092830291909101820152865184919088908490811061487657614876615964565b602002602001015163ffffffff16901b8117905085828151811061489c5761489c615964565b6020908102919091018101516000838152600e8352604090208151815492909301516001600160601b0316640100000000026fffffffffffffffffffffffffffffffff1990921663ffffffff90931692909217179055855186908390811061490657614906615964565b602002602001015160000151886080018181516149239190615f0f565b63ffffffff1690525085516001600160601b0384169087908490811061494b5761494b615964565b6020026020010151602001516001600160601b031611156149875785828151811061497857614978615964565b60200260200101516020015192505b508061499281615990565b915050614813565b506001600160601b038116865260808601516000906149ba906002615f2e565b6149c5906001615f0f565b63ffffffff1690506149d8600382615f70565b6000036149f1576149ea600382615f84565b9050614a0a565b6149fc600382615f84565b614a079060016159c6565b90505b80876060015163ffffffff161080614a355750866080015163ffffffff16876060015163ffffffff16115b15614a74576060870151608088015160405163eb3a8ba360e01b815263ffffffff92831660048201526024810184905291166044820152606401610dda565b50505050505050565b614a878282614b6d565b6001600160a01b0382163b15614b6957604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af1158015614afb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b1f91906159a9565b6001600160e01b03191614614b695760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610dda565b5050565b6001600160a01b038216614bb75760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610dda565b6000818152600260205260409020546001600160a01b031615614c1c5760405162461bcd60e51b815260206004820152600e60248201527f414c52454144595f4d494e5445440000000000000000000000000000000000006044820152606401610dda565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b5080546000825590600052602060002090810190614ca59190614de8565b50565b82805482825590600052602060002090600701600890048101928215614d475791602002820160005b83821115614d1557835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614cd1565b8015614d455782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614d15565b505b50614d53929150614e18565b5090565b508054600082556007016008900490600052602060002090810190614ca59190614e18565b5080546000825590600052602060002090810190614ca59190614e18565b82805482825590600052602060002090600701600890048101928215614d47576000526020600020916007016008900482015b82811115614d47578254825591600101919060010190614dcd565b5b80821115614d5357805477ffffffffffffffffffffffffffffffffffffffffffffffff19168155600101614de9565b5b80821115614d535760008155600101614e19565b6001600160e01b031981168114614ca557600080fd5b600060208284031215614e5557600080fd5b8135614e6081614e2d565b9392505050565b60005b83811015614e82578181015183820152602001614e6a565b83811115614e91576000848401525b50505050565b60008151808452614eaf816020860160208601614e67565b601f01601f19169290920160200192915050565b602081526000614e606020830184614e97565b600060208284031215614ee857600080fd5b5035919050565b6001600160a01b0381168114614ca557600080fd5b60008060408385031215614f1757600080fd5b8235614f2281614eef565b946020939093013593505050565b600060208284031215614f4257600080fd5b8135614e6081614eef565b6000604080830185845260208281860152818651808452606087019150828801935060005b81811015614fa6578451805163ffffffff1684528401516001600160601b0316848401529383019391850191600101614f72565b509098975050505050505050565b60008060408385031215614fc757600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b8381101561500f5781516001600160a01b031687529582019590820190600101614fea565b509495945050505050565b8281526040602082015260006150336040830184614fd6565b949350505050565b60008060006060848603121561505057600080fd5b833561505b81614eef565b9250602084013561506b81614eef565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b600681106150b057634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03881681526001600160a01b03871660208201526040810186905263ffffffff85811660608301528481166080830152831660a082015260e0810161510360c0830184615092565b98975050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156151485761514861510f565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156151775761517761510f565b604052919050565b600067ffffffffffffffff8311156151995761519961510f565b6151ac601f8401601f191660200161514e565b90508281528383830111156151c057600080fd5b828260208301376000602084830101529392505050565b6000602082840312156151e957600080fd5b813567ffffffffffffffff81111561520057600080fd5b8201601f8101841361521157600080fd5b6150338482356020840161517f565b600067ffffffffffffffff82111561523a5761523a61510f565b5060051b60200190565b600082601f83011261525557600080fd5b8135602061526a61526583615220565b61514e565b82815260059290921b8401810191818101908684111561528957600080fd5b8286015b848110156152ad5780356152a081614eef565b835291830191830161528d565b509695505050505050565b80356001600160601b038116811461172457600080fd5b6000806000606084860312156152e457600080fd5b833567ffffffffffffffff808211156152fc57600080fd5b61530887838801615244565b945060209150818601358181111561531f57600080fd5b86019050601f8101871361533257600080fd5b803561534061526582615220565b81815260059190911b8201830190838101908983111561535f57600080fd5b928401925b8284101561538457615375846152b8565b82529284019290840190615364565b96999698505050506040949094013593505050565b600080604083850312156153ac57600080fd5b82356153b781614eef565b9150602083013580151581146153cc57600080fd5b809150509250929050565b600080604083850312156153ea57600080fd5b823560028110614f2257600080fd5b600081518084526020808501945080840160005b8381101561500f57815163ffffffff168752958201959082019060010161540d565b82815260406020820152600061503360408301846153f9565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156154895784518352938301939183019160010161546d565b5090979650505050505050565b6000806000806000608086880312156154ae57600080fd5b85356154b981614eef565b945060208601356154c981614eef565b935060408601359250606086013567ffffffffffffffff808211156154ed57600080fd5b818801915088601f83011261550157600080fd5b81358181111561551057600080fd5b89602082850101111561552257600080fd5b9699959850939650602001949392505050565b63ffffffff81168114614ca557600080fd5b600082601f83011261555857600080fd5b8135602061556861526583615220565b82815260059290921b8401810191818101908684111561558757600080fd5b8286015b848110156152ad57803561559e81615535565b835291830191830161558b565b600082601f8301126155bc57600080fd5b813560206155cc61526583615220565b82815260069290921b840181019181810190868411156155eb57600080fd5b8286015b848110156152ad57604081890312156156085760008081fd5b615610615125565b813561561b81615535565b81526156288286016152b8565b818601528352918301916040016155ef565b60008060008060008060c0878903121561565357600080fd5b863561565e81614eef565b955060208701359450604087013567ffffffffffffffff8082111561568257600080fd5b61568e8a838b01615547565b955060608901359150808211156156a457600080fd5b506156b189828a016155ab565b93505060808701356156c281615535565b8092505060a087013590509295509295509295565b600080600080608085870312156156ed57600080fd5b84356156f881614eef565b935060208501359250604085013567ffffffffffffffff8082111561571c57600080fd5b61572888838901615244565b9350606087013591508082111561573e57600080fd5b5061574b87828801615547565b91505092959194509250565b6000806040838503121561576a57600080fd5b823561577581614eef565b915060208301356153cc81614eef565b602081526001600160601b0382511660208201526001600160a01b03602083015116604082015260408201516060820152600060608301516157cf608084018263ffffffff169052565b50608083015163ffffffff811660a08401525060a083015163ffffffff811660c08401525060c083015161580660e0840182615092565b5060e0830151610100838101526150336101208401826153f9565b6000806000806080858703121561583757600080fd5b843561584281614eef565b935060208501359250604085013561585981614eef565b9150606085013567ffffffffffffffff81111561587557600080fd5b8501601f8101871361588657600080fd5b61574b8782356020840161517f565b600080600080600060a086880312156158ad57600080fd5b85356158b881614eef565b945060208601359350604086013567ffffffffffffffff808211156158dc57600080fd5b6158e889838a01615547565b945060608801359150808211156158fe57600080fd5b5061590b888289016155ab565b925050608086013561591c81615535565b809150509295509295909350565b600181811c9082168061593e57607f821691505b60208210810361595e57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016159a2576159a261597a565b5060010190565b6000602082840312156159bb57600080fd5b8151614e6081614e2d565b600082198211156159d9576159d961597a565b500190565b601f82111561156b57600081815260208120601f850160051c81016020861015615a055750805b601f850160051c820191505b818110156147be57828155600101615a11565b815167ffffffffffffffff811115615a3e57615a3e61510f565b615a5281615a4c845461592a565b846159de565b602080601f831160018114615a875760008415615a6f5750858301515b600019600386901b1c1916600185901b1785556147be565b600085815260208120601f198616915b82811015615ab657888601518255948401946001909101908401615a97565b5085821015615ad45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006001600160601b03808316818516808303821115615b0657615b0661597a565b01949350505050565b60006001600160601b0383811690831681811015615b2f57615b2f61597a565b039392505050565b600063ffffffff83811690831681811015615b2f57615b2f61597a565b60006001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b6000808654615bb68161592a565b60018281168015615bce5760018114615be357615c12565b60ff1984168752821515830287019450615c12565b8a60005260208060002060005b85811015615c095781548a820152908401908201615bf0565b50505082870194505b505050508551615c26818360208a01614e67565b019384525050602082015260400192915050565b600063ffffffff808316818103615c5357615c5361597a565b6001019392505050565b606081526000615c706060830186614fd6565b63ffffffff851660208401528281036040840152615c8e8185614e97565b9695505050505050565b600060208284031215615caa57600080fd5b8151614e6081614eef565b60006020808301818452808554615cd0818490815260200190565b60008881526020812094509092505b81600782011015615d5557835463ffffffff808216855281871c811687860152604082811c821690860152606082811c821690860152608082811c82169086015260a082811c82169086015260c082811c9091169085015260e090811c9084015260019093019261010090920191600801615cdf565b92549281811015615d715763ffffffff84168352918401916001015b81811015615d8c5783851c63ffffffff168352918401916001015b81811015615da957604084901c63ffffffff168352918401916001015b81811015615dc657606084901c63ffffffff168352918401916001015b81811015615de357608084901c63ffffffff168352918401916001015b81811015615e005760a084901c63ffffffff168352918401916001015b81811015615e1d5760c084901c63ffffffff168352918401916001015b81811015615e315760e084901c8352918401915b50909695505050505050565b60006020808385031215615e5057600080fd5b825167ffffffffffffffff811115615e6757600080fd5b8301601f81018513615e7857600080fd5b8051615e8661526582615220565b81815260059190911b82018301908381019087831115615ea557600080fd5b928401925b82841015615ecc578351615ebd81615535565b82529284019290840190615eaa565b979650505050505050565b6000816000190483118215151615615ef157615ef161597a565b500290565b600060208284031215615f0857600080fd5b5051919050565b600063ffffffff808316818516808303821115615b0657615b0661597a565b600063ffffffff80831681851681830481118215151615615f5157615f5161597a565b02949350505050565b634e487b7160e01b600052601260045260246000fd5b600082615f7f57615f7f615f5a565b500690565b600082615f9357615f93615f5a565b50049056fea2646970667358221220c6f47c49865f99357fc7f3a83dfde648490b39975e4ec4242e3bcab08caabf3664736f6c634300080f0033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/service_registry/build/ServiceRegistryL2.json b/trader_backup/vendor/valory/contracts/service_registry/build/ServiceRegistryL2.json deleted file mode 100644 index 0054fd27a..000000000 --- a/trader_backup/vendor/valory/contracts/service_registry/build/ServiceRegistryL2.json +++ /dev/null @@ -1,1899 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ServiceRegistryL2", - "sourceName": "contracts/ServiceRegistryL2.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - }, - { - "internalType": "string", - "name": "_baseURI", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "AgentInstanceRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentInstancesSlotsFilled", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "AgentNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentNotInService", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "componentId", - "type": "uint256" - } - ], - "name": "ComponentNotFound", - "type": "error" - }, - { - "inputs": [], - "name": "HashExists", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectAgentBondingValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectRegistrationDepositValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "provided", - "type": "address" - }, - { - "internalType": "address", - "name": "expected", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OnlyOwnServiceMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorHasNoInstances", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "Overflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerOnly", - "type": "error" - }, - { - "inputs": [], - "name": "Paused", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrancyGuard", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceMustBeInactive", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "TransferFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "UnauthorizedMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "WrongAgentId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "numValues1", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numValues2", - "type": "uint256" - } - ], - "name": "WrongArrayLength", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongOperator", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "state", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceState", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "currentThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxThreshold", - "type": "uint256" - } - ], - "name": "WrongThreshold", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ActivateRegistration", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "string", - "name": "baseURI", - "type": "string" - } - ], - "name": "BaseURIChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "CreateMultisigWithAgents", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - } - ], - "name": "CreateService", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "DeployService", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "drainer", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Drain", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "drainer", - "type": "address" - } - ], - "name": "DrainerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorSlashed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorUnbond", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "receiver", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Refund", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "agentInstance", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "RegisterInstance", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "TerminateService", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - } - ], - "name": "UpdateService", - "type": "event" - }, - { - "inputs": [], - "name": "CID_PREFIX", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "activateRegistration", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newDrainer", - "type": "address" - } - ], - "name": "changeDrainer", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newManager", - "type": "address" - } - ], - "name": "changeManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "bool", - "name": "permission", - "type": "bool" - } - ], - "name": "changeMultisigPermission", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "changeOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "internalType": "struct AgentParams[]", - "name": "agentParams", - "type": "tuple[]" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - } - ], - "name": "create", - "outputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "multisigImplementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "deploy", - "outputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "drain", - "outputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "drainer", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "name": "exists", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getAgentInstances", - "outputs": [ - { - "internalType": "uint256", - "name": "numAgentInstances", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getAgentParams", - "outputs": [ - { - "internalType": "uint256", - "name": "numAgentIds", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "internalType": "struct AgentParams[]", - "name": "agentParams", - "type": "tuple[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "getInstancesForAgentId", - "outputs": [ - { - "internalType": "uint256", - "name": "numAgentInstances", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getOperatorBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getPreviousHashes", - "outputs": [ - { - "internalType": "uint256", - "name": "numHashes", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "configHashes", - "type": "bytes32[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getService", - "outputs": [ - { - "components": [ - { - "internalType": "uint96", - "name": "securityDeposit", - "type": "uint96" - }, - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "maxNumAgentInstances", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "numAgentInstances", - "type": "uint32" - }, - { - "internalType": "enum ServiceRegistryL2.ServiceState", - "name": "state", - "type": "uint8" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - } - ], - "internalType": "struct ServiceRegistryL2.Service", - "name": "service", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "manager", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapAgentInstanceOperators", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapConfigHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapMultisigs", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapOperatorAndServiceIdAgentInstances", - "outputs": [ - { - "internalType": "address", - "name": "instance", - "type": "address" - }, - { - "internalType": "uint32", - "name": "agentId", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapOperatorAndServiceIdOperatorBalances", - "outputs": [ - { - "internalType": "uint96", - "name": "", - "type": "uint96" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceAndAgentIdAgentInstances", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceAndAgentIdAgentParams", - "outputs": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServices", - "outputs": [ - { - "internalType": "uint96", - "name": "securityDeposit", - "type": "uint96" - }, - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "maxNumAgentInstances", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "numAgentInstances", - "type": "uint32" - }, - { - "internalType": "enum ServiceRegistryL2.ServiceState", - "name": "state", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - } - ], - "name": "registerAgents", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "bURI", - "type": "string" - } - ], - "name": "setBaseURI", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - }, - { - "internalType": "uint96[]", - "name": "amounts", - "type": "uint96[]" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "slash", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "slashedFunds", - "outputs": [ - { - "internalType": "uint96", - "name": "", - "type": "uint96" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "terminate", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "refund", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "tokenByIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "unbond", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "refund", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "internalType": "struct AgentParams[]", - "name": "agentParams", - "type": "tuple[]" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "update", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x60806040526001600a553480156200001657600080fd5b5060405162005bcb38038062005bcb83398101604081905262000039916200014d565b828260006200004983826200026d565b5060016200005882826200026d565b50600891506200006b905082826200026d565b5050600680546001600160a01b0319163317905550620003399050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000b057600080fd5b81516001600160401b0380821115620000cd57620000cd62000088565b604051601f8301601f19908116603f01168101908282118183101715620000f857620000f862000088565b816040528381526020925086838588010111156200011557600080fd5b600091505b838210156200013957858201830151818301840152908201906200011a565b600093810190920192909252949350505050565b6000806000606084860312156200016357600080fd5b83516001600160401b03808211156200017b57600080fd5b62000189878388016200009e565b94506020860151915080821115620001a057600080fd5b620001ae878388016200009e565b93506040860151915080821115620001c557600080fd5b50620001d4868287016200009e565b9150509250925092565b600181811c90821680620001f357607f821691505b6020821081036200021457634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200026857600081815260208120601f850160051c81016020861015620002435750805b601f850160051c820191505b8181101562000264578281556001016200024f565b5050505b505050565b81516001600160401b0381111562000289576200028962000088565b620002a1816200029a8454620001de565b846200021a565b602080601f831160018114620002d95760008415620002c05750858301515b600019600386901b1c1916600185901b17855562000264565b600085815260208120601f198616915b828110156200030a57888601518255948401946001909101908401620002e9565b5085821015620003295787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61588280620003496000396000f3fe6080604052600436106103345760003560e01c806370a08231116101b0578063a60e4c3c116100ec578063dff7672411610095578063ef0e239b1161006f578063ef0e239b14610af7578063f908bc7714610b24578063fbdeb3d714610b44578063ffa1ad7414610b6457600080fd5b8063dff7672414610a96578063e23f6fb414610aa9578063e985e9c514610abc57600080fd5b8063c87b56dd116100c6578063c87b56dd14610a36578063cbf994f814610a56578063ccc9305d14610a7657600080fd5b8063a60e4c3c146109c8578063a6f9dae1146109f6578063b88d4fde14610a1657600080fd5b80638a2bd86f116101595780639890220b116101335780639890220b1461093c578063a22cb46514610951578063a3fbbaae14610971578063a5d059ca1461099157600080fd5b80638a2bd86f146108c25780638da5cb5b1461090757806395d89b411461092757600080fd5b80637c5e63e01161018a5780637c5e63e01461084d57806382694b1d1461088257806386a2bdd4146108a257600080fd5b806370a08231146107c9578063718934d8146107e957806373b8b6a21461082d57600080fd5b806342842e0e1161027f57806355f804b3116102285780636352211e116102025780636352211e1461070a57806363dd76151461072a5780636c0360eb146107945780636f99f15c146107a957600080fd5b806355f804b3146106a357806357838e85146106c35780635e4507fa146106ea57600080fd5b80634eb780da116102595780634eb780da1461062d5780634f558e79146106635780634f6ccce71461068357600080fd5b806342842e0e146105cd578063481c6a75146105ed5780634d486f851461060d57600080fd5b806318160ddd116102e157806323b872dd116102bb57806323b872dd146104d057806342144854146104f05780634236aff81461053e57600080fd5b806318160ddd146104505780631de286ba1461047457806321e4f7bb146104a257600080fd5b8063095ea7b311610312578063095ea7b3146103de57806310c6aa191461040057806317351f7e1461042057600080fd5b806301ffc9a71461033957806306fdde031461036e578063081812fc14610390575b600080fd5b34801561034557600080fd5b506103596103543660046149a2565b610b95565b60405190151581526020015b60405180910390f35b34801561037a57600080fd5b50610383610be7565b6040516103659190614a16565b34801561039c57600080fd5b506103c66103ab366004614a29565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610365565b3480156103ea57600080fd5b506103fe6103f9366004614a57565b610c75565b005b34801561040c57600080fd5b506103fe61041b366004614a83565b610d5c565b34801561042c57600080fd5b5061035961043b366004614a83565b60126020526000908152604090205460ff1681565b34801561045c57600080fd5b5061046660095481565b604051908152602001610365565b34801561048057600080fd5b5061049461048f366004614a29565b610e15565b604051610365929190614aa0565b3480156104ae57600080fd5b506104c26104bd366004614b07565b61106b565b604051610365929190614b6d565b3480156104dc57600080fd5b506103fe6104eb366004614b8e565b611159565b3480156104fc57600080fd5b5061052661050b366004614a29565b6010602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610365565b34801561054a57600080fd5b506105ba610559366004614a29565b6013602052600090815260409020805460018201546002909201546001600160601b03821692600160601b928390046001600160a01b031692909163ffffffff808216926401000000008304821692600160401b8104909216910460ff1687565b6040516103659796959493929190614c07565b3480156105d957600080fd5b506103fe6105e8366004614b8e565b611333565b3480156105f957600080fd5b506007546103c6906001600160a01b031681565b34801561061957600080fd5b506104c2610628366004614a29565b611428565b34801561063957600080fd5b506103c6610648366004614a83565b6011602052600090815260409020546001600160a01b031681565b34801561066f57600080fd5b5061035961067e366004614a29565b61157a565b34801561068f57600080fd5b5061046661069e366004614a29565b61159c565b3480156106af57600080fd5b506103fe6106be366004614d2a565b6115e1565b3480156106cf57600080fd5b50600b546103c690600160601b90046001600160a01b031681565b3480156106f657600080fd5b506103c6610705366004614b07565b61168a565b34801561071657600080fd5b506103c6610725366004614a29565b6116c2565b34801561073657600080fd5b50610770610745366004614a29565b600e6020526000908152604090205463ffffffff81169064010000000090046001600160601b031682565b6040805163ffffffff90931683526001600160601b03909116602083015201610365565b3480156107a057600080fd5b50610383611727565b3480156107b557600080fd5b50600b54610526906001600160601b031681565b3480156107d557600080fd5b506104666107e4366004614a83565b611734565b3480156107f557600080fd5b50610809610804366004614b07565b6117a8565b604080516001600160a01b03909316835263ffffffff909116602083015201610365565b34801561083957600080fd5b50610359610848366004614e22565b6117ee565b34801561085957600080fd5b506103836040518060400160405280600981526020016806630313730313232360bc1b81525081565b34801561088e57600080fd5b5061035961089d366004614eec565b611c43565b3480156108ae57600080fd5b506104666108bd366004614b07565b611cdc565b3480156108ce57600080fd5b506104666108dd366004614a57565b60a01b6001600160a01b03909116176000908152601060205260409020546001600160601b031690565b34801561091357600080fd5b506006546103c6906001600160a01b031681565b34801561093357600080fd5b50610383611d0d565b34801561094857600080fd5b50610466611d1a565b34801561095d57600080fd5b506103fe61096c366004614eec565b611e78565b34801561097d57600080fd5b506103fe61098c366004614a83565b611ee4565b34801561099d57600080fd5b506109b16109ac366004614a57565b611f95565b604080519215158352602083019190915201610365565b3480156109d457600080fd5b506109e86109e3366004614a29565b612431565b604051610365929190614f2a565b348015610a0257600080fd5b506103fe610a11366004614a83565b612495565b348015610a2257600080fd5b506103fe610a31366004614f78565b612546565b348015610a4257600080fd5b50610383610a51366004614a29565b61262b565b348015610a6257600080fd5b50610359610a7136600461511a565b6126a5565b348015610a8257600080fd5b506109b1610a91366004614a57565b612c33565b610359610aa43660046151b3565b612f95565b610359610ab7366004614a57565b613590565b348015610ac857600080fd5b50610359610ad7366004615233565b600560209081526000928352604080842090915290825290205460ff1681565b348015610b0357600080fd5b50610b17610b12366004614a29565b61370f565b6040516103659190615297565b348015610b3057600080fd5b506103c6610b3f366004615333565b61388f565b348015610b5057600080fd5b50610466610b5f3660046153a7565b613c60565b348015610b7057600080fd5b50610383604051806040016040528060058152602001640312e302e360dc1b81525081565b60006301ffc9a760e01b6001600160e01b031983161480610bc657506380ac58cd60e01b6001600160e01b03198316145b80610be15750635b5e139f60e01b6001600160e01b03198316145b92915050565b60008054610bf490615438565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2090615438565b8015610c6d5780601f10610c4257610100808354040283529160200191610c6d565b820191906000526020600020905b815481529060010190602001808311610c5057829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b031633811480610cbe57506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b610d005760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6006546001600160a01b03163314610d9c5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038116610dc35760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160601b0316600160601b6001600160a01b038416908102919091179091556040517f8d1e8547016120917daad7f81c42b48f7fee379badc48f1889f0f43bb619472590600090a250565b600081815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff9104166005811115610eb657610eb6614bcf565b6005811115610ec757610ec7614bcf565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015610f4657602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411610f095790505b50505050508152505090508060e001515192508267ffffffffffffffff811115610f7257610f72614c62565b604051908082528060200260200182016040528015610fb757816020015b6040805180820190915260008082526020820152815260200190600190039081610f905790505b50915060005b8381101561106457600085905060208360e001518381518110610fe257610fe2615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260409081902081518083019092525492831681526401000000009092046001600160601b031692820192909252845185908490811061104757611047615472565b6020026020010181905250508061105d9061549e565b9050610fbd565b5050915091565b602081811b83176000818152600f909252604090912054906060908267ffffffffffffffff81111561109f5761109f614c62565b6040519080825280602002602001820160405280156110c8578160200160208202803683370190505b50915060005b83811015611150576000828152600f602052604090208054829081106110f6576110f6615472565b9060005260206000200160009054906101000a90046001600160a01b031683828151811061112657611126615472565b6001600160a01b0390921660209283029190910190910152806111488161549e565b9150506110ce565b50509250929050565b6000818152600260205260409020546001600160a01b038481169116146111c25760405162461bcd60e51b815260206004820152600a60248201527f57524f4e475f46524f4d000000000000000000000000000000000000000000006044820152606401610cf7565b6001600160a01b03821661120c5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610cf7565b336001600160a01b038416148061124657506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061126757506000818152600460205260409020546001600160a01b031633145b6112a45760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610cf7565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61133e838383611159565b6001600160a01b0382163b1561142357604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af11580156113b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d991906154b7565b6001600160e01b031916146114235760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b505050565b600081815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff91041660058111156114c9576114c9614bcf565b60058111156114da576114da614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561155957602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff168152602001906004019060208260030104928301926001038202915080841161151c5790505b505050505081525050905061156e8185613f67565b91508151925050915091565b60008082118015610be157506009546115949060016154d4565b821092915050565b60006115a98260016154d4565b90506009548111156115dc57600954604051637ae5968560e01b8152610cf7918391600401918252602082015260400190565b919050565b6006546001600160a01b031633146116215760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b805160000361164357604051637c946ed760e01b815260040160405180910390fd5b600861164f8282615535565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf68160405161167f9190614a16565b60405180910390a150565b600f60205281600052604060002081815481106116a657600080fd5b6000918252602090912001546001600160a01b03169150829050565b6000818152600260205260409020546001600160a01b0316806115dc5760405162461bcd60e51b815260206004820152600a60248201527f4e4f545f4d494e544544000000000000000000000000000000000000000000006044820152606401610cf7565b60088054610bf490615438565b60006001600160a01b03821661178c5760405162461bcd60e51b815260206004820152600c60248201527f5a45524f5f4144445245535300000000000000000000000000000000000000006044820152606401610cf7565b506001600160a01b031660009081526003602052604090205490565b600d60205281600052604060002081815481106117c457600080fd5b6000918252602090912001546001600160a01b0381169250600160a01b900463ffffffff16905082565b600081815260136020908152604080832081516101008101835281546001600160601b0381168252600160601b908190046001600160a01b031694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a0840152849360c08401910460ff16600581111561188557611885614bcf565b600581111561189657611896614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561191557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116118d85790505b50505050508152505090506004600581111561193357611933614bcf565b8160c00151600581111561194957611949614bcf565b14611988578060c00151600581111561196457611964614bcf565b604051633c053f9d60e21b8152600481019190915260248101849052604401610cf7565b83518551146119b757845184516040516308151c1160e41b815260048101929092526024820152604401610cf7565b80602001516001600160a01b0316336001600160a01b031614611a0b5760208101516040516379f91cd360e01b81523360048201526001600160a01b03909116602482015260448101849052606401610cf7565b845160005b81811015611c3657600060116000898481518110611a3057611a30615472565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081205490931660a08a901b81178085526010909252919092205489519193506001600160601b03169081908a9086908110611a9557611a95615472565b60200260200101516001611aa991906155f5565b6001600160601b03161115611b0357600b8054829190600090611ad69084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060009050611b87565b888481518110611b1557611b15615472565b6020908102919091010151600b8054600090611b3b9084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550888481518110611b7157611b71615472565b602002602001015181611b84919061561c565b90505b600082815260106020526040902080546bffffffffffffffffffffffff19166001600160601b038316179055885188906001600160a01b038516907fa2e524bd0f71903485fbb3d6d50cb305f61005ceea2047c3ac92aa7e0d104306908c9088908110611bf657611bf6615472565b6020026020010151604051611c1a91906001600160601b0391909116815260200190565b60405180910390a350505080611c2f9061549e565b9050611a10565b5060019695505050505050565b6006546000906001600160a01b03163314611c865760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038316611cad5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b03919091166000908152601260205260409020805460ff1916911515919091179055600190565b600c6020528160005260406000208181548110611cf857600080fd5b90600052602060002001600091509150505481565b60018054610bf490615438565b60006001600a541115611d40576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a55600b54600160601b90046001600160a01b03163314611d9257600b5460405163312d21ff60e11b8152336004820152600160601b9091046001600160a01b03166024820152604401610cf7565b50600b546001600160601b03168015611e7057600b80546bffffffffffffffffffffffff19169055604051600090339083908381818185875af1925050503d8060008114611dfc576040519150601f19603f3d011682016040523d82523d6000602084013e611e01565b606091505b5050905080611e395760405163cd3f165960e01b81526000600482015230602482015233604482015260648101839052608401610cf7565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2505b6001600a5590565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6006546001600160a01b03163314611f245760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038116611f4b5760405163d92e233d60e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f2c1c11af44aa5608f1dca38c00275c30ea091e02417d36e70e9a1538689c433d90600090a250565b6000806001600a541115611fbc576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146120015760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b0384166120285760405163d92e233d60e01b815260040160405180910390fd5b600083815260136020526040902060056002820154600160601b900460ff16600581111561205857612058614bcf565b146120a1576002810154600160601b900460ff16600581111561207d5761207d614bcf565b604051633c053f9d60e21b8152600481019190915260248101859052604401610cf7565b60a084901b6001600160a01b038616176000818152600d6020908152604080832080548251818502810185019093528083529192909190849084015b8282101561212957600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900463ffffffff16818301528252600190920191016120dd565b50508251929350505060008190036121665760405163df2ddd7360e01b81526001600160a01b038916600482015260248101889052604401610cf7565b808460020160088282829054906101000a900463ffffffff16612189919061563c565b92506101000a81548163ffffffff021916908363ffffffff1602179055508360020160089054906101000a900463ffffffff1663ffffffff166000036121df5760028401805460ff60601b1916600160601b1790555b60005b818110156122a7576000889050602084838151811061220357612203615472565b60209081029190910181015181015163ffffffff1690911b919091176000818152600e90925260409091205461224a9064010000000090046001600160601b0316886154d4565b96506011600085848151811061226257612262615472565b602090810291909101810151516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055508061229f8161549e565b9150506121e2565b506000838152600d602052604081206122bf91614859565b6000838152601060205260409020546001600160601b0316808611156122ec57806001600160601b031695505b85156123e55760008481526010602052604080822080546bffffffffffffffffffffffff19169055516001600160a01b038b169088908381818185875af1925050503d806000811461235a576040519150601f19603f3d011682016040523d82523d6000602084013e61235f565b606091505b50509050806123a05760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038b16604482015260648101889052608401610cf7565b896001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d886040516123db91815260200190565b60405180910390a2505b60405188906001600160a01b038b16907f5ebf7fe30be09f0f03b9195632508d95c8b67bf010c93abda67f70d5d9599d1e90600090a350506001600a8190559793965092945050505050565b6000818152600c60209081526040808320805482518185028101850190935280835260609383018282801561248557602002820191906000526020600020905b815481526020019060010190808311612471575b5050505050905080519150915091565b6006546001600160a01b031633146124d55760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b0381166124fc5760405163d92e233d60e01b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b90600090a250565b612551858585611159565b6001600160a01b0384163b1561262457604051630a85bd0160e11b808252906001600160a01b0386169063150b7a02906125979033908a90899089908990600401615659565b6020604051808303816000875af11580156125b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125da91906154b7565b6001600160e01b031916146126245760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b5050505050565b6000818152601360205260408120600101546060915060086040518060400160405280600981526020016806630313730313232360bc1b81525061266e836140b8565b61267b608085901b6140b8565b60405160200161268e94939291906156ad565b604051602081830303815290604052915050919050565b6007546000906001600160a01b031633146126e85760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b60006126f3836116c2565b9050876001600160a01b0316816001600160a01b03161461273a5760405163521eb56d60e11b81526001600160a01b03808a16600483015282166024820152604401610cf7565b600083815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a08401529192909160c084019160ff91041660058111156127d4576127d4614bcf565b60058111156127e5576127e5614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561286457602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116128275790505b50505050508152505090506001600581111561288257612882614bcf565b8160c00151600581111561289857612898614bcf565b146128b3578060c00151600581111561207d5761207d614bcf565b6128be888888614288565b63ffffffff85166060820152600060808201819052875167ffffffffffffffff8111156128ed576128ed614c62565b604051908082528060200260200182016040528015612916578160200160208202803683370190505b5090506000885167ffffffffffffffff81111561293557612935614c62565b60405190808252806020026020018201604052801561297a57816020015b60408051808201909152600080825260208201528152602001906001900390816129535790505b5090506000805b8a51811015612aaf5789818151811061299c5761299c615472565b60200260200101516000015163ffffffff16600003612a1157600088905060208c83815181106129ce576129ce615472565b60209081029190910181015163ffffffff1690911b919091176000908152600e9091526040902080546fffffffffffffffffffffffffffffffff19169055612a9d565b8a8181518110612a2357612a23615472565b6020026020010151848381518110612a3d57612a3d615472565b602002602001019063ffffffff16908163ffffffff1681525050898181518110612a6957612a69615472565b6020026020010151838381518110612a8357612a83615472565b60200260200101819052508180612a999061549e565b9250505b80612aa78161549e565b915050612981565b5060408401518b8114612ae6576000888152600c602090815260408083208054600181018255908452919092200182905585018c90525b612af3858585858c614398565b6000888152601360209081526040918290208751918801516001600160a01b0316600160601b9081026001600160601b03909316929092178155918701516001830155606087015160028301805460808a015160a08b015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c08a01518a9594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115612bc857612bc8614bcf565b021790555060e08201518051612be891600384019160209091019061487a565b50506040518d81528991507fff312ce131c4d73ac90ece91266be7090486c5e15f78b7ea2b108c36dfd475299060200160405180910390a25060019c9b505050505050505050505050565b6000806001600a541115612c5a576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314612c9f5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6000612caa846116c2565b9050846001600160a01b0316816001600160a01b031614612cf15760405163521eb56d60e11b81526001600160a01b03808716600483015282166024820152604401610cf7565b600084815260136020526040902060016002820154600160601b900460ff166005811115612d2157612d21614bcf565b1480612d4c575060056002820154600160601b900460ff166005811115612d4a57612d4a614bcf565b145b15612d95576002810154600160601b900460ff166005811115612d7157612d71614bcf565b604051633c053f9d60e21b8152600481019190915260248101869052604401610cf7565b6002810154600160401b900463ffffffff1615612dcf5760028101805460ff60601b19166c05000000000000000000000000179055612de5565b60028101805460ff60601b1916600160601b1790555b60005b6003820154811015612e725760008690506020836003018381548110612e1057612e10615472565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff16901b81179050600f60008281526020019081526020016000206000612e619190614929565b50612e6b8161549e565b9050612de8565b5080546040516001600160601b0390911693506000906001600160a01b0388169085908381818185875af1925050503d8060008114612ecd576040519150601f19603f3d011682016040523d82523d6000602084013e612ed2565b606091505b5050905080612f135760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038816604482015260648101859052608401610cf7565b866001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d85604051612f4e91815260200190565b60405180910390a260405186907fe45f5b9540df4f71b7e044809fa318806328c1ea2388a70c7373d97ccf8a0faa90600090a250506001600a819055959194509092505050565b6007546000906001600160a01b03163314612fd85760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b815183511461300757825182516040516308151c1160e41b815260048101929092526024820152604401610cf7565b6000848152601360205260409020600280820154600160601b900460ff16600581111561303657613036614bcf565b1461305b576002810154600160601b900460ff166005811115612d7157612d71614bcf565b83516000805b82811015613150576000889050602087838151811061308257613082615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260408082208151808301909252549384168082526401000000009094046001600160601b0316948101949094529092919003613123578783815181106130ee576130ee615472565b60200260200101518a6040516332832be560e21b8152600401610cf792919063ffffffff929092168252602082015260400190565b602081015161313b906001600160601b0316856154d4565b93505050806131499061549e565b9050613061565b5080341461318157604051637ebbcab960e11b81523460048201526024810182905260448101889052606401610cf7565b6001600160a01b0388811660009081526011602052604090205416156131bd576040516322ddebd960e21b815260048101889052602401610cf7565b60a087901b6001600160a01b0389161760005b838110156134b15760008882815181106131ec576131ec615472565b60200260200101519050600088838151811061320a5761320a615472565b60200260200101519050816001600160a01b03168c6001600160a01b031603613249576040516322ddebd960e21b8152600481018c9052602401610cf7565b6001600160a01b0382811660009081526011602052604090205416156132a0576001600160a01b038281166000908152601160205260409081902054905163631695bd60e01b815291166004820152602401610cf7565b60008b905060208a85815181106132b9576132b9615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e8452604080822054600f90955290205490929091169003613312576040516304ad100760e21b8152600481018d9052602401610cf7565b6000818152600f602090815260408083208054600181810183559185528385200180546001600160a01b03808a166001600160a01b031990921682179092558a8652600d8552838620845180860190955290845263ffffffff8089168587019081528254948501835591875294909520925192909101805494518416600160a01b0277ffffffffffffffffffffffffffffffffffffffffffffffff19909516929091169190911792909217909155600289018054600160401b90049091169060086133dc8361573f565b91906101000a81548163ffffffff021916908363ffffffff160217905550508c60116000856001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001600160a01b03168c8e6001600160a01b03167f6835389a6da5341647f18cbe0a89c56f473f4c17bfaee6e6d07d61f1928e0b7c85604051613495919063ffffffff91909116815260200190565b60405180910390a4505050806134aa9061549e565b90506131d0565b50600284015463ffffffff64010000000082048116600160401b90920416036134f35760028401805460ff60601b19166c030000000000000000000000001790555b6000818152601060205260408120805434929061351a9084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550886001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161357991815260200190565b60405180910390a250600198975050505050505050565b6007546000906001600160a01b031633146135d35760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b60006135de836116c2565b9050836001600160a01b0316816001600160a01b0316146136255760405163521eb56d60e11b81526001600160a01b03808616600483015282166024820152604401610cf7565b600083815260136020526040902060016002820154600160601b900460ff16600581111561365557613655614bcf565b1461367657604051635960d22f60e11b815260048101859052602401610cf7565b80546001600160601b031634146136bb578054604051631c30abbb60e31b81523460048201526001600160601b03909116602482015260448101859052606401610cf7565b60028101805460ff60601b19166c0200000000000000000000000017905560405184907fa48b531f972c0e4aca57afcc5c099c52a7bd21bc5e2a1b733eec3be9e88da97a90600090a2506001949350505050565b6137576040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b60008281526013602090815260409182902082516101008101845281546001600160601b0381168252600160601b908190046001600160a01b031693820193909352600182015493810193909352600281015463ffffffff8082166060860152640100000000820481166080860152600160401b82041660a0850152909160c08401910460ff1660058111156137ef576137ef614bcf565b600581111561380057613800614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561387f57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116138425790505b5050505050815250509050919050565b60006001600a5411156138b5576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146138fa5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6000613905856116c2565b9050856001600160a01b0316816001600160a01b03161461394c5760405163521eb56d60e11b81526001600160a01b03808816600483015282166024820152604401610cf7565b6001600160a01b03841660009081526012602052604090205460ff1661398f5760405162a2307960e51b81526001600160a01b0385166004820152602401610cf7565b600085815260136020526040902060036002820154600160601b900460ff1660058111156139bf576139bf614bcf565b14613a08576002810154600160601b900460ff1660058111156139e4576139e4614bcf565b604051633c053f9d60e21b8152600481019190915260248101879052604401610cf7565b604080516101008101825282546001600160601b0381168252600160601b908190046001600160a01b03166020830152600184015492820192909252600283015463ffffffff8082166060840152640100000000820481166080840152600160401b82041660a0830152600092613b359291859160c08401910460ff166005811115613a9657613a96614bcf565b6005811115613aa757613aa7614bcf565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613b2657602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613ae95790505b50505050508152505088613f67565b6002830154604051631e731b7560e31b81529192506001600160a01b0388169163f398dba891613b7291859163ffffffff16908a90600401615762565b6020604051808303816000875af1158015613b91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb5919061579d565b82546001600160601b0316600160601b6001600160a01b03831690810291909117845560028401805460ff60601b19166c040000000000000000000000001790556040519195509088907f2d53f895cd5faf3cddba94a25c2ced2105885b5b37450ff430ffa3cbdf332c7490600090a360405187907fa133ed72c03a7d008deaae618a61613c4fd41c67bba1cad1a6bc0a1c5a9c156e90600090a250506001600a5550949350505050565b60006001600a541115613c86576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314613ccb5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038616613cf25760405163d92e233d60e01b815260040160405180910390fd5b613cfd858585614288565b60005b8451811015613d9157838181518110613d1b57613d1b615472565b60200260200101516000015163ffffffff1660001480613d615750838181518110613d4857613d48615472565b6020026020010151602001516001600160601b03166000145b15613d7f57604051637c946ed760e01b815260040160405180910390fd5b80613d898161549e565b915050613d00565b505060095480613da08161549e565b915050613deb6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b63ffffffff8316606082015260408101869052600160c082018181525050613e17818686885186614398565b6000828152601360209081526040918290208351918401516001600160a01b0316600160601b9081026001600160601b039093169290921781559183015160018301556060830151600283018054608086015160a087015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c0860151869594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115613eec57613eec614bcf565b021790555060e08201518051613f0c91600384019160209091019061487a565b5050506009829055613f1e878361464f565b817fb34c1e02384201736eb4693b9b173306cb41bff12f15894dea5773088e9a3b1c87604051613f5091815260200190565b60405180910390a2506001600a5595945050505050565b60608260a0015163ffffffff1667ffffffffffffffff811115613f8c57613f8c614c62565b604051908082528060200260200182016040528015613fb5578160200160208202803683370190505b5090506000805b8460e00151518110156140b057600084905060208660e001518381518110613fe657613fe6615472565b602002602001015163ffffffff16901b8117905060005b6000828152600f602052604090205481101561409b576000828152600f6020526040902080548290811061403357614033615472565b9060005260206000200160009054906101000a90046001600160a01b031685858151811061406357614063615472565b6001600160a01b0390921660209283029190910190910152836140858161549e565b94505080806140939061549e565b915050613ffd565b505080806140a89061549e565b915050613fbc565b505092915050565b7aff00000000000000ff00000000000000ff00000000000000ff00006bffffffff0000000000000000604083901c9081167bffffffff00000000000000000000000000000000000000000000000084161760201c6fffffffff000000000000000000000000919091166001600160e01b031984161717601081901c9182167eff00000000000000ff00000000000000ff00000000000000ff000000000000821617600890811c7bff00000000000000ff00000000000000ff00000000000000ff000000939093167fff00000000000000ff00000000000000ff00000000000000ff000000000000009290921691909117919091179081901c7e0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f167f0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f00600492831c161790614224827f06060606060606060606060606060606060606060606060606060606060606066154d4565b901c7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f16602761425491906157ba565b61427e827f30303030303030303030303030303030303030303030303030303030303030306154d4565b610be191906154d4565b60008390036142aa57604051637c946ed760e01b815260040160405180910390fd5b815115806142ba57508051825114155b156142e557815181516040516308151c1160e41b815260048101929092526024820152604401610cf7565b6000805b8351811015612624576142fd8260016154d4565b84828151811061430f5761430f615472565b602002602001015163ffffffff1610156143635783818151811061433557614335615472565b6020026020010151604051632ab10b0b60e21b8152600401610cf7919063ffffffff91909116815260200190565b83818151811061437557614375615472565b602002602001015163ffffffff16915080806143909061549e565b9150506142e9565b60008267ffffffffffffffff8111156143b3576143b3614c62565b6040519080825280602002602001820160405280156143dc578160200160208202803683370190505b5060e087015260005b8381101561456c578581815181106143ff576143ff615472565b60200260200101518760e00151828151811061441d5761441d615472565b63ffffffff909216602092830291909101820152865184919088908490811061444857614448615472565b602002602001015163ffffffff16901b8117905085828151811061446e5761446e615472565b6020908102919091018101516000838152600e8352604090208151815492909301516001600160601b0316640100000000026fffffffffffffffffffffffffffffffff1990921663ffffffff9093169290921717905585518690839081106144d8576144d8615472565b602002602001015160000151886080018181516144f591906157d1565b63ffffffff1690525085516001600160601b0384169087908490811061451d5761451d615472565b6020026020010151602001516001600160601b031611156145595785828151811061454a5761454a615472565b60200260200101516020015192505b50806145648161549e565b9150506143e5565b506001600160601b0381168652608086015160009061458c9060026157ee565b6145979060016157d1565b63ffffffff1690506145aa600382615824565b6000036145c3576145bc600382615838565b90506145dc565b6145ce600382615838565b6145d99060016154d4565b90505b80876060015163ffffffff1610806146075750866080015163ffffffff16876060015163ffffffff16115b15614646576060870151608088015160405163eb3a8ba360e01b815263ffffffff92831660048201526024810184905291166044820152606401610cf7565b50505050505050565b614659828261473f565b6001600160a01b0382163b1561473b57604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af11580156146cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146f191906154b7565b6001600160e01b0319161461473b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b5050565b6001600160a01b0382166147895760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610cf7565b6000818152600260205260409020546001600160a01b0316156147ee5760405162461bcd60e51b815260206004820152600e60248201527f414c52454144595f4d494e5445440000000000000000000000000000000000006044820152606401610cf7565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b50805460008255906000526020600020908101906148779190614947565b50565b828054828255906000526020600020906007016008900481019282156149195791602002820160005b838211156148e757835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026148a3565b80156149175782816101000a81549063ffffffff02191690556004016020816003010492830192600103026148e7565b505b50614925929150614977565b5090565b50805460008255906000526020600020908101906148779190614977565b5b8082111561492557805477ffffffffffffffffffffffffffffffffffffffffffffffff19168155600101614948565b5b808211156149255760008155600101614978565b6001600160e01b03198116811461487757600080fd5b6000602082840312156149b457600080fd5b81356149bf8161498c565b9392505050565b60005b838110156149e15781810151838201526020016149c9565b50506000910152565b60008151808452614a028160208601602086016149c6565b601f01601f19169290920160200192915050565b6020815260006149bf60208301846149ea565b600060208284031215614a3b57600080fd5b5035919050565b6001600160a01b038116811461487757600080fd5b60008060408385031215614a6a57600080fd5b8235614a7581614a42565b946020939093013593505050565b600060208284031215614a9557600080fd5b81356149bf81614a42565b6000604080830185845260208281860152818651808452606087019150828801935060005b81811015614af9578451805163ffffffff1684528401516001600160601b0316848401529383019391850191600101614ac5565b509098975050505050505050565b60008060408385031215614b1a57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015614b625781516001600160a01b031687529582019590820190600101614b3d565b509495945050505050565b828152604060208201526000614b866040830184614b29565b949350505050565b600080600060608486031215614ba357600080fd5b8335614bae81614a42565b92506020840135614bbe81614a42565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b60068110614c0357634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03881681526001600160a01b03871660208201526040810186905263ffffffff85811660608301528481166080830152831660a082015260e08101614c5660c0830184614be5565b98975050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715614c9b57614c9b614c62565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614cca57614cca614c62565b604052919050565b600067ffffffffffffffff831115614cec57614cec614c62565b614cff601f8401601f1916602001614ca1565b9050828152838383011115614d1357600080fd5b828260208301376000602084830101529392505050565b600060208284031215614d3c57600080fd5b813567ffffffffffffffff811115614d5357600080fd5b8201601f81018413614d6457600080fd5b614b8684823560208401614cd2565b600067ffffffffffffffff821115614d8d57614d8d614c62565b5060051b60200190565b600082601f830112614da857600080fd5b81356020614dbd614db883614d73565b614ca1565b82815260059290921b84018101918181019086841115614ddc57600080fd5b8286015b84811015614e00578035614df381614a42565b8352918301918301614de0565b509695505050505050565b80356001600160601b03811681146115dc57600080fd5b600080600060608486031215614e3757600080fd5b833567ffffffffffffffff80821115614e4f57600080fd5b614e5b87838801614d97565b9450602091508186013581811115614e7257600080fd5b86019050601f81018713614e8557600080fd5b8035614e93614db882614d73565b81815260059190911b82018301908381019089831115614eb257600080fd5b928401925b82841015614ed757614ec884614e0b565b82529284019290840190614eb7565b96999698505050506040949094013593505050565b60008060408385031215614eff57600080fd5b8235614f0a81614a42565b915060208301358015158114614f1f57600080fd5b809150509250929050565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015614f6b57845183529383019391830191600101614f4f565b5090979650505050505050565b600080600080600060808688031215614f9057600080fd5b8535614f9b81614a42565b94506020860135614fab81614a42565b935060408601359250606086013567ffffffffffffffff80821115614fcf57600080fd5b818801915088601f830112614fe357600080fd5b813581811115614ff257600080fd5b89602082850101111561500457600080fd5b9699959850939650602001949392505050565b803563ffffffff811681146115dc57600080fd5b600082601f83011261503c57600080fd5b8135602061504c614db883614d73565b82815260059290921b8401810191818101908684111561506b57600080fd5b8286015b84811015614e005761508081615017565b835291830191830161506f565b600082601f83011261509e57600080fd5b813560206150ae614db883614d73565b82815260069290921b840181019181810190868411156150cd57600080fd5b8286015b84811015614e0057604081890312156150ea5760008081fd5b6150f2614c78565b6150fb82615017565b8152615108858301614e0b565b818601528352918301916040016150d1565b60008060008060008060c0878903121561513357600080fd5b863561513e81614a42565b955060208701359450604087013567ffffffffffffffff8082111561516257600080fd5b61516e8a838b0161502b565b9550606089013591508082111561518457600080fd5b5061519189828a0161508d565b9350506151a060808801615017565b915060a087013590509295509295509295565b600080600080608085870312156151c957600080fd5b84356151d481614a42565b935060208501359250604085013567ffffffffffffffff808211156151f857600080fd5b61520488838901614d97565b9350606087013591508082111561521a57600080fd5b506152278782880161502b565b91505092959194509250565b6000806040838503121561524657600080fd5b823561525181614a42565b91506020830135614f1f81614a42565b600081518084526020808501945080840160005b83811015614b6257815163ffffffff1687529582019590820190600101615275565b602081526001600160601b0382511660208201526001600160a01b03602083015116604082015260408201516060820152600060608301516152e1608084018263ffffffff169052565b50608083015163ffffffff811660a08401525060a083015163ffffffff811660c08401525060c083015161531860e0840182614be5565b5060e083015161010083810152614b86610120840182615261565b6000806000806080858703121561534957600080fd5b843561535481614a42565b935060208501359250604085013561536b81614a42565b9150606085013567ffffffffffffffff81111561538757600080fd5b8501601f8101871361539857600080fd5b61522787823560208401614cd2565b600080600080600060a086880312156153bf57600080fd5b85356153ca81614a42565b945060208601359350604086013567ffffffffffffffff808211156153ee57600080fd5b6153fa89838a0161502b565b9450606088013591508082111561541057600080fd5b5061541d8882890161508d565b92505061542c60808701615017565b90509295509295909350565b600181811c9082168061544c57607f821691505b60208210810361546c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016154b0576154b0615488565b5060010190565b6000602082840312156154c957600080fd5b81516149bf8161498c565b80820180821115610be157610be1615488565b601f82111561142357600081815260208120601f850160051c8101602086101561550e5750805b601f850160051c820191505b8181101561552d5782815560010161551a565b505050505050565b815167ffffffffffffffff81111561554f5761554f614c62565b6155638161555d8454615438565b846154e7565b602080601f83116001811461559857600084156155805750858301515b600019600386901b1c1916600185901b17855561552d565b600085815260208120601f198616915b828110156155c7578886015182559484019460019091019084016155a8565b50858210156155e55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160601b0381811683821601908082111561561557615615615488565b5092915050565b6001600160601b0382811682821603908082111561561557615615615488565b63ffffffff82811682821603908082111561561557615615615488565b60006001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b60008086546156bb81615438565b600182811680156156d357600181146156e857615717565b60ff1984168752821515830287019450615717565b8a60005260208060002060005b8581101561570e5781548a8201529084019082016156f5565b50505082870194505b50505050855161572b818360208a016149c6565b019384525050602082015260400192915050565b600063ffffffff80831681810361575857615758615488565b6001019392505050565b6060815260006157756060830186614b29565b63ffffffff85166020840152828103604084015261579381856149ea565b9695505050505050565b6000602082840312156157af57600080fd5b81516149bf81614a42565b8082028115828204841417610be157610be1615488565b63ffffffff81811683821601908082111561561557615615615488565b63ffffffff8181168382160280821691908281146140b0576140b0615488565b634e487b7160e01b600052601260045260246000fd5b6000826158335761583361580e565b500690565b6000826158475761584761580e565b50049056fea2646970667358221220ee3dd136eb9c3aaae80969db0d981f4555af6520415662932908c79dee30e48b64736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106103345760003560e01c806370a08231116101b0578063a60e4c3c116100ec578063dff7672411610095578063ef0e239b1161006f578063ef0e239b14610af7578063f908bc7714610b24578063fbdeb3d714610b44578063ffa1ad7414610b6457600080fd5b8063dff7672414610a96578063e23f6fb414610aa9578063e985e9c514610abc57600080fd5b8063c87b56dd116100c6578063c87b56dd14610a36578063cbf994f814610a56578063ccc9305d14610a7657600080fd5b8063a60e4c3c146109c8578063a6f9dae1146109f6578063b88d4fde14610a1657600080fd5b80638a2bd86f116101595780639890220b116101335780639890220b1461093c578063a22cb46514610951578063a3fbbaae14610971578063a5d059ca1461099157600080fd5b80638a2bd86f146108c25780638da5cb5b1461090757806395d89b411461092757600080fd5b80637c5e63e01161018a5780637c5e63e01461084d57806382694b1d1461088257806386a2bdd4146108a257600080fd5b806370a08231146107c9578063718934d8146107e957806373b8b6a21461082d57600080fd5b806342842e0e1161027f57806355f804b3116102285780636352211e116102025780636352211e1461070a57806363dd76151461072a5780636c0360eb146107945780636f99f15c146107a957600080fd5b806355f804b3146106a357806357838e85146106c35780635e4507fa146106ea57600080fd5b80634eb780da116102595780634eb780da1461062d5780634f558e79146106635780634f6ccce71461068357600080fd5b806342842e0e146105cd578063481c6a75146105ed5780634d486f851461060d57600080fd5b806318160ddd116102e157806323b872dd116102bb57806323b872dd146104d057806342144854146104f05780634236aff81461053e57600080fd5b806318160ddd146104505780631de286ba1461047457806321e4f7bb146104a257600080fd5b8063095ea7b311610312578063095ea7b3146103de57806310c6aa191461040057806317351f7e1461042057600080fd5b806301ffc9a71461033957806306fdde031461036e578063081812fc14610390575b600080fd5b34801561034557600080fd5b506103596103543660046149a2565b610b95565b60405190151581526020015b60405180910390f35b34801561037a57600080fd5b50610383610be7565b6040516103659190614a16565b34801561039c57600080fd5b506103c66103ab366004614a29565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610365565b3480156103ea57600080fd5b506103fe6103f9366004614a57565b610c75565b005b34801561040c57600080fd5b506103fe61041b366004614a83565b610d5c565b34801561042c57600080fd5b5061035961043b366004614a83565b60126020526000908152604090205460ff1681565b34801561045c57600080fd5b5061046660095481565b604051908152602001610365565b34801561048057600080fd5b5061049461048f366004614a29565b610e15565b604051610365929190614aa0565b3480156104ae57600080fd5b506104c26104bd366004614b07565b61106b565b604051610365929190614b6d565b3480156104dc57600080fd5b506103fe6104eb366004614b8e565b611159565b3480156104fc57600080fd5b5061052661050b366004614a29565b6010602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610365565b34801561054a57600080fd5b506105ba610559366004614a29565b6013602052600090815260409020805460018201546002909201546001600160601b03821692600160601b928390046001600160a01b031692909163ffffffff808216926401000000008304821692600160401b8104909216910460ff1687565b6040516103659796959493929190614c07565b3480156105d957600080fd5b506103fe6105e8366004614b8e565b611333565b3480156105f957600080fd5b506007546103c6906001600160a01b031681565b34801561061957600080fd5b506104c2610628366004614a29565b611428565b34801561063957600080fd5b506103c6610648366004614a83565b6011602052600090815260409020546001600160a01b031681565b34801561066f57600080fd5b5061035961067e366004614a29565b61157a565b34801561068f57600080fd5b5061046661069e366004614a29565b61159c565b3480156106af57600080fd5b506103fe6106be366004614d2a565b6115e1565b3480156106cf57600080fd5b50600b546103c690600160601b90046001600160a01b031681565b3480156106f657600080fd5b506103c6610705366004614b07565b61168a565b34801561071657600080fd5b506103c6610725366004614a29565b6116c2565b34801561073657600080fd5b50610770610745366004614a29565b600e6020526000908152604090205463ffffffff81169064010000000090046001600160601b031682565b6040805163ffffffff90931683526001600160601b03909116602083015201610365565b3480156107a057600080fd5b50610383611727565b3480156107b557600080fd5b50600b54610526906001600160601b031681565b3480156107d557600080fd5b506104666107e4366004614a83565b611734565b3480156107f557600080fd5b50610809610804366004614b07565b6117a8565b604080516001600160a01b03909316835263ffffffff909116602083015201610365565b34801561083957600080fd5b50610359610848366004614e22565b6117ee565b34801561085957600080fd5b506103836040518060400160405280600981526020016806630313730313232360bc1b81525081565b34801561088e57600080fd5b5061035961089d366004614eec565b611c43565b3480156108ae57600080fd5b506104666108bd366004614b07565b611cdc565b3480156108ce57600080fd5b506104666108dd366004614a57565b60a01b6001600160a01b03909116176000908152601060205260409020546001600160601b031690565b34801561091357600080fd5b506006546103c6906001600160a01b031681565b34801561093357600080fd5b50610383611d0d565b34801561094857600080fd5b50610466611d1a565b34801561095d57600080fd5b506103fe61096c366004614eec565b611e78565b34801561097d57600080fd5b506103fe61098c366004614a83565b611ee4565b34801561099d57600080fd5b506109b16109ac366004614a57565b611f95565b604080519215158352602083019190915201610365565b3480156109d457600080fd5b506109e86109e3366004614a29565b612431565b604051610365929190614f2a565b348015610a0257600080fd5b506103fe610a11366004614a83565b612495565b348015610a2257600080fd5b506103fe610a31366004614f78565b612546565b348015610a4257600080fd5b50610383610a51366004614a29565b61262b565b348015610a6257600080fd5b50610359610a7136600461511a565b6126a5565b348015610a8257600080fd5b506109b1610a91366004614a57565b612c33565b610359610aa43660046151b3565b612f95565b610359610ab7366004614a57565b613590565b348015610ac857600080fd5b50610359610ad7366004615233565b600560209081526000928352604080842090915290825290205460ff1681565b348015610b0357600080fd5b50610b17610b12366004614a29565b61370f565b6040516103659190615297565b348015610b3057600080fd5b506103c6610b3f366004615333565b61388f565b348015610b5057600080fd5b50610466610b5f3660046153a7565b613c60565b348015610b7057600080fd5b50610383604051806040016040528060058152602001640312e302e360dc1b81525081565b60006301ffc9a760e01b6001600160e01b031983161480610bc657506380ac58cd60e01b6001600160e01b03198316145b80610be15750635b5e139f60e01b6001600160e01b03198316145b92915050565b60008054610bf490615438565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2090615438565b8015610c6d5780601f10610c4257610100808354040283529160200191610c6d565b820191906000526020600020905b815481529060010190602001808311610c5057829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b031633811480610cbe57506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b610d005760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6006546001600160a01b03163314610d9c5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038116610dc35760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160601b0316600160601b6001600160a01b038416908102919091179091556040517f8d1e8547016120917daad7f81c42b48f7fee379badc48f1889f0f43bb619472590600090a250565b600081815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff9104166005811115610eb657610eb6614bcf565b6005811115610ec757610ec7614bcf565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015610f4657602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411610f095790505b50505050508152505090508060e001515192508267ffffffffffffffff811115610f7257610f72614c62565b604051908082528060200260200182016040528015610fb757816020015b6040805180820190915260008082526020820152815260200190600190039081610f905790505b50915060005b8381101561106457600085905060208360e001518381518110610fe257610fe2615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260409081902081518083019092525492831681526401000000009092046001600160601b031692820192909252845185908490811061104757611047615472565b6020026020010181905250508061105d9061549e565b9050610fbd565b5050915091565b602081811b83176000818152600f909252604090912054906060908267ffffffffffffffff81111561109f5761109f614c62565b6040519080825280602002602001820160405280156110c8578160200160208202803683370190505b50915060005b83811015611150576000828152600f602052604090208054829081106110f6576110f6615472565b9060005260206000200160009054906101000a90046001600160a01b031683828151811061112657611126615472565b6001600160a01b0390921660209283029190910190910152806111488161549e565b9150506110ce565b50509250929050565b6000818152600260205260409020546001600160a01b038481169116146111c25760405162461bcd60e51b815260206004820152600a60248201527f57524f4e475f46524f4d000000000000000000000000000000000000000000006044820152606401610cf7565b6001600160a01b03821661120c5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610cf7565b336001600160a01b038416148061124657506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061126757506000818152600460205260409020546001600160a01b031633145b6112a45760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610cf7565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61133e838383611159565b6001600160a01b0382163b1561142357604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af11580156113b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d991906154b7565b6001600160e01b031916146114235760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b505050565b600081815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff91041660058111156114c9576114c9614bcf565b60058111156114da576114da614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561155957602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff168152602001906004019060208260030104928301926001038202915080841161151c5790505b505050505081525050905061156e8185613f67565b91508151925050915091565b60008082118015610be157506009546115949060016154d4565b821092915050565b60006115a98260016154d4565b90506009548111156115dc57600954604051637ae5968560e01b8152610cf7918391600401918252602082015260400190565b919050565b6006546001600160a01b031633146116215760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b805160000361164357604051637c946ed760e01b815260040160405180910390fd5b600861164f8282615535565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf68160405161167f9190614a16565b60405180910390a150565b600f60205281600052604060002081815481106116a657600080fd5b6000918252602090912001546001600160a01b03169150829050565b6000818152600260205260409020546001600160a01b0316806115dc5760405162461bcd60e51b815260206004820152600a60248201527f4e4f545f4d494e544544000000000000000000000000000000000000000000006044820152606401610cf7565b60088054610bf490615438565b60006001600160a01b03821661178c5760405162461bcd60e51b815260206004820152600c60248201527f5a45524f5f4144445245535300000000000000000000000000000000000000006044820152606401610cf7565b506001600160a01b031660009081526003602052604090205490565b600d60205281600052604060002081815481106117c457600080fd5b6000918252602090912001546001600160a01b0381169250600160a01b900463ffffffff16905082565b600081815260136020908152604080832081516101008101835281546001600160601b0381168252600160601b908190046001600160a01b031694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a0840152849360c08401910460ff16600581111561188557611885614bcf565b600581111561189657611896614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561191557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116118d85790505b50505050508152505090506004600581111561193357611933614bcf565b8160c00151600581111561194957611949614bcf565b14611988578060c00151600581111561196457611964614bcf565b604051633c053f9d60e21b8152600481019190915260248101849052604401610cf7565b83518551146119b757845184516040516308151c1160e41b815260048101929092526024820152604401610cf7565b80602001516001600160a01b0316336001600160a01b031614611a0b5760208101516040516379f91cd360e01b81523360048201526001600160a01b03909116602482015260448101849052606401610cf7565b845160005b81811015611c3657600060116000898481518110611a3057611a30615472565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081205490931660a08a901b81178085526010909252919092205489519193506001600160601b03169081908a9086908110611a9557611a95615472565b60200260200101516001611aa991906155f5565b6001600160601b03161115611b0357600b8054829190600090611ad69084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060009050611b87565b888481518110611b1557611b15615472565b6020908102919091010151600b8054600090611b3b9084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550888481518110611b7157611b71615472565b602002602001015181611b84919061561c565b90505b600082815260106020526040902080546bffffffffffffffffffffffff19166001600160601b038316179055885188906001600160a01b038516907fa2e524bd0f71903485fbb3d6d50cb305f61005ceea2047c3ac92aa7e0d104306908c9088908110611bf657611bf6615472565b6020026020010151604051611c1a91906001600160601b0391909116815260200190565b60405180910390a350505080611c2f9061549e565b9050611a10565b5060019695505050505050565b6006546000906001600160a01b03163314611c865760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038316611cad5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b03919091166000908152601260205260409020805460ff1916911515919091179055600190565b600c6020528160005260406000208181548110611cf857600080fd5b90600052602060002001600091509150505481565b60018054610bf490615438565b60006001600a541115611d40576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a55600b54600160601b90046001600160a01b03163314611d9257600b5460405163312d21ff60e11b8152336004820152600160601b9091046001600160a01b03166024820152604401610cf7565b50600b546001600160601b03168015611e7057600b80546bffffffffffffffffffffffff19169055604051600090339083908381818185875af1925050503d8060008114611dfc576040519150601f19603f3d011682016040523d82523d6000602084013e611e01565b606091505b5050905080611e395760405163cd3f165960e01b81526000600482015230602482015233604482015260648101839052608401610cf7565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2505b6001600a5590565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6006546001600160a01b03163314611f245760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038116611f4b5760405163d92e233d60e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f2c1c11af44aa5608f1dca38c00275c30ea091e02417d36e70e9a1538689c433d90600090a250565b6000806001600a541115611fbc576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146120015760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b0384166120285760405163d92e233d60e01b815260040160405180910390fd5b600083815260136020526040902060056002820154600160601b900460ff16600581111561205857612058614bcf565b146120a1576002810154600160601b900460ff16600581111561207d5761207d614bcf565b604051633c053f9d60e21b8152600481019190915260248101859052604401610cf7565b60a084901b6001600160a01b038616176000818152600d6020908152604080832080548251818502810185019093528083529192909190849084015b8282101561212957600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900463ffffffff16818301528252600190920191016120dd565b50508251929350505060008190036121665760405163df2ddd7360e01b81526001600160a01b038916600482015260248101889052604401610cf7565b808460020160088282829054906101000a900463ffffffff16612189919061563c565b92506101000a81548163ffffffff021916908363ffffffff1602179055508360020160089054906101000a900463ffffffff1663ffffffff166000036121df5760028401805460ff60601b1916600160601b1790555b60005b818110156122a7576000889050602084838151811061220357612203615472565b60209081029190910181015181015163ffffffff1690911b919091176000818152600e90925260409091205461224a9064010000000090046001600160601b0316886154d4565b96506011600085848151811061226257612262615472565b602090810291909101810151516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055508061229f8161549e565b9150506121e2565b506000838152600d602052604081206122bf91614859565b6000838152601060205260409020546001600160601b0316808611156122ec57806001600160601b031695505b85156123e55760008481526010602052604080822080546bffffffffffffffffffffffff19169055516001600160a01b038b169088908381818185875af1925050503d806000811461235a576040519150601f19603f3d011682016040523d82523d6000602084013e61235f565b606091505b50509050806123a05760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038b16604482015260648101889052608401610cf7565b896001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d886040516123db91815260200190565b60405180910390a2505b60405188906001600160a01b038b16907f5ebf7fe30be09f0f03b9195632508d95c8b67bf010c93abda67f70d5d9599d1e90600090a350506001600a8190559793965092945050505050565b6000818152600c60209081526040808320805482518185028101850190935280835260609383018282801561248557602002820191906000526020600020905b815481526020019060010190808311612471575b5050505050905080519150915091565b6006546001600160a01b031633146124d55760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b0381166124fc5760405163d92e233d60e01b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b90600090a250565b612551858585611159565b6001600160a01b0384163b1561262457604051630a85bd0160e11b808252906001600160a01b0386169063150b7a02906125979033908a90899089908990600401615659565b6020604051808303816000875af11580156125b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125da91906154b7565b6001600160e01b031916146126245760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b5050505050565b6000818152601360205260408120600101546060915060086040518060400160405280600981526020016806630313730313232360bc1b81525061266e836140b8565b61267b608085901b6140b8565b60405160200161268e94939291906156ad565b604051602081830303815290604052915050919050565b6007546000906001600160a01b031633146126e85760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b60006126f3836116c2565b9050876001600160a01b0316816001600160a01b03161461273a5760405163521eb56d60e11b81526001600160a01b03808a16600483015282166024820152604401610cf7565b600083815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a08401529192909160c084019160ff91041660058111156127d4576127d4614bcf565b60058111156127e5576127e5614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561286457602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116128275790505b50505050508152505090506001600581111561288257612882614bcf565b8160c00151600581111561289857612898614bcf565b146128b3578060c00151600581111561207d5761207d614bcf565b6128be888888614288565b63ffffffff85166060820152600060808201819052875167ffffffffffffffff8111156128ed576128ed614c62565b604051908082528060200260200182016040528015612916578160200160208202803683370190505b5090506000885167ffffffffffffffff81111561293557612935614c62565b60405190808252806020026020018201604052801561297a57816020015b60408051808201909152600080825260208201528152602001906001900390816129535790505b5090506000805b8a51811015612aaf5789818151811061299c5761299c615472565b60200260200101516000015163ffffffff16600003612a1157600088905060208c83815181106129ce576129ce615472565b60209081029190910181015163ffffffff1690911b919091176000908152600e9091526040902080546fffffffffffffffffffffffffffffffff19169055612a9d565b8a8181518110612a2357612a23615472565b6020026020010151848381518110612a3d57612a3d615472565b602002602001019063ffffffff16908163ffffffff1681525050898181518110612a6957612a69615472565b6020026020010151838381518110612a8357612a83615472565b60200260200101819052508180612a999061549e565b9250505b80612aa78161549e565b915050612981565b5060408401518b8114612ae6576000888152600c602090815260408083208054600181018255908452919092200182905585018c90525b612af3858585858c614398565b6000888152601360209081526040918290208751918801516001600160a01b0316600160601b9081026001600160601b03909316929092178155918701516001830155606087015160028301805460808a015160a08b015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c08a01518a9594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115612bc857612bc8614bcf565b021790555060e08201518051612be891600384019160209091019061487a565b50506040518d81528991507fff312ce131c4d73ac90ece91266be7090486c5e15f78b7ea2b108c36dfd475299060200160405180910390a25060019c9b505050505050505050505050565b6000806001600a541115612c5a576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314612c9f5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6000612caa846116c2565b9050846001600160a01b0316816001600160a01b031614612cf15760405163521eb56d60e11b81526001600160a01b03808716600483015282166024820152604401610cf7565b600084815260136020526040902060016002820154600160601b900460ff166005811115612d2157612d21614bcf565b1480612d4c575060056002820154600160601b900460ff166005811115612d4a57612d4a614bcf565b145b15612d95576002810154600160601b900460ff166005811115612d7157612d71614bcf565b604051633c053f9d60e21b8152600481019190915260248101869052604401610cf7565b6002810154600160401b900463ffffffff1615612dcf5760028101805460ff60601b19166c05000000000000000000000000179055612de5565b60028101805460ff60601b1916600160601b1790555b60005b6003820154811015612e725760008690506020836003018381548110612e1057612e10615472565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff16901b81179050600f60008281526020019081526020016000206000612e619190614929565b50612e6b8161549e565b9050612de8565b5080546040516001600160601b0390911693506000906001600160a01b0388169085908381818185875af1925050503d8060008114612ecd576040519150601f19603f3d011682016040523d82523d6000602084013e612ed2565b606091505b5050905080612f135760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038816604482015260648101859052608401610cf7565b866001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d85604051612f4e91815260200190565b60405180910390a260405186907fe45f5b9540df4f71b7e044809fa318806328c1ea2388a70c7373d97ccf8a0faa90600090a250506001600a819055959194509092505050565b6007546000906001600160a01b03163314612fd85760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b815183511461300757825182516040516308151c1160e41b815260048101929092526024820152604401610cf7565b6000848152601360205260409020600280820154600160601b900460ff16600581111561303657613036614bcf565b1461305b576002810154600160601b900460ff166005811115612d7157612d71614bcf565b83516000805b82811015613150576000889050602087838151811061308257613082615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260408082208151808301909252549384168082526401000000009094046001600160601b0316948101949094529092919003613123578783815181106130ee576130ee615472565b60200260200101518a6040516332832be560e21b8152600401610cf792919063ffffffff929092168252602082015260400190565b602081015161313b906001600160601b0316856154d4565b93505050806131499061549e565b9050613061565b5080341461318157604051637ebbcab960e11b81523460048201526024810182905260448101889052606401610cf7565b6001600160a01b0388811660009081526011602052604090205416156131bd576040516322ddebd960e21b815260048101889052602401610cf7565b60a087901b6001600160a01b0389161760005b838110156134b15760008882815181106131ec576131ec615472565b60200260200101519050600088838151811061320a5761320a615472565b60200260200101519050816001600160a01b03168c6001600160a01b031603613249576040516322ddebd960e21b8152600481018c9052602401610cf7565b6001600160a01b0382811660009081526011602052604090205416156132a0576001600160a01b038281166000908152601160205260409081902054905163631695bd60e01b815291166004820152602401610cf7565b60008b905060208a85815181106132b9576132b9615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e8452604080822054600f90955290205490929091169003613312576040516304ad100760e21b8152600481018d9052602401610cf7565b6000818152600f602090815260408083208054600181810183559185528385200180546001600160a01b03808a166001600160a01b031990921682179092558a8652600d8552838620845180860190955290845263ffffffff8089168587019081528254948501835591875294909520925192909101805494518416600160a01b0277ffffffffffffffffffffffffffffffffffffffffffffffff19909516929091169190911792909217909155600289018054600160401b90049091169060086133dc8361573f565b91906101000a81548163ffffffff021916908363ffffffff160217905550508c60116000856001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001600160a01b03168c8e6001600160a01b03167f6835389a6da5341647f18cbe0a89c56f473f4c17bfaee6e6d07d61f1928e0b7c85604051613495919063ffffffff91909116815260200190565b60405180910390a4505050806134aa9061549e565b90506131d0565b50600284015463ffffffff64010000000082048116600160401b90920416036134f35760028401805460ff60601b19166c030000000000000000000000001790555b6000818152601060205260408120805434929061351a9084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550886001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161357991815260200190565b60405180910390a250600198975050505050505050565b6007546000906001600160a01b031633146135d35760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b60006135de836116c2565b9050836001600160a01b0316816001600160a01b0316146136255760405163521eb56d60e11b81526001600160a01b03808616600483015282166024820152604401610cf7565b600083815260136020526040902060016002820154600160601b900460ff16600581111561365557613655614bcf565b1461367657604051635960d22f60e11b815260048101859052602401610cf7565b80546001600160601b031634146136bb578054604051631c30abbb60e31b81523460048201526001600160601b03909116602482015260448101859052606401610cf7565b60028101805460ff60601b19166c0200000000000000000000000017905560405184907fa48b531f972c0e4aca57afcc5c099c52a7bd21bc5e2a1b733eec3be9e88da97a90600090a2506001949350505050565b6137576040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b60008281526013602090815260409182902082516101008101845281546001600160601b0381168252600160601b908190046001600160a01b031693820193909352600182015493810193909352600281015463ffffffff8082166060860152640100000000820481166080860152600160401b82041660a0850152909160c08401910460ff1660058111156137ef576137ef614bcf565b600581111561380057613800614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561387f57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116138425790505b5050505050815250509050919050565b60006001600a5411156138b5576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146138fa5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6000613905856116c2565b9050856001600160a01b0316816001600160a01b03161461394c5760405163521eb56d60e11b81526001600160a01b03808816600483015282166024820152604401610cf7565b6001600160a01b03841660009081526012602052604090205460ff1661398f5760405162a2307960e51b81526001600160a01b0385166004820152602401610cf7565b600085815260136020526040902060036002820154600160601b900460ff1660058111156139bf576139bf614bcf565b14613a08576002810154600160601b900460ff1660058111156139e4576139e4614bcf565b604051633c053f9d60e21b8152600481019190915260248101879052604401610cf7565b604080516101008101825282546001600160601b0381168252600160601b908190046001600160a01b03166020830152600184015492820192909252600283015463ffffffff8082166060840152640100000000820481166080840152600160401b82041660a0830152600092613b359291859160c08401910460ff166005811115613a9657613a96614bcf565b6005811115613aa757613aa7614bcf565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613b2657602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613ae95790505b50505050508152505088613f67565b6002830154604051631e731b7560e31b81529192506001600160a01b0388169163f398dba891613b7291859163ffffffff16908a90600401615762565b6020604051808303816000875af1158015613b91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb5919061579d565b82546001600160601b0316600160601b6001600160a01b03831690810291909117845560028401805460ff60601b19166c040000000000000000000000001790556040519195509088907f2d53f895cd5faf3cddba94a25c2ced2105885b5b37450ff430ffa3cbdf332c7490600090a360405187907fa133ed72c03a7d008deaae618a61613c4fd41c67bba1cad1a6bc0a1c5a9c156e90600090a250506001600a5550949350505050565b60006001600a541115613c86576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314613ccb5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038616613cf25760405163d92e233d60e01b815260040160405180910390fd5b613cfd858585614288565b60005b8451811015613d9157838181518110613d1b57613d1b615472565b60200260200101516000015163ffffffff1660001480613d615750838181518110613d4857613d48615472565b6020026020010151602001516001600160601b03166000145b15613d7f57604051637c946ed760e01b815260040160405180910390fd5b80613d898161549e565b915050613d00565b505060095480613da08161549e565b915050613deb6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b63ffffffff8316606082015260408101869052600160c082018181525050613e17818686885186614398565b6000828152601360209081526040918290208351918401516001600160a01b0316600160601b9081026001600160601b039093169290921781559183015160018301556060830151600283018054608086015160a087015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c0860151869594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115613eec57613eec614bcf565b021790555060e08201518051613f0c91600384019160209091019061487a565b5050506009829055613f1e878361464f565b817fb34c1e02384201736eb4693b9b173306cb41bff12f15894dea5773088e9a3b1c87604051613f5091815260200190565b60405180910390a2506001600a5595945050505050565b60608260a0015163ffffffff1667ffffffffffffffff811115613f8c57613f8c614c62565b604051908082528060200260200182016040528015613fb5578160200160208202803683370190505b5090506000805b8460e00151518110156140b057600084905060208660e001518381518110613fe657613fe6615472565b602002602001015163ffffffff16901b8117905060005b6000828152600f602052604090205481101561409b576000828152600f6020526040902080548290811061403357614033615472565b9060005260206000200160009054906101000a90046001600160a01b031685858151811061406357614063615472565b6001600160a01b0390921660209283029190910190910152836140858161549e565b94505080806140939061549e565b915050613ffd565b505080806140a89061549e565b915050613fbc565b505092915050565b7aff00000000000000ff00000000000000ff00000000000000ff00006bffffffff0000000000000000604083901c9081167bffffffff00000000000000000000000000000000000000000000000084161760201c6fffffffff000000000000000000000000919091166001600160e01b031984161717601081901c9182167eff00000000000000ff00000000000000ff00000000000000ff000000000000821617600890811c7bff00000000000000ff00000000000000ff00000000000000ff000000939093167fff00000000000000ff00000000000000ff00000000000000ff000000000000009290921691909117919091179081901c7e0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f167f0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f00600492831c161790614224827f06060606060606060606060606060606060606060606060606060606060606066154d4565b901c7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f16602761425491906157ba565b61427e827f30303030303030303030303030303030303030303030303030303030303030306154d4565b610be191906154d4565b60008390036142aa57604051637c946ed760e01b815260040160405180910390fd5b815115806142ba57508051825114155b156142e557815181516040516308151c1160e41b815260048101929092526024820152604401610cf7565b6000805b8351811015612624576142fd8260016154d4565b84828151811061430f5761430f615472565b602002602001015163ffffffff1610156143635783818151811061433557614335615472565b6020026020010151604051632ab10b0b60e21b8152600401610cf7919063ffffffff91909116815260200190565b83818151811061437557614375615472565b602002602001015163ffffffff16915080806143909061549e565b9150506142e9565b60008267ffffffffffffffff8111156143b3576143b3614c62565b6040519080825280602002602001820160405280156143dc578160200160208202803683370190505b5060e087015260005b8381101561456c578581815181106143ff576143ff615472565b60200260200101518760e00151828151811061441d5761441d615472565b63ffffffff909216602092830291909101820152865184919088908490811061444857614448615472565b602002602001015163ffffffff16901b8117905085828151811061446e5761446e615472565b6020908102919091018101516000838152600e8352604090208151815492909301516001600160601b0316640100000000026fffffffffffffffffffffffffffffffff1990921663ffffffff9093169290921717905585518690839081106144d8576144d8615472565b602002602001015160000151886080018181516144f591906157d1565b63ffffffff1690525085516001600160601b0384169087908490811061451d5761451d615472565b6020026020010151602001516001600160601b031611156145595785828151811061454a5761454a615472565b60200260200101516020015192505b50806145648161549e565b9150506143e5565b506001600160601b0381168652608086015160009061458c9060026157ee565b6145979060016157d1565b63ffffffff1690506145aa600382615824565b6000036145c3576145bc600382615838565b90506145dc565b6145ce600382615838565b6145d99060016154d4565b90505b80876060015163ffffffff1610806146075750866080015163ffffffff16876060015163ffffffff16115b15614646576060870151608088015160405163eb3a8ba360e01b815263ffffffff92831660048201526024810184905291166044820152606401610cf7565b50505050505050565b614659828261473f565b6001600160a01b0382163b1561473b57604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af11580156146cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146f191906154b7565b6001600160e01b0319161461473b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b5050565b6001600160a01b0382166147895760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610cf7565b6000818152600260205260409020546001600160a01b0316156147ee5760405162461bcd60e51b815260206004820152600e60248201527f414c52454144595f4d494e5445440000000000000000000000000000000000006044820152606401610cf7565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b50805460008255906000526020600020908101906148779190614947565b50565b828054828255906000526020600020906007016008900481019282156149195791602002820160005b838211156148e757835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026148a3565b80156149175782816101000a81549063ffffffff02191690556004016020816003010492830192600103026148e7565b505b50614925929150614977565b5090565b50805460008255906000526020600020908101906148779190614977565b5b8082111561492557805477ffffffffffffffffffffffffffffffffffffffffffffffff19168155600101614948565b5b808211156149255760008155600101614978565b6001600160e01b03198116811461487757600080fd5b6000602082840312156149b457600080fd5b81356149bf8161498c565b9392505050565b60005b838110156149e15781810151838201526020016149c9565b50506000910152565b60008151808452614a028160208601602086016149c6565b601f01601f19169290920160200192915050565b6020815260006149bf60208301846149ea565b600060208284031215614a3b57600080fd5b5035919050565b6001600160a01b038116811461487757600080fd5b60008060408385031215614a6a57600080fd5b8235614a7581614a42565b946020939093013593505050565b600060208284031215614a9557600080fd5b81356149bf81614a42565b6000604080830185845260208281860152818651808452606087019150828801935060005b81811015614af9578451805163ffffffff1684528401516001600160601b0316848401529383019391850191600101614ac5565b509098975050505050505050565b60008060408385031215614b1a57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015614b625781516001600160a01b031687529582019590820190600101614b3d565b509495945050505050565b828152604060208201526000614b866040830184614b29565b949350505050565b600080600060608486031215614ba357600080fd5b8335614bae81614a42565b92506020840135614bbe81614a42565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b60068110614c0357634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03881681526001600160a01b03871660208201526040810186905263ffffffff85811660608301528481166080830152831660a082015260e08101614c5660c0830184614be5565b98975050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715614c9b57614c9b614c62565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614cca57614cca614c62565b604052919050565b600067ffffffffffffffff831115614cec57614cec614c62565b614cff601f8401601f1916602001614ca1565b9050828152838383011115614d1357600080fd5b828260208301376000602084830101529392505050565b600060208284031215614d3c57600080fd5b813567ffffffffffffffff811115614d5357600080fd5b8201601f81018413614d6457600080fd5b614b8684823560208401614cd2565b600067ffffffffffffffff821115614d8d57614d8d614c62565b5060051b60200190565b600082601f830112614da857600080fd5b81356020614dbd614db883614d73565b614ca1565b82815260059290921b84018101918181019086841115614ddc57600080fd5b8286015b84811015614e00578035614df381614a42565b8352918301918301614de0565b509695505050505050565b80356001600160601b03811681146115dc57600080fd5b600080600060608486031215614e3757600080fd5b833567ffffffffffffffff80821115614e4f57600080fd5b614e5b87838801614d97565b9450602091508186013581811115614e7257600080fd5b86019050601f81018713614e8557600080fd5b8035614e93614db882614d73565b81815260059190911b82018301908381019089831115614eb257600080fd5b928401925b82841015614ed757614ec884614e0b565b82529284019290840190614eb7565b96999698505050506040949094013593505050565b60008060408385031215614eff57600080fd5b8235614f0a81614a42565b915060208301358015158114614f1f57600080fd5b809150509250929050565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015614f6b57845183529383019391830191600101614f4f565b5090979650505050505050565b600080600080600060808688031215614f9057600080fd5b8535614f9b81614a42565b94506020860135614fab81614a42565b935060408601359250606086013567ffffffffffffffff80821115614fcf57600080fd5b818801915088601f830112614fe357600080fd5b813581811115614ff257600080fd5b89602082850101111561500457600080fd5b9699959850939650602001949392505050565b803563ffffffff811681146115dc57600080fd5b600082601f83011261503c57600080fd5b8135602061504c614db883614d73565b82815260059290921b8401810191818101908684111561506b57600080fd5b8286015b84811015614e005761508081615017565b835291830191830161506f565b600082601f83011261509e57600080fd5b813560206150ae614db883614d73565b82815260069290921b840181019181810190868411156150cd57600080fd5b8286015b84811015614e0057604081890312156150ea5760008081fd5b6150f2614c78565b6150fb82615017565b8152615108858301614e0b565b818601528352918301916040016150d1565b60008060008060008060c0878903121561513357600080fd5b863561513e81614a42565b955060208701359450604087013567ffffffffffffffff8082111561516257600080fd5b61516e8a838b0161502b565b9550606089013591508082111561518457600080fd5b5061519189828a0161508d565b9350506151a060808801615017565b915060a087013590509295509295509295565b600080600080608085870312156151c957600080fd5b84356151d481614a42565b935060208501359250604085013567ffffffffffffffff808211156151f857600080fd5b61520488838901614d97565b9350606087013591508082111561521a57600080fd5b506152278782880161502b565b91505092959194509250565b6000806040838503121561524657600080fd5b823561525181614a42565b91506020830135614f1f81614a42565b600081518084526020808501945080840160005b83811015614b6257815163ffffffff1687529582019590820190600101615275565b602081526001600160601b0382511660208201526001600160a01b03602083015116604082015260408201516060820152600060608301516152e1608084018263ffffffff169052565b50608083015163ffffffff811660a08401525060a083015163ffffffff811660c08401525060c083015161531860e0840182614be5565b5060e083015161010083810152614b86610120840182615261565b6000806000806080858703121561534957600080fd5b843561535481614a42565b935060208501359250604085013561536b81614a42565b9150606085013567ffffffffffffffff81111561538757600080fd5b8501601f8101871361539857600080fd5b61522787823560208401614cd2565b600080600080600060a086880312156153bf57600080fd5b85356153ca81614a42565b945060208601359350604086013567ffffffffffffffff808211156153ee57600080fd5b6153fa89838a0161502b565b9450606088013591508082111561541057600080fd5b5061541d8882890161508d565b92505061542c60808701615017565b90509295509295909350565b600181811c9082168061544c57607f821691505b60208210810361546c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016154b0576154b0615488565b5060010190565b6000602082840312156154c957600080fd5b81516149bf8161498c565b80820180821115610be157610be1615488565b601f82111561142357600081815260208120601f850160051c8101602086101561550e5750805b601f850160051c820191505b8181101561552d5782815560010161551a565b505050505050565b815167ffffffffffffffff81111561554f5761554f614c62565b6155638161555d8454615438565b846154e7565b602080601f83116001811461559857600084156155805750858301515b600019600386901b1c1916600185901b17855561552d565b600085815260208120601f198616915b828110156155c7578886015182559484019460019091019084016155a8565b50858210156155e55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160601b0381811683821601908082111561561557615615615488565b5092915050565b6001600160601b0382811682821603908082111561561557615615615488565b63ffffffff82811682821603908082111561561557615615615488565b60006001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b60008086546156bb81615438565b600182811680156156d357600181146156e857615717565b60ff1984168752821515830287019450615717565b8a60005260208060002060005b8581101561570e5781548a8201529084019082016156f5565b50505082870194505b50505050855161572b818360208a016149c6565b019384525050602082015260400192915050565b600063ffffffff80831681810361575857615758615488565b6001019392505050565b6060815260006157756060830186614b29565b63ffffffff85166020840152828103604084015261579381856149ea565b9695505050505050565b6000602082840312156157af57600080fd5b81516149bf81614a42565b8082028115828204841417610be157610be1615488565b63ffffffff81811683821601908082111561561557615615615488565b63ffffffff8181168382160280821691908281146140b0576140b0615488565b634e487b7160e01b600052601260045260246000fd5b6000826158335761583361580e565b500690565b6000826158475761584761580e565b50049056fea2646970667358221220ee3dd136eb9c3aaae80969db0d981f4555af6520415662932908c79dee30e48b64736f6c63430008130033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/service_registry/contract.py b/trader_backup/vendor/valory/contracts/service_registry/contract.py deleted file mode 100644 index 20e21888a..000000000 --- a/trader_backup/vendor/valory/contracts/service_registry/contract.py +++ /dev/null @@ -1,402 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 the class to connect to the Service Registry contract.""" - -import hashlib -import json -import logging -from pathlib import Path -from typing import Any, Dict, FrozenSet, List, Optional, Tuple, Union, cast - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from web3.types import BlockData, EventData, TxReceipt - - -PUBLIC_ID = PublicId.from_str("valory/service_registry:0.1.0") -ETHEREUM_IDENTIFIER = "ethereum" -UNIT_HASH_PREFIX = "0x{metadata_hash}" -EXPECTED_CONTRACT_ADDRESS_BY_CHAIN_ID = { - 1: "0x48b6af7B12C71f09e2fC8aF4855De4Ff54e775cA", - 5: "0x1cEe30D08943EB58EFF84DD1AB44a6ee6FEff63a", - 100: "0x9338b5153AE39BB89f50468E608eD9d764B755fD", - 137: "0xE3607b00E75f6405248323A9417ff6b39B244b50", - 31337: "0x998abeb3E57409262aE5b751f60747921B33613E", -} -DEPLOYED_BYTECODE_MD5_HASH_BY_CHAIN_ID = { - 1: "6f9fc7f3c2348801737120e6b5f8fa8e9670c65152c66d128ff4cddb465b4d705340c559e352f5e7f29bda3b84a8d36d4a9448b791cfe2d370e31c01276e0244", - 5: "d4a860f21f17762c99d93359244b39a878dd5bac9ea6056c0ff29c7558d6653aa0d5962aa819fc9f05f237d068845125cfc37a7fd7761b11c29a709ad5c48157", - 100: "10e2cfb500481d6c5a3b6b90507e4ac04d8b0d88741cea5568306ed4115f24e8b9747055423da5fca05838d5ccefebf41fb47d2ba1fb45215b6b21c0a27823be", - 137: "10e2cfb500481d6c5a3b6b90507e4ac04d8b0d88741cea5568306ed4115f24e8b9747055423da5fca05838d5ccefebf41fb47d2ba1fb45215b6b21c0a27823be", - 31337: "41ab54d43fd4bdfdc929658a0dc9bedd970c7339eecafbefda9892ab54c02c396bceedaa3a84a0f4690bee03dc11195a3267a264de7859c420efbf4291f1fef0", -} -L1_CHAINS = ( - 1, - 5, - 31337, -) -L2_BUILD_FILENAME = "ServiceRegistryL2.json" - -ServiceInfo = Tuple[int, str, bytes, int, int, int, int, List[int]] - -_logger = logging.getLogger( - f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" -) - - -class ServiceRegistryContract(Contract): - """The Service Registry contract.""" - - contract_id = PUBLIC_ID - - @classmethod - def get_raw_transaction( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get the Safe transaction.""" - raise NotImplementedError # pragma: nocover - - @classmethod - def get_raw_message( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[bytes]: - """Get raw message.""" - raise NotImplementedError # pragma: nocover - - @classmethod - def get_state( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get state.""" - raise NotImplementedError # pragma: nocover - - @staticmethod - def is_l1_chain(ledger_api: LedgerApi) -> bool: - """Check if we're interecting with an L1 chain""" - return ledger_api.api.eth.chain_id in L1_CHAINS - - @staticmethod - def load_l2_build() -> JSONLike: - """Load L2 ABI""" - path = Path(__file__).parent / "build" / L2_BUILD_FILENAME - return json.loads(path.read_text(encoding="utf-8")) - - @classmethod - def get_instance( - cls, - ledger_api: LedgerApi, - contract_address: Optional[str] = None, - ) -> Any: - """Get contract instance.""" - if ledger_api.identifier != ETHEREUM_IDENTIFIER: - return super().get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - if cls.is_l1_chain(ledger_api=ledger_api): - contract_interface = cls.contract_interface.get(ledger_api.identifier, {}) - else: - contract_interface = cls.load_l2_build() - instance = ledger_api.get_contract_instance( - contract_interface, contract_address - ) - return instance - - @classmethod - def verify_contract( - cls, ledger_api: LedgerApi, contract_address: str - ) -> Dict[str, Union[bool, str]]: - """ - Verify the contract's bytecode - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :return: the verified status - """ - verified = False - chain_id = ledger_api.api.eth.chain_id - expected_address = EXPECTED_CONTRACT_ADDRESS_BY_CHAIN_ID[chain_id] - if contract_address != expected_address: - _logger.error( - f"For chain_id {chain_id} expected {expected_address} and got {contract_address}." - ) - return dict(verified=verified) - deployed_bytecode = ledger_api.api.eth.get_code(contract_address).hex() - sha512_hash = hashlib.sha512(deployed_bytecode.encode("utf-8")).hexdigest() - verified = DEPLOYED_BYTECODE_MD5_HASH_BY_CHAIN_ID[chain_id] == sha512_hash - if not verified: # pragma: nocover - _logger.error( - f"CONTRACT NOT VERIFIED! Contract address: {contract_address}, chain_id: {chain_id}." - ) - return dict(verified=verified) - - @classmethod - def exists( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> bool: - """Check if the service id exists""" - - contract_instance = cls.get_instance(ledger_api, contract_address) - exists = ledger_api.contract_method_call( - contract_instance=contract_instance, - method_name="exists", - unitId=service_id, - ) - - return cast(bool, exists) - - @classmethod - def get_agent_instances( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> Dict[str, Any]: - """Retrieve on-chain agent instances.""" - - contract_instance = cls.get_instance(ledger_api, contract_address) - service_info = ledger_api.contract_method_call( - contract_instance=contract_instance, - method_name="getAgentInstances", - serviceId=service_id, - ) - - return dict( - numAgentInstances=service_info[0], - agentInstances=service_info[1], - ) - - @classmethod - def get_service_owner( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> Dict[str, Any]: - """Retrieve the service owner.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - service_owner = contract_instance.functions.ownerOf(service_id).call() - checksum_service_owner = ledger_api.api.to_checksum_address(service_owner) - return dict( - service_owner=checksum_service_owner, - ) - - @classmethod - def get_service_information( - cls, - ledger_api: LedgerApi, - contract_address: str, - token_id: int, - ) -> ServiceInfo: - """Retrieve service information""" - - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - return contract_interface.functions.getService(token_id).call() - - @classmethod - def get_token_uri( - cls, - ledger_api: LedgerApi, - contract_address: str, - token_id: int, - ) -> str: - """Returns the latest metadata URI for a component.""" - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - return contract_interface.functions.tokenURI(token_id).call() - - @classmethod - def get_create_events( # pragma: nocover - cls, - ledger_api: LedgerApi, - contract_address: str, - receipt: JSONLike, - ) -> Optional[int]: - """Returns `CreateUnit` event filter.""" - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - return contract_interface.events.CreateService().process_receipt(receipt) - - @classmethod - def get_update_events( # pragma: nocover - cls, - ledger_api: LedgerApi, - contract_address: str, - receipt: JSONLike, - ) -> Optional[int]: - """Returns `CreateUnit` event filter.""" - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - return contract_interface.events.UpdateService().process_receipt(receipt) - - @classmethod - def get_update_hash_events( # pragma: nocover - cls, - ledger_api: LedgerApi, - contract_address: str, - receipt: JSONLike, - ) -> Optional[int]: - """Returns `CreateUnit` event filter.""" - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - return contract_interface.events.UpdateUnitHash().process_receipt(receipt) - - @classmethod - def get_events( # pragma: nocover - cls, - ledger_api: LedgerApi, - contract_address: str, - event: str, - receipt: JSONLike, - ) -> Dict: - """Process receipt for events.""" - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - Event = getattr(contract_interface.events, event, None) - if Event is None: - return {"events": []} - return {"events": Event().process_receipt(receipt)} - - @classmethod - def process_receipt( - cls, - ledger_api: LedgerApi, - contract_address: str, - event: str, - receipt: JSONLike, - ) -> JSONLike: - """Checks for a successful service registration event in the latest block""" - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - Event = getattr(contract_interface.events, event, None) - if Event is None: - return {"events": []} - return {"events": Event().process_receipt(receipt)} - - @classmethod - def get_slash_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - agent_instances: List[str], - amounts: List[int], - service_id: int, - ) -> Dict[str, bytes]: - """Gets the encoded arguments for a slashing tx, which should only be called via the multisig.""" - - contract_instance = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - - slash_kwargs = dict( - agentInstances=agent_instances, - amounts=amounts, - serviceId=service_id, - ) - - data = contract_instance.encodeABI(fn_name="slash", kwargs=slash_kwargs) - return {"data": bytes.fromhex(data[2:])} - - @classmethod - def process_slash_receipt( - cls, - ledger_api: LedgerApi, - contract_address: str, - tx_hash: str, - ) -> Optional[JSONLike]: - """ - Process the slash receipt. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param tx_hash: the hash of a slash tx to be processed. - :return: a dictionary with the timestamp of the slashing and the `OperatorSlashed` events. - """ - contract = cls.get_instance(ledger_api, contract_address) - receipt: TxReceipt = ledger_api.api.eth.get_transaction_receipt(tx_hash) - logs: List[EventData] = list( - contract.events.OperatorSlashed().process_receipt(receipt) - ) - - if len(logs) == 0: - _logger.error(f"No `OperatorSlashed` event was emitted in tx {tx_hash}.") - return None - - block: BlockData = ledger_api.api.eth.get_block(receipt["blockNumber"]) - - return { - "slash_timestamp": block["timestamp"], - "events": [log["args"] for log in logs], - } - - @classmethod - def _get_operator( - cls, - ledger_api: LedgerApi, - contract_address: str, - agent_instance: str, - ) -> str: - """Retrieve an operator given its agent instance.""" - - contract_instance = cls.get_instance(ledger_api, contract_address) - map_fn = contract_instance.functions.mapAgentInstanceOperators - return map_fn(agent_instance).call() - - @classmethod - def get_operators_mapping( - cls, - ledger_api: LedgerApi, - contract_address: str, - agent_instances: FrozenSet[str], - ) -> Dict[str, str]: - """ - Retrieve a mapping of the given agent instances to their operators. - - Please keep in mind that this method performs a call for each agent instance. - - :param ledger_api: the ledger api. - :param contract_address: the contract address. - :param agent_instances: the agent instances to be mapped. - :return: a mapping of the given agent instances to their operators. - """ - return { - agent: cls._get_operator(ledger_api, contract_address, agent) - for agent in agent_instances - } diff --git a/trader_backup/vendor/valory/contracts/service_registry/contract.yaml b/trader_backup/vendor/valory/contracts/service_registry/contract.yaml deleted file mode 100644 index 5158c37ff..000000000 --- a/trader_backup/vendor/valory/contracts/service_registry/contract.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: service_registry -author: valory -version: 0.1.0 -type: contract -description: Service Registry contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeidey4syohls5hxmso6qsp5p4uhtzle5txv2mlbym6ktjzknich6oa - build/ServiceRegistry.json: bafybeia4qi2vstrutejzrxfpbb6eift7va5cjs7bparaal2fafiiczuiyy - build/ServiceRegistryL2.json: bafybeic2jylwfod4nmdtbs4izyxyi246pd3f35aoqyahnmyrvzn7j3sv4e - contract.py: bafybeihaixq3vettolpxspv6nog6vltqwshug7ltbpvb2i3rw2mps5o2li - tests/__init__.py: bafybeicl2oklx774jomlt6wwwegfdzrxh6iazjxwcyc7h4gepjljkpl4ji - tests/test_contract.py: bafybeicj535veqf35zb3ycu5iqjvqgj4a2kdmogmx5ba7fiolt5chah42a -fingerprint_ignore_patterns: [] -contracts: [] -class_name: ServiceRegistryContract -contract_interface_paths: - ethereum: build/ServiceRegistry.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - web3: - version: <7,>=6.0.0 diff --git a/trader_backup/vendor/valory/contracts/service_registry/tests/__init__.py b/trader_backup/vendor/valory/contracts/service_registry/tests/__init__.py deleted file mode 100644 index 230ef096b..000000000 --- a/trader_backup/vendor/valory/contracts/service_registry/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/service_registry contract.""" diff --git a/trader_backup/vendor/valory/contracts/service_registry/tests/test_contract.py b/trader_backup/vendor/valory/contracts/service_registry/tests/test_contract.py deleted file mode 100644 index a54e84143..000000000 --- a/trader_backup/vendor/valory/contracts/service_registry/tests/test_contract.py +++ /dev/null @@ -1,239 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/service_registry contract.""" -from pathlib import Path -from typing import Any -from unittest import mock - -import pytest -from aea_ledger_ethereum import EthereumCrypto -from aea_test_autonomy.base_test_classes.contracts import BaseRegistriesContractsTest -from aea_test_autonomy.docker.base import skip_docker_tests - -from packages.valory.contracts.service_registry.contract import ( - DEPLOYED_BYTECODE_MD5_HASH_BY_CHAIN_ID, - EXPECTED_CONTRACT_ADDRESS_BY_CHAIN_ID, - ServiceRegistryContract, -) - - -PACKAGE_DIR = Path(__file__).parent.parent - -SERVICE_REGISTRY_INVALID = "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed" -VALID_SERVICE_ID = 1 -INVALID_SERVICE_ID = 0 -CHAIN_ID = 31337 -AGENT_INSTANCES = [ - "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", - "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", - "0x90F79bf6EB2c4f870365E785982E1f101E93b906", -] -OPERATOR = "0xBcd4042DE499D14e55001CcbB24a551F3b954096" -OPERATORS_MAPPING = dict.fromkeys(AGENT_INSTANCES, OPERATOR) - - -def event_filter_patch(event: str, return_value: Any) -> mock._patch: - """Returns an event filter patch for the given event name.""" - return mock.patch.object( - ServiceRegistryContract, - "get_instance", - return_value=mock.MagicMock( - events=mock.MagicMock( - **{ - event: mock.MagicMock( - create_filter=lambda **_: mock.MagicMock( - get_all_entries=lambda *_: return_value - ) - ) - } - ) - ), - ) - - -class BaseServiceRegistryContractTest(BaseRegistriesContractsTest): - """Base class for Service Registry contract tests""" - - contract: ServiceRegistryContract - contract_address = EXPECTED_CONTRACT_ADDRESS_BY_CHAIN_ID[CHAIN_ID] - invalid_contract_address = SERVICE_REGISTRY_INVALID - path_to_contract = PACKAGE_DIR - ledger_identifier = EthereumCrypto.identifier - contract_directory = PACKAGE_DIR - - -@skip_docker_tests -class TestServiceRegistryContract(BaseServiceRegistryContractTest): - """Test Service Registry Contract""" - - @pytest.mark.parametrize("valid_address", (True, False)) - def test_verify_contract(self, valid_address: bool) -> None: - """Run verify test. If abi file is updated tests + addresses need updating""" - bytecode = DEPLOYED_BYTECODE_MD5_HASH_BY_CHAIN_ID[CHAIN_ID] - - if valid_address: - contract_address = self.contract_address - else: - contract_address = self.invalid_contract_address - bytecode += "invalid" - - result = self.contract.verify_contract( - self.ledger_api, - contract_address, - ) - - assert result["verified"] is valid_address, result - - @pytest.mark.parametrize( - "service_id, expected", [(INVALID_SERVICE_ID, False), (VALID_SERVICE_ID, True)] - ) - def test_exists(self, service_id: int, expected: int) -> None: - """Test whether service id exists""" - exists = self.contract.exists( - self.ledger_api, - self.contract_address, - service_id, - ) - - assert exists is expected - - def test_get_agent_instances(self) -> None: - """Test agent instances retrieval""" - - return_value = { - "numAgentInstances": 4, - "agentInstances": AGENT_INSTANCES, - } - - assert self.contract_address is not None - - result = self.contract.get_agent_instances( - self.ledger_api, - self.contract_address, - VALID_SERVICE_ID, - ) - - assert result == return_value - - def test_get_service_owner(self) -> None: - """Test service owner retrieval.""" - service_owner = AGENT_INSTANCES[0] - assert self.contract_address is not None - - actual = self.contract.get_service_owner( - self.ledger_api, - self.contract_address, - VALID_SERVICE_ID, - ) - - expected = dict(service_owner=service_owner) - assert expected == actual - - def test_get_token_uri(self) -> None: - """Test `get_token_uri` method.""" - - token_uri = self.contract.get_token_uri( - self.ledger_api, - self.contract_address, - VALID_SERVICE_ID, - ) - - assert ( - token_uri - == "https://gateway.autonolas.tech/ipfs/f017012205555555555555555555555555555555555555555555555555555555555555555" # nosec - ) - - def test_get_service_information(self) -> None: - """Test `test_get_service_information` method.""" - - ( - security_deposit, - multisig_address, - ipfs_hash_for_config, - threshold, - max_number_of_agent_instances, - number_of_agent_instances, - service_state, - list_of_cannonical_agents, - ) = self.contract.get_service_information( - self.ledger_api, - self.contract_address, - VALID_SERVICE_ID, - ) - - assert security_deposit == 10000000000000000 - assert multisig_address == "0x77b783e911F4398D75908Cc60C7138Bd1eFe35Fd" - assert ipfs_hash_for_config == b"UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" - assert threshold == 3 - assert max_number_of_agent_instances == 4 - assert number_of_agent_instances == 4 - assert service_state == 4 - assert list_of_cannonical_agents == [1] - - def test_get_slash_data(self) -> None: - """Test the `get_slash_data`.""" - result = self.contract.get_slash_data( - self.ledger_api, - self.contract_address, - AGENT_INSTANCES, - [0, 0, 0, 1], - service_id=1, - ) - - assert result.get("data", b"") == ( - b"s\xb8\xb6\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf3\x9f\xd6\xe5\x1a\xad\x88\xf6\xf4\xcej\xb8\x82ry\xcf" - b'\xff\xb9"f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x99yp\xc5\x18\x12\xdc:\x01\x0c}\x01\xb5\x0e\r' - b"\x17\xdcy\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 None: - """Test `get_operator` method.""" - for agent_instance, expected_operator in OPERATORS_MAPPING.items(): - actual_operator = ( - self.contract._get_operator( # pylint: disable=protected-access - self.ledger_api, - self.contract_address, - agent_instance, - ) - ) - assert actual_operator == expected_operator - - def test_get_operators_mapping(self) -> None: - """Test `get_operator` method.""" - actual_mapping = self.contract.get_operators_mapping( - self.ledger_api, - self.contract_address, - frozenset(OPERATORS_MAPPING.keys()), - ) - assert actual_mapping == OPERATORS_MAPPING diff --git a/trader_backup/vendor/valory/contracts/service_staking_token/__init__.py b/trader_backup/vendor/valory/contracts/service_staking_token/__init__.py deleted file mode 100644 index cf1e8467e..000000000 --- a/trader_backup/vendor/valory/contracts/service_staking_token/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for the agent registry contract.""" diff --git a/trader_backup/vendor/valory/contracts/service_staking_token/build/ServiceStakingToken.json b/trader_backup/vendor/valory/contracts/service_staking_token/build/ServiceStakingToken.json deleted file mode 100644 index e1405c0bf..000000000 --- a/trader_backup/vendor/valory/contracts/service_staking_token/build/ServiceStakingToken.json +++ /dev/null @@ -1,1355 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ServiceStakingToken", - "sourceName": "contracts/staking/ServiceStakingToken.sol", - "abi": [ - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "maxNumServices", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "rewardsPerSecond", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minStakingDeposit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minNumStakingPeriods", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxNumInactivityPeriods", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "livenessPeriod", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "livenessRatio", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numAgentInstances", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "agentIds", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - } - ], - "internalType": "struct ServiceStakingBase.StakingParams", - "name": "_stakingParams", - "type": "tuple" - }, - { - "internalType": "address", - "name": "_serviceRegistry", - "type": "address" - }, - { - "internalType": "address", - "name": "_serviceRegistryTokenUtility", - "type": "address" - }, - { - "internalType": "address", - "name": "_stakingToken", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "_proxyHash", - "type": "bytes32" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "AgentInstanceRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentInstancesSlotsFilled", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "AgentNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentNotInService", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "componentId", - "type": "uint256" - } - ], - "name": "ComponentNotFound", - "type": "error" - }, - { - "inputs": [], - "name": "HashExists", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectAgentBondingValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectRegistrationDepositValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "LowerThan", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "maxNumServices", - "type": "uint256" - } - ], - "name": "MaxNumServicesReached", - "type": "error" - }, - { - "inputs": [], - "name": "NoRewardsAvailable", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "tsProvided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "tsExpected", - "type": "uint256" - } - ], - "name": "NotEnoughTimeStaked", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "provided", - "type": "address" - }, - { - "internalType": "address", - "name": "expected", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OnlyOwnServiceMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorHasNoInstances", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "Overflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerOnly", - "type": "error" - }, - { - "inputs": [], - "name": "Paused", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrancyGuard", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceMustBeInactive", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceNotUnstaked", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "TokenTransferFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "TransferFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "UnauthorizedMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "ValueLowerThan", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "WrongAgentId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "numValues1", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numValues2", - "type": "uint256" - } - ], - "name": "WrongArrayLength", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongOperator", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceConfiguration", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "state", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceState", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "expected", - "type": "address" - }, - { - "internalType": "address", - "name": "provided", - "type": "address" - } - ], - "name": "WrongStakingToken", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "currentThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxThreshold", - "type": "uint256" - } - ], - "name": "WrongThreshold", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "availableRewards", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "serviceIds", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "rewards", - "type": "uint256[]" - } - ], - "name": "Checkpoint", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "balance", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "availableRewards", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - } - ], - "name": "ServiceStaked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "reward", - "type": "uint256" - } - ], - "name": "ServiceUnstaked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "serviceIds", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "owners", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "multisigs", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "serviceInactivity", - "type": "uint256[]" - } - ], - "name": "ServicesEvicted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Withdraw", - "type": "event" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "agentIds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "availableRewards", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "balance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "calculateServiceStakingLastReward", - "outputs": [ - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "calculateServiceStakingReward", - "outputs": [ - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "checkpoint", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[][]", - "name": "", - "type": "uint256[][]" - }, - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "evictServiceIds", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "configHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "deposit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "epochCounter", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getAgentIds", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNextRewardCheckpointTimestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "tsNext", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getServiceIds", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getServiceInfo", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "tsStart", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "inactivity", - "type": "uint256" - } - ], - "internalType": "struct ServiceInfo", - "name": "sInfo", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getServiceStakingState", - "outputs": [ - { - "internalType": "enum ServiceStakingBase.ServiceStakingState", - "name": "stakingState", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "livenessPeriod", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "livenessRatio", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceInfo", - "outputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tsStart", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "inactivity", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxInactivityDuration", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxNumInactivityPeriods", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxNumServices", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minStakingDeposit", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minStakingDuration", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "numAgentInstances", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC721Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "proxyHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "rewardsPerSecond", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "serviceRegistry", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "serviceRegistryTokenUtility", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "setServiceIds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "stake", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "stakingToken", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "threshold", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "tsCheckpoint", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "unstake", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x6102606040523480156200001257600080fd5b506040516200383a3803806200383a833981016040819052620000359162000453565b8484828260000151600014806200004e57506020830151155b806200005c575060a0830151155b806200006a575060c0830151155b8062000078575060e0830151155b806200008657506060830151155b806200009457506080830151155b15620000b357604051637c946ed760e01b815260040160405180910390fd5b826080015183606001511015620000f5576060830151608084015160405163491a2bb160e01b8152600481019290925260248201526044015b60405180910390fd5b6002836040015110156200012d57604080840151905163491a2bb160e01b8152600481019190915260026024820152604401620000ec565b6001600160a01b038216620001555760405163d92e233d60e01b815260040160405180910390fd5b82516080908152602084015160a0908152604085015160c09081529185015160e0908152908501516101005290840151610120908152908401516101409081526001600160a01b0384166101a0529084015161016052830151610180526000805b846101000151518110156200029257818561010001518281518110620001e057620001e062000576565b6020026020010151116200022d57846101000151818151811062000208576200020862000576565b6020026020010151604051632ab10b0b60e21b8152600401620000ec91815260200190565b846101000151818151811062000247576200024762000576565b602090810291909101015160048054600181810183556000929092527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0182905590925001620001b6565b5081620002b257604051637c946ed760e01b815260040160405180910390fd5b6101c0829052610100516060850151620002cd91906200058c565b6101e052610100516080850151620002e691906200058c565b6102005250504260035550506001600160a01b03821615806200031057506001600160a01b038316155b156200032f5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b0390811661024052166102205250620005b89050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b03811182821017156200038957620003896200034d565b60405290565b600082601f830112620003a157600080fd5b815160206001600160401b0380831115620003c057620003c06200034d565b8260051b604051601f19603f83011681018181108482111715620003e857620003e86200034d565b60405293845260208187018101949081019250878511156200040957600080fd5b6020870191505b848210156200042b5781518352918301919083019062000410565b979650505050505050565b80516001600160a01b03811681146200044e57600080fd5b919050565b600080600080600060a086880312156200046c57600080fd5b85516001600160401b03808211156200048457600080fd5b90870190610160828a0312156200049a57600080fd5b620004a462000363565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010080840151838111156200050357600080fd5b620005118c8287016200038f565b918301919091525061012083810151908201526101409283015192810192909252509450620005436020870162000436565b9350620005536040870162000436565b9250620005636060870162000436565b9150608086015190509295509295909350565b634e487b7160e01b600052603260045260246000fd5b8082028115828204841417620005b257634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161311962000721600039600081816104110152818161130901528181611c1401528181611d1e0152611d6201526000818161030501528181611ca40152611e0e01526000818161068e015281816118a50152611b1401526000818161024b0152818161074d015261079f01526000818161044b0152610fca0152600081816105cf01528181610a0101528181610d8601526111bd0152600081816105f601528181610e4e0152610e7d01526000818161036201528181610ec40152610ef80152600081816103c30152610e0c0152600081816103ea015261294a01526000818161038901528181611bc60152611fb80152600061049b01526000818161061d0152611d9901526000818161064401526122ae0152600081816102de01528181610d0d0152610d4101526131196000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c8063a0ed60e011610145578063cbcf252a116100bd578063eb338c961161008c578063f4dce71411610071578063f4dce71414610681578063f86ad2b614610689578063ffa1ad74146106b057600080fd5b8063eb338c9614610666578063f189e85a1461067957600080fd5b8063cbcf252a146105ca578063e1f1176d146105f1578063e77cdcc914610618578063eacdaabc1461063f57600080fd5b8063b69ef8a811610114578063c2c4c5c1116100f9578063c2c4c5c11461057e578063c889921d14610597578063cae2a5f0146105aa57600080fd5b8063b69ef8a814610562578063b6b55f251461056b57600080fd5b8063a0ed60e014610496578063a694fc3a146104bd578063a74466ad146104d0578063b15087601461054d57600080fd5b806352c824f5116101d857806372f702f3116101a7578063809cee2f1161018c578063809cee2f1461044657806382a8ea581461046d578063879d90901461048d57600080fd5b806372f702f31461040c57806378e061361461043357600080fd5b806352c824f51461038457806356e76058146103ab5780635829c5ec146103be578063592cf3fb146103e557600080fd5b8063287140511161021457806328714051146103005780632e17de781461033f5780633e7329971461035457806342cde4e81461035d57600080fd5b806308ae7e541461024657806314b19c5a14610280578063150b7a021461028957806316a75172146102d9575b600080fd5b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61026d60005481565b6102a8610297366004612a0a565b630a85bd0160e11b95945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610277565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b61035261034d366004612aa9565b6106e1565b005b61026d60035481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d6103b9366004612aa9565b610acf565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d610441366004612aa9565b610af0565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61048061047b366004612aa9565b610bba565b6040516102779190612afe565b61026d60025481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103526104cb366004612aa9565b610cb1565b61051a6104de366004612aa9565b6005602081905260009182526040909120805460018201546003830154600484015493909401546001600160a01b039283169492909116929085565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610277565b61055561127e565b6040516102779190612b65565b61026d60015481565b610352610579366004612aa9565b6112d6565b610586611378565b604051610277959493929190612b78565b61026d6105a5366004612aa9565b6119ad565b6105bd6105b8366004612aa9565b611a69565b6040516102779190612c3d565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d610674366004612aa9565b611b5c565b610555611b6c565b61026d611bc2565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6106d4604051806040016040528060058152602001640302e312e360dc1b81525081565b6040516102779190612c65565b600081815260056020526040902060018101546001600160a01b0316331461073857600181015460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b600381015460006107498242612cca565b90507f0000000000000000000000000000000000000000000000000000000000000000811115801561077d57506000600254115b156107cb5760405163ba2bbc6b60e01b815260048101859052602481018290527f0000000000000000000000000000000000000000000000000000000000000000604482015260640161072f565b6000806107d6611378565b945050505091508151600003610837576107ee611b6c565b9150815167ffffffffffffffff81111561080a5761080a612cdd565b604051908082528060200260200182016040528015610833578160200160208202803683370190505b5090505b6000805b8351821015610898578783838151811061085757610857612cf3565b60200260200101510315610898578784838151811061087857610878612cf3565b60200260200101510361088d57506001610898565b81600101915061083b565b600487015460028801805460408051602080840282018101909252828152600093909290918301828280156108ec57602002820191906000526020600020905b8154815260200190600101908083116108d8575b50508c5460008f8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff19908116825560018201805490911690559596506001600160a01b03909116949350915061094890506002830182612974565b506000600382018190556004820181905560059091015583156109d7576006805461097590600190612cca565b8154811061098557610985612cf3565b9060005260206000200154600686815481106109a3576109a3612cf3565b60009182526020909120015560068054806109c0576109c0612d09565b600190038181906000526020600020016000905590555b604051632142170760e11b8152306004820152336024820152604481018c90526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342842e0e90606401600060405180830381600087803b158015610a4557600080fd5b505af1158015610a59573d6000803e3d6000fd5b505050506000831115610a7057610a708184611bf7565b806001600160a01b0316336001600160a01b03168c7f950733f4c0bf951b8e770f3cc619a4288e7b59b1236d59aeaf2c238488e8ae816000548688604051610aba93929190612d1f565b60405180910390a45050505050505050505050565b60048181548110610adf57600080fd5b600091825260209091200154905081565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015610b7057602002820191906000526020600020905b815481526020019060010190808311610b5c575b505050505081526020016003820154815260200160048201548152602001600582015481525050905080608001519150610ba9836119ad565b610bb39083612d48565b9392505050565b610c056040518060c0016040528060006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016000815260200160008152602001600081525090565b600082815260056020908152604091829020825160c08101845281546001600160a01b0390811682526001830154168184015260028201805485518186028101860187528181529295939493860193830182828015610c8357602002820191906000526020600020905b815481526020019060010190808311610c6f575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050919050565b600254600003610cd45760405163afb0be3360e01b815260040160405180910390fd5b6000818152600560205260409020600381015415610d085760405163b4817ce760e01b81526004810183905260240161072f565b6006547f00000000000000000000000000000000000000000000000000000000000000008103610d6d5760405163fd20861560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260240161072f565b60405163ef0e239b60e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ef0e239b90602401600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dfd9190810190612e79565b9050806080015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014610e4c57604051637ad404bf60e11b81526004810185905260240161072f565b7f000000000000000000000000000000000000000000000000000000000000000015801590610e9f575080604001517f000000000000000000000000000000000000000000000000000000000000000014155b15610ec057604051637ad404bf60e11b81526004810185905260240161072f565b60007f0000000000000000000000000000000000000000000000000000000000000000118015610f1a5750806060015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014155b15610f3b57604051637ad404bf60e11b81526004810185905260240161072f565b60048160c001516005811115610f5357610f53612c27565b14610f92578060c001516005811115610f6e57610f6e612c27565b604051633c053f9d60e21b815260048101919091526024810185905260440161072f565b600081602001516001600160a01b0316803b806020016040519081016040528181526000908060200190933c805190602001209050807f00000000000000000000000000000000000000000000000000000000000000001461101757602082015160405162a2307960e51b81526001600160a01b03909116600482015260240161072f565b60045480156110e05760e08301515181811461104957604051637ad404bf60e11b81526004810188905260240161072f565b60005b818110156110dd578460e00151818151811061106a5761106a612cf3565b602002602001015163ffffffff166004828154811061108b5761108b612cf3565b9060005260206000200154146110d557600481815481106110ae576110ae612cf3565b9060005260206000200154604051632ab10b0b60e21b815260040161072f91815260200190565b60010161104c565b50505b6111018684600001516bffffffffffffffffffffffff168560e00151611c81565b602083015185546001600160a01b03821673ffffffffffffffffffffffffffffffffffffffff199182161787556001870180549091163317905560009061114790611f02565b805190915061115f9060028801906020840190612995565b50426003870155600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01879055604051632142170760e11b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342842e0e90606401600060405180830381600087803b15801561120957600080fd5b505af115801561121d573d6000803e3d6000fd5b5050505083602001516001600160a01b0316336001600160a01b0316887faa6b005b4958114a0c90492461c24af6525ae0178db7fbf44125ae9217c69ccb6000548560405161126d929190612f57565b60405180910390a450505050505050565b606060048054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020905b8154815260200190600101908083116112b8575b5050505050905090565b6000816001546112e69190612d48565b90506000826002546112f89190612d48565b6001839055600281905590506113307f0000000000000000000000000000000000000000000000000000000000000000333086611f13565b604080518481526020810184905290810182905233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9060600160405180910390a2505050565b6060806060806060600080600080600080600080611394611f9d565b97509750975097509750975097509750606080845167ffffffffffffffff8111156113c1576113c1612cdd565b6040519080825280602002602001820160405280156113ea578160200160208202803683370190505b509a506000891561177d578967ffffffffffffffff81111561140e5761140e612cdd565b604051908082528060200260200182016040528015611437578160200160208202803683370190505b5092508967ffffffffffffffff81111561145357611453612cdd565b60405190808252806020026020018201604052801561147c578160200160208202803683370190505b5091508a8911156116865760008060015b8c811015611579578b8e8b83815181106114a9576114a9612cf3565b60200260200101516114bb9190612f70565b6114c59190612f87565b92506114d18383612d48565b91508a81815181106114e5576114e5612cf3565b602002602001015193508a818151811061150157611501612cf3565b602002602001015186828151811061151b5761151b612cf3565b6020026020010181815250508285828151811061153a5761153a612cf3565b6020026020010181815250508260056000868152602001908152602001600020600401600082825461156c9190612d48565b909155505060010161148d565b508a8d8a60008151811061158f5761158f612cf3565b60200260200101516115a19190612f70565b6115ab9190612f87565b91506115b78282612d48565b9050896000815181106115cc576115cc612cf3565b60200260200101519250896000815181106115e9576115e9612cf3565b60200260200101518560008151811061160457611604612cf3565b602002602001018181525050808d111561162f57611622818e612cca565b61162c9083612d48565b91505b818460008151811061164357611643612cf3565b602002602001018181525050816005600085815260200190815260200160002060040160008282546116759190612d48565b9091555060009d5061177792505050565b60005b8a811015611769578881815181106116a3576116a3612cf3565b602002602001015191508881815181106116bf576116bf612cf3565b60200260200101518482815181106116d9576116d9612cf3565b6020026020010181815250508781815181106116f7576116f7612cf3565b602002602001015183828151811061171157611711612cf3565b60200260200101818152505087818151811061172f5761172f612cf3565b602002602001015160056000848152602001908152602001600020600401600082825461175c9190612d48565b9091555050600101611689565b50611774898c612cca565b9a505b60028b90555b855115611997576000995060005b8651811015611930578681815181106117a6576117a6612cf3565b602002602001015191508581815181106117c2576117c2612cf3565b60200260200101516005600084815260200190815260200160002060020190805190602001906117f3929190612995565b50600085828151811061180857611808612cf3565b602002602001015111156119155784818151811061182857611828612cf3565b602002602001015160056000848152602001908152602001600020600501546118519190612d48565b85828151811061186357611863612cf3565b60200260200101818152505084818151811061188157611881612cf3565b602002602001015160056000848152602001908152602001600020600501819055507f00000000000000000000000000000000000000000000000000000000000000008582815181106118d6576118d6612cf3565b6020026020010151111561191057818d82815181106118f7576118f7612cf3565b60209081029190910101528a61190c81612fa9565b9b50505b611928565b6000828152600560208190526040822001555b60010161178b565b508915611942576119428c858c61239b565b42600355600054611954816001612d48565b60005560405181907f06a98bdd4732811ab3214800ed1ada2dce66a2bce301d250c3ca7d6b461ee6669061198d908f9088908890612fc2565b60405180910390a2505b50939e929d509b50919950969750505050505050565b6000806000806000806119be611f9d565b5050509450945094509450945060005b84811015611a5e57878382815181106119e9576119e9612cf3565b602002602001015103611a565785841115611a35578386838381518110611a1257611a12612cf3565b6020026020010151611a249190612f70565b611a2e9190612f87565b9650611a5e565b818181518110611a4757611a47612cf3565b60200260200101519650611a5e565b6001016119ce565b505050505050919050565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015611ae957602002820191906000526020600020905b815481526020019060010190808311611ad5575b50505050508152602001600382015481526020016004820154815260200160058201548152505090507f00000000000000000000000000000000000000000000000000000000000000008160a001511115611b475760029150611b56565b606081015115611b5657600191505b50919050565b60068181548110610adf57600080fd5b606060068054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020908154815260200190600101908083116112b8575050505050905090565b60007f0000000000000000000000000000000000000000000000000000000000000000600354611bf29190612d48565b905090565b8060016000828254611c099190612cca565b90915550611c3a90507f00000000000000000000000000000000000000000000000000000000000000008383612760565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051611c7591815260200190565b60405180910390a25050565b604051633cebfa4f60e01b81526004810184905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633cebfa4f906024016040805180830381865afa158015611cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0e9190612ff7565b91509150816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611d9757604051630b80380d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161072f565b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff8216811115611dfe57604051632b30b24760e21b81526bffffffffffffffffffffffff831660048201526024810182905260440161072f565b60005b8451811015611ef95760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166375c1f93489888581518110611e4e57611e4e612cf3565b60200260200101516040518363ffffffff1660e01b8152600401611e8292919091825263ffffffff16602082015260400190565b602060405180830381865afa158015611e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec3919061302c565b905082811015611ef057604051632b30b24760e21b8152600481018290526024810184905260440161072f565b50600101611e01565b50505050505050565b6060611f0d826127e3565b92915050565b60006040516323b872dd60e01b6000528460045283602452826044526020600060646000808a5af13d15601f3d1160016000511416171691506000606052806040525080611f965760405163abae3d6d60e01b81526001600160a01b0380871660048301528086166024830152841660448201526064810183905260840161072f565b5050505050565b600080600060608060608060606000600354905060025498507f00000000000000000000000000000000000000000000000000000000000000008142611fe39190612cca565b10158015611ff15750600089115b15612390576006548067ffffffffffffffff81111561201257612012612cdd565b60405190808252806020026020018201604052801561203b578160200160208202803683370190505b5094508067ffffffffffffffff81111561205757612057612cdd565b604051908082528060200260200182016040528015612080578160200160208202803683370190505b5096508067ffffffffffffffff81111561209c5761209c612cdd565b6040519080825280602002602001820160405280156120c5578160200160208202803683370190505b5095508067ffffffffffffffff8111156120e1576120e1612cdd565b60405190808252806020026020018201604052801561211457816020015b60608152602001906001900390816120ff5790505b5093508067ffffffffffffffff81111561213057612130612cdd565b604051908082528060200260200182016040528015612159578160200160208202803683370190505b50925060005b8181101561238d576006818154811061217a5761217a612cf3565b906000526020600020015486828151811061219757612197612cf3565b6020026020010181815250506000600560008884815181106121bb576121bb612cf3565b602090810291909101810151825281019190915260400160002080549091506121ec906001600160a01b0316611f02565b8683815181106121fe576121fe612cf3565b6020908102919091010152600381015484908181111561221c578091505b6122268242612cca565b905060006122a089868151811061223f5761223f612cf3565b60200260200101518560020180548060200260200160405190810160405280929190818152602001828054801561229557602002820191906000526020600020905b815481526020019060010190808311612281575b50505050508461288b565b9050801561235e576122d2827f0000000000000000000000000000000000000000000000000000000000000000612f70565b8b8f815181106122e4576122e4612cf3565b6020026020010181815250508a8e8151811061230257612302612cf3565b60200260200101518d6123159190612d48565b9c5089858151811061232957612329612cf3565b60200260200101518c8f8151811061234357612343612cf3565b60209081029190910101526123578e612fa9565b9d5061237e565b8188868151811061237157612371612cf3565b6020026020010181815250505b5050505080600101905061215f565b50505b509091929394959697565b825160008267ffffffffffffffff8111156123b8576123b8612cdd565b6040519080825280602002602001820160405280156123e1578160200160208202803683370190505b50905060008367ffffffffffffffff8111156123ff576123ff612cdd565b604051908082528060200260200182016040528015612428578160200160208202803683370190505b50905060008467ffffffffffffffff81111561244657612446612cdd565b60405190808252806020026020018201604052801561246f578160200160208202803683370190505b50905060008567ffffffffffffffff81111561248d5761248d612cdd565b6040519080825280602002602001820160405280156124b6578160200160208202803683370190505b50905060008667ffffffffffffffff8111156124d4576124d4612cdd565b6040519080825280602002602001820160405280156124fd578160200160208202803683370190505b50905060008060005b8881101561265d5760008c828151811061252257612522612cf3565b60200260200101511115612655578b818151811061254257612542612cf3565b602002602001015191508188848151811061255f5761255f612cf3565b6020908102919091018101919091526000838152600590915260409020600181015488516001600160a01b03909116908990869081106125a1576125a1612cf3565b6001600160a01b039283166020918202929092010152815488519116908890869081106125d0576125d0612cf3565b60200260200101906001600160a01b031690816001600160a01b0316815250508b828151811061260257612602612cf3565b602002602001015186858151811061261c5761261c612cf3565b6020026020010181815250508185858151811061263b5761263b612cf3565b60209081029190910101528361265081612fa9565b945050505b600101612506565b50885b8015612712578861267081613045565b99506000905084612682600184612cca565b8151811061269257612692612cf3565b6020026020010151905060068a815481106126af576126af612cf3565b9060005260206000200154600682815481106126cd576126cd612cf3565b60009182526020909120015560068054806126ea576126ea612d09565b60019003818190600052602060002001600090559055508061270b90613045565b9050612660565b506000547fd19a3d42ed383465e4058c322d9411aeac76ddb8454d22e139fc99808bd569528888888860405161274b9493929190613096565b60405180910390a25050505050505050505050565b600060405163a9059cbb60e01b6000528360045282602452602060006044600080895af13d15601f3d11600160005114161716915060006060528060405250806127dd5760405163abae3d6d60e01b81526001600160a01b038086166004830152306024830152841660448201526064810183905260840161072f565b50505050565b60408051600180825281830190925260609160208083019080368337019050509050816001600160a01b031663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612843573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612867919061302c565b8160008151811061287a5761287a612cf3565b602002602001018181525050919050565b60006128988484846128a0565b949350505050565b600080821180156128e45750826000815181106128bf576128bf612cf3565b6020026020010151846000815181106128da576128da612cf3565b6020026020010151115b15610bb357600082846000815181106128ff576128ff612cf3565b60200260200101518660008151811061291a5761291a612cf3565b602002602001015161292c9190612cca565b61293e90670de0b6b3a7640000612f70565b6129489190612f87565b7f0000000000000000000000000000000000000000000000000000000000000000111595945050505050565b508054600082559060005260206000209081019061299291906129e0565b50565b8280548282559060005260206000209081019282156129d0579160200282015b828111156129d05782518255916020019190600101906129b5565b506129dc9291506129e0565b5090565b5b808211156129dc57600081556001016129e1565b6001600160a01b038116811461299257600080fd5b600080600080600060808688031215612a2257600080fd5b8535612a2d816129f5565b94506020860135612a3d816129f5565b935060408601359250606086013567ffffffffffffffff80821115612a6157600080fd5b818801915088601f830112612a7557600080fd5b813581811115612a8457600080fd5b896020828501011115612a9657600080fd5b9699959850939650602001949392505050565b600060208284031215612abb57600080fd5b5035919050565b60008151808452602080850194506020840160005b83811015612af357815187529582019590820190600101612ad7565b509495945050505050565b6020815260006001600160a01b0380845116602084015280602085015116604084015250604083015160c06060840152612b3b60e0840182612ac2565b905060608401516080840152608084015160a084015260a084015160c08401528091505092915050565b602081526000610bb36020830184612ac2565b60a081526000612b8b60a0830188612ac2565b6020838203818501528188518084528284019150828160051b850101838b0160005b83811015612bdb57601f19878403018552612bc9838351612ac2565b94860194925090850190600101612bad565b50508681036040880152612bef818b612ac2565b9450505050508281036060840152612c078186612ac2565b90508281036080840152612c1b8185612ac2565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6020810160038310612c5f57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020808352835180602085015260005b81811015612c9357858101830151858201604001528201612c77565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115611f0d57611f0d612cb4565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b838152606060208201526000612d386060830185612ac2565b9050826040830152949350505050565b80820180821115611f0d57611f0d612cb4565b604051610100810167ffffffffffffffff81118282101715612d7f57612d7f612cdd565b60405290565b80516bffffffffffffffffffffffff81168114612da157600080fd5b919050565b8051612da1816129f5565b805163ffffffff81168114612da157600080fd5b805160068110612da157600080fd5b600082601f830112612de557600080fd5b8151602067ffffffffffffffff80831115612e0257612e02612cdd565b8260051b604051601f19603f83011681018181108482111715612e2757612e27612cdd565b6040529384526020818701810194908101925087851115612e4757600080fd5b6020870191505b84821015612e6e57612e5f82612db1565b83529183019190830190612e4e565b979650505050505050565b600060208284031215612e8b57600080fd5b815167ffffffffffffffff80821115612ea357600080fd5b908301906101008286031215612eb857600080fd5b612ec0612d5b565b612ec983612d85565b8152612ed760208401612da6565b602082015260408301516040820152612ef260608401612db1565b6060820152612f0360808401612db1565b6080820152612f1460a08401612db1565b60a0820152612f2560c08401612dc5565b60c082015260e083015182811115612f3c57600080fd5b612f4887828601612dd4565b60e08301525095945050505050565b8281526040602082015260006128986040830184612ac2565b8082028115828204841417611f0d57611f0d612cb4565b600082612fa457634e487b7160e01b600052601260045260246000fd5b500490565b600060018201612fbb57612fbb612cb4565b5060010190565b838152606060208201526000612fdb6060830185612ac2565b8281036040840152612fed8185612ac2565b9695505050505050565b6000806040838503121561300a57600080fd5b8251613015816129f5565b915061302360208401612d85565b90509250929050565b60006020828403121561303e57600080fd5b5051919050565b60008161305457613054612cb4565b506000190190565b60008151808452602080850194506020840160005b83811015612af35781516001600160a01b031687529582019590820190600101613071565b6080815260006130a96080830187612ac2565b82810360208401526130bb818761305c565b905082810360408401526130cf818661305c565b90508281036060840152612e6e8185612ac256fea26469706673582212201cbb3243bdf2246a74a754c4b24385dc52b256b192f67778a3b3a76648374a5864736f6c63430008170033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102415760003560e01c8063a0ed60e011610145578063cbcf252a116100bd578063eb338c961161008c578063f4dce71411610071578063f4dce71414610681578063f86ad2b614610689578063ffa1ad74146106b057600080fd5b8063eb338c9614610666578063f189e85a1461067957600080fd5b8063cbcf252a146105ca578063e1f1176d146105f1578063e77cdcc914610618578063eacdaabc1461063f57600080fd5b8063b69ef8a811610114578063c2c4c5c1116100f9578063c2c4c5c11461057e578063c889921d14610597578063cae2a5f0146105aa57600080fd5b8063b69ef8a814610562578063b6b55f251461056b57600080fd5b8063a0ed60e014610496578063a694fc3a146104bd578063a74466ad146104d0578063b15087601461054d57600080fd5b806352c824f5116101d857806372f702f3116101a7578063809cee2f1161018c578063809cee2f1461044657806382a8ea581461046d578063879d90901461048d57600080fd5b806372f702f31461040c57806378e061361461043357600080fd5b806352c824f51461038457806356e76058146103ab5780635829c5ec146103be578063592cf3fb146103e557600080fd5b8063287140511161021457806328714051146103005780632e17de781461033f5780633e7329971461035457806342cde4e81461035d57600080fd5b806308ae7e541461024657806314b19c5a14610280578063150b7a021461028957806316a75172146102d9575b600080fd5b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61026d60005481565b6102a8610297366004612a0a565b630a85bd0160e11b95945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610277565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b61035261034d366004612aa9565b6106e1565b005b61026d60035481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d6103b9366004612aa9565b610acf565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d610441366004612aa9565b610af0565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61048061047b366004612aa9565b610bba565b6040516102779190612afe565b61026d60025481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103526104cb366004612aa9565b610cb1565b61051a6104de366004612aa9565b6005602081905260009182526040909120805460018201546003830154600484015493909401546001600160a01b039283169492909116929085565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610277565b61055561127e565b6040516102779190612b65565b61026d60015481565b610352610579366004612aa9565b6112d6565b610586611378565b604051610277959493929190612b78565b61026d6105a5366004612aa9565b6119ad565b6105bd6105b8366004612aa9565b611a69565b6040516102779190612c3d565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d610674366004612aa9565b611b5c565b610555611b6c565b61026d611bc2565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6106d4604051806040016040528060058152602001640302e312e360dc1b81525081565b6040516102779190612c65565b600081815260056020526040902060018101546001600160a01b0316331461073857600181015460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b600381015460006107498242612cca565b90507f0000000000000000000000000000000000000000000000000000000000000000811115801561077d57506000600254115b156107cb5760405163ba2bbc6b60e01b815260048101859052602481018290527f0000000000000000000000000000000000000000000000000000000000000000604482015260640161072f565b6000806107d6611378565b945050505091508151600003610837576107ee611b6c565b9150815167ffffffffffffffff81111561080a5761080a612cdd565b604051908082528060200260200182016040528015610833578160200160208202803683370190505b5090505b6000805b8351821015610898578783838151811061085757610857612cf3565b60200260200101510315610898578784838151811061087857610878612cf3565b60200260200101510361088d57506001610898565b81600101915061083b565b600487015460028801805460408051602080840282018101909252828152600093909290918301828280156108ec57602002820191906000526020600020905b8154815260200190600101908083116108d8575b50508c5460008f8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff19908116825560018201805490911690559596506001600160a01b03909116949350915061094890506002830182612974565b506000600382018190556004820181905560059091015583156109d7576006805461097590600190612cca565b8154811061098557610985612cf3565b9060005260206000200154600686815481106109a3576109a3612cf3565b60009182526020909120015560068054806109c0576109c0612d09565b600190038181906000526020600020016000905590555b604051632142170760e11b8152306004820152336024820152604481018c90526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342842e0e90606401600060405180830381600087803b158015610a4557600080fd5b505af1158015610a59573d6000803e3d6000fd5b505050506000831115610a7057610a708184611bf7565b806001600160a01b0316336001600160a01b03168c7f950733f4c0bf951b8e770f3cc619a4288e7b59b1236d59aeaf2c238488e8ae816000548688604051610aba93929190612d1f565b60405180910390a45050505050505050505050565b60048181548110610adf57600080fd5b600091825260209091200154905081565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015610b7057602002820191906000526020600020905b815481526020019060010190808311610b5c575b505050505081526020016003820154815260200160048201548152602001600582015481525050905080608001519150610ba9836119ad565b610bb39083612d48565b9392505050565b610c056040518060c0016040528060006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016000815260200160008152602001600081525090565b600082815260056020908152604091829020825160c08101845281546001600160a01b0390811682526001830154168184015260028201805485518186028101860187528181529295939493860193830182828015610c8357602002820191906000526020600020905b815481526020019060010190808311610c6f575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050919050565b600254600003610cd45760405163afb0be3360e01b815260040160405180910390fd5b6000818152600560205260409020600381015415610d085760405163b4817ce760e01b81526004810183905260240161072f565b6006547f00000000000000000000000000000000000000000000000000000000000000008103610d6d5760405163fd20861560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260240161072f565b60405163ef0e239b60e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ef0e239b90602401600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dfd9190810190612e79565b9050806080015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014610e4c57604051637ad404bf60e11b81526004810185905260240161072f565b7f000000000000000000000000000000000000000000000000000000000000000015801590610e9f575080604001517f000000000000000000000000000000000000000000000000000000000000000014155b15610ec057604051637ad404bf60e11b81526004810185905260240161072f565b60007f0000000000000000000000000000000000000000000000000000000000000000118015610f1a5750806060015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014155b15610f3b57604051637ad404bf60e11b81526004810185905260240161072f565b60048160c001516005811115610f5357610f53612c27565b14610f92578060c001516005811115610f6e57610f6e612c27565b604051633c053f9d60e21b815260048101919091526024810185905260440161072f565b600081602001516001600160a01b0316803b806020016040519081016040528181526000908060200190933c805190602001209050807f00000000000000000000000000000000000000000000000000000000000000001461101757602082015160405162a2307960e51b81526001600160a01b03909116600482015260240161072f565b60045480156110e05760e08301515181811461104957604051637ad404bf60e11b81526004810188905260240161072f565b60005b818110156110dd578460e00151818151811061106a5761106a612cf3565b602002602001015163ffffffff166004828154811061108b5761108b612cf3565b9060005260206000200154146110d557600481815481106110ae576110ae612cf3565b9060005260206000200154604051632ab10b0b60e21b815260040161072f91815260200190565b60010161104c565b50505b6111018684600001516bffffffffffffffffffffffff168560e00151611c81565b602083015185546001600160a01b03821673ffffffffffffffffffffffffffffffffffffffff199182161787556001870180549091163317905560009061114790611f02565b805190915061115f9060028801906020840190612995565b50426003870155600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01879055604051632142170760e11b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342842e0e90606401600060405180830381600087803b15801561120957600080fd5b505af115801561121d573d6000803e3d6000fd5b5050505083602001516001600160a01b0316336001600160a01b0316887faa6b005b4958114a0c90492461c24af6525ae0178db7fbf44125ae9217c69ccb6000548560405161126d929190612f57565b60405180910390a450505050505050565b606060048054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020905b8154815260200190600101908083116112b8575b5050505050905090565b6000816001546112e69190612d48565b90506000826002546112f89190612d48565b6001839055600281905590506113307f0000000000000000000000000000000000000000000000000000000000000000333086611f13565b604080518481526020810184905290810182905233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9060600160405180910390a2505050565b6060806060806060600080600080600080600080611394611f9d565b97509750975097509750975097509750606080845167ffffffffffffffff8111156113c1576113c1612cdd565b6040519080825280602002602001820160405280156113ea578160200160208202803683370190505b509a506000891561177d578967ffffffffffffffff81111561140e5761140e612cdd565b604051908082528060200260200182016040528015611437578160200160208202803683370190505b5092508967ffffffffffffffff81111561145357611453612cdd565b60405190808252806020026020018201604052801561147c578160200160208202803683370190505b5091508a8911156116865760008060015b8c811015611579578b8e8b83815181106114a9576114a9612cf3565b60200260200101516114bb9190612f70565b6114c59190612f87565b92506114d18383612d48565b91508a81815181106114e5576114e5612cf3565b602002602001015193508a818151811061150157611501612cf3565b602002602001015186828151811061151b5761151b612cf3565b6020026020010181815250508285828151811061153a5761153a612cf3565b6020026020010181815250508260056000868152602001908152602001600020600401600082825461156c9190612d48565b909155505060010161148d565b508a8d8a60008151811061158f5761158f612cf3565b60200260200101516115a19190612f70565b6115ab9190612f87565b91506115b78282612d48565b9050896000815181106115cc576115cc612cf3565b60200260200101519250896000815181106115e9576115e9612cf3565b60200260200101518560008151811061160457611604612cf3565b602002602001018181525050808d111561162f57611622818e612cca565b61162c9083612d48565b91505b818460008151811061164357611643612cf3565b602002602001018181525050816005600085815260200190815260200160002060040160008282546116759190612d48565b9091555060009d5061177792505050565b60005b8a811015611769578881815181106116a3576116a3612cf3565b602002602001015191508881815181106116bf576116bf612cf3565b60200260200101518482815181106116d9576116d9612cf3565b6020026020010181815250508781815181106116f7576116f7612cf3565b602002602001015183828151811061171157611711612cf3565b60200260200101818152505087818151811061172f5761172f612cf3565b602002602001015160056000848152602001908152602001600020600401600082825461175c9190612d48565b9091555050600101611689565b50611774898c612cca565b9a505b60028b90555b855115611997576000995060005b8651811015611930578681815181106117a6576117a6612cf3565b602002602001015191508581815181106117c2576117c2612cf3565b60200260200101516005600084815260200190815260200160002060020190805190602001906117f3929190612995565b50600085828151811061180857611808612cf3565b602002602001015111156119155784818151811061182857611828612cf3565b602002602001015160056000848152602001908152602001600020600501546118519190612d48565b85828151811061186357611863612cf3565b60200260200101818152505084818151811061188157611881612cf3565b602002602001015160056000848152602001908152602001600020600501819055507f00000000000000000000000000000000000000000000000000000000000000008582815181106118d6576118d6612cf3565b6020026020010151111561191057818d82815181106118f7576118f7612cf3565b60209081029190910101528a61190c81612fa9565b9b50505b611928565b6000828152600560208190526040822001555b60010161178b565b508915611942576119428c858c61239b565b42600355600054611954816001612d48565b60005560405181907f06a98bdd4732811ab3214800ed1ada2dce66a2bce301d250c3ca7d6b461ee6669061198d908f9088908890612fc2565b60405180910390a2505b50939e929d509b50919950969750505050505050565b6000806000806000806119be611f9d565b5050509450945094509450945060005b84811015611a5e57878382815181106119e9576119e9612cf3565b602002602001015103611a565785841115611a35578386838381518110611a1257611a12612cf3565b6020026020010151611a249190612f70565b611a2e9190612f87565b9650611a5e565b818181518110611a4757611a47612cf3565b60200260200101519650611a5e565b6001016119ce565b505050505050919050565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015611ae957602002820191906000526020600020905b815481526020019060010190808311611ad5575b50505050508152602001600382015481526020016004820154815260200160058201548152505090507f00000000000000000000000000000000000000000000000000000000000000008160a001511115611b475760029150611b56565b606081015115611b5657600191505b50919050565b60068181548110610adf57600080fd5b606060068054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020908154815260200190600101908083116112b8575050505050905090565b60007f0000000000000000000000000000000000000000000000000000000000000000600354611bf29190612d48565b905090565b8060016000828254611c099190612cca565b90915550611c3a90507f00000000000000000000000000000000000000000000000000000000000000008383612760565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051611c7591815260200190565b60405180910390a25050565b604051633cebfa4f60e01b81526004810184905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633cebfa4f906024016040805180830381865afa158015611cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0e9190612ff7565b91509150816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611d9757604051630b80380d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161072f565b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff8216811115611dfe57604051632b30b24760e21b81526bffffffffffffffffffffffff831660048201526024810182905260440161072f565b60005b8451811015611ef95760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166375c1f93489888581518110611e4e57611e4e612cf3565b60200260200101516040518363ffffffff1660e01b8152600401611e8292919091825263ffffffff16602082015260400190565b602060405180830381865afa158015611e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec3919061302c565b905082811015611ef057604051632b30b24760e21b8152600481018290526024810184905260440161072f565b50600101611e01565b50505050505050565b6060611f0d826127e3565b92915050565b60006040516323b872dd60e01b6000528460045283602452826044526020600060646000808a5af13d15601f3d1160016000511416171691506000606052806040525080611f965760405163abae3d6d60e01b81526001600160a01b0380871660048301528086166024830152841660448201526064810183905260840161072f565b5050505050565b600080600060608060608060606000600354905060025498507f00000000000000000000000000000000000000000000000000000000000000008142611fe39190612cca565b10158015611ff15750600089115b15612390576006548067ffffffffffffffff81111561201257612012612cdd565b60405190808252806020026020018201604052801561203b578160200160208202803683370190505b5094508067ffffffffffffffff81111561205757612057612cdd565b604051908082528060200260200182016040528015612080578160200160208202803683370190505b5096508067ffffffffffffffff81111561209c5761209c612cdd565b6040519080825280602002602001820160405280156120c5578160200160208202803683370190505b5095508067ffffffffffffffff8111156120e1576120e1612cdd565b60405190808252806020026020018201604052801561211457816020015b60608152602001906001900390816120ff5790505b5093508067ffffffffffffffff81111561213057612130612cdd565b604051908082528060200260200182016040528015612159578160200160208202803683370190505b50925060005b8181101561238d576006818154811061217a5761217a612cf3565b906000526020600020015486828151811061219757612197612cf3565b6020026020010181815250506000600560008884815181106121bb576121bb612cf3565b602090810291909101810151825281019190915260400160002080549091506121ec906001600160a01b0316611f02565b8683815181106121fe576121fe612cf3565b6020908102919091010152600381015484908181111561221c578091505b6122268242612cca565b905060006122a089868151811061223f5761223f612cf3565b60200260200101518560020180548060200260200160405190810160405280929190818152602001828054801561229557602002820191906000526020600020905b815481526020019060010190808311612281575b50505050508461288b565b9050801561235e576122d2827f0000000000000000000000000000000000000000000000000000000000000000612f70565b8b8f815181106122e4576122e4612cf3565b6020026020010181815250508a8e8151811061230257612302612cf3565b60200260200101518d6123159190612d48565b9c5089858151811061232957612329612cf3565b60200260200101518c8f8151811061234357612343612cf3565b60209081029190910101526123578e612fa9565b9d5061237e565b8188868151811061237157612371612cf3565b6020026020010181815250505b5050505080600101905061215f565b50505b509091929394959697565b825160008267ffffffffffffffff8111156123b8576123b8612cdd565b6040519080825280602002602001820160405280156123e1578160200160208202803683370190505b50905060008367ffffffffffffffff8111156123ff576123ff612cdd565b604051908082528060200260200182016040528015612428578160200160208202803683370190505b50905060008467ffffffffffffffff81111561244657612446612cdd565b60405190808252806020026020018201604052801561246f578160200160208202803683370190505b50905060008567ffffffffffffffff81111561248d5761248d612cdd565b6040519080825280602002602001820160405280156124b6578160200160208202803683370190505b50905060008667ffffffffffffffff8111156124d4576124d4612cdd565b6040519080825280602002602001820160405280156124fd578160200160208202803683370190505b50905060008060005b8881101561265d5760008c828151811061252257612522612cf3565b60200260200101511115612655578b818151811061254257612542612cf3565b602002602001015191508188848151811061255f5761255f612cf3565b6020908102919091018101919091526000838152600590915260409020600181015488516001600160a01b03909116908990869081106125a1576125a1612cf3565b6001600160a01b039283166020918202929092010152815488519116908890869081106125d0576125d0612cf3565b60200260200101906001600160a01b031690816001600160a01b0316815250508b828151811061260257612602612cf3565b602002602001015186858151811061261c5761261c612cf3565b6020026020010181815250508185858151811061263b5761263b612cf3565b60209081029190910101528361265081612fa9565b945050505b600101612506565b50885b8015612712578861267081613045565b99506000905084612682600184612cca565b8151811061269257612692612cf3565b6020026020010151905060068a815481106126af576126af612cf3565b9060005260206000200154600682815481106126cd576126cd612cf3565b60009182526020909120015560068054806126ea576126ea612d09565b60019003818190600052602060002001600090559055508061270b90613045565b9050612660565b506000547fd19a3d42ed383465e4058c322d9411aeac76ddb8454d22e139fc99808bd569528888888860405161274b9493929190613096565b60405180910390a25050505050505050505050565b600060405163a9059cbb60e01b6000528360045282602452602060006044600080895af13d15601f3d11600160005114161716915060006060528060405250806127dd5760405163abae3d6d60e01b81526001600160a01b038086166004830152306024830152841660448201526064810183905260840161072f565b50505050565b60408051600180825281830190925260609160208083019080368337019050509050816001600160a01b031663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612843573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612867919061302c565b8160008151811061287a5761287a612cf3565b602002602001018181525050919050565b60006128988484846128a0565b949350505050565b600080821180156128e45750826000815181106128bf576128bf612cf3565b6020026020010151846000815181106128da576128da612cf3565b6020026020010151115b15610bb357600082846000815181106128ff576128ff612cf3565b60200260200101518660008151811061291a5761291a612cf3565b602002602001015161292c9190612cca565b61293e90670de0b6b3a7640000612f70565b6129489190612f87565b7f0000000000000000000000000000000000000000000000000000000000000000111595945050505050565b508054600082559060005260206000209081019061299291906129e0565b50565b8280548282559060005260206000209081019282156129d0579160200282015b828111156129d05782518255916020019190600101906129b5565b506129dc9291506129e0565b5090565b5b808211156129dc57600081556001016129e1565b6001600160a01b038116811461299257600080fd5b600080600080600060808688031215612a2257600080fd5b8535612a2d816129f5565b94506020860135612a3d816129f5565b935060408601359250606086013567ffffffffffffffff80821115612a6157600080fd5b818801915088601f830112612a7557600080fd5b813581811115612a8457600080fd5b896020828501011115612a9657600080fd5b9699959850939650602001949392505050565b600060208284031215612abb57600080fd5b5035919050565b60008151808452602080850194506020840160005b83811015612af357815187529582019590820190600101612ad7565b509495945050505050565b6020815260006001600160a01b0380845116602084015280602085015116604084015250604083015160c06060840152612b3b60e0840182612ac2565b905060608401516080840152608084015160a084015260a084015160c08401528091505092915050565b602081526000610bb36020830184612ac2565b60a081526000612b8b60a0830188612ac2565b6020838203818501528188518084528284019150828160051b850101838b0160005b83811015612bdb57601f19878403018552612bc9838351612ac2565b94860194925090850190600101612bad565b50508681036040880152612bef818b612ac2565b9450505050508281036060840152612c078186612ac2565b90508281036080840152612c1b8185612ac2565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6020810160038310612c5f57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020808352835180602085015260005b81811015612c9357858101830151858201604001528201612c77565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115611f0d57611f0d612cb4565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b838152606060208201526000612d386060830185612ac2565b9050826040830152949350505050565b80820180821115611f0d57611f0d612cb4565b604051610100810167ffffffffffffffff81118282101715612d7f57612d7f612cdd565b60405290565b80516bffffffffffffffffffffffff81168114612da157600080fd5b919050565b8051612da1816129f5565b805163ffffffff81168114612da157600080fd5b805160068110612da157600080fd5b600082601f830112612de557600080fd5b8151602067ffffffffffffffff80831115612e0257612e02612cdd565b8260051b604051601f19603f83011681018181108482111715612e2757612e27612cdd565b6040529384526020818701810194908101925087851115612e4757600080fd5b6020870191505b84821015612e6e57612e5f82612db1565b83529183019190830190612e4e565b979650505050505050565b600060208284031215612e8b57600080fd5b815167ffffffffffffffff80821115612ea357600080fd5b908301906101008286031215612eb857600080fd5b612ec0612d5b565b612ec983612d85565b8152612ed760208401612da6565b602082015260408301516040820152612ef260608401612db1565b6060820152612f0360808401612db1565b6080820152612f1460a08401612db1565b60a0820152612f2560c08401612dc5565b60c082015260e083015182811115612f3c57600080fd5b612f4887828601612dd4565b60e08301525095945050505050565b8281526040602082015260006128986040830184612ac2565b8082028115828204841417611f0d57611f0d612cb4565b600082612fa457634e487b7160e01b600052601260045260246000fd5b500490565b600060018201612fbb57612fbb612cb4565b5060010190565b838152606060208201526000612fdb6060830185612ac2565b8281036040840152612fed8185612ac2565b9695505050505050565b6000806040838503121561300a57600080fd5b8251613015816129f5565b915061302360208401612d85565b90509250929050565b60006020828403121561303e57600080fd5b5051919050565b60008161305457613054612cb4565b506000190190565b60008151808452602080850194506020840160005b83811015612af35781516001600160a01b031687529582019590820190600101613071565b6080815260006130a96080830187612ac2565b82810360208401526130bb818761305c565b905082810360408401526130cf818661305c565b90508281036060840152612e6e8185612ac256fea26469706673582212201cbb3243bdf2246a74a754c4b24385dc52b256b192f67778a3b3a76648374a5864736f6c63430008170033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/trader_backup/vendor/valory/contracts/service_staking_token/contract.py b/trader_backup/vendor/valory/contracts/service_staking_token/contract.py deleted file mode 100644 index 3817febe4..000000000 --- a/trader_backup/vendor/valory/contracts/service_staking_token/contract.py +++ /dev/null @@ -1,192 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the class to connect to the `ServiceStakingTokenMechUsage` contract.""" - -from enum import Enum - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi - - -class ServiceStakingTokenContract(Contract): - """The Service Staking contract.""" - - contract_id = PublicId.from_str("valory/service_staking_token:0.1.0") - - @classmethod - def get_service_staking_state( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Check whether the service is staked.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - res = contract_instance.functions.getServiceStakingState(service_id).call() - return dict(data=res) - - @classmethod - def build_stake_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Build stake tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("stake", args=[service_id]) - return dict(data=bytes.fromhex(data[2:])) - - @classmethod - def build_checkpoint_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Build checkpoint tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("checkpoint") - return dict(data=bytes.fromhex(data[2:])) - - @classmethod - def build_unstake_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Build unstake tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("unstake", args=[service_id]) - return dict(data=bytes.fromhex(data[2:])) - - @classmethod - def available_rewards( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Get the available rewards.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - res = contract_instance.functions.availableRewards().call() - return dict(data=res) - - @classmethod - def get_staking_rewards( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Get the service's staking rewards.""" - contract = cls.get_instance(ledger_api, contract_address) - reward = contract.functions.calculateServiceStakingReward(service_id).call() - return dict(data=reward) - - @classmethod - def get_next_checkpoint_ts( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Get the next checkpoint's timestamp.""" - contract = cls.get_instance(ledger_api, contract_address) - ts = contract.functions.getNextRewardCheckpointTimestamp().call() - return dict(data=ts) - - @classmethod - def ts_checkpoint( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the checkpoint's timestamp.""" - contract = cls.get_instance(ledger_api, contract_address) - ts_checkpoint = contract.functions.tsCheckpoint().call() - return dict(data=ts_checkpoint) - - @classmethod - def liveness_ratio( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the liveness ratio.""" - contract = cls.get_instance(ledger_api, contract_address) - liveness_ratio = contract.functions.livenessRatio().call() - return dict(data=liveness_ratio) - - @classmethod - def get_liveness_period( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the liveness period.""" - contract = cls.get_instance(ledger_api, contract_address) - liveness_period = contract.functions.livenessPeriod().call() - return dict(data=liveness_period) - - @classmethod - def get_service_info( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Retrieve the service info for a service.""" - contract = cls.get_instance(ledger_api, contract_address) - info = contract.functions.getServiceInfo(service_id).call() - return dict(data=info) - - @classmethod - def max_num_services( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the max number of services.""" - contract = cls.get_instance(ledger_api, contract_address) - max_num_services = contract.functions.maxNumServices().call() - return dict(data=max_num_services) - - @classmethod - def get_service_ids( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the service IDs.""" - contract = cls.get_instance(ledger_api, contract_address) - service_ids = contract.functions.getServiceIds().call() - return dict(data=service_ids) - - @classmethod - def get_min_staking_duration( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the service IDs.""" - contract = cls.get_instance(ledger_api, contract_address) - duration = contract.functions.minStakingDuration().call() - return dict(data=duration) diff --git a/trader_backup/vendor/valory/contracts/service_staking_token/contract.yaml b/trader_backup/vendor/valory/contracts/service_staking_token/contract.yaml deleted file mode 100644 index 70df67a5c..000000000 --- a/trader_backup/vendor/valory/contracts/service_staking_token/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: service_staking_token -author: valory -version: 0.1.0 -type: contract -description: Service staking token contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeid3wfzglolebuo6jrrsopswzu4lk77bm76mvw3euizlsjtnt3wmgu - build/ServiceStakingToken.json: bafybeib6frfpqtr4dfyxuylehqmic2iawofydx7u24t7j5zbrsc4m4ijoi - contract.py: bafybeiboxlbmmhnsreimqyrnn3yamzueiucno6v75xjfrvfvbx4pqrnlsy -fingerprint_ignore_patterns: [] -contracts: [] -class_name: ServiceStakingTokenContract -contract_interface_paths: - ethereum: build/ServiceStakingToken.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - web3: - version: <7,>=6.0.0 diff --git a/trader_backup/vendor/valory/contracts/staking_token/__init__.py b/trader_backup/vendor/valory/contracts/staking_token/__init__.py deleted file mode 100644 index 4682f8155..000000000 --- a/trader_backup/vendor/valory/contracts/staking_token/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the support resources for the staking contract.""" diff --git a/trader_backup/vendor/valory/contracts/staking_token/build/StakingToken.json b/trader_backup/vendor/valory/contracts/staking_token/build/StakingToken.json deleted file mode 100644 index 070508dba..000000000 --- a/trader_backup/vendor/valory/contracts/staking_token/build/StakingToken.json +++ /dev/null @@ -1,1336 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "StakingToken", - "sourceName": "contracts/staking/StakingToken.sol", - "abi": [ - { - "inputs": [], - "name": "AlreadyInitialized", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "activityChecker", - "type": "address" - } - ], - "name": "ContractOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "LowerThan", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "maxNumServices", - "type": "uint256" - } - ], - "name": "MaxNumServicesReached", - "type": "error" - }, - { - "inputs": [], - "name": "NoRewardsAvailable", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "tsProvided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "tsExpected", - "type": "uint256" - } - ], - "name": "NotEnoughTimeStaked", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceNotUnstaked", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "TokenTransferFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "UnauthorizedMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "ValueLowerThan", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "WrongAgentId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceConfiguration", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "state", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceState", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "expected", - "type": "address" - }, - { - "internalType": "address", - "name": "provided", - "type": "address" - } - ], - "name": "WrongStakingToken", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroTokenAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "availableRewards", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "serviceIds", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "rewards", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "epochLength", - "type": "uint256" - } - ], - "name": "Checkpoint", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "balance", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "availableRewards", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "reward", - "type": "uint256" - } - ], - "name": "RewardClaimed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "reward", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "availableRewards", - "type": "uint256" - } - ], - "name": "ServiceForceUnstaked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "serviceInactivity", - "type": "uint256" - } - ], - "name": "ServiceInactivityWarning", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - } - ], - "name": "ServiceStaked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "reward", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "availableRewards", - "type": "uint256" - } - ], - "name": "ServiceUnstaked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "serviceIds", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "owners", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "multisigs", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "serviceInactivity", - "type": "uint256[]" - } - ], - "name": "ServicesEvicted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Withdraw", - "type": "event" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "activityChecker", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "agentIds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "availableRewards", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "balance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "calculateStakingLastReward", - "outputs": [ - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "calculateStakingReward", - "outputs": [ - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "checkpoint", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "evictServiceIds", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "checkpointAndClaim", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "claim", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "configHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "deposit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "emissionsAmount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "epochCounter", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "forcedUnstake", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getAgentIds", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNextRewardCheckpointTimestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "tsNext", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getServiceIds", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getServiceInfo", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "tsStart", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "inactivity", - "type": "uint256" - } - ], - "internalType": "struct ServiceInfo", - "name": "sInfo", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getStakingState", - "outputs": [ - { - "internalType": "enum StakingBase.StakingState", - "name": "stakingState", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "metadataHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "maxNumServices", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "rewardsPerSecond", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minStakingDeposit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minNumStakingPeriods", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxNumInactivityPeriods", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "livenessPeriod", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "timeForEmissions", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numAgentInstances", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "agentIds", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "proxyHash", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "serviceRegistry", - "type": "address" - }, - { - "internalType": "address", - "name": "activityChecker", - "type": "address" - } - ], - "internalType": "struct StakingBase.StakingParams", - "name": "_stakingParams", - "type": "tuple" - }, - { - "internalType": "address", - "name": "_serviceRegistryTokenUtility", - "type": "address" - }, - { - "internalType": "address", - "name": "_stakingToken", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "livenessPeriod", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceInfo", - "outputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tsStart", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "inactivity", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxInactivityDuration", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxNumInactivityPeriods", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxNumServices", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "metadataHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minStakingDeposit", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minStakingDuration", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "numAgentInstances", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC721Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "proxyHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "rewardsPerSecond", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "serviceRegistry", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "serviceRegistryTokenUtility", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "setServiceIds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "stake", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "stakingToken", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "threshold", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "timeForEmissions", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "tsCheckpoint", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "unstake", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x608060405234801561000f575f80fd5b50600436106102cd575f3560e01c806393ac752f1161017c578063c5a1d7f0116100dd578063eb338c9611610093578063f86ad2b61161006e578063f86ad2b6146105db578063fd0bba8c146105e4578063ffa1ad7414610604575f80fd5b8063eb338c96146105b8578063f189e85a146105cb578063f4dce714146105d3575f80fd5b8063e1f1176d116100c3578063e1f1176d1461059d578063e77cdcc9146105a6578063eacdaabc146105af575f80fd5b8063c5a1d7f014610582578063cbcf252a1461058a575f80fd5b8063b150876011610132578063b69ef8a811610118578063b69ef8a81461054e578063b6b55f2514610557578063c2c4c5c11461056a575f80fd5b8063b150876014610526578063b267c67b1461053b575f80fd5b8063a0ed60e011610162578063a0ed60e01461048f578063a694fc3a14610498578063a74466ad146104ab575f80fd5b806393ac752f146104715780639573236114610486575f80fd5b806352c824f5116102315780637fbe2833116101e757806383f9eb22116101c257806383f9eb2214610442578063879d9090146104555780638f9e0a621461045e575f80fd5b80637fbe283314610406578063809cee2f1461041957806382a8ea5814610422575f80fd5b806356e760581161021757806356e76058146103d75780635829c5ec146103ea57806372f702f3146103f3575f80fd5b806352c824f5146103bb578063546af2e0146103c4575f80fd5b80632871405111610286578063379607f51161026c578063379607f5146103965780633e732997146103a957806342cde4e8146103b2575f80fd5b806328714051146103585780632e17de7814610383575f80fd5b8063150b7a02116102b6578063150b7a02146102f657806316a75172146103465780631f7794081461034f575f80fd5b806308ae7e54146102d157806314b19c5a146102ed575b5f80fd5b6102da600d5481565b6040519081526020015b60405180910390f35b6102da600f5481565b610315610304366004612c65565b630a85bd0160e11b95945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016102e4565b6102da60015481565b6102da60065481565b60175461036b906001600160a01b031681565b6040516001600160a01b0390911681526020016102e4565b6102da610391366004612cfc565b610635565b6102da6103a4366004612cfc565b610646565b6102da60135481565b6102da60085481565b6102da60055481565b6102da6103d2366004612cfc565b610651565b6102da6103e5366004612cfc565b61065d565b6102da60075481565b60185461036b906001600160a01b031681565b6102da610414366004612cfc565b61067c565b6102da600a5481565b610435610430366004612cfc565b610743565b6040516102e49190612d13565b6102da610450366004612cfc565b610832565b6102da60115481565b600c5461036b906001600160a01b031681565b61048461047f366004612cfc565b6108ea565b005b6102da60125481565b6102da60045481565b6104846104a6366004612cfc565b6108f9565b6104f36104b9366004612cfc565b60156020525f9081526040902080546001820154600383015460048401546005909401546001600160a01b03938416949390921692909185565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a0016102e4565b61052e610de9565b6040516102e49190612ddf565b610484610549366004612f13565b610e3f565b6102da60105481565b610484610565366004612cfc565b610eb5565b610572610f42565b6040516102e49493929190613047565b6102da5f5481565b600b5461036b906001600160a01b031681565b6102da60095481565b6102da60035481565b6102da60025481565b6102da6105c6366004612cfc565b6115d6565b61052e6115e5565b6102da611639565b6102da600e5481565b6105f76105f2366004612cfc565b61164f565b6040516102e491906130b2565b610628604051806040016040528060058152602001640302e322e360dc1b81525081565b6040516102e491906130d8565b5f610640825f611721565b92915050565b5f610640825f611aa8565b5f610640826001611aa8565b6014818154811061066c575f80fd5b5f91825260209091200154905081565b5f818152601560209081526040808320815160c08101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287969395860193909291908301828280156106f957602002820191905f5260205f20905b8154815260200190600101908083116106e5575b50505050508152602001600382015481526020016004820154815260200160058201548152505090508060800151915061073283610832565b61073c9083613121565b9392505050565b6107896040518060c001604052805f6001600160a01b031681526020015f6001600160a01b03168152602001606081526020015f81526020015f81526020015f81525090565b5f82815260156020908152604091829020825160c08101845281546001600160a01b039081168252600183015416818401526002820180548551818602810186018752818152929593949386019383018282801561080457602002820191905f5260205f20905b8154815260200190600101908083116107f0575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050919050565b5f805f805f80610840611bab565b505050945094509450945094505f5b848110156108df578783828151811061086a5761086a613134565b6020026020010151036108d757858411156108b657838683838151811061089357610893613134565b60200260200101516108a59190613148565b6108af9190613173565b96506108df565b8181815181106108c8576108c8613134565b602002602001015196506108df565b60010161084f565b505050505050919050565b6108f5816001611721565b5050565b610901610f42565b505050506011545f036109275760405163afb0be3360e01b815260040160405180910390fd5b5f81815260156020526040902060038101541561095f5760405163b4817ce760e01b8152600481018390526024015b60405180910390fd5b601654600154810361098a5760015460405163fd20861560e01b815260040161095691815260200190565b600b5460405163ef0e239b60e01b8152600481018590525f916001600160a01b03169063ef0e239b906024015f60405180830381865afa1580156109d0573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526109f79190810190613230565b9050806080015163ffffffff1660075414610a2857604051637ad404bf60e11b815260048101859052602401610956565b60095415801590610a3f5750806040015160095414155b15610a6057604051637ad404bf60e11b815260048101859052602401610956565b5f600854118015610a7d5750806060015163ffffffff1660085414155b15610a9e57604051637ad404bf60e11b815260048101859052602401610956565b60048160c001516005811115610ab657610ab661309e565b14610af5578060c001516005811115610ad157610ad161309e565b604051633c053f9d60e21b8152600481019190915260248101859052604401610956565b5f81602001516001600160a01b0316803b806020016040519081016040528181525f908060200190933c80519060200120905080600a5414610b5a57602082015160405162a2307960e51b81526001600160a01b039091166004820152602401610956565b6014548015610c1e5760e083015151818114610b8c57604051637ad404bf60e11b815260048101889052602401610956565b5f5b81811015610c1b578460e001518181518110610bac57610bac613134565b602002602001015163ffffffff1660148281548110610bcd57610bcd613134565b905f5260205f20015414610c135760148181548110610bee57610bee613134565b905f5260205f200154604051632ab10b0b60e21b815260040161095691815260200190565b600101610b8e565b50505b610c3e86845f01516bffffffffffffffffffffffff168560e00151611f4b565b602083015185546001600160a01b039182166001600160a01b0319918216811788556001880180549092163317909155600c5460405163d564c4bf60e01b815260048101929092525f92169063d564c4bf906024015f60405180830381865afa158015610cad573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610cd49190810190613309565b8051909150610cec9060028801906020840190612bc6565b50426003870155601680546001810182555f919091527fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b512428901879055600b54604051632142170760e11b8152336004820152306024820152604481018990526001600160a01b03909116906342842e0e906064015f604051808303815f87803b158015610d76575f80fd5b505af1158015610d88573d5f803e3d5ffd5b5050505083602001516001600160a01b0316336001600160a01b0316887faa6b005b4958114a0c90492461c24af6525ae0178db7fbf44125ae9217c69ccb600f5485604051610dd892919061338a565b60405180910390a450505050505050565b60606014805480602002602001604051908101604052809291908181526020018280548015610e3557602002820191905f5260205f20905b815481526020019060010190808311610e21575b5050505050905090565b610e4883612134565b6001600160a01b0381161580610e6557506001600160a01b038216155b15610e8357604051636b093aad60e01b815260040160405180910390fd5b601880546001600160a01b039283166001600160a01b0319918216179091556017805493909216921691909117905550565b5f81601054610ec49190613121565b90505f82601154610ed59190613121565b60108390556011819055601854909150610efa906001600160a01b03163330866124b2565b604080518481526020810184905290810182905233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9060600160405180910390a2505050565b6060806060805f805f805f805f80610f58611bab565b97509750975097509750975097509750606080845167ffffffffffffffff811115610f8557610f85612df1565b604051908082528060200260200182016040528015610fae578160200160208202803683370190505b509a505f891561132f578967ffffffffffffffff811115610fd157610fd1612df1565b604051908082528060200260200182016040528015610ffa578160200160208202803683370190505b5092508967ffffffffffffffff81111561101657611016612df1565b60405190808252806020026020018201604052801561103f578160200160208202803683370190505b5091508a89111561123c575f8060015b8c811015611138578b8e8b838151811061106b5761106b613134565b602002602001015161107d9190613148565b6110879190613173565b92506110938383613121565b91508a81815181106110a7576110a7613134565b602002602001015193508a81815181106110c3576110c3613134565b60200260200101518682815181106110dd576110dd613134565b602002602001018181525050828582815181106110fc576110fc613134565b6020026020010181815250508260155f8681526020019081526020015f206004015f82825461112b9190613121565b909155505060010161104f565b508a8d8a5f8151811061114d5761114d613134565b602002602001015161115f9190613148565b6111699190613173565b91506111758282613121565b9050895f8151811061118957611189613134565b60200260200101519250895f815181106111a5576111a5613134565b6020026020010151855f815181106111bf576111bf613134565b602002602001018181525050808d11156111ea576111dd818e6133aa565b6111e79083613121565b91505b81845f815181106111fd576111fd613134565b6020026020010181815250508160155f8581526020019081526020015f206004015f82825461122c9190613121565b909155505f9d5061132992505050565b5f5b8a81101561131b5788818151811061125857611258613134565b6020026020010151915088818151811061127457611274613134565b602002602001015184828151811061128e5761128e613134565b6020026020010181815250508781815181106112ac576112ac613134565b60200260200101518382815181106112c6576112c6613134565b6020026020010181815250508781815181106112e4576112e4613134565b602002602001015160155f8481526020019081526020015f206004015f82825461130e9190613121565b909155505060010161123e565b50611326898c6133aa565b9a505b60118b90555b8551156115a257600f545f9a508a5b875181101561151d5787818151811061135957611359613134565b6020026020010151925086818151811061137557611375613134565b602002602001015160155f8581526020019081526020015f2060020190805190602001906113a4929190612bc6565b505f8682815181106113b8576113b8613134565b60200260200101511115611503578581815181106113d8576113d8613134565b602002602001015160155f8581526020019081526020015f20600501546113ff9190613121565b86828151811061141157611411613134565b60200260200101818152505085818151811061142f5761142f613134565b602002602001015160155f8581526020019081526020015f2060050181905550600e5486828151811061146457611464613134565b602002602001015111156114a257828e828151811061148557611485613134565b60209081029190910101528b61149a816133bd565b9c5050611515565b827f33dc5cdf1e035de8a7fe16ad7a30a441d30ee51719d3f07703ee35d4348f0779838884815181106114d7576114d7613134565b60200260200101516040516114f6929190918252602082015260400190565b60405180910390a2611515565b5f838152601560205260408120600501555b60010161133e565b508a156115365761152f8d868d612536565b9c5061153b565b60609c505b5f6013544261154a91906133aa565b42601355905061155b826001613121565b600f81905550817f48b735a18ed32318d316214e41387be29c52e29df4598f2b8e40fa843be3f9408e87878560405161159794939291906133d5565b60405180910390a250505b855115806115b057505f8c51115b156115c0576115bd6115e5565b95505b50939c509a509198505050505050505090919293565b6016818154811061066c575f80fd5b60606016805480602002602001604051908101604052809291908181526020018280548015610e3557602002820191905f5260205f2090815481526020019060010190808311610e21575050505050905090565b5f60055460135461164a9190613121565b905090565b5f818152601560209081526040808320815160c08101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287969395860193909291908301828280156116cc57602002820191905f5260205f20905b8154815260200190600101908083116116b8575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050600e548160a00151111561170c576002915061171b565b60608101511561171b57600191505b50919050565b5f82815260156020526040812060018101546001600160a01b0316331461177257600181015460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610956565b5f61177b610f42565b505050600483015460115460038501549195509192505f9061179d90426133aa565b9050600d5481111580156117b057505f82115b156117e357600d5460405163ba2bbc6b60e01b815260048101899052602481018390526044810191909152606401610956565b5f805b8451821015611822578885838151811061180257611802613134565b60200260200101510361181757506001611822565b8160010191506117e6565b5f8660020180548060200260200160405190810160405280929190818152602001828054801561186f57602002820191905f5260205f20905b81548152602001906001019080831161185b575b50508a545f8f815260156020526040812080546001600160a01b0319908116825560018201805490911690559596506001600160a01b0390911694935091506118bd90506002830182612c0f565b505f60038201819055600482018190556005909101558215611953576016545f906118ea906001906133aa565b9050801561192d576016818154811061190557611905613134565b905f5260205f2001546016868154811061192157611921613134565b5f918252602090912001555b601680548061193e5761193e613411565b600190038181905f5260205f20015f90559055505b600b546040516323b872dd60e01b8152306004820152336024820152604481018d90526001600160a01b03909116906323b872dd906064015f604051808303815f87803b1580156119a2575f80fd5b505af11580156119b4573d5f803e3d5ffd5b505050505f8911156119e65789156119dc576119d08987613121565b601181905595506119e6565b6119e6818a6128ee565b8915611a4557806001600160a01b0316336001600160a01b03168c7f91c9f7c7f307bcc0ae02ba613bd8d07c29e94952f0a28803ded176fcd7d96d64600f54868e8c604051611a389493929190613425565b60405180910390a4611a9a565b806001600160a01b0316336001600160a01b03168c7f6d789d063e079a4c156e77a20008529fc448dca2cd7e5e7a20abf969fffb9226600f54868e8c604051611a919493929190613425565b60405180910390a45b505050505050505092915050565b5f82815260156020526040812060018101546001600160a01b03163314611af957600181015460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610956565b8215611b0c57611b07610f42565b505050505b80600401549150815f03611b3357604051637c946ed760e01b815260040160405180910390fd5b5f600482015580546001600160a01b0316611b4e81846128ee565b806001600160a01b0316336001600160a01b0316867f31add0166dae59ea66bbc180e4fae85b72fc9b7b5fc7b0f7257e4721a840c96e600f548660020188604051611b9b93929190613450565b60405180910390a4505092915050565b60135460115460165490915f91829160609182918291829182918015801590611bdf5750600554611bdc83426133aa565b10155b8015611bea57505f8a115b15611f3f578067ffffffffffffffff811115611c0857611c08612df1565b604051908082528060200260200182016040528015611c31578160200160208202803683370190505b5094508067ffffffffffffffff811115611c4d57611c4d612df1565b604051908082528060200260200182016040528015611c76578160200160208202803683370190505b5096508067ffffffffffffffff811115611c9257611c92612df1565b604051908082528060200260200182016040528015611cbb578160200160208202803683370190505b5095508067ffffffffffffffff811115611cd757611cd7612df1565b604051908082528060200260200182016040528015611d0a57816020015b6060815260200190600190039081611cf55790505b5093508067ffffffffffffffff811115611d2657611d26612df1565b604051908082528060200260200182016040528015611d4f578160200160208202803683370190505b5092505f5b81811015611f3d5760168181548110611d6f57611d6f613134565b905f5260205f200154868281518110611d8a57611d8a613134565b6020026020010181815250505f60155f888481518110611dac57611dac613134565b602002602001015181526020019081526020015f2090505f8490505f8260030154905081811115611ddb578091505b611de582426133aa565b8354600285018054604080516020808402820181019092528281529495505f94611e4f946001600160a01b03169390929091830182828015611e4457602002820191905f5260205f20905b815481526020019060010190808311611e30575b505050505084612962565b8a8781518110611e6157611e61613134565b602090810291909101015290508015611f0e5781600254611e829190613148565b8b8f81518110611e9457611e94613134565b6020026020010181815250508a8e81518110611eb257611eb2613134565b60200260200101518d611ec59190613121565b9c50898581518110611ed957611ed9613134565b60200260200101518c8f81518110611ef357611ef3613134565b6020908102919091010152611f078e6133bd565b9d50611f2e565b81888681518110611f2157611f21613134565b6020026020010181815250505b50505050806001019050611d54565b505b50509091929394959697565b601754604051633cebfa4f60e01b8152600481018590525f9182916001600160a01b0390911690633cebfa4f906024016040805180830381865afa158015611f95573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fb991906134aa565b60185491935091506001600160a01b0380841691161461200357601854604051630b80380d60e31b81526001600160a01b0391821660048201529083166024820152604401610956565b6003546bffffffffffffffffffffffff821681111561204c57604051632b30b24760e21b81526bffffffffffffffffffffffff8316600482015260248101829052604401610956565b5f5b845181101561212b5760175485515f916001600160a01b0316906375c1f934908a9089908690811061208257612082613134565b60200260200101516040518363ffffffff1660e01b81526004016120b692919091825263ffffffff16602082015260400190565b602060405180830381865afa1580156120d1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120f591906134dd565b90508281101561212257604051632b30b24760e21b81526004810182905260248101849052604401610956565b5060010161204e565b50505050505050565b600b546001600160a01b03161561215d5760405162dc149f60e41b815260040160405180910390fd5b8051158061216d57506020810151155b8061217a57506040810151155b80612187575060c0810151155b806121955750610100810151155b806121a2575060e0810151155b806121af57506080810151155b806121bc575060a0810151155b156121da57604051637c946ed760e01b815260040160405180910390fd5b8060a001518160800151101561221657608081015160a082015160405163491a2bb160e01b815260048101929092526024820152604401610956565b60028160600151101561224c57606081015160405163491a2bb160e01b8152600481019190915260026024820152604401610956565b6101a08101516001600160a01b0316158061227357506101c08101516001600160a01b0316155b156122915760405163d92e233d60e01b815260040160405180910390fd5b806101c001516001600160a01b03163b5f036122d2576101c081015160405163601c0c2160e01b81526001600160a01b039091166004820152602401610956565b80515f90815560208201516001556040820151600255606082015160035560a082015160045560c082015160055560e08201516006556101008201516007556101a0820151600b80546001600160a01b039283166001600160a01b0319918216179091556101c0840151600c8054919093169116179055610140820151600855610160820151600955805b8261012001515181101561242b5781836101200151828151811061238357612383613134565b6020026020010151116123cb5782610120015181815181106123a7576123a7613134565b6020026020010151604051632ab10b0b60e21b815260040161095691815260200190565b82610120015181815181106123e2576123e2613134565b602090810291909101015160148054600181810183555f929092527fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec018290559092500161235d565b506101808201515f0361245157604051637c946ed760e01b815260040160405180910390fd5b610180820151600a55600554608083015161246c9190613148565b600d5560055460a08301516124819190613148565b600e5560e08201516020830151604084015161249d9190613148565b6124a79190613148565b601255505042601355565b5f6040516323b872dd60e01b5f5284600452836024528260445260205f60645f808a5af13d15601f3d1160015f511416171691505f60605280604052508061252f5760405163abae3d6d60e01b81526001600160a01b03808716600483015280861660248301528416604482015260648101839052608401610956565b5050505050565b82516060908267ffffffffffffffff81111561255457612554612df1565b60405190808252806020026020018201604052801561257d578160200160208202803683370190505b5091505f8367ffffffffffffffff81111561259a5761259a612df1565b6040519080825280602002602001820160405280156125c3578160200160208202803683370190505b5090505f8467ffffffffffffffff8111156125e0576125e0612df1565b604051908082528060200260200182016040528015612609578160200160208202803683370190505b5090505f8567ffffffffffffffff81111561262657612626612df1565b60405190808252806020026020018201604052801561264f578160200160208202803683370190505b5090505f8667ffffffffffffffff81111561266c5761266c612df1565b604051908082528060200260200182016040528015612695578160200160208202803683370190505b5090505f805f5b878110156127f1575f8c82815181106126b7576126b7613134565b602002602001015111156127e9578b81815181106126d7576126d7613134565b60200260200101519150818984815181106126f4576126f4613134565b6020908102919091018101919091525f838152601590915260409020600181015488516001600160a01b039091169089908690811061273557612735613134565b6001600160a01b0392831660209182029290920101528154885191169088908690811061276457612764613134565b60200260200101906001600160a01b031690816001600160a01b0316815250508b828151811061279657612796613134565b60200260200101518685815181106127b0576127b0613134565b602002602001018181525050818585815181106127cf576127cf613134565b6020908102919091010152836127e4816133bd565b945050505b60010161269c565b50885b801561289f5787612804816134f4565b98505f9050846128156001846133aa565b8151811061282557612825613134565b602002602001015190506016898154811061284257612842613134565b905f5260205f2001546016828154811061285e5761285e613134565b5f91825260209091200155601680548061287a5761287a613411565b600190038181905f5260205f20015f905590555080612898906134f4565b90506127f4565b50600f547fd19a3d42ed383465e4058c322d9411aeac76ddb8454d22e139fc99808bd56952898888886040516128d89493929190613541565b60405180910390a2505050505050509392505050565b8060105f8282546128ff91906133aa565b909155505060185461291b906001600160a01b03168383612b49565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243648260405161295691815260200190565b60405180910390a25050565b6040516001600160a01b03841660248201525f90606090829060440160408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663d564c4bf60e01b179052600c5490519192505f9182916001600160a01b0316906129de908590613579565b5f60405180830381855afa9150503d805f8114612a16576040519150601f19603f3d011682016040523d82523d5f602084013e612a1b565b606091505b5091509150818015612a2e5750603f8151115b8015612a45575060208151612a43919061358f565b155b15612b3e5780806020019051810190612a5e9190613309565b9350838787604051602401612a75939291906135a2565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663184023a560e01b179052600c5490519194506001600160a01b031690612ad1908590613579565b5f60405180830381855afa9150503d805f8114612b09576040519150601f19603f3d011682016040523d82523d5f602084013e612b0e565b606091505b509092509050818015612b22575080516020145b15612b3e5780806020019051810190612b3b91906135d7565b94505b505050935093915050565b5f60405163a9059cbb60e01b5f52836004528260245260205f60445f80895af13d15601f3d1160015f511416171691505f606052806040525080612bc05760405163abae3d6d60e01b81526001600160a01b0380861660048301523060248301528416604482015260648101839052608401610956565b50505050565b828054828255905f5260205f20908101928215612bff579160200282015b82811115612bff578251825591602001919060010190612be4565b50612c0b929150612c2d565b5090565b5080545f8255905f5260205f2090810190612c2a9190612c2d565b50565b5b80821115612c0b575f8155600101612c2e565b6001600160a01b0381168114612c2a575f80fd5b8035612c6081612c41565b919050565b5f805f805f60808688031215612c79575f80fd5b8535612c8481612c41565b94506020860135612c9481612c41565b935060408601359250606086013567ffffffffffffffff80821115612cb7575f80fd5b818801915088601f830112612cca575f80fd5b813581811115612cd8575f80fd5b896020828501011115612ce9575f80fd5b9699959850939650602001949392505050565b5f60208284031215612d0c575f80fd5b5035919050565b602080825282516001600160a01b0390811683830152838201511660408084019190915283015160c06060840152805160e084018190525f929182019083906101008601905b80831015612d795783518252928401926001929092019190840190612d59565b5060608701516080870152608087015160a087015260a087015160c08701528094505050505092915050565b5f815180845260208085019450602084015f5b83811015612dd457815187529582019590820190600101612db8565b509495945050505050565b602081525f61073c6020830184612da5565b634e487b7160e01b5f52604160045260245ffd5b6040516101e0810167ffffffffffffffff81118282101715612e2957612e29612df1565b60405290565b604051610100810167ffffffffffffffff81118282101715612e2957612e29612df1565b604051601f8201601f1916810167ffffffffffffffff81118282101715612e7c57612e7c612df1565b604052919050565b5f67ffffffffffffffff821115612e9d57612e9d612df1565b5060051b60200190565b5f82601f830112612eb6575f80fd5b81356020612ecb612ec683612e84565b612e53565b8083825260208201915060208460051b870101935086841115612eec575f80fd5b602086015b84811015612f085780358352918301918301612ef1565b509695505050505050565b5f805f60608486031215612f25575f80fd5b833567ffffffffffffffff80821115612f3c575f80fd5b908501906101e08288031215612f50575f80fd5b612f58612e05565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c082015260e083013560e08201526101008084013581830152506101208084013583811115612fc1575f80fd5b612fcd8a828701612ea7565b91830191909152506101408381013590820152610160808401359082015261018080840135908201526101a09150613006828401612c55565b828201526101c0915061301a828401612c55565b8282015280955050505061303060208501612c55565b915061303e60408501612c55565b90509250925092565b608081525f6130596080830187612da5565b828103602084015261306b8187612da5565b9050828103604084015261307f8186612da5565b905082810360608401526130938185612da5565b979650505050505050565b634e487b7160e01b5f52602160045260245ffd5b60208101600383106130d257634e487b7160e01b5f52602160045260245ffd5b91905290565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156106405761064061310d565b634e487b7160e01b5f52603260045260245ffd5b80820281158282048414176106405761064061310d565b634e487b7160e01b5f52601260045260245ffd5b5f826131815761318161315f565b500490565b80516bffffffffffffffffffffffff81168114612c60575f80fd5b8051612c6081612c41565b805163ffffffff81168114612c60575f80fd5b805160068110612c60575f80fd5b5f82601f8301126131dc575f80fd5b815160206131ec612ec683612e84565b8083825260208201915060208460051b87010193508684111561320d575f80fd5b602086015b84811015612f0857613223816131ac565b8352918301918301613212565b5f60208284031215613240575f80fd5b815167ffffffffffffffff80821115613257575f80fd5b90830190610100828603121561326b575f80fd5b613273612e2f565b61327c83613186565b815261328a602084016131a1565b6020820152604083015160408201526132a5606084016131ac565b60608201526132b6608084016131ac565b60808201526132c760a084016131ac565b60a08201526132d860c084016131bf565b60c082015260e0830151828111156132ee575f80fd5b6132fa878286016131cd565b60e08301525095945050505050565b5f602080838503121561331a575f80fd5b825167ffffffffffffffff811115613330575f80fd5b8301601f81018513613340575f80fd5b805161334e612ec682612e84565b81815260059190911b8201830190838101908783111561336c575f80fd5b928401925b8284101561309357835182529284019290840190613371565b828152604060208201525f6133a26040830184612da5565b949350505050565b818103818111156106405761064061310d565b5f600182016133ce576133ce61310d565b5060010190565b848152608060208201525f6133ed6080830186612da5565b82810360408401526133ff8186612da5565b91505082606083015295945050505050565b634e487b7160e01b5f52603160045260245ffd5b848152608060208201525f61343d6080830186612da5565b6040830194909452506060015292915050565b5f60608201858352602060606020850152818654808452608086019150875f5260205f2093505f5b8181101561349457845483526001948501949284019201613478565b5050809350505050826040830152949350505050565b5f80604083850312156134bb575f80fd5b82516134c681612c41565b91506134d460208401613186565b90509250929050565b5f602082840312156134ed575f80fd5b5051919050565b5f816135025761350261310d565b505f190190565b5f815180845260208085019450602084015f5b83811015612dd45781516001600160a01b03168752958201959082019060010161351c565b608081525f6135536080830187612da5565b82810360208401526135658187613509565b9050828103604084015261307f8186613509565b5f82518060208501845e5f920191825250919050565b5f8261359d5761359d61315f565b500690565b606081525f6135b46060830186612da5565b82810360208401526135c68186612da5565b915050826040830152949350505050565b5f602082840312156135e7575f80fd5b8151801515811461073c575f80fdfea26469706673582212205776961a63fdaa13bebe3a0b2e71165c50721be211795e8926959409ae3d540364736f6c63430008190033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/staking_token/contract.py b/trader_backup/vendor/valory/contracts/staking_token/contract.py deleted file mode 100644 index 8bc883783..000000000 --- a/trader_backup/vendor/valory/contracts/staking_token/contract.py +++ /dev/null @@ -1,192 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the class to connect to the `StakingToken` contract.""" - -from enum import Enum - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi - - -class StakingTokenContract(Contract): - """The Staking Token contract.""" - - contract_id = PublicId.from_str("valory/staking_token:0.1.0") - - @classmethod - def get_service_staking_state( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Check whether the service is staked.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - res = contract_instance.functions.getStakingState(service_id).call() - return dict(data=res) - - @classmethod - def build_stake_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Build stake tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("stake", args=[service_id]) - return dict(data=bytes.fromhex(data[2:])) - - @classmethod - def build_checkpoint_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Build checkpoint tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("checkpoint") - return dict(data=bytes.fromhex(data[2:])) - - @classmethod - def build_unstake_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Build unstake tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("unstake", args=[service_id]) - return dict(data=bytes.fromhex(data[2:])) - - @classmethod - def available_rewards( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Get the available rewards.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - res = contract_instance.functions.availableRewards().call() - return dict(data=res) - - @classmethod - def get_staking_rewards( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Get the service's staking rewards.""" - contract = cls.get_instance(ledger_api, contract_address) - reward = contract.functions.calculateStakingReward(service_id).call() - return dict(data=reward) - - @classmethod - def get_next_checkpoint_ts( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Get the next checkpoint's timestamp.""" - contract = cls.get_instance(ledger_api, contract_address) - ts = contract.functions.getNextRewardCheckpointTimestamp().call() - return dict(data=ts) - - @classmethod - def ts_checkpoint( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the checkpoint's timestamp.""" - contract = cls.get_instance(ledger_api, contract_address) - ts_checkpoint = contract.functions.tsCheckpoint().call() - return dict(data=ts_checkpoint) - - @classmethod - def liveness_ratio( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the liveness ratio.""" - contract = cls.get_instance(ledger_api, contract_address) - liveness_ratio = contract.functions.livenessRatio().call() - return dict(data=liveness_ratio) - - @classmethod - def get_liveness_period( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the liveness period.""" - contract = cls.get_instance(ledger_api, contract_address) - liveness_period = contract.functions.livenessPeriod().call() - return dict(data=liveness_period) - - @classmethod - def get_service_info( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Retrieve the service info for a service.""" - contract = cls.get_instance(ledger_api, contract_address) - info = contract.functions.getServiceInfo(service_id).call() - return dict(data=info) - - @classmethod - def max_num_services( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the max number of services.""" - contract = cls.get_instance(ledger_api, contract_address) - max_num_services = contract.functions.maxNumServices().call() - return dict(data=max_num_services) - - @classmethod - def get_service_ids( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the service IDs.""" - contract = cls.get_instance(ledger_api, contract_address) - service_ids = contract.functions.getServiceIds().call() - return dict(data=service_ids) - - @classmethod - def get_min_staking_duration( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the service IDs.""" - contract = cls.get_instance(ledger_api, contract_address) - duration = contract.functions.minStakingDuration().call() - return dict(data=duration) diff --git a/trader_backup/vendor/valory/contracts/staking_token/contract.yaml b/trader_backup/vendor/valory/contracts/staking_token/contract.yaml deleted file mode 100644 index e1a858361..000000000 --- a/trader_backup/vendor/valory/contracts/staking_token/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: staking_token -author: valory -version: 0.1.0 -type: contract -description: Service staking token contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeicmgkagyhgwn2ktcdjbprijalbdyj26cvza4d3b7uvmehvy4mmr3i - build/StakingToken.json: bafybeibhcwyawq377innrpq4ytpw5kotufjqo7cyd2rjhyit34mnbks5b4 - contract.py: bafybeigjt7a2biiorp4vmj4d3qkm3xbbohnawoetywojye5akhavlvkrxm -fingerprint_ignore_patterns: [] -contracts: [] -class_name: StakingTokenContract -contract_interface_paths: - ethereum: build/StakingToken.json -dependencies: - open-aea-ledger-ethereum: - version: <2,>=1.53.0 - open-aea-test-autonomy: - version: <1,>=0.14.14.post1 - web3: - version: <7,>=6.0.0 diff --git a/trader_backup/vendor/valory/contracts/transfer_nft_condition/README.md b/trader_backup/vendor/valory/contracts/transfer_nft_condition/README.md deleted file mode 100644 index e4d57e82f..000000000 --- a/trader_backup/vendor/valory/contracts/transfer_nft_condition/README.md +++ /dev/null @@ -1 +0,0 @@ -# TRANSFER_NFT_CONDITION token contract diff --git a/trader_backup/vendor/valory/contracts/transfer_nft_condition/__init__.py b/trader_backup/vendor/valory/contracts/transfer_nft_condition/__init__.py deleted file mode 100644 index d8773d74b..000000000 --- a/trader_backup/vendor/valory/contracts/transfer_nft_condition/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the support resources for TransferNFTCondition.""" diff --git a/trader_backup/vendor/valory/contracts/transfer_nft_condition/build/TransferNFTCondition.json b/trader_backup/vendor/valory/contracts/transfer_nft_condition/build/TransferNFTCondition.json deleted file mode 100644 index ddfe15e47..000000000 --- a/trader_backup/vendor/valory/contracts/transfer_nft_condition/build/TransferNFTCondition.json +++ /dev/null @@ -1,1148 +0,0 @@ -{ - "_format": "", - "contractName": "", - "sourceName": "", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "_receiver", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "_conditionId", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "_contract", - "type": "address" - } - ], - "name": "Fulfilled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "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": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } - ], - "name": "RoleAdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleGranted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleRevoked", - "type": "event" - }, - { - "inputs": [], - "name": "DEFAULT_ADMIN_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_id", - "type": "bytes32" - } - ], - "name": "abortByTimeOut", - "outputs": [ - { - "internalType": "enum ConditionStoreLibrary.ConditionState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_addr", - "type": "address" - } - ], - "name": "addressToBytes32", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_b32", - "type": "bytes32" - } - ], - "name": "bytes32ToAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256[]", - "name": "_amounts", - "type": "uint256[]" - } - ], - "name": "calculateTotalAmount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftHolder", - "type": "address" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockPaymentCondition", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "_transfer", - "type": "bool" - } - ], - "name": "encodeParams", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockPaymentCondition", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "_transfer", - "type": "bool" - } - ], - "name": "fulfill", - "outputs": [ - { - "internalType": "enum ConditionStoreLibrary.ConditionState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockPaymentCondition", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "_transfer", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "_expirationBlock", - "type": "uint256" - } - ], - "name": "fulfill", - "outputs": [ - { - "internalType": "enum ConditionStoreLibrary.ConditionState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockPaymentCondition", - "type": "bytes32" - } - ], - "name": "fulfill", - "outputs": [ - { - "internalType": "enum ConditionStoreLibrary.ConditionState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftHolder", - "type": "address" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockPaymentCondition", - "type": "bytes32" - }, - { - "internalType": "bool", - "name": "_transfer", - "type": "bool" - } - ], - "name": "fulfillForDelegate", - "outputs": [ - { - "internalType": "enum ConditionStoreLibrary.ConditionState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftHolder", - "type": "address" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockPaymentCondition", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "_transfer", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "_expirationBlock", - "type": "uint256" - } - ], - "name": "fulfillForDelegate", - "outputs": [ - { - "internalType": "enum ConditionStoreLibrary.ConditionState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_account", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "_params", - "type": "bytes" - } - ], - "name": "fulfillProxy", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_valueHash", - "type": "bytes32" - } - ], - "name": "generateId", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getCurrentBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNFTDefaultAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNvmConfigAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } - ], - "name": "getRoleAdmin", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getTrustedForwarder", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - } - ], - "name": "grantMarketRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_address", - "type": "address" - } - ], - "name": "grantProxyRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "grantRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "a", - "type": "address" - } - ], - "name": "hasNVMOperatorRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "hasRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftHolder", - "type": "address" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockCondition", - "type": "bytes32" - } - ], - "name": "hashValues", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftHolder", - "type": "address" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockCondition", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "_transfer", - "type": "bool" - } - ], - "name": "hashValues", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "internalType": "address", - "name": "_conditionStoreManagerAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "_didRegistryAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "_ercAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "isContract", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "forwarder", - "type": "address" - } - ], - "name": "isTrustedForwarder", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "renounceRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - } - ], - "name": "revokeMarketRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_address", - "type": "address" - } - ], - "name": "revokeProxyRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "revokeRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_id", - "type": "bytes32" - }, - { - "name": "_did", - "type": "bytes32" - }, - { - "name": "_conditionIds", - "type": "bytes32[]" - }, - { - "name": "_timeLocks", - "type": "uint256[]" - }, - { - "name": "_timeOuts", - "type": "uint256[]" - }, - { - "name": "_accessConsumer", - "type": "address" - }, - { - "name": "_idx", - "type": "uint256" - }, - { - "name": "_rewardAddress", - "type": "address" - }, - { - "name": "_tokenAddress", - "type": "address" - }, - { - "name": "_amounts", - "type": "uint256[]" - }, - { - "name": "_receivers", - "type": "address[]" - } - ], - "name": "createAgreementAndPayEscrow", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [ - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_backup/vendor/valory/contracts/transfer_nft_condition/contract.py b/trader_backup/vendor/valory/contracts/transfer_nft_condition/contract.py deleted file mode 100644 index b20b37ad4..000000000 --- a/trader_backup/vendor/valory/contracts/transfer_nft_condition/contract.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the class to connect to an TRANSFER_NFT_CONDITION token contract.""" - -from typing import Dict, List - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi -from web3 import Web3 - -PUBLIC_ID = PublicId.from_str("valory/transfer_nft_condition:0.1.0") - - -class TransferNftCondition(Contract): - """The TransferNftCondition contract.""" - - contract_id = PUBLIC_ID - - @classmethod - def build_order_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - agreement_id: str, - did: str, - condition_ids: List[str], - time_locks: List[int], - time_outs: List[int], - consumer: str, - index: int, - reward_address: str, - token_address: str, - amounts: List[int], - receives: List[str], - ) -> Dict[str, bytes]: - """Build an TransferNftCondition approval.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("createAgreementAndPayEscrow", args=( - bytes.fromhex(agreement_id[2:]), - bytes.fromhex(did[2:]), - [bytes.fromhex(condition_id[2:]) for condition_id in condition_ids], - time_locks, - time_outs, - Web3.to_checksum_address(consumer), - index, - Web3.to_checksum_address(reward_address), - Web3.to_checksum_address(token_address), - amounts, - [Web3.to_checksum_address(receive) for receive in receives], - )) - return {"data": bytes.fromhex(data[2:])} - - @classmethod - def balance_of( - cls, - ledger_api: LedgerApi, - contract_address: str, - address: str, - did: str, - ) -> JSONLike: - """Get the balance of an address.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - balance = contract_instance.functions.balanceOf( - Web3.to_checksum_address(address), - int(did, 16) - ).call() - return dict(data=balance) - - @classmethod - def is_approved_for_all( - cls, - ledger_api: LedgerApi, - contract_address: str, - account: str, - operator: str, - ) -> JSONLike: - """Get the balance of an address.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - is_approved = contract_instance.functions.isApprovedForAll( - Web3.to_checksum_address(account), - Web3.to_checksum_address(operator), - ).call() - return dict(data=is_approved) - - @classmethod - def build_set_approval_for_all_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - operator: str, - approved: bool, - ) -> Dict[str, bytes]: - """Build an TransferNftCondition approval.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("setApprovalForAll", args=( - Web3.to_checksum_address(operator), - approved, - )) - return {"data": bytes.fromhex(data[2:])} - diff --git a/trader_backup/vendor/valory/contracts/transfer_nft_condition/contract.yaml b/trader_backup/vendor/valory/contracts/transfer_nft_condition/contract.yaml deleted file mode 100644 index fcc24b09a..000000000 --- a/trader_backup/vendor/valory/contracts/transfer_nft_condition/contract.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: transfer_nft_condition -author: valory -version: 0.1.0 -type: contract -description: TRANSFER_NFT_CONDITION token contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeidiaep6cpoqlabnajvsgegpt72hqnbtozayicaxclzxzftopvlw5u - __init__.py: bafybeigz4j3ow7nagttswpbrpajnxqtxrl35oznejzxwi6bhfdeltnab5i - build/TransferNFTCondition.json: bafybeigxqddrgr4tuyhxyt5zblgnhwgpn4szjvyu5kvznslw4xfi7x2pp4 - contract.py: bafybeibievlshamdrcanb7rd4625jhmvmdwspovpnyudshahjiq4vzvyrm -fingerprint_ignore_patterns: [] -contracts: [] -class_name: TransferNftCondition -contract_interface_paths: - ethereum: build/TransferNFTCondition.json -dependencies: - ecdsa: - version: '>=0.15' - eth_typing: {} - hexbytes: {} - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - packaging: {} - py-eth-sig-utils: {} - requests: - version: ==2.28.1 - web3: - version: <7,>=6.0.0 diff --git a/trader_backup/vendor/valory/customs/__init__.py b/trader_backup/vendor/valory/customs/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_backup/vendor/valory/customs/bet_amount_per_threshold/__init__.py b/trader_backup/vendor/valory/customs/bet_amount_per_threshold/__init__.py deleted file mode 100644 index 93e631216..000000000 --- a/trader_backup/vendor/valory/customs/bet_amount_per_threshold/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the bet amount per threshold strategy.""" diff --git a/trader_backup/vendor/valory/customs/bet_amount_per_threshold/bet_amount_per_threshold.py b/trader_backup/vendor/valory/customs/bet_amount_per_threshold/bet_amount_per_threshold.py deleted file mode 100644 index c9bd5a75e..000000000 --- a/trader_backup/vendor/valory/customs/bet_amount_per_threshold/bet_amount_per_threshold.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 simple strategy that returns a bet amount based on a mapping.""" - -from typing import Union, List, Dict, Tuple, Any - -REQUIRED_FIELDS = ("confidence", "bet_amount_per_threshold") - - -def check_missing_fields(kwargs: Dict[str, Any]) -> List[str]: - """Check for missing fields and return them, if any.""" - missing = [] - for field in REQUIRED_FIELDS: - if kwargs.get(field, None) is None: - missing.append(field) - return missing - - -def remove_irrelevant_fields(kwargs: Dict[str, Any]) -> Dict[str, Any]: - """Remove the irrelevant fields from the given kwargs.""" - return {key: value for key, value in kwargs.items() if key in REQUIRED_FIELDS} - - -def amount_per_threshold( - confidence: float, bet_amount_per_threshold: Dict[str, int] -) -> Dict[str, Union[int, Tuple[str]]]: - """Get the bet amount per threshold strategy's result.""" - # we need the threshold as a string, because the agent/service overrides cannot be given with `int`s as keys - threshold = str(round(confidence, 1)) - bet_amount = bet_amount_per_threshold.get(threshold, None) - - if bet_amount is None: - return { - "error": ( - f"No amount was found in {bet_amount_per_threshold=} for {confidence=}.", - ) - } - return {"bet_amount": bet_amount} - - -def run(*_args, **kwargs) -> Dict[str, Union[int, Tuple[str]]]: - """Run the strategy.""" - missing = check_missing_fields(kwargs) - if len(missing) > 0: - return {"error": (f"Required kwargs {missing} were not provided.",)} - - kwargs = remove_irrelevant_fields(kwargs) - return amount_per_threshold(**kwargs) diff --git a/trader_backup/vendor/valory/customs/bet_amount_per_threshold/component.yaml b/trader_backup/vendor/valory/customs/bet_amount_per_threshold/component.yaml deleted file mode 100644 index 31fe6fc32..000000000 --- a/trader_backup/vendor/valory/customs/bet_amount_per_threshold/component.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: bet_amount_per_threshold -author: valory -version: 0.1.0 -type: custom -description: A simple strategy that bets a fixed amount when the confidence is of - a given threshold. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeibbn67pnrrm4qm3n3kbelvbs3v7fjlrjniywmw2vbizarippidtvi - bet_amount_per_threshold.py: bafybeih7kv24wtfotp3rskyo4runchu74qf4nlxyq53pzuy5qles545nza -fingerprint_ignore_patterns: [] -entry_point: bet_amount_per_threshold.py -callable: run -dependencies: {} diff --git a/trader_backup/vendor/valory/customs/kelly_criterion_no_conf/__init__.py b/trader_backup/vendor/valory/customs/kelly_criterion_no_conf/__init__.py deleted file mode 100644 index 3a7196fde..000000000 --- a/trader_backup/vendor/valory/customs/kelly_criterion_no_conf/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the kelly criterion strategy without confidence factor in the formula.""" diff --git a/trader_backup/vendor/valory/customs/kelly_criterion_no_conf/component.yaml b/trader_backup/vendor/valory/customs/kelly_criterion_no_conf/component.yaml deleted file mode 100644 index 66dd77c4b..000000000 --- a/trader_backup/vendor/valory/customs/kelly_criterion_no_conf/component.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: kelly_criterion_no_conf -author: valory -version: 0.1.0 -type: custom -description: The kelly criterion trading strategy without confidence factor in the - formula. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeidog73nvs6bfta5pmaxufwly6pc52knbnxqlwcwka4cpnyneeykqi - kelly_criterion_no_conf.py: bafybeifrdnpes4jbhnkesuuk5pktyz2udlx4d5yr73ebgqpzpiqywixhom -fingerprint_ignore_patterns: [] -entry_point: kelly_criterion_no_conf.py -callable: run -dependencies: {} diff --git a/trader_backup/vendor/valory/customs/kelly_criterion_no_conf/kelly_criterion_no_conf.py b/trader_backup/vendor/valory/customs/kelly_criterion_no_conf/kelly_criterion_no_conf.py deleted file mode 100644 index 71be7fc7d..000000000 --- a/trader_backup/vendor/valory/customs/kelly_criterion_no_conf/kelly_criterion_no_conf.py +++ /dev/null @@ -1,186 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the kelly criterion strategy without confidence factor in the formula.""" - -from typing import Dict, Any, List, Union, Optional - -REQUIRED_FIELDS = frozenset( - { - # the fraction of the calculated kelly bet amount to use for placing the bet - "bet_kelly_fraction", - "bankroll", - "win_probability", - "confidence", - "selected_type_tokens_in_pool", - "other_tokens_in_pool", - "bet_fee", - "weighted_accuracy", - "floor_balance", - } -) -OPTIONAL_FIELDS = frozenset({"max_bet"}) -ALL_FIELDS = REQUIRED_FIELDS.union(OPTIONAL_FIELDS) -DEFAULT_MAX_BET = 8e17 - - -def check_missing_fields(kwargs: Dict[str, Any]) -> List[str]: - """Check for missing fields and return them, if any.""" - missing = [] - for field in REQUIRED_FIELDS: - if kwargs.get(field, None) is None: - missing.append(field) - return missing - - -def remove_irrelevant_fields(kwargs: Dict[str, Any]) -> Dict[str, Any]: - """Remove the irrelevant fields from the given kwargs.""" - return {key: value for key, value in kwargs.items() if key in ALL_FIELDS} - - -def get_adjusted_kelly_amount( - kelly_bet_amount: float, - weighted_accuracy: Optional[float], - static_kelly_fraction: float, - error: list, -): - """This function adjusts the kelly bet amount based on the weighted accuracy metric - of the selected tool to make the prediction. Default use-case: it uses the static kelly fraction - """ - if weighted_accuracy is None: - error.append( - f"No weighted accuracy information for this tool. Using static fraction." - ) - return int(kelly_bet_amount * static_kelly_fraction) - # weighted_accuracy must be always between [0, 1] - if not (0 <= weighted_accuracy <= 1): - error.append( - f"Wrong value for the weighted accuracy {weighted_accuracy}. Accepted range [0, 1]. Using static fraction" - ) - return int(kelly_bet_amount * static_kelly_fraction) - dynamic_kelly_fraction = static_kelly_fraction + weighted_accuracy - return int(kelly_bet_amount * dynamic_kelly_fraction) - - -def calculate_kelly_bet_amount_no_conf( - x: int, y: int, p: float, b: int, f: float -) -> int: - """Calculate the Kelly bet amount.""" - if b == 0: - return 0 - numerator = ( - -4 * x**2 * y - + b * y**2 * p * f - + 2 * b * x * y * p * f - + b * x**2 * p * f - - 2 * b * y**2 * f - - 2 * b * x * y * f - + ( - ( - 4 * x**2 * y - - b * y**2 * p * f - - 2 * b * x * y * p * f - - b * x**2 * p * f - + 2 * b * y**2 * f - + 2 * b * x * y * f - ) - ** 2 - - ( - 4 - * (x**2 * f - y**2 * f) - * (-4 * b * x * y**2 * p - 4 * b * x**2 * y * p + 4 * b * x * y**2) - ) - ) - ** (1 / 2) - ) - denominator = 2 * (x**2 * f - y**2 * f) - if denominator == 0: - return 0 - kelly_bet_amount = numerator / denominator - return int(kelly_bet_amount) - - -def wei_to_native(wei: int) -> float: - """Convert WEI to native token.""" - return wei / 10**18 - - -def get_bet_amount_kelly( # pylint: disable=too-many-arguments - bet_kelly_fraction: float, - bankroll: int, - win_probability: float, - confidence: float, - selected_type_tokens_in_pool: int, - other_tokens_in_pool: int, - bet_fee: int, - weighted_accuracy: float, - floor_balance: int, - max_bet: int = DEFAULT_MAX_BET, -) -> Dict[str, Union[int, List[str]]]: - """Calculate the Kelly bet amount.""" - # keep `floor_balance` xDAI in the bankroll - bankroll_adj = bankroll - floor_balance - bankroll_adj = min(bankroll_adj, max_bet) - bankroll_adj_xdai = wei_to_native(bankroll_adj) - info = [f"Adjusted bankroll: {bankroll_adj_xdai} xDAI."] - error = [] - if bankroll_adj <= 0: - error.append( - f"Bankroll ({bankroll_adj}) is less than the floor balance ({floor_balance})." - ) - error.append("Set bet amount to 0.") - error.append("Top up safe with DAI or wait for redeeming.") - return {"bet_amount": 0, "info": info, "error": error} - - fee_fraction = 1 - wei_to_native(bet_fee) - info.append(f"Fee fraction: {fee_fraction}") - kelly_bet_amount = calculate_kelly_bet_amount_no_conf( - selected_type_tokens_in_pool, - other_tokens_in_pool, - win_probability, - bankroll_adj, - fee_fraction, - ) - if kelly_bet_amount < 0: - info.append( - f"Invalid value for kelly bet amount: {kelly_bet_amount}\nSet bet amount to 0." - ) - return {"bet_amount": 0, "info": info, "error": error} - - info.append(f"Kelly bet amount: {wei_to_native(kelly_bet_amount)} xDAI") - info.append(f"Bet kelly fraction: {bet_kelly_fraction}") - info.append( - f"Applying dynamic kelly fraction to all bets. Weighted accuracy of the tool={weighted_accuracy}" - ) - adj_kelly_bet_amount = get_adjusted_kelly_amount( - kelly_bet_amount, weighted_accuracy, bet_kelly_fraction, error - ) - info.append( - f"Adjusted Kelly bet amount: {wei_to_native(adj_kelly_bet_amount)} xDAI" - ) - return {"bet_amount": adj_kelly_bet_amount, "info": info, "error": error} - - -def run(*_args, **kwargs) -> Dict[str, Union[int, List[str]]]: - """Run the strategy.""" - missing = check_missing_fields(kwargs) - if len(missing) > 0: - return {"error": [f"Required kwargs {missing} were not provided."]} - kwargs = remove_irrelevant_fields(kwargs) - return get_bet_amount_kelly(**kwargs) diff --git a/trader_backup/vendor/valory/customs/mike_strat/__init__.py b/trader_backup/vendor/valory/customs/mike_strat/__init__.py deleted file mode 100644 index 93e631216..000000000 --- a/trader_backup/vendor/valory/customs/mike_strat/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the bet amount per threshold strategy.""" diff --git a/trader_backup/vendor/valory/customs/mike_strat/component.yaml b/trader_backup/vendor/valory/customs/mike_strat/component.yaml deleted file mode 100644 index 12b0baf52..000000000 --- a/trader_backup/vendor/valory/customs/mike_strat/component.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: mike_strat -author: valory -version: 0.1.0 -type: custom -description: A simple strategy that bets a fixed amount when the confidence is of - a given threshold. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeibbn67pnrrm4qm3n3kbelvbs3v7fjlrjniywmw2vbizarippidtvi - mike_strat.py: bafybeifbxlcl6kvubdudnjilantbqbghuvhmgheyh35jhiiaqpmq7va6ji -fingerprint_ignore_patterns: [] -entry_point: mike_strat.py -callable: run -dependencies: {} diff --git a/trader_backup/vendor/valory/customs/mike_strat/mike_strat.py b/trader_backup/vendor/valory/customs/mike_strat/mike_strat.py deleted file mode 100644 index 88790b7bd..000000000 --- a/trader_backup/vendor/valory/customs/mike_strat/mike_strat.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 simple strategy that returns a bet amount based on a mapping.""" - -from typing import Union, List, Dict, Tuple, Any - -REQUIRED_FIELDS = ("confidence", "bet_amount_per_threshold") - - -def check_missing_fields(kwargs: Dict[str, Any]) -> List[str]: - """Check for missing fields and return them, if any.""" - missing = [] - for field in REQUIRED_FIELDS: - if kwargs.get(field, None) is None: - missing.append(field) - return missing - - -def remove_irrelevant_fields(kwargs: Dict[str, Any]) -> Dict[str, Any]: - """Remove the irrelevant fields from the given kwargs.""" - return {key: value for key, value in kwargs.items() if key in REQUIRED_FIELDS} - - -def amount_per_threshold( - confidence: float, bet_amount_per_threshold: Dict[str, int] -) -> Dict[str, Union[int, Tuple[str]]]: - """Get the bet amount per threshold strategy's result.""" - # we need the threshold as a string, because the agent/service overrides cannot be given with `int`s as keys - threshold = str(round(confidence, 1)) - bet_amount = bet_amount_per_threshold.get(threshold, None) - - if bet_amount is None: - return { - "error": ( - f"No amount was found in {bet_amount_per_threshold=} for {confidence=}.", - ) - } - return {"bet_amount": bet_amount * confidence} - - -def run(*_args, **kwargs) -> Dict[str, Union[int, Tuple[str]]]: - """Run the strategy.""" - missing = check_missing_fields(kwargs) - if len(missing) > 0: - return {"error": (f"Required kwargs {missing} were not provided.",)} - - kwargs = remove_irrelevant_fields(kwargs) - return amount_per_threshold(**kwargs) diff --git a/trader_backup/vendor/valory/protocols/__init__.py b/trader_backup/vendor/valory/protocols/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_backup/vendor/valory/protocols/abci/README.md b/trader_backup/vendor/valory/protocols/abci/README.md deleted file mode 100644 index 63209a74d..000000000 --- a/trader_backup/vendor/valory/protocols/abci/README.md +++ /dev/null @@ -1,414 +0,0 @@ -# ABCI Protocol - -## Description - -This is a protocol for interacting with an ABCI client/server requests and responses. - -## Specification - -The specification is inspired from -[the Protobuf file `types.proto` for the ABCI protocol](https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto). - -```yaml ---- -name: abci -author: valory -version: 0.1.0 -description: A protocol for ABCI requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: valory/abci:0.1.0 -speech_acts: - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L42 - request_echo: - message: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L46 - request_flush: {} - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L48 - request_info: - version: pt:str - block_version: pt:int - p2p_version: pt:int - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L55 - request_set_option: - option_key: pt:str - option_value: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L60 - request_init_chain: - time: ct:Timestamp - chain_id: pt:str - consensus_params: pt:optional[ct:ConsensusParams] - validators: ct:ValidatorUpdates - app_state_bytes: pt:bytes - initial_height: pt:int - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L70 - request_query: - query_data: pt:bytes - path: pt:str - height: pt:int - prove: pt:bool - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L77 - request_begin_block: - hash: pt:bytes - header: ct:Header - last_commit_info: ct:LastCommitInfo - byzantine_validators: ct:Evidences - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L89 - request_check_tx: - tx: pt:bytes - type: ct:CheckTxType - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L94 - request_deliver_tx: - tx: pt:bytes - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L98 - request_end_block: - height: pt:int - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L102 - request_commit: {} - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L105 - request_list_snapshots: {} - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L109 - request_offer_snapshot: - snapshot: ct:Snapshot # snapshot offered by peers - app_hash: pt:bytes # light client-verified app hash for snapshot height - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L115 - request_load_snapshot_chunk: - height: pt:int - format: pt:int - chunk_index: pt:int - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L115 - request_apply_snapshot_chunk: - index: pt:int - chunk: pt:bytes - chunk_sender: pt:str # 'sender' conflicts with the attribute of 'Message' - # responses - response_exception: { - error: pt:str - } - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L157 - response_echo: - message: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L161 - response_flush: {} - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L163 - response_info: - info_data: pt:str - version: pt:str - app_version: pt:int - last_block_height: pt:int - last_block_app_hash: pt:bytes - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L174 - response_set_option: - code: pt:int - log: pt:str - info: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L181 - response_init_chain: - consensus_params: pt:optional[ct:ConsensusParams] - validators: ct:ValidatorUpdates - app_hash: pt:bytes - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L187 - response_query: - code: pt:int - log: pt:str - info: pt:str - index: pt:int - key: pt:bytes - value: pt:bytes - proof_ops: ct:ProofOps - height: pt:int - codespace: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L200 - response_begin_block: - events: ct:Events - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L205 - response_check_tx: - code: pt:int - data: pt:bytes - log: pt:str - info: pt:str - gas_wanted: pt:int - gas_used: pt:int - events: ct:Events - codespace: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L217 - response_deliver_tx: - code: pt:int - data: pt:bytes - log: pt:str - info: pt:str - gas_wanted: pt:int - gas_used: pt:int - events: ct:Events - codespace: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L229 - response_end_block: - validator_updates: ct:ValidatorUpdates - consensus_param_updates: pt:optional[ct:ConsensusParams] - events: ct:Events - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L237 - response_commit: - data: pt:bytes - retain_height: pt:int - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L243 - response_list_snapshots: - snapshots: ct:SnapShots - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L247 - response_offer_snapshot: - result: ct:Result - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L260 - response_load_snapshot_chunk: - chunk: pt:bytes - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L264 - response_apply_snapshot_chunk: - result: ct:Result - refetch_chunks: pt:list[pt:int] # Chunks to refetch and reapply - reject_senders: pt:list[pt:str] # Chunk senders to reject and ban - # dummy performative to make custom types used at least once - dummy: - dummy_consensus_params: ct:ConsensusParams -... ---- -# https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L284 -ct:ConsensusParams: | - message Duration { - int64 seconds = 1; - int32 nanos = 2; - } - message BlockParams { - int64 max_bytes = 1; - int64 max_gas = 2; - } - message EvidenceParams { - int64 max_age_num_blocks = 1; - Duration max_age_duration = 2; - int64 max_bytes = 3; - } - message ValidatorParams { - repeated string pub_key_types = 1; - } - message VersionParams { - uint64 app_version = 1; - } - BlockParams block = 1; - EvidenceParams evidence = 2; - ValidatorParams validator = 3; - VersionParams version = 4; -# https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L343 -ct:ValidatorUpdates: | - message PublicKey { - oneof sum { - bytes ed25519 = 1; - bytes secp256k1 = 2; - } - } - message ValidatorUpdate { - PublicKey pub_key = 1; - int64 power = 2; - } - repeated ValidatorUpdate validators = 1; -# google.protobuf.Timestamp -ct:Timestamp: | - // Represents seconds of UTC time since Unix epoch - // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - // 9999-12-31T23:59:59Z inclusive. - int64 seconds = 1; - // Non-negative fractions of a second at nanosecond resolution. Negative - // second values with fractions must still have non-negative nanos values - // that count forward in time. Must be from 0 to 999,999,999 - // inclusive. - int32 nanos = 2; -# https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/crypto/proof.proto#L39 -ct:ProofOps: | - message ProofOp { - string type = 1; - bytes key = 2; - bytes data = 3; - } - repeated ProofOp ops = 1; -# https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/types/types.proto#L58 -ct:Header: | - message ConsensusVersion { - uint64 block = 1; - uint64 app = 2; - } - message BlockID { - bytes hash = 1; - PartSetHeader part_set_header = 2; - } - message PartSetHeader { - uint32 total = 1; - bytes hash = 2; - } - ConsensusVersion version = 1; - string chain_id = 2; - int64 height = 3; - Timestamp time = 4; - - // prev block info - BlockID last_block_id = 5; - - // hashes of block data - bytes last_commit_hash = 6; // commit from validators from the last block - bytes data_hash = 7; // transactions - - // hashes from the app output from the prev block - bytes validators_hash = 8; // validators for the current block - bytes next_validators_hash = 9; // validators for the next block - bytes consensus_hash = 10; // consensus params for current block - bytes app_hash = 11; // state after txs from the previous block - bytes last_results_hash = 12; // root hash of all results from the txs from the previous block - - // consensus info - bytes evidence_hash = 13; // evidence included in the block - bytes proposer_address = 14; // original proposer of the block -# https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L299 -ct:LastCommitInfo: | - message Validator { - bytes address = 1; // The first 20 bytes of SHA256(public key) - // PubKey pub_key = 2 [(gogoproto.nullable)=false]; - int64 power = 3; // The voting power - } - message VoteInfo { - Validator validator = 1; - bool signed_last_block = 2; - } - int32 round = 1; - repeated VoteInfo votes = 2; -# https://github.com/tendermint/tendermint/blob/2f231ceb952a2426cf3c0abaf0b455aadd11e5b2/proto/tendermint/abci/types.proto#L360 -ct:Evidences: | - message Evidence { - enum EvidenceType { - UNKNOWN = 0; - DUPLICATE_VOTE = 1; - LIGHT_CLIENT_ATTACK = 2; - } - EvidenceType type = 1; - // The offending validator - LastCommitInfo.Validator validator = 2; - // The height when the offense occurred - int64 height = 3; - // The corresponding time where the offense occurred - Timestamp time = 4; - // Total voting power of the validator set in case the ABCI application does - // not store historical validators. - // https://github.com/tendermint/tendermint/issues/4581 - int64 total_voting_power = 5; - } - repeated Evidence byzantine_validators = 1; -ct:CheckTxType: | - enum _CheckTxType { - NEW = 0; - RECHECK = 1; - } - _CheckTxType type = 1; -# https://github.com/tendermint/tendermint/blob/2f231ceb952a2426cf3c0abaf0b455aadd11e5b2/proto/tendermint/abci/types.proto#L307 -ct:Events: | - message EventAttribute { - bytes key = 1; - bytes value = 2; - bool index = 3; // nondeterministic - } - message Event { - string type = 1; - repeated EventAttribute attributes = 2; - } - repeated Event events = 1; -ct:Result: | - enum ResultType { - UNKNOWN = 0; // Unknown result, abort all snapshot restoration - ACCEPT = 1; // Snapshot accepted, apply chunks - ABORT = 2; // Abort all snapshot restoration - REJECT = 3; // Reject this specific snapshot, try others - REJECT_FORMAT = 4; // Reject all snapshots of this format, try others - REJECT_SENDER = 5; // Reject all snapshots from the sender(s), try others - } - ResultType result_type = 1; -ct:Snapshot: | - // State Sync Types - uint64 height = 1; // The height at which the snapshot was taken - uint32 format = 2; // The application-specific snapshot format - uint32 chunks = 3; // Number of chunks in the snapshot - bytes hash = 4; // Arbitrary snapshot hash, equal only if identical - bytes metadata = 5; // Arbitrary application metadata -ct:SnapShots: | - repeated Snapshot snapshots = 1; -... ---- -initiation: -- request_echo -- request_flush -- request_info -- request_set_option -- request_init_chain -- request_query -- request_begin_block -- request_check_tx -- request_deliver_tx -- request_end_block -- request_commit -- request_list_snapshots -- request_offer_snapshot -- request_apply_snapshot_chunk -- request_load_snapshot_chunk -- dummy -reply: - request_echo: [response_echo, response_exception] - response_echo: [] - response_exception: [] - request_flush: [response_flush, response_exception] - response_flush: [] - request_info: [response_info, response_exception] - response_info: [] - request_set_option: [response_set_option, response_exception] - response_set_option: [] - request_init_chain: [response_init_chain, response_exception] - response_init_chain: [] - request_query: [response_query, response_exception] - response_query: [] - request_begin_block: [response_begin_block, response_exception] - response_begin_block: [] - request_check_tx: [response_check_tx, response_exception] - response_check_tx: [] - request_deliver_tx: [response_deliver_tx, response_exception] - response_deliver_tx: [] - request_end_block: [response_end_block, response_exception] - response_end_block: [] - request_commit: [response_commit, response_exception] - response_commit: [] - request_list_snapshots: [response_list_snapshots, response_exception] - response_list_snapshots: [] - request_offer_snapshot: [response_offer_snapshot, response_exception] - response_offer_snapshot: [] - request_apply_snapshot_chunk: [response_apply_snapshot_chunk, response_exception] - response_apply_snapshot_chunk: [] - request_load_snapshot_chunk: [response_load_snapshot_chunk, response_exception] - response_load_snapshot_chunk: [] - dummy: [] -termination: - - response_exception - - response_echo - - response_flush - - response_info - - response_set_option - - response_init_chain - - response_query - - response_begin_block - - response_check_tx - - response_deliver_tx - - response_end_block - - response_commit - - response_list_snapshots - - response_offer_snapshot - - response_apply_snapshot_chunk - - response_load_snapshot_chunk - - dummy -roles: {client, server} -end_states: [successful] -keep_terminal_state_dialogues: false -... -``` - -## Links - -* HTTP Specification diff --git a/trader_backup/vendor/valory/protocols/abci/__init__.py b/trader_backup/vendor/valory/protocols/abci/__init__.py deleted file mode 100644 index 79b88d47f..000000000 --- a/trader_backup/vendor/valory/protocols/abci/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the abci protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.abci.message import AbciMessage -from packages.valory.protocols.abci.serialization import AbciSerializer - - -AbciMessage.serializer = AbciSerializer diff --git a/trader_backup/vendor/valory/protocols/abci/abci.proto b/trader_backup/vendor/valory/protocols/abci/abci.proto deleted file mode 100644 index aa5f82878..000000000 --- a/trader_backup/vendor/valory/protocols/abci/abci.proto +++ /dev/null @@ -1,407 +0,0 @@ -syntax = "proto3"; - -package aea.valory.abci.v0_1_0; - -message AbciMessage{ - - // Custom Types - message CheckTxType{ - enum _CheckTxType { - NEW = 0; - RECHECK = 1; - } - _CheckTxType type = 1; - } - - message ConsensusParams{ - message Duration { - int64 seconds = 1; - int32 nanos = 2; - } - message BlockParams { - int64 max_bytes = 1; - int64 max_gas = 2; - } - message EvidenceParams { - int64 max_age_num_blocks = 1; - Duration max_age_duration = 2; - int64 max_bytes = 3; - } - message ValidatorParams { - repeated string pub_key_types = 1; - } - message VersionParams { - uint64 app_version = 1; - } - BlockParams block = 1; - EvidenceParams evidence = 2; - ValidatorParams validator = 3; - VersionParams version = 4; - } - - message Events{ - message EventAttribute { - bytes key = 1; - bytes value = 2; - bool index = 3; // nondeterministic - } - message Event { - string type = 1; - repeated EventAttribute attributes = 2; - } - repeated Event events = 1; - } - - message Evidences{ - message Evidence { - enum EvidenceType { - UNKNOWN = 0; - DUPLICATE_VOTE = 1; - LIGHT_CLIENT_ATTACK = 2; - } - EvidenceType type = 1; - // The offending validator - LastCommitInfo.Validator validator = 2; - // The height when the offense occurred - int64 height = 3; - // The corresponding time where the offense occurred - Timestamp time = 4; - // Total voting power of the validator set in case the ABCI application does - // not store historical validators. - // https://github.com/tendermint/tendermint/issues/4581 - int64 total_voting_power = 5; - } - repeated Evidence byzantine_validators = 1; - } - - message Header{ - message ConsensusVersion { - uint64 block = 1; - uint64 app = 2; - } - message BlockID { - bytes hash = 1; - PartSetHeader part_set_header = 2; - } - message PartSetHeader { - uint32 total = 1; - bytes hash = 2; - } - ConsensusVersion version = 1; - string chain_id = 2; - int64 height = 3; - Timestamp time = 4; - - // prev block info - BlockID last_block_id = 5; - - // hashes of block data - bytes last_commit_hash = 6; // commit from validators from the last block - bytes data_hash = 7; // transactions - - // hashes from the app output from the prev block - bytes validators_hash = 8; // validators for the current block - bytes next_validators_hash = 9; // validators for the next block - bytes consensus_hash = 10; // consensus params for current block - bytes app_hash = 11; // state after txs from the previous block - bytes last_results_hash = 12; // root hash of all results from the txs from the previous block - - // consensus info - bytes evidence_hash = 13; // evidence included in the block - bytes proposer_address = 14; // original proposer of the block - } - - message LastCommitInfo{ - message Validator { - bytes address = 1; // The first 20 bytes of SHA256(public key) - // PubKey pub_key = 2 [(gogoproto.nullable)=false]; - int64 power = 3; // The voting power - } - message VoteInfo { - Validator validator = 1; - bool signed_last_block = 2; - } - int32 round = 1; - repeated VoteInfo votes = 2; - } - - message ProofOps{ - message ProofOp { - string type = 1; - bytes key = 2; - bytes data = 3; - } - repeated ProofOp ops = 1; - } - - message Result{ - enum ResultType { - UNKNOWN = 0; // Unknown result, abort all snapshot restoration - ACCEPT = 1; // Snapshot accepted, apply chunks - ABORT = 2; // Abort all snapshot restoration - REJECT = 3; // Reject this specific snapshot, try others - REJECT_FORMAT = 4; // Reject all snapshots of this format, try others - REJECT_SENDER = 5; // Reject all snapshots from the sender(s), try others - } - ResultType result_type = 1; - } - - message SnapShots{ - repeated Snapshot snapshots = 1; - } - - message Snapshot{ - // State Sync Types - uint64 height = 1; // The height at which the snapshot was taken - uint32 format = 2; // The application-specific snapshot format - uint32 chunks = 3; // Number of chunks in the snapshot - bytes hash = 4; // Arbitrary snapshot hash, equal only if identical - bytes metadata = 5; // Arbitrary application metadata - } - - message Timestamp{ - // Represents seconds of UTC time since Unix epoch - // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - // 9999-12-31T23:59:59Z inclusive. - int64 seconds = 1; - // Non-negative fractions of a second at nanosecond resolution. Negative - // second values with fractions must still have non-negative nanos values - // that count forward in time. Must be from 0 to 999,999,999 - // inclusive. - int32 nanos = 2; - } - - message ValidatorUpdates{ - message PublicKey { - oneof sum { - bytes ed25519 = 1; - bytes secp256k1 = 2; - } - } - message ValidatorUpdate { - PublicKey pub_key = 1; - int64 power = 2; - } - repeated ValidatorUpdate validators = 1; - } - - - // Performatives and contents - message Request_Echo_Performative{ - string message = 1; - } - - message Request_Flush_Performative{ - } - - message Request_Info_Performative{ - string version = 1; - int32 block_version = 2; - int32 p2p_version = 3; - } - - message Request_Set_Option_Performative{ - string option_key = 1; - string option_value = 2; - } - - message Request_Init_Chain_Performative{ - Timestamp time = 1; - string chain_id = 2; - ConsensusParams consensus_params = 3; - bool consensus_params_is_set = 4; - ValidatorUpdates validators = 5; - bytes app_state_bytes = 6; - int32 initial_height = 7; - } - - message Request_Query_Performative{ - bytes query_data = 1; - string path = 2; - int32 height = 3; - bool prove = 4; - } - - message Request_Begin_Block_Performative{ - bytes hash = 1; - Header header = 2; - LastCommitInfo last_commit_info = 3; - Evidences byzantine_validators = 4; - } - - message Request_Check_Tx_Performative{ - bytes tx = 1; - CheckTxType type = 2; - } - - message Request_Deliver_Tx_Performative{ - bytes tx = 1; - } - - message Request_End_Block_Performative{ - int32 height = 1; - } - - message Request_Commit_Performative{ - } - - message Request_List_Snapshots_Performative{ - } - - message Request_Offer_Snapshot_Performative{ - Snapshot snapshot = 1; - bytes app_hash = 2; - } - - message Request_Load_Snapshot_Chunk_Performative{ - int32 height = 1; - int32 format = 2; - int32 chunk_index = 3; - } - - message Request_Apply_Snapshot_Chunk_Performative{ - int32 index = 1; - bytes chunk = 2; - string chunk_sender = 3; - } - - message Response_Exception_Performative{ - string error = 1; - } - - message Response_Echo_Performative{ - string message = 1; - } - - message Response_Flush_Performative{ - } - - message Response_Info_Performative{ - string info_data = 1; - string version = 2; - int32 app_version = 3; - int32 last_block_height = 4; - bytes last_block_app_hash = 5; - } - - message Response_Set_Option_Performative{ - int32 code = 1; - string log = 2; - string info = 3; - } - - message Response_Init_Chain_Performative{ - ConsensusParams consensus_params = 1; - bool consensus_params_is_set = 2; - ValidatorUpdates validators = 3; - bytes app_hash = 4; - } - - message Response_Query_Performative{ - int32 code = 1; - string log = 2; - string info = 3; - int32 index = 4; - bytes key = 5; - bytes value = 6; - ProofOps proof_ops = 7; - int32 height = 8; - string codespace = 9; - } - - message Response_Begin_Block_Performative{ - Events events = 1; - } - - message Response_Check_Tx_Performative{ - int32 code = 1; - bytes data = 2; - string log = 3; - string info = 4; - int32 gas_wanted = 5; - int32 gas_used = 6; - Events events = 7; - string codespace = 8; - } - - message Response_Deliver_Tx_Performative{ - int32 code = 1; - bytes data = 2; - string log = 3; - string info = 4; - int32 gas_wanted = 5; - int32 gas_used = 6; - Events events = 7; - string codespace = 8; - } - - message Response_End_Block_Performative{ - ValidatorUpdates validator_updates = 1; - ConsensusParams consensus_param_updates = 2; - bool consensus_param_updates_is_set = 3; - Events events = 4; - } - - message Response_Commit_Performative{ - bytes data = 1; - int32 retain_height = 2; - } - - message Response_List_Snapshots_Performative{ - SnapShots snapshots = 1; - } - - message Response_Offer_Snapshot_Performative{ - Result result = 1; - } - - message Response_Load_Snapshot_Chunk_Performative{ - bytes chunk = 1; - } - - message Response_Apply_Snapshot_Chunk_Performative{ - Result result = 1; - repeated int32 refetch_chunks = 2; - repeated string reject_senders = 3; - } - - message Dummy_Performative{ - ConsensusParams dummy_consensus_params = 1; - } - - - oneof performative{ - Dummy_Performative dummy = 5; - Request_Apply_Snapshot_Chunk_Performative request_apply_snapshot_chunk = 6; - Request_Begin_Block_Performative request_begin_block = 7; - Request_Check_Tx_Performative request_check_tx = 8; - Request_Commit_Performative request_commit = 9; - Request_Deliver_Tx_Performative request_deliver_tx = 10; - Request_Echo_Performative request_echo = 11; - Request_End_Block_Performative request_end_block = 12; - Request_Flush_Performative request_flush = 13; - Request_Info_Performative request_info = 14; - Request_Init_Chain_Performative request_init_chain = 15; - Request_List_Snapshots_Performative request_list_snapshots = 16; - Request_Load_Snapshot_Chunk_Performative request_load_snapshot_chunk = 17; - Request_Offer_Snapshot_Performative request_offer_snapshot = 18; - Request_Query_Performative request_query = 19; - Request_Set_Option_Performative request_set_option = 20; - Response_Apply_Snapshot_Chunk_Performative response_apply_snapshot_chunk = 21; - Response_Begin_Block_Performative response_begin_block = 22; - Response_Check_Tx_Performative response_check_tx = 23; - Response_Commit_Performative response_commit = 24; - Response_Deliver_Tx_Performative response_deliver_tx = 25; - Response_Echo_Performative response_echo = 26; - Response_End_Block_Performative response_end_block = 27; - Response_Exception_Performative response_exception = 28; - Response_Flush_Performative response_flush = 29; - Response_Info_Performative response_info = 30; - Response_Init_Chain_Performative response_init_chain = 31; - Response_List_Snapshots_Performative response_list_snapshots = 32; - Response_Load_Snapshot_Chunk_Performative response_load_snapshot_chunk = 33; - Response_Offer_Snapshot_Performative response_offer_snapshot = 34; - Response_Query_Performative response_query = 35; - Response_Set_Option_Performative response_set_option = 36; - } -} diff --git a/trader_backup/vendor/valory/protocols/abci/abci_pb2.py b/trader_backup/vendor/valory/protocols/abci/abci_pb2.py deleted file mode 100644 index b1454d434..000000000 --- a/trader_backup/vendor/valory/protocols/abci/abci_pb2.py +++ /dev/null @@ -1,177 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: abci.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\nabci.proto\x12\x16\x61\x65\x61.valory.abci.v0_1_0"\x86P\n\x0b\x41\x62\x63iMessage\x12G\n\x05\x64ummy\x18\x05 \x01(\x0b\x32\x36.aea.valory.abci.v0_1_0.AbciMessage.Dummy_PerformativeH\x00\x12u\n\x1crequest_apply_snapshot_chunk\x18\x06 \x01(\x0b\x32M.aea.valory.abci.v0_1_0.AbciMessage.Request_Apply_Snapshot_Chunk_PerformativeH\x00\x12\x63\n\x13request_begin_block\x18\x07 \x01(\x0b\x32\x44.aea.valory.abci.v0_1_0.AbciMessage.Request_Begin_Block_PerformativeH\x00\x12]\n\x10request_check_tx\x18\x08 \x01(\x0b\x32\x41.aea.valory.abci.v0_1_0.AbciMessage.Request_Check_Tx_PerformativeH\x00\x12Y\n\x0erequest_commit\x18\t \x01(\x0b\x32?.aea.valory.abci.v0_1_0.AbciMessage.Request_Commit_PerformativeH\x00\x12\x61\n\x12request_deliver_tx\x18\n \x01(\x0b\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.Request_Deliver_Tx_PerformativeH\x00\x12U\n\x0crequest_echo\x18\x0b \x01(\x0b\x32=.aea.valory.abci.v0_1_0.AbciMessage.Request_Echo_PerformativeH\x00\x12_\n\x11request_end_block\x18\x0c \x01(\x0b\x32\x42.aea.valory.abci.v0_1_0.AbciMessage.Request_End_Block_PerformativeH\x00\x12W\n\rrequest_flush\x18\r \x01(\x0b\x32>.aea.valory.abci.v0_1_0.AbciMessage.Request_Flush_PerformativeH\x00\x12U\n\x0crequest_info\x18\x0e \x01(\x0b\x32=.aea.valory.abci.v0_1_0.AbciMessage.Request_Info_PerformativeH\x00\x12\x61\n\x12request_init_chain\x18\x0f \x01(\x0b\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.Request_Init_Chain_PerformativeH\x00\x12i\n\x16request_list_snapshots\x18\x10 \x01(\x0b\x32G.aea.valory.abci.v0_1_0.AbciMessage.Request_List_Snapshots_PerformativeH\x00\x12s\n\x1brequest_load_snapshot_chunk\x18\x11 \x01(\x0b\x32L.aea.valory.abci.v0_1_0.AbciMessage.Request_Load_Snapshot_Chunk_PerformativeH\x00\x12i\n\x16request_offer_snapshot\x18\x12 \x01(\x0b\x32G.aea.valory.abci.v0_1_0.AbciMessage.Request_Offer_Snapshot_PerformativeH\x00\x12W\n\rrequest_query\x18\x13 \x01(\x0b\x32>.aea.valory.abci.v0_1_0.AbciMessage.Request_Query_PerformativeH\x00\x12\x61\n\x12request_set_option\x18\x14 \x01(\x0b\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.Request_Set_Option_PerformativeH\x00\x12w\n\x1dresponse_apply_snapshot_chunk\x18\x15 \x01(\x0b\x32N.aea.valory.abci.v0_1_0.AbciMessage.Response_Apply_Snapshot_Chunk_PerformativeH\x00\x12\x65\n\x14response_begin_block\x18\x16 \x01(\x0b\x32\x45.aea.valory.abci.v0_1_0.AbciMessage.Response_Begin_Block_PerformativeH\x00\x12_\n\x11response_check_tx\x18\x17 \x01(\x0b\x32\x42.aea.valory.abci.v0_1_0.AbciMessage.Response_Check_Tx_PerformativeH\x00\x12[\n\x0fresponse_commit\x18\x18 \x01(\x0b\x32@.aea.valory.abci.v0_1_0.AbciMessage.Response_Commit_PerformativeH\x00\x12\x63\n\x13response_deliver_tx\x18\x19 \x01(\x0b\x32\x44.aea.valory.abci.v0_1_0.AbciMessage.Response_Deliver_Tx_PerformativeH\x00\x12W\n\rresponse_echo\x18\x1a \x01(\x0b\x32>.aea.valory.abci.v0_1_0.AbciMessage.Response_Echo_PerformativeH\x00\x12\x61\n\x12response_end_block\x18\x1b \x01(\x0b\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.Response_End_Block_PerformativeH\x00\x12\x61\n\x12response_exception\x18\x1c \x01(\x0b\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.Response_Exception_PerformativeH\x00\x12Y\n\x0eresponse_flush\x18\x1d \x01(\x0b\x32?.aea.valory.abci.v0_1_0.AbciMessage.Response_Flush_PerformativeH\x00\x12W\n\rresponse_info\x18\x1e \x01(\x0b\x32>.aea.valory.abci.v0_1_0.AbciMessage.Response_Info_PerformativeH\x00\x12\x63\n\x13response_init_chain\x18\x1f \x01(\x0b\x32\x44.aea.valory.abci.v0_1_0.AbciMessage.Response_Init_Chain_PerformativeH\x00\x12k\n\x17response_list_snapshots\x18 \x01(\x0b\x32H.aea.valory.abci.v0_1_0.AbciMessage.Response_List_Snapshots_PerformativeH\x00\x12u\n\x1cresponse_load_snapshot_chunk\x18! \x01(\x0b\x32M.aea.valory.abci.v0_1_0.AbciMessage.Response_Load_Snapshot_Chunk_PerformativeH\x00\x12k\n\x17response_offer_snapshot\x18" \x01(\x0b\x32H.aea.valory.abci.v0_1_0.AbciMessage.Response_Offer_Snapshot_PerformativeH\x00\x12Y\n\x0eresponse_query\x18# \x01(\x0b\x32?.aea.valory.abci.v0_1_0.AbciMessage.Response_Query_PerformativeH\x00\x12\x63\n\x13response_set_option\x18$ \x01(\x0b\x32\x44.aea.valory.abci.v0_1_0.AbciMessage.Response_Set_Option_PerformativeH\x00\x1a\x7f\n\x0b\x43heckTxType\x12J\n\x04type\x18\x01 \x01(\x0e\x32<.aea.valory.abci.v0_1_0.AbciMessage.CheckTxType._CheckTxType"$\n\x0c_CheckTxType\x12\x07\n\x03NEW\x10\x00\x12\x0b\n\x07RECHECK\x10\x01\x1a\xac\x05\n\x0f\x43onsensusParams\x12N\n\x05\x62lock\x18\x01 \x01(\x0b\x32?.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams.BlockParams\x12T\n\x08\x65vidence\x18\x02 \x01(\x0b\x32\x42.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams.EvidenceParams\x12V\n\tvalidator\x18\x03 \x01(\x0b\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams.ValidatorParams\x12R\n\x07version\x18\x04 \x01(\x0b\x32\x41.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams.VersionParams\x1a*\n\x08\x44uration\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x1a\x31\n\x0b\x42lockParams\x12\x11\n\tmax_bytes\x18\x01 \x01(\x03\x12\x0f\n\x07max_gas\x18\x02 \x01(\x03\x1a\x97\x01\n\x0e\x45videnceParams\x12\x1a\n\x12max_age_num_blocks\x18\x01 \x01(\x03\x12V\n\x10max_age_duration\x18\x02 \x01(\x0b\x32<.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams.Duration\x12\x11\n\tmax_bytes\x18\x03 \x01(\x03\x1a(\n\x0fValidatorParams\x12\x15\n\rpub_key_types\x18\x01 \x03(\t\x1a$\n\rVersionParams\x12\x13\n\x0b\x61pp_version\x18\x01 \x01(\x04\x1a\xed\x01\n\x06\x45vents\x12@\n\x06\x65vents\x18\x01 \x03(\x0b\x32\x30.aea.valory.abci.v0_1_0.AbciMessage.Events.Event\x1a;\n\x0e\x45ventAttribute\x12\x0b\n\x03key\x18\x01 \x01(\x0c\x12\r\n\x05value\x18\x02 \x01(\x0c\x12\r\n\x05index\x18\x03 \x01(\x08\x1a\x64\n\x05\x45vent\x12\x0c\n\x04type\x18\x01 \x01(\t\x12M\n\nattributes\x18\x02 \x03(\x0b\x32\x39.aea.valory.abci.v0_1_0.AbciMessage.Events.EventAttribute\x1a\xc5\x03\n\tEvidences\x12T\n\x14\x62yzantine_validators\x18\x01 \x03(\x0b\x32\x36.aea.valory.abci.v0_1_0.AbciMessage.Evidences.Evidence\x1a\xe1\x02\n\x08\x45vidence\x12Q\n\x04type\x18\x01 \x01(\x0e\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.Evidences.Evidence.EvidenceType\x12O\n\tvalidator\x18\x02 \x01(\x0b\x32<.aea.valory.abci.v0_1_0.AbciMessage.LastCommitInfo.Validator\x12\x0e\n\x06height\x18\x03 \x01(\x03\x12;\n\x04time\x18\x04 \x01(\x0b\x32-.aea.valory.abci.v0_1_0.AbciMessage.Timestamp\x12\x1a\n\x12total_voting_power\x18\x05 \x01(\x03"H\n\x0c\x45videnceType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x12\n\x0e\x44UPLICATE_VOTE\x10\x01\x12\x17\n\x13LIGHT_CLIENT_ATTACK\x10\x02\x1a\xa4\x05\n\x06Header\x12L\n\x07version\x18\x01 \x01(\x0b\x32;.aea.valory.abci.v0_1_0.AbciMessage.Header.ConsensusVersion\x12\x10\n\x08\x63hain_id\x18\x02 \x01(\t\x12\x0e\n\x06height\x18\x03 \x01(\x03\x12;\n\x04time\x18\x04 \x01(\x0b\x32-.aea.valory.abci.v0_1_0.AbciMessage.Timestamp\x12I\n\rlast_block_id\x18\x05 \x01(\x0b\x32\x32.aea.valory.abci.v0_1_0.AbciMessage.Header.BlockID\x12\x18\n\x10last_commit_hash\x18\x06 \x01(\x0c\x12\x11\n\tdata_hash\x18\x07 \x01(\x0c\x12\x17\n\x0fvalidators_hash\x18\x08 \x01(\x0c\x12\x1c\n\x14next_validators_hash\x18\t \x01(\x0c\x12\x16\n\x0e\x63onsensus_hash\x18\n \x01(\x0c\x12\x10\n\x08\x61pp_hash\x18\x0b \x01(\x0c\x12\x19\n\x11last_results_hash\x18\x0c \x01(\x0c\x12\x15\n\revidence_hash\x18\r \x01(\x0c\x12\x18\n\x10proposer_address\x18\x0e \x01(\x0c\x1a.\n\x10\x43onsensusVersion\x12\r\n\x05\x62lock\x18\x01 \x01(\x04\x12\x0b\n\x03\x61pp\x18\x02 \x01(\x04\x1aj\n\x07\x42lockID\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12Q\n\x0fpart_set_header\x18\x02 \x01(\x0b\x32\x38.aea.valory.abci.v0_1_0.AbciMessage.Header.PartSetHeader\x1a,\n\rPartSetHeader\x12\r\n\x05total\x18\x01 \x01(\r\x12\x0c\n\x04hash\x18\x02 \x01(\x0c\x1a\x90\x02\n\x0eLastCommitInfo\x12\r\n\x05round\x18\x01 \x01(\x05\x12J\n\x05votes\x18\x02 \x03(\x0b\x32;.aea.valory.abci.v0_1_0.AbciMessage.LastCommitInfo.VoteInfo\x1a+\n\tValidator\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0c\x12\r\n\x05power\x18\x03 \x01(\x03\x1av\n\x08VoteInfo\x12O\n\tvalidator\x18\x01 \x01(\x0b\x32<.aea.valory.abci.v0_1_0.AbciMessage.LastCommitInfo.Validator\x12\x19\n\x11signed_last_block\x18\x02 \x01(\x08\x1a\x81\x01\n\x08ProofOps\x12\x41\n\x03ops\x18\x01 \x03(\x0b\x32\x34.aea.valory.abci.v0_1_0.AbciMessage.ProofOps.ProofOp\x1a\x32\n\x07ProofOp\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\x1a\xb8\x01\n\x06Result\x12J\n\x0bresult_type\x18\x01 \x01(\x0e\x32\x35.aea.valory.abci.v0_1_0.AbciMessage.Result.ResultType"b\n\nResultType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x41\x43\x43\x45PT\x10\x01\x12\t\n\x05\x41\x42ORT\x10\x02\x12\n\n\x06REJECT\x10\x03\x12\x11\n\rREJECT_FORMAT\x10\x04\x12\x11\n\rREJECT_SENDER\x10\x05\x1aL\n\tSnapShots\x12?\n\tsnapshots\x18\x01 \x03(\x0b\x32,.aea.valory.abci.v0_1_0.AbciMessage.Snapshot\x1aZ\n\x08Snapshot\x12\x0e\n\x06height\x18\x01 \x01(\x04\x12\x0e\n\x06\x66ormat\x18\x02 \x01(\r\x12\x0e\n\x06\x63hunks\x18\x03 \x01(\r\x12\x0c\n\x04hash\x18\x04 \x01(\x0c\x12\x10\n\x08metadata\x18\x05 \x01(\x0c\x1a+\n\tTimestamp\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x1a\x9b\x02\n\x10ValidatorUpdates\x12X\n\nvalidators\x18\x01 \x03(\x0b\x32\x44.aea.valory.abci.v0_1_0.AbciMessage.ValidatorUpdates.ValidatorUpdate\x1a:\n\tPublicKey\x12\x11\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x01 \x01(\x0cH\x00\x12\x13\n\tsecp256k1\x18\x02 \x01(\x0cH\x00\x42\x05\n\x03sum\x1aq\n\x0fValidatorUpdate\x12O\n\x07pub_key\x18\x01 \x01(\x0b\x32>.aea.valory.abci.v0_1_0.AbciMessage.ValidatorUpdates.PublicKey\x12\r\n\x05power\x18\x02 \x01(\x03\x1a,\n\x19Request_Echo_Performative\x12\x0f\n\x07message\x18\x01 \x01(\t\x1a\x1c\n\x1aRequest_Flush_Performative\x1aX\n\x19Request_Info_Performative\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x15\n\rblock_version\x18\x02 \x01(\x05\x12\x13\n\x0bp2p_version\x18\x03 \x01(\x05\x1aK\n\x1fRequest_Set_Option_Performative\x12\x12\n\noption_key\x18\x01 \x01(\t\x12\x14\n\x0coption_value\x18\x02 \x01(\t\x1a\xdb\x02\n\x1fRequest_Init_Chain_Performative\x12;\n\x04time\x18\x01 \x01(\x0b\x32-.aea.valory.abci.v0_1_0.AbciMessage.Timestamp\x12\x10\n\x08\x63hain_id\x18\x02 \x01(\t\x12M\n\x10\x63onsensus_params\x18\x03 \x01(\x0b\x32\x33.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams\x12\x1f\n\x17\x63onsensus_params_is_set\x18\x04 \x01(\x08\x12H\n\nvalidators\x18\x05 \x01(\x0b\x32\x34.aea.valory.abci.v0_1_0.AbciMessage.ValidatorUpdates\x12\x17\n\x0f\x61pp_state_bytes\x18\x06 \x01(\x0c\x12\x16\n\x0einitial_height\x18\x07 \x01(\x05\x1a]\n\x1aRequest_Query_Performative\x12\x12\n\nquery_data\x18\x01 \x01(\x0c\x12\x0c\n\x04path\x18\x02 \x01(\t\x12\x0e\n\x06height\x18\x03 \x01(\x05\x12\r\n\x05prove\x18\x04 \x01(\x08\x1a\x87\x02\n Request_Begin_Block_Performative\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12:\n\x06header\x18\x02 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Header\x12L\n\x10last_commit_info\x18\x03 \x01(\x0b\x32\x32.aea.valory.abci.v0_1_0.AbciMessage.LastCommitInfo\x12K\n\x14\x62yzantine_validators\x18\x04 \x01(\x0b\x32-.aea.valory.abci.v0_1_0.AbciMessage.Evidences\x1aj\n\x1dRequest_Check_Tx_Performative\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12=\n\x04type\x18\x02 \x01(\x0b\x32/.aea.valory.abci.v0_1_0.AbciMessage.CheckTxType\x1a-\n\x1fRequest_Deliver_Tx_Performative\x12\n\n\x02tx\x18\x01 \x01(\x0c\x1a\x30\n\x1eRequest_End_Block_Performative\x12\x0e\n\x06height\x18\x01 \x01(\x05\x1a\x1d\n\x1bRequest_Commit_Performative\x1a%\n#Request_List_Snapshots_Performative\x1aw\n#Request_Offer_Snapshot_Performative\x12>\n\x08snapshot\x18\x01 \x01(\x0b\x32,.aea.valory.abci.v0_1_0.AbciMessage.Snapshot\x12\x10\n\x08\x61pp_hash\x18\x02 \x01(\x0c\x1a_\n(Request_Load_Snapshot_Chunk_Performative\x12\x0e\n\x06height\x18\x01 \x01(\x05\x12\x0e\n\x06\x66ormat\x18\x02 \x01(\x05\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\x05\x1a_\n)Request_Apply_Snapshot_Chunk_Performative\x12\r\n\x05index\x18\x01 \x01(\x05\x12\r\n\x05\x63hunk\x18\x02 \x01(\x0c\x12\x14\n\x0c\x63hunk_sender\x18\x03 \x01(\t\x1a\x30\n\x1fResponse_Exception_Performative\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x1a-\n\x1aResponse_Echo_Performative\x12\x0f\n\x07message\x18\x01 \x01(\t\x1a\x1d\n\x1bResponse_Flush_Performative\x1a\x8d\x01\n\x1aResponse_Info_Performative\x12\x11\n\tinfo_data\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12\x13\n\x0b\x61pp_version\x18\x03 \x01(\x05\x12\x19\n\x11last_block_height\x18\x04 \x01(\x05\x12\x1b\n\x13last_block_app_hash\x18\x05 \x01(\x0c\x1aK\n Response_Set_Option_Performative\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0b\n\x03log\x18\x02 \x01(\t\x12\x0c\n\x04info\x18\x03 \x01(\t\x1a\xee\x01\n Response_Init_Chain_Performative\x12M\n\x10\x63onsensus_params\x18\x01 \x01(\x0b\x32\x33.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams\x12\x1f\n\x17\x63onsensus_params_is_set\x18\x02 \x01(\x08\x12H\n\nvalidators\x18\x03 \x01(\x0b\x32\x34.aea.valory.abci.v0_1_0.AbciMessage.ValidatorUpdates\x12\x10\n\x08\x61pp_hash\x18\x04 \x01(\x0c\x1a\xd5\x01\n\x1bResponse_Query_Performative\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0b\n\x03log\x18\x02 \x01(\t\x12\x0c\n\x04info\x18\x03 \x01(\t\x12\r\n\x05index\x18\x04 \x01(\x05\x12\x0b\n\x03key\x18\x05 \x01(\x0c\x12\r\n\x05value\x18\x06 \x01(\x0c\x12?\n\tproof_ops\x18\x07 \x01(\x0b\x32,.aea.valory.abci.v0_1_0.AbciMessage.ProofOps\x12\x0e\n\x06height\x18\x08 \x01(\x05\x12\x11\n\tcodespace\x18\t \x01(\t\x1a_\n!Response_Begin_Block_Performative\x12:\n\x06\x65vents\x18\x01 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Events\x1a\xcc\x01\n\x1eResponse_Check_Tx_Performative\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x0b\n\x03log\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t\x12\x12\n\ngas_wanted\x18\x05 \x01(\x05\x12\x10\n\x08gas_used\x18\x06 \x01(\x05\x12:\n\x06\x65vents\x18\x07 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Events\x12\x11\n\tcodespace\x18\x08 \x01(\t\x1a\xce\x01\n Response_Deliver_Tx_Performative\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x0b\n\x03log\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t\x12\x12\n\ngas_wanted\x18\x05 \x01(\x05\x12\x10\n\x08gas_used\x18\x06 \x01(\x05\x12:\n\x06\x65vents\x18\x07 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Events\x12\x11\n\tcodespace\x18\x08 \x01(\t\x1a\xac\x02\n\x1fResponse_End_Block_Performative\x12O\n\x11validator_updates\x18\x01 \x01(\x0b\x32\x34.aea.valory.abci.v0_1_0.AbciMessage.ValidatorUpdates\x12T\n\x17\x63onsensus_param_updates\x18\x02 \x01(\x0b\x32\x33.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams\x12&\n\x1e\x63onsensus_param_updates_is_set\x18\x03 \x01(\x08\x12:\n\x06\x65vents\x18\x04 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Events\x1a\x43\n\x1cResponse_Commit_Performative\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x12\x15\n\rretain_height\x18\x02 \x01(\x05\x1ah\n$Response_List_Snapshots_Performative\x12@\n\tsnapshots\x18\x01 \x01(\x0b\x32-.aea.valory.abci.v0_1_0.AbciMessage.SnapShots\x1a\x62\n$Response_Offer_Snapshot_Performative\x12:\n\x06result\x18\x01 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Result\x1a:\n)Response_Load_Snapshot_Chunk_Performative\x12\r\n\x05\x63hunk\x18\x01 \x01(\x0c\x1a\x98\x01\n*Response_Apply_Snapshot_Chunk_Performative\x12:\n\x06result\x18\x01 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Result\x12\x16\n\x0erefetch_chunks\x18\x02 \x03(\x05\x12\x16\n\x0ereject_senders\x18\x03 \x03(\t\x1ai\n\x12\x44ummy_Performative\x12S\n\x16\x64ummy_consensus_params\x18\x01 \x01(\x0b\x32\x33.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParamsB\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "abci_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals["_ABCIMESSAGE"]._serialized_start = 39 - _globals["_ABCIMESSAGE"]._serialized_end = 10285 - _globals["_ABCIMESSAGE_CHECKTXTYPE"]._serialized_start = 3222 - _globals["_ABCIMESSAGE_CHECKTXTYPE"]._serialized_end = 3349 - _globals["_ABCIMESSAGE_CHECKTXTYPE__CHECKTXTYPE"]._serialized_start = 3313 - _globals["_ABCIMESSAGE_CHECKTXTYPE__CHECKTXTYPE"]._serialized_end = 3349 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS"]._serialized_start = 3352 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS"]._serialized_end = 4036 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_DURATION"]._serialized_start = 3709 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_DURATION"]._serialized_end = 3751 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_BLOCKPARAMS"]._serialized_start = 3753 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_BLOCKPARAMS"]._serialized_end = 3802 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_EVIDENCEPARAMS"]._serialized_start = 3805 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_EVIDENCEPARAMS"]._serialized_end = 3956 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_VALIDATORPARAMS"]._serialized_start = 3958 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_VALIDATORPARAMS"]._serialized_end = 3998 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_VERSIONPARAMS"]._serialized_start = 4000 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_VERSIONPARAMS"]._serialized_end = 4036 - _globals["_ABCIMESSAGE_EVENTS"]._serialized_start = 4039 - _globals["_ABCIMESSAGE_EVENTS"]._serialized_end = 4276 - _globals["_ABCIMESSAGE_EVENTS_EVENTATTRIBUTE"]._serialized_start = 4115 - _globals["_ABCIMESSAGE_EVENTS_EVENTATTRIBUTE"]._serialized_end = 4174 - _globals["_ABCIMESSAGE_EVENTS_EVENT"]._serialized_start = 4176 - _globals["_ABCIMESSAGE_EVENTS_EVENT"]._serialized_end = 4276 - _globals["_ABCIMESSAGE_EVIDENCES"]._serialized_start = 4279 - _globals["_ABCIMESSAGE_EVIDENCES"]._serialized_end = 4732 - _globals["_ABCIMESSAGE_EVIDENCES_EVIDENCE"]._serialized_start = 4379 - _globals["_ABCIMESSAGE_EVIDENCES_EVIDENCE"]._serialized_end = 4732 - _globals["_ABCIMESSAGE_EVIDENCES_EVIDENCE_EVIDENCETYPE"]._serialized_start = 4660 - _globals["_ABCIMESSAGE_EVIDENCES_EVIDENCE_EVIDENCETYPE"]._serialized_end = 4732 - _globals["_ABCIMESSAGE_HEADER"]._serialized_start = 4735 - _globals["_ABCIMESSAGE_HEADER"]._serialized_end = 5411 - _globals["_ABCIMESSAGE_HEADER_CONSENSUSVERSION"]._serialized_start = 5211 - _globals["_ABCIMESSAGE_HEADER_CONSENSUSVERSION"]._serialized_end = 5257 - _globals["_ABCIMESSAGE_HEADER_BLOCKID"]._serialized_start = 5259 - _globals["_ABCIMESSAGE_HEADER_BLOCKID"]._serialized_end = 5365 - _globals["_ABCIMESSAGE_HEADER_PARTSETHEADER"]._serialized_start = 5367 - _globals["_ABCIMESSAGE_HEADER_PARTSETHEADER"]._serialized_end = 5411 - _globals["_ABCIMESSAGE_LASTCOMMITINFO"]._serialized_start = 5414 - _globals["_ABCIMESSAGE_LASTCOMMITINFO"]._serialized_end = 5686 - _globals["_ABCIMESSAGE_LASTCOMMITINFO_VALIDATOR"]._serialized_start = 5523 - _globals["_ABCIMESSAGE_LASTCOMMITINFO_VALIDATOR"]._serialized_end = 5566 - _globals["_ABCIMESSAGE_LASTCOMMITINFO_VOTEINFO"]._serialized_start = 5568 - _globals["_ABCIMESSAGE_LASTCOMMITINFO_VOTEINFO"]._serialized_end = 5686 - _globals["_ABCIMESSAGE_PROOFOPS"]._serialized_start = 5689 - _globals["_ABCIMESSAGE_PROOFOPS"]._serialized_end = 5818 - _globals["_ABCIMESSAGE_PROOFOPS_PROOFOP"]._serialized_start = 5768 - _globals["_ABCIMESSAGE_PROOFOPS_PROOFOP"]._serialized_end = 5818 - _globals["_ABCIMESSAGE_RESULT"]._serialized_start = 5821 - _globals["_ABCIMESSAGE_RESULT"]._serialized_end = 6005 - _globals["_ABCIMESSAGE_RESULT_RESULTTYPE"]._serialized_start = 5907 - _globals["_ABCIMESSAGE_RESULT_RESULTTYPE"]._serialized_end = 6005 - _globals["_ABCIMESSAGE_SNAPSHOTS"]._serialized_start = 6007 - _globals["_ABCIMESSAGE_SNAPSHOTS"]._serialized_end = 6083 - _globals["_ABCIMESSAGE_SNAPSHOT"]._serialized_start = 6085 - _globals["_ABCIMESSAGE_SNAPSHOT"]._serialized_end = 6175 - _globals["_ABCIMESSAGE_TIMESTAMP"]._serialized_start = 6177 - _globals["_ABCIMESSAGE_TIMESTAMP"]._serialized_end = 6220 - _globals["_ABCIMESSAGE_VALIDATORUPDATES"]._serialized_start = 6223 - _globals["_ABCIMESSAGE_VALIDATORUPDATES"]._serialized_end = 6506 - _globals["_ABCIMESSAGE_VALIDATORUPDATES_PUBLICKEY"]._serialized_start = 6333 - _globals["_ABCIMESSAGE_VALIDATORUPDATES_PUBLICKEY"]._serialized_end = 6391 - _globals["_ABCIMESSAGE_VALIDATORUPDATES_VALIDATORUPDATE"]._serialized_start = 6393 - _globals["_ABCIMESSAGE_VALIDATORUPDATES_VALIDATORUPDATE"]._serialized_end = 6506 - _globals["_ABCIMESSAGE_REQUEST_ECHO_PERFORMATIVE"]._serialized_start = 6508 - _globals["_ABCIMESSAGE_REQUEST_ECHO_PERFORMATIVE"]._serialized_end = 6552 - _globals["_ABCIMESSAGE_REQUEST_FLUSH_PERFORMATIVE"]._serialized_start = 6554 - _globals["_ABCIMESSAGE_REQUEST_FLUSH_PERFORMATIVE"]._serialized_end = 6582 - _globals["_ABCIMESSAGE_REQUEST_INFO_PERFORMATIVE"]._serialized_start = 6584 - _globals["_ABCIMESSAGE_REQUEST_INFO_PERFORMATIVE"]._serialized_end = 6672 - _globals["_ABCIMESSAGE_REQUEST_SET_OPTION_PERFORMATIVE"]._serialized_start = 6674 - _globals["_ABCIMESSAGE_REQUEST_SET_OPTION_PERFORMATIVE"]._serialized_end = 6749 - _globals["_ABCIMESSAGE_REQUEST_INIT_CHAIN_PERFORMATIVE"]._serialized_start = 6752 - _globals["_ABCIMESSAGE_REQUEST_INIT_CHAIN_PERFORMATIVE"]._serialized_end = 7099 - _globals["_ABCIMESSAGE_REQUEST_QUERY_PERFORMATIVE"]._serialized_start = 7101 - _globals["_ABCIMESSAGE_REQUEST_QUERY_PERFORMATIVE"]._serialized_end = 7194 - _globals["_ABCIMESSAGE_REQUEST_BEGIN_BLOCK_PERFORMATIVE"]._serialized_start = 7197 - _globals["_ABCIMESSAGE_REQUEST_BEGIN_BLOCK_PERFORMATIVE"]._serialized_end = 7460 - _globals["_ABCIMESSAGE_REQUEST_CHECK_TX_PERFORMATIVE"]._serialized_start = 7462 - _globals["_ABCIMESSAGE_REQUEST_CHECK_TX_PERFORMATIVE"]._serialized_end = 7568 - _globals["_ABCIMESSAGE_REQUEST_DELIVER_TX_PERFORMATIVE"]._serialized_start = 7570 - _globals["_ABCIMESSAGE_REQUEST_DELIVER_TX_PERFORMATIVE"]._serialized_end = 7615 - _globals["_ABCIMESSAGE_REQUEST_END_BLOCK_PERFORMATIVE"]._serialized_start = 7617 - _globals["_ABCIMESSAGE_REQUEST_END_BLOCK_PERFORMATIVE"]._serialized_end = 7665 - _globals["_ABCIMESSAGE_REQUEST_COMMIT_PERFORMATIVE"]._serialized_start = 7667 - _globals["_ABCIMESSAGE_REQUEST_COMMIT_PERFORMATIVE"]._serialized_end = 7696 - _globals[ - "_ABCIMESSAGE_REQUEST_LIST_SNAPSHOTS_PERFORMATIVE" - ]._serialized_start = 7698 - _globals["_ABCIMESSAGE_REQUEST_LIST_SNAPSHOTS_PERFORMATIVE"]._serialized_end = 7735 - _globals[ - "_ABCIMESSAGE_REQUEST_OFFER_SNAPSHOT_PERFORMATIVE" - ]._serialized_start = 7737 - _globals["_ABCIMESSAGE_REQUEST_OFFER_SNAPSHOT_PERFORMATIVE"]._serialized_end = 7856 - _globals[ - "_ABCIMESSAGE_REQUEST_LOAD_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_start = 7858 - _globals[ - "_ABCIMESSAGE_REQUEST_LOAD_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_end = 7953 - _globals[ - "_ABCIMESSAGE_REQUEST_APPLY_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_start = 7955 - _globals[ - "_ABCIMESSAGE_REQUEST_APPLY_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_end = 8050 - _globals["_ABCIMESSAGE_RESPONSE_EXCEPTION_PERFORMATIVE"]._serialized_start = 8052 - _globals["_ABCIMESSAGE_RESPONSE_EXCEPTION_PERFORMATIVE"]._serialized_end = 8100 - _globals["_ABCIMESSAGE_RESPONSE_ECHO_PERFORMATIVE"]._serialized_start = 8102 - _globals["_ABCIMESSAGE_RESPONSE_ECHO_PERFORMATIVE"]._serialized_end = 8147 - _globals["_ABCIMESSAGE_RESPONSE_FLUSH_PERFORMATIVE"]._serialized_start = 8149 - _globals["_ABCIMESSAGE_RESPONSE_FLUSH_PERFORMATIVE"]._serialized_end = 8178 - _globals["_ABCIMESSAGE_RESPONSE_INFO_PERFORMATIVE"]._serialized_start = 8181 - _globals["_ABCIMESSAGE_RESPONSE_INFO_PERFORMATIVE"]._serialized_end = 8322 - _globals["_ABCIMESSAGE_RESPONSE_SET_OPTION_PERFORMATIVE"]._serialized_start = 8324 - _globals["_ABCIMESSAGE_RESPONSE_SET_OPTION_PERFORMATIVE"]._serialized_end = 8399 - _globals["_ABCIMESSAGE_RESPONSE_INIT_CHAIN_PERFORMATIVE"]._serialized_start = 8402 - _globals["_ABCIMESSAGE_RESPONSE_INIT_CHAIN_PERFORMATIVE"]._serialized_end = 8640 - _globals["_ABCIMESSAGE_RESPONSE_QUERY_PERFORMATIVE"]._serialized_start = 8643 - _globals["_ABCIMESSAGE_RESPONSE_QUERY_PERFORMATIVE"]._serialized_end = 8856 - _globals["_ABCIMESSAGE_RESPONSE_BEGIN_BLOCK_PERFORMATIVE"]._serialized_start = 8858 - _globals["_ABCIMESSAGE_RESPONSE_BEGIN_BLOCK_PERFORMATIVE"]._serialized_end = 8953 - _globals["_ABCIMESSAGE_RESPONSE_CHECK_TX_PERFORMATIVE"]._serialized_start = 8956 - _globals["_ABCIMESSAGE_RESPONSE_CHECK_TX_PERFORMATIVE"]._serialized_end = 9160 - _globals["_ABCIMESSAGE_RESPONSE_DELIVER_TX_PERFORMATIVE"]._serialized_start = 9163 - _globals["_ABCIMESSAGE_RESPONSE_DELIVER_TX_PERFORMATIVE"]._serialized_end = 9369 - _globals["_ABCIMESSAGE_RESPONSE_END_BLOCK_PERFORMATIVE"]._serialized_start = 9372 - _globals["_ABCIMESSAGE_RESPONSE_END_BLOCK_PERFORMATIVE"]._serialized_end = 9672 - _globals["_ABCIMESSAGE_RESPONSE_COMMIT_PERFORMATIVE"]._serialized_start = 9674 - _globals["_ABCIMESSAGE_RESPONSE_COMMIT_PERFORMATIVE"]._serialized_end = 9741 - _globals[ - "_ABCIMESSAGE_RESPONSE_LIST_SNAPSHOTS_PERFORMATIVE" - ]._serialized_start = 9743 - _globals["_ABCIMESSAGE_RESPONSE_LIST_SNAPSHOTS_PERFORMATIVE"]._serialized_end = 9847 - _globals[ - "_ABCIMESSAGE_RESPONSE_OFFER_SNAPSHOT_PERFORMATIVE" - ]._serialized_start = 9849 - _globals["_ABCIMESSAGE_RESPONSE_OFFER_SNAPSHOT_PERFORMATIVE"]._serialized_end = 9947 - _globals[ - "_ABCIMESSAGE_RESPONSE_LOAD_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_start = 9949 - _globals[ - "_ABCIMESSAGE_RESPONSE_LOAD_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_end = 10007 - _globals[ - "_ABCIMESSAGE_RESPONSE_APPLY_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_start = 10010 - _globals[ - "_ABCIMESSAGE_RESPONSE_APPLY_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_end = 10162 - _globals["_ABCIMESSAGE_DUMMY_PERFORMATIVE"]._serialized_start = 10164 - _globals["_ABCIMESSAGE_DUMMY_PERFORMATIVE"]._serialized_end = 10269 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/protocols/abci/custom_types.py b/trader_backup/vendor/valory/protocols/abci/custom_types.py deleted file mode 100644 index ab07951fb..000000000 --- a/trader_backup/vendor/valory/protocols/abci/custom_types.py +++ /dev/null @@ -1,1622 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021 valory -# -# 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 class representations corresponding to every custom type in the protocol specification.""" -import datetime -from enum import Enum -from typing import List, Optional - -from aea.exceptions import enforce - -from packages.valory.protocols.abci import abci_pb2 - - -class BlockParams: - """This class represents an instance of BlockParams.""" - - __slots__ = ["max_bytes", "max_gas"] - - def __init__(self, max_bytes: int, max_gas: int): - """Initialise an instance of BlockParams.""" - self.max_bytes = max_bytes - self.max_gas = max_gas - - @staticmethod - def encode( - block_params_protobuf_object, block_params_object: "BlockParams" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the block_params_protobuf_object argument is matched with the instance of this class in the 'block_params_object' argument. - - :param block_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param block_params_object: an instance of this class to be encoded in the protocol buffer object. - """ - block_params_protobuf_object.max_bytes = block_params_object.max_bytes - block_params_protobuf_object.max_gas = block_params_object.max_gas - - @classmethod - def decode(cls, block_params_protobuf_object) -> "BlockParams": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'block_params_protobuf_object' argument. - - :param block_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'block_params_protobuf_object' argument. - """ - return BlockParams( - block_params_protobuf_object.max_bytes, block_params_protobuf_object.max_gas - ) - - def __eq__(self, other) -> bool: - """Compare with another object.""" - return ( - isinstance(other, BlockParams) - and self.max_bytes == other.max_bytes - and self.max_gas == other.max_gas - ) - - -class Duration: - """This class represents an instance of Duration.""" - - __slots__ = ["seconds", "nanos"] - - def __init__(self, seconds: int, nanos: int): - """ - Initialise an instance of Duration. - - :param seconds: Signed seconds of the span of time. - Must be from -315,576,000,000 to +315,576,000,000 inclusive. - :param nanos: Signed fractions of a second at nanosecond resolution of the span of time. - Durations less than one second are represented with a 0 seconds field and - a positive or negative nanos field. For durations of one second or more, - a non-zero value for the nanos field must be of the same sign as the seconds field. - Must be from -999,999,999 to +999,999,999 inclusive. - """ - self.seconds = seconds - self.nanos = nanos - - @staticmethod - def encode(duration_protobuf_object, duration_object: "Duration") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the duration_protobuf_object argument is matched with the instance of this class in the 'duration_object' argument. - - :param duration_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param duration_object: an instance of this class to be encoded in the protocol buffer object. - """ - duration_protobuf_object.seconds = duration_object.seconds - duration_protobuf_object.nanos = duration_object.nanos - - @classmethod - def decode(cls, duration_protobuf_object) -> "Duration": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'duration_protobuf_object' argument. - - :param duration_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'duration_protobuf_object' argument. - """ - return Duration( - duration_protobuf_object.seconds, duration_protobuf_object.nanos - ) - - def __eq__(self, other) -> bool: - """Compare with another object.""" - return ( - isinstance(other, Duration) - and self.seconds == other.seconds - and self.nanos == other.nanos - ) - - -class EvidenceParams: - """This class represents an instance of EvidenceParams.""" - - __slots__ = [ - "max_age_num_blocks", - "max_age_duration", - "max_bytes", - ] - - def __init__( - self, max_age_num_blocks: int, max_age_duration: Duration, max_bytes: int - ): - """Initialise an instance of BlockParams.""" - self.max_age_num_blocks = max_age_num_blocks - self.max_age_duration = max_age_duration - self.max_bytes = max_bytes - - @staticmethod - def encode( - evidence_params_protobuf_object, evidence_params_object: "EvidenceParams" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the evidence_params_protobuf_object argument is matched with the instance of this class in the 'evidence_params_object' argument. - - :param evidence_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param evidence_params_object: an instance of this class to be encoded in the protocol buffer object. - """ - evidence_params_protobuf_object.max_age_num_blocks = ( - evidence_params_object.max_age_num_blocks - ) - Duration.encode( - evidence_params_protobuf_object.max_age_duration, - evidence_params_object.max_age_duration, - ) - evidence_params_protobuf_object.max_bytes = evidence_params_object.max_bytes - - @classmethod - def decode(cls, evidence_params_protobuf_object) -> "EvidenceParams": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'evidence_params_protobuf_object' argument. - - :param evidence_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'evidence_params_protobuf_object' argument. - """ - duration = Duration.decode(evidence_params_protobuf_object.max_age_duration) - return EvidenceParams( - evidence_params_protobuf_object.max_age_num_blocks, - duration, - evidence_params_protobuf_object.max_bytes, - ) - - def __eq__(self, other) -> bool: - """Compare with another object.""" - return ( - isinstance(other, EvidenceParams) - and self.max_age_num_blocks == other.max_age_num_blocks - and self.max_age_duration == other.max_age_duration - and self.max_bytes == other.max_bytes - ) - - -class ValidatorParams: - """This class represents an instance of ValidatorParams.""" - - __slots__ = [ - "pub_key_types", - ] - - def __init__(self, pub_key_types: List[str]): - """Initialise an instance of BlockParams.""" - self.pub_key_types = pub_key_types - - @staticmethod - def encode( - validator_params_protobuf_object, validator_params_object: "ValidatorParams" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the validator_params_protobuf_object argument is matched with the instance of this class in the 'validator_params_object' argument. - - :param validator_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param validator_params_object: an instance of this class to be encoded in the protocol buffer object. - """ - validator_params_protobuf_object.pub_key_types.extend( - validator_params_object.pub_key_types - ) - - @classmethod - def decode(cls, validator_params_protobuf_object) -> "ValidatorParams": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'validator_params_protobuf_object' argument. - - :param validator_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'validator_params_protobuf_object' argument. - """ - pub_key_types = list(validator_params_protobuf_object.pub_key_types) - return ValidatorParams( - pub_key_types, - ) - - def __eq__(self, other) -> bool: - """Compare with another object.""" - return ( - isinstance(other, ValidatorParams) - and self.pub_key_types == other.pub_key_types - ) - - -class VersionParams: - """This class represents an instance of VersionParams.""" - - __slots__ = [ - "app_version", - ] - - def __init__(self, app_version: int): - """Initialise an instance of BlockParams.""" - self.app_version = app_version - - @staticmethod - def encode( - version_params_protobuf_object, version_params_object: "VersionParams" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the version_params_protobuf_object argument is matched with the instance of this class in the 'version_params_object' argument. - - :param version_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param version_params_object: an instance of this class to be encoded in the protocol buffer object. - """ - version_params_protobuf_object.app_version = version_params_object.app_version - - @classmethod - def decode(cls, version_params_protobuf_object) -> "VersionParams": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'version_params_protobuf_object' argument. - - :param version_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'version_params_protobuf_object' argument. - """ - app_version = version_params_protobuf_object.app_version - return VersionParams( - app_version, - ) - - def __eq__(self, other) -> bool: - """Compare with another object.""" - return ( - isinstance(other, VersionParams) and self.app_version == other.app_version - ) - - -class ConsensusParams: - """This class represents an instance of ConsensusParams.""" - - def __init__( - self, - block: "BlockParams", - evidence_params: "EvidenceParams", - validator_params: "ValidatorParams", - version_params: "VersionParams", - ): - """Initialise an instance of ConsensusParams.""" - self.block = block - self.evidence_params = evidence_params - self.validator_params = validator_params - self.version_params = version_params - - @staticmethod - def encode( - consensus_params_protobuf_object, - consensus_params_object: Optional["ConsensusParams"], - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the consensus_params_protobuf_object argument is matched with the instance of this class in the 'consensus_params_object' argument. - - :param consensus_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param consensus_params_object: an instance of this class to be encoded in the protocol buffer object. - """ - BlockParams.encode( - consensus_params_protobuf_object.block, consensus_params_object.block - ) - EvidenceParams.encode( - consensus_params_protobuf_object.evidence, - consensus_params_object.evidence_params, - ) - ValidatorParams.encode( - consensus_params_protobuf_object.validator, - consensus_params_object.validator_params, - ) - VersionParams.encode( - consensus_params_protobuf_object.version, - consensus_params_object.version_params, - ) - - @classmethod - def decode(cls, consensus_params_protobuf_object) -> "ConsensusParams": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'consensus_params_protobuf_object' argument. - - :param consensus_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'consensus_params_protobuf_object' argument. - """ - block_params = BlockParams.decode(consensus_params_protobuf_object.block) - evidence_params = EvidenceParams.decode( - consensus_params_protobuf_object.evidence - ) - validator_params = ValidatorParams.decode( - consensus_params_protobuf_object.validator - ) - version_params = VersionParams.decode(consensus_params_protobuf_object.version) - return ConsensusParams( - block_params, evidence_params, validator_params, version_params - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, ConsensusParams) - and self.block == other.block - and self.evidence_params == other.evidence_params - and self.validator_params == other.validator_params - and self.version_params == other.version_params - ) - - -class EventAttribute: - """This class represents an instance of EventAttribute.""" - - def __init__(self, key: bytes, value: bytes, index: bool): - """Initialise an instance of EventAttribute.""" - self.key = key - self.value = value - self.index = index - - @staticmethod - def encode( - event_attribute_protobuf_object, event_attribute_object: "EventAttribute" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the event_attribute_protobuf_object argument is matched with the instance of this class in the 'event_attribute_object' argument. - - :param event_attribute_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param event_attribute_object: an instance of this class to be encoded in the protocol buffer object. - """ - event_attribute_protobuf_object.key = event_attribute_object.key - event_attribute_protobuf_object.value = event_attribute_object.value - event_attribute_protobuf_object.index = event_attribute_object.index - - @classmethod - def decode(cls, event_attribute_protobuf_object) -> "EventAttribute": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'event_attribute_protobuf_object' argument. - - :param event_attribute_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'event_attribute_protobuf_object' argument. - """ - return EventAttribute( - event_attribute_protobuf_object.key, - event_attribute_protobuf_object.value, - event_attribute_protobuf_object.index, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, EventAttribute) - and self.key == other.key - and self.value == other.value - and self.index == other.index - ) - - -class Event: - """This class represents an instance of Event.""" - - def __init__(self, type_: str, attributes: List[EventAttribute]): - """Initialise an instance of Event.""" - self.type_ = type_ - self.attributes = attributes - - @staticmethod - def encode(event_protobuf_object, event_object: "Event") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the event_protobuf_object argument is matched with the instance of this class in the 'event_object' argument. - - :param event_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param event_object: an instance of this class to be encoded in the protocol buffer object. - """ - event_protobuf_object.type = event_object.type_ - - event_attribute_protobuf_objects = [] - for event_attribute_object in event_object.attributes: - event_attribute_protobuf_object = ( - abci_pb2.AbciMessage.Events.EventAttribute() - ) - EventAttribute.encode( - event_attribute_protobuf_object, event_attribute_object - ) - event_attribute_protobuf_objects.append(event_attribute_protobuf_object) - - event_protobuf_object.attributes.extend(event_attribute_protobuf_objects) - - @classmethod - def decode(cls, event_protobuf_object) -> "Event": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'event_protobuf_object' argument. - - :param event_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'event_protobuf_object' argument. - """ - attributes = [] - for event_attribute_protobuf_object in list(event_protobuf_object.attributes): - attribute = EventAttribute.decode(event_attribute_protobuf_object) - attributes.append(attribute) - return Event(event_protobuf_object.type, attributes) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, Event) - and self.type_ == other.type_ - and self.attributes == other.attributes - ) - - -class Events: - """This class represents an instance of Events.""" - - def __init__(self, events: List[Event]): - """Initialise an instance of Events.""" - self.events = events - - @staticmethod - def encode(events_protobuf_object, events_object: "Events") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the events_protobuf_object argument is matched with the instance of this class in the 'events_object' argument. - - :param events_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param events_object: an instance of this class to be encoded in the protocol buffer object. - """ - event_protobuf_objects = [] - for event_object in events_object.events: - event_protobuf_object = abci_pb2.AbciMessage.Events.Event() - Event.encode(event_protobuf_object, event_object) - event_protobuf_objects.append(event_protobuf_object) - events_protobuf_object.events.extend(event_protobuf_objects) - - @classmethod - def decode(cls, events_protobuf_object) -> "Events": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'events_protobuf_object' argument. - - :param events_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'events_protobuf_object' argument. - """ - event_objects = [] - for event_protobuf_object in list(events_protobuf_object.events): - event_object = Event.decode(event_protobuf_object) - event_objects.append(event_object) - return Events(event_objects) - - def __eq__(self, other): - """Compare with another object.""" - return isinstance(other, Events) and self.events == other.events - - -class EvidenceType(Enum): - """This class represent an instance of EvidenceType.""" - - UNKNOWN = 0 - DUPLICATE_VOTE = 1 - LIGHT_CLIENT_ATTACK = 2 - - -class Evidence: - """This class represent an instance of Evidence.""" - - def __init__( - self, - evidence_type: EvidenceType, - validator: "Validator", - height: int, - time: "Timestamp", - total_voting_power: int, - ): - """Initialise an instance of Evidences.""" - self.evidence_type = evidence_type - self.validator = validator - self.height = height - self.time = time - self.total_voting_power = total_voting_power - - @staticmethod - def encode(evidence_protobuf_object, evidence_object: "Evidence") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the evidence_protobuf_object argument is matched with the instance of this class in the 'evidence_object' argument. - - :param evidence_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param evidence_object: an instance of this class to be encoded in the protocol buffer object. - """ - evidence_protobuf_object.type = evidence_object.evidence_type.value - - validator_protobuf_object = abci_pb2.AbciMessage.LastCommitInfo.Validator() - Validator.encode(validator_protobuf_object, evidence_object.validator) - evidence_protobuf_object.validator.CopyFrom(validator_protobuf_object) - - evidence_protobuf_object.height = evidence_object.height - - timestamp_protobuf_object = abci_pb2.AbciMessage.Timestamp() - Timestamp.encode(timestamp_protobuf_object, evidence_object.time) - evidence_protobuf_object.time.CopyFrom(timestamp_protobuf_object) - - evidence_protobuf_object.total_voting_power = evidence_object.total_voting_power - - @classmethod - def decode(cls, evidence_protobuf_object) -> "Evidence": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'evidence_protobuf_object' argument. - - :param evidence_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'evidence_protobuf_object' argument. - """ - evidence_type = EvidenceType(evidence_protobuf_object.type) - validator = Validator.decode(evidence_protobuf_object.validator) - height = evidence_protobuf_object.height - time = Timestamp.decode(evidence_protobuf_object.time) - total_voting_power = evidence_protobuf_object.total_voting_power - return Evidence(evidence_type, validator, height, time, total_voting_power) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, Evidence) - and self.evidence_type == other.evidence_type - and self.validator == other.validator - and self.height == other.height - and self.time == other.time - and self.total_voting_power == other.total_voting_power - ) - - -class Evidences: - """This class represents an instance of Evidences.""" - - def __init__(self, byzantine_validators: List[Evidence]): - """Initialise an instance of Evidences.""" - self.byzantine_validators = byzantine_validators - - @staticmethod - def encode(evidences_protobuf_object, evidences_object: "Evidences") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the evidences_protobuf_object argument is matched with the instance of this class in the 'evidences_object' argument. - - :param evidences_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param evidences_object: an instance of this class to be encoded in the protocol buffer object. - """ - validators_protobuf_objects = [] - for validator in evidences_object.byzantine_validators: - evidence_protobuf_object = abci_pb2.AbciMessage.Evidences.Evidence() - Evidence.encode(evidence_protobuf_object, validator) - validators_protobuf_objects.append(evidence_protobuf_object) - evidences_protobuf_object.byzantine_validators.extend( - validators_protobuf_objects - ) - - @classmethod - def decode(cls, evidences_protobuf_object) -> "Evidences": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'evidences_protobuf_object' argument. - - :param evidences_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'evidences_protobuf_object' argument. - """ - validator_objects = [] - for validator_protobuf_object in list( - evidences_protobuf_object.byzantine_validators - ): - validator_object = Evidence.decode(validator_protobuf_object) - validator_objects.append(validator_object) - return Evidences(validator_objects) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, Evidences) - and self.byzantine_validators == other.byzantine_validators - ) - - -class CheckTxTypeEnum(Enum): - """CheckTxTypeEnum for tx check.""" - - NEW = 0 - RECHECK = 1 - - -class CheckTxType: - """This class represents an instance of CheckTxType.""" - - def __init__(self, check_tx_type: CheckTxTypeEnum): - """Initialise an instance of CheckTxType.""" - self.check_tx_type = check_tx_type - - @staticmethod - def encode( - check_tx_type_protobuf_object, check_tx_type_object: "CheckTxType" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the check_tx_type_protobuf_object argument is matched with the instance of this class in the 'check_tx_type_object' argument. - - :param check_tx_type_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param check_tx_type_object: an instance of this class to be encoded in the protocol buffer object. - """ - check_tx_type_protobuf_object.type = check_tx_type_object.check_tx_type.value - - @classmethod - def decode(cls, check_tx_type_protobuf_object) -> "CheckTxType": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'check_tx_type_protobuf_object' argument. - - :param check_tx_type_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'check_tx_type_protobuf_object' argument. - """ - return CheckTxType(CheckTxTypeEnum(check_tx_type_protobuf_object.type)) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, CheckTxType) and self.check_tx_type == other.check_tx_type - ) - - -class ConsensusVersion: - """This class represents an instance of ConsensusVersion.""" - - def __init__(self, block: int, app: int): - """Initialise an instance of ConsensusVersion.""" - self.block = block - self.app = app - - @staticmethod - def encode( - consensus_version_protobuf_object, consensus_version_object: "ConsensusVersion" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the consensus_version_protobuf_object argument is matched with the instance of this class in the 'consensus_version_object' argument. - - :param consensus_version_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param consensus_version_object: an instance of this class to be encoded in the protocol buffer object. - """ - consensus_version_protobuf_object.block = consensus_version_object.block - consensus_version_protobuf_object.app = consensus_version_object.app - - @classmethod - def decode(cls, consensus_version_protobuf_object) -> "ConsensusVersion": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'consensus_version_protobuf_object' argument. - - :param consensus_version_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'consensus_version_protobuf_object' argument. - """ - return ConsensusVersion( - consensus_version_protobuf_object.block, - consensus_version_protobuf_object.app, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, ConsensusVersion) - and self.block == other.block - and self.app == other.app - ) - - -class PartSetHeader: - """This class represents an instance of PartSetHeader.""" - - def __init__(self, total: int, hash_: bytes): - """Initialise an instance of PartSetHeader.""" - self.total = total - self.hash_ = hash_ - - @staticmethod - def encode( - part_set_header_protobuf_object, part_set_header_object: "PartSetHeader" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the part_set_header_protobuf_object argument is matched with the instance of this class in the 'part_set_header_object' argument. - - :param part_set_header_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param part_set_header_object: an instance of this class to be encoded in the protocol buffer object. - """ - part_set_header_protobuf_object.total = part_set_header_object.total - part_set_header_protobuf_object.hash = part_set_header_object.hash_ - - @classmethod - def decode(cls, part_set_header_protobuf_object) -> "PartSetHeader": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'part_set_header_protobuf_object' argument. - - :param part_set_header_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'part_set_header_protobuf_object' argument. - """ - return PartSetHeader( - part_set_header_protobuf_object.total, - part_set_header_protobuf_object.hash, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, PartSetHeader) - and self.total == other.total - and self.hash_ == other.hash_ - ) - - -class BlockID: - """This class represents an instance of BlockID.""" - - def __init__(self, hash_: bytes, part_set_header: PartSetHeader): - """Initialise an instance of BlockID.""" - self.hash_ = hash_ - self.part_set_header = part_set_header - - @staticmethod - def encode(block_id_protobuf_object, block_id_object: "BlockID") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the block_id_protobuf_object argument is matched with the instance of this class in the 'block_id_object' argument. - - :param block_id_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param block_id_object: an instance of this class to be encoded in the protocol buffer object. - """ - block_id_protobuf_object.hash = block_id_object.hash_ - part_set_header_protobuf_object = abci_pb2.AbciMessage.Header.PartSetHeader() - PartSetHeader.encode( - part_set_header_protobuf_object, block_id_object.part_set_header - ) - block_id_protobuf_object.part_set_header.CopyFrom( - part_set_header_protobuf_object - ) - - @classmethod - def decode(cls, block_id_protobuf_object) -> "BlockID": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'block_id_protobuf_object' argument. - - :param block_id_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'block_id_protobuf_object' argument. - """ - part_set_header = PartSetHeader.decode(block_id_protobuf_object.part_set_header) - return BlockID( - block_id_protobuf_object.hash, - part_set_header, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, BlockID) - and self.hash_ == other.hash_ - and self.part_set_header == other.part_set_header - ) - - -class Header: # pylint: disable=too-many-instance-attributes - """This class represents an instance of Header.""" - - def __init__( # pylint: disable=too-many-arguments - self, - version: ConsensusVersion, - chain_id: str, - height: int, - time: "Timestamp", - last_block_id: BlockID, - last_commit_hash: bytes, - data_hash: bytes, - validators_hash: bytes, - next_validators_hash: bytes, - consensus_hash: bytes, - app_hash: bytes, - last_results_hash: bytes, - evidence_hash: bytes, - proposer_address: bytes, - ): - """Initialise an instance of Header.""" - self.version = version - self.chain_id = chain_id - self.height = height - self.time = time - self.last_block_id = last_block_id - self.last_commit_hash = last_commit_hash - self.data_hash = data_hash - self.validators_hash = validators_hash - self.next_validators_hash = next_validators_hash - self.consensus_hash = consensus_hash - self.app_hash = app_hash - self.last_results_hash = last_results_hash - self.evidence_hash = evidence_hash - self.proposer_address = proposer_address - - @property - def timestamp(self) -> datetime.datetime: - """Get the block timestamp.""" - timestamp: Timestamp = self.time - nanoseconds = timestamp.nanos / 10**9 - seconds = timestamp.seconds - return datetime.datetime.fromtimestamp(seconds + nanoseconds) - - @staticmethod - def encode(header_protobuf_object, header_object: "Header") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the header_protobuf_object argument is matched with the instance of this class in the 'header_object' argument. - - :param header_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param header_object: an instance of this class to be encoded in the protocol buffer object. - """ - consensus_version_protobuf_obj = abci_pb2.AbciMessage.Header.ConsensusVersion() - ConsensusVersion.encode(consensus_version_protobuf_obj, header_object.version) - header_protobuf_object.version.CopyFrom(consensus_version_protobuf_obj) - - header_protobuf_object.chain_id = header_object.chain_id - header_protobuf_object.height = header_object.height - - timestamp_protobuf_obj = abci_pb2.AbciMessage.Timestamp() - Timestamp.encode(timestamp_protobuf_obj, header_object.time) - header_protobuf_object.time.CopyFrom(timestamp_protobuf_obj) - - last_block_id_protobuf_obj = abci_pb2.AbciMessage.Header.BlockID() - BlockID.encode(last_block_id_protobuf_obj, header_object.last_block_id) - header_protobuf_object.last_block_id.CopyFrom(last_block_id_protobuf_obj) - - header_protobuf_object.last_commit_hash = header_object.last_commit_hash - header_protobuf_object.data_hash = header_object.data_hash - header_protobuf_object.validators_hash = header_object.validators_hash - header_protobuf_object.next_validators_hash = header_object.next_validators_hash - header_protobuf_object.consensus_hash = header_object.consensus_hash - header_protobuf_object.app_hash = header_object.app_hash - header_protobuf_object.last_results_hash = header_object.last_results_hash - header_protobuf_object.evidence_hash = header_object.evidence_hash - header_protobuf_object.proposer_address = header_object.proposer_address - - @classmethod - def decode( # pylint: disable=too-many-locals - cls, header_protobuf_object - ) -> "Header": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'header_protobuf_object' argument. - - :param header_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'header_protobuf_object' argument. - """ - consensus_version_obj = ConsensusVersion.decode(header_protobuf_object.version) - chain_id = header_protobuf_object.chain_id - height = header_protobuf_object.height - time = Timestamp.decode(header_protobuf_object.time) - - last_block_id = BlockID.decode(header_protobuf_object.last_block_id) - - last_commit_hash = header_protobuf_object.last_commit_hash - data_hash = header_protobuf_object.data_hash - validators_hash = header_protobuf_object.validators_hash - next_validators_hash = header_protobuf_object.next_validators_hash - consensus_hash = header_protobuf_object.consensus_hash - app_hash = header_protobuf_object.app_hash - last_results_hash = header_protobuf_object.last_results_hash - evidence_hash = header_protobuf_object.evidence_hash - proposer_address = header_protobuf_object.proposer_address - return Header( - consensus_version_obj, - chain_id, - height, - time, - last_block_id, - last_commit_hash, - data_hash, - validators_hash, - next_validators_hash, - consensus_hash, - app_hash, - last_results_hash, - evidence_hash, - proposer_address, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, Header) - and self.version == other.version - and self.chain_id == other.chain_id - and self.height == other.height - and self.time == other.time - and self.last_block_id == other.last_block_id - and self.last_commit_hash == other.last_commit_hash - and self.data_hash == other.data_hash - and self.validators_hash == other.validators_hash - and self.next_validators_hash == other.next_validators_hash - and self.consensus_hash == other.consensus_hash - and self.app_hash == other.app_hash - and self.last_results_hash == other.last_results_hash - and self.evidence_hash == other.evidence_hash - and self.proposer_address == other.proposer_address - ) - - -class Validator: - """This class represents an instance of Validator.""" - - def __init__(self, address: bytes, power: int): - """Initialise an instance of Validator.""" - self.address = address - self.power = power - - @staticmethod - def encode(validator_protobuf_object, validator_object: "Validator") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the validator_protobuf_object argument is matched with the instance of this class in the 'validator_object' argument. - - :param validator_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param validator_object: an instance of this class to be encoded in the protocol buffer object. - """ - validator_protobuf_object.address = validator_object.address - validator_protobuf_object.power = validator_object.power - - @classmethod - def decode(cls, validator_protobuf_object) -> "Validator": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'validator_protobuf_object' argument. - - :param validator_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'validator_protobuf_object' argument. - """ - return Validator( - validator_protobuf_object.address, - validator_protobuf_object.power, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, Validator) - and self.address == other.address - and self.power == other.power - ) - - -class VoteInfo: - """This class represents an instance of VoteInfo.""" - - def __init__(self, validator: Validator, signed_last_block: bool): - """Initialise an instance of Validator.""" - self.validator = validator - self.signed_last_block = signed_last_block - - @staticmethod - def encode(vote_info_protobuf_object, vote_info_object: "VoteInfo") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the vote_info_protobuf_object argument is matched with the instance of this class in the 'vote_info_object' argument. - - :param vote_info_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param vote_info_object: an instance of this class to be encoded in the protocol buffer object. - """ - validator_protobuf_object = abci_pb2.AbciMessage.LastCommitInfo.Validator() - Validator.encode(validator_protobuf_object, vote_info_object.validator) - vote_info_protobuf_object.validator.CopyFrom(validator_protobuf_object) - - vote_info_protobuf_object.signed_last_block = vote_info_object.signed_last_block - - @classmethod - def decode(cls, vote_info_protobuf_object) -> "VoteInfo": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'vote_info_protobuf_object' argument. - - :param vote_info_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'vote_info_protobuf_object' argument. - """ - validator = Validator.decode(vote_info_protobuf_object.validator) - return VoteInfo( - validator, - vote_info_protobuf_object.signed_last_block, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, VoteInfo) - and self.validator == other.validator - and self.signed_last_block == other.signed_last_block - ) - - -class LastCommitInfo: - """This class represents an instance of LastCommitInfo.""" - - def __init__(self, round_: int, votes: List[VoteInfo]): - """Initialise an instance of LastCommitInfo.""" - self.round_ = round_ - self.votes = votes - - @staticmethod - def encode( - last_commit_info_protobuf_object, last_commit_info_object: "LastCommitInfo" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the last_commit_info_protobuf_object argument is matched with the instance of this class in the 'last_commit_info_object' argument. - - :param last_commit_info_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param last_commit_info_object: an instance of this class to be encoded in the protocol buffer object. - """ - last_commit_info_protobuf_object.round = last_commit_info_object.round_ - - votes_protobuf_objects = [] - for vote_info in last_commit_info_object.votes: - vote_info_protobuf_object = abci_pb2.AbciMessage.LastCommitInfo.VoteInfo() - VoteInfo.encode(vote_info_protobuf_object, vote_info) - votes_protobuf_objects.append(vote_info_protobuf_object) - last_commit_info_protobuf_object.votes.extend(votes_protobuf_objects) - - @classmethod - def decode(cls, last_commit_info_protobuf_object) -> "LastCommitInfo": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'last_commit_info_protobuf_object' argument. - - :param last_commit_info_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'last_commit_info_protobuf_object' argument. - """ - vote_info_objects = [] - for vote_info_protobuf_object in list(last_commit_info_protobuf_object.votes): - vote_info = VoteInfo.decode(vote_info_protobuf_object) - vote_info_objects.append(vote_info) - - return LastCommitInfo(last_commit_info_protobuf_object.round, vote_info_objects) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, LastCommitInfo) - and self.round_ == other.round_ - and self.votes == other.votes - ) - - -class ProofOp: - """This class represents an instance of ProofOp.""" - - def __init__(self, type_: str, key: bytes, data: bytes): - """ - Initialise an instance of ProofOp. - - ProofOp defines an operation used for calculating Merkle root - The data could be arbitrary format, providing necessary data - for example neighbouring node hash. - - :param type_: the type - :param key: the key - :param data: the data - """ - self.type_ = type_ - self.key = key - self.data = data - - @staticmethod - def encode(proof_op_protobuf_object, proof_op_object: "ProofOp") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the proof_op_protobuf_object argument is matched with the instance of this class in the 'proof_op_object' argument. - - :param proof_op_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param proof_op_object: an instance of this class to be encoded in the protocol buffer object. - """ - proof_op_protobuf_object.type = proof_op_object.type_ - proof_op_protobuf_object.key = proof_op_object.key - proof_op_protobuf_object.data = proof_op_object.data - - @classmethod - def decode(cls, proof_op_protobuf_object) -> "ProofOp": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'proof_op_protobuf_object' argument. - - :param proof_op_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'proof_op_protobuf_object' argument. - """ - return ProofOp( - proof_op_protobuf_object.type, - proof_op_protobuf_object.key, - proof_op_protobuf_object.data, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, ProofOp) - and self.type_ == other.type_ - and self.key == other.key - and self.data == other.data - ) - - -class ProofOps: - """This class represents an instance of ProofOps.""" - - def __init__(self, proof_ops: List[ProofOp]): - """ - Initialise an instance of ProofOps. - - :param proof_ops: a list of ProofOp instances. - """ - self.proof_ops = proof_ops - - @staticmethod - def encode(proof_ops_protobuf_object, proof_ops_object: "ProofOps") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the proof_ops_protobuf_object argument is matched with the instance of this class in the 'proof_ops_object' argument. - - :param proof_ops_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param proof_ops_object: an instance of this class to be encoded in the protocol buffer object. - """ - proof_ops_protobuf_objects = [] - for proof_op in proof_ops_object.proof_ops: - proof_op_protobuf_object = abci_pb2.AbciMessage.ProofOps.ProofOp() - ProofOp.encode(proof_op_protobuf_object, proof_op) - proof_ops_protobuf_objects.append(proof_op_protobuf_object) - proof_ops_protobuf_object.ops.extend(proof_ops_protobuf_objects) - - @classmethod - def decode(cls, proof_ops_protobuf_object) -> "ProofOps": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'proof_ops_protobuf_object' argument. - - :param proof_ops_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'proof_ops_protobuf_object' argument. - """ - proof_ops_objects = [] - for proof_op_protobuf_object in list(proof_ops_protobuf_object.ops): - proof_ops_objects.append(ProofOp.decode(proof_op_protobuf_object)) - return ProofOps(proof_ops_objects) - - def __eq__(self, other): - """Compare with another object.""" - return isinstance(other, ProofOps) and self.proof_ops == other.proof_ops - - -class ResultType(Enum): - """This class represents an instance of ResultType.""" - - UNKNOWN = 0 # Unknown result, abort all snapshot restoration - ACCEPT = 1 # Snapshot accepted, apply chunks - ABORT = 2 # Abort all snapshot restoration - REJECT = 3 # Reject this specific snapshot, try others - REJECT_FORMAT = 4 # Reject all snapshots of this format, try others - REJECT_SENDER = 5 # Reject all snapshots from the sender(s), try others - - -class Result: - """This class represents an instance of Result.""" - - def __init__(self, result_type: ResultType): - """Initialise an instance of Result.""" - self.result_type = result_type - - @staticmethod - def encode(result_protobuf_object, result_object: "Result") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the result_protobuf_object argument is matched with the instance of this class in the 'result_object' argument. - - :param result_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param result_object: an instance of this class to be encoded in the protocol buffer object. - """ - result_protobuf_object.result_type = result_object.result_type.value - - @classmethod - def decode(cls, result_protobuf_object) -> "Result": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'result_protobuf_object' argument. - - :param result_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'result_protobuf_object' argument. - """ - return Result(ResultType(result_protobuf_object.result_type)) - - def __eq__(self, other): - """Compare with another object.""" - return isinstance(other, Result) and self.result_type == other.result_type - - -class Snapshot: - """This class represents an instance of Snapshot.""" - - def __init__( - self, height: int, format_: int, chunks: int, hash_: bytes, metadata: bytes - ): - """Initialise an instance of Snapshot.""" - self.height = height - self.format_ = format_ - self.chunks = chunks - self.hash_ = hash_ - self.metadata = metadata - - @staticmethod - def encode(snapshot_protobuf_object, snapshot_object: "Snapshot") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the snapshot_protobuf_object argument is matched with the instance of this class in the 'snapshot_object' argument. - - :param snapshot_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param snapshot_object: an instance of this class to be encoded in the protocol buffer object. - """ - snapshot_protobuf_object.height = snapshot_object.height - snapshot_protobuf_object.format = snapshot_object.format_ - snapshot_protobuf_object.chunks = snapshot_object.chunks - snapshot_protobuf_object.hash = snapshot_object.hash_ - snapshot_protobuf_object.metadata = snapshot_object.metadata - - @classmethod - def decode(cls, snapshot_protobuf_object) -> "Snapshot": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'snapshot_protobuf_object' argument. - - :param snapshot_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'snapshot_protobuf_object' argument. - """ - return Snapshot( - snapshot_protobuf_object.height, - snapshot_protobuf_object.format, - snapshot_protobuf_object.chunks, - snapshot_protobuf_object.hash, - snapshot_protobuf_object.metadata, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, Snapshot) - and self.height == other.height - and self.format_ == other.format_ - and self.chunks == other.chunks - and self.hash_ == other.hash_ - and self.metadata == other.metadata - ) - - -class SnapShots: - """This class represents an instance of SnapShots.""" - - def __init__(self, snapshots: List[Snapshot]): - """Initialise an instance of SnapShots.""" - self.snapshots = snapshots - - @staticmethod - def encode(snapshots_protobuf_object, snapshots_object: "SnapShots") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the snapshots_protobuf_object argument is matched with the instance of this class in the 'snapshots_object' argument. - - :param snapshots_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param snapshots_object: an instance of this class to be encoded in the protocol buffer object. - """ - snapshot_protobuf_objects = [] - for snapshot_object in snapshots_object.snapshots: - snapshot_protobuf_object = abci_pb2.AbciMessage.Snapshot() - Snapshot.encode(snapshot_protobuf_object, snapshot_object) - snapshot_protobuf_objects.append(snapshot_protobuf_object) - snapshots_protobuf_object.snapshots.extend(snapshot_protobuf_objects) - - @classmethod - def decode(cls, snapshots_protobuf_object) -> "SnapShots": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'snapshots_protobuf_object' argument. - - :param snapshots_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'snapshots_protobuf_object' argument. - """ - snapshot_objects = [] - for snapshot_protobuf_object in list(snapshots_protobuf_object.snapshots): - snapshot_objects.append(Snapshot.decode(snapshot_protobuf_object)) - return SnapShots(snapshot_objects) - - def __eq__(self, other): - """Compare with another object.""" - return isinstance(other, SnapShots) and self.snapshots == other.snapshots - - -class Timestamp: - """This class represents an instance of Timestamp.""" - - __slots__ = ["seconds", "nanos"] - - def __init__(self, seconds: int, nanos: int): - """ - Initialise an instance of Timestamp. - - :param seconds: Represents seconds of UTC time since Unix epoch - 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - 9999-12-31T23:59:59Z inclusive. - :param nanos: Non-negative fractions of a second at nanosecond resolution. - Negative second values with fractions must still have non-negative nanos values - that count forward in time. Must be from 0 to 999,999,999 inclusive. - """ - self.seconds = seconds - self.nanos = nanos - enforce( - 0 <= nanos < 10**9, - "nanos argument must be from 0 to 999,999,999 inclusive", - exception_class=ValueError, - ) - - @staticmethod - def encode(timestamp_protobuf_object, timestamp_object: "Timestamp") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the timestamp_protobuf_object argument is matched with the instance of this class in the 'timestamp_object' argument. - - :param timestamp_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param timestamp_object: an instance of this class to be encoded in the protocol buffer object. - """ - timestamp_protobuf_object.seconds = timestamp_object.seconds - timestamp_protobuf_object.nanos = timestamp_object.nanos - - @classmethod - def decode(cls, timestamp_protobuf_object) -> "Timestamp": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'timestamp_protobuf_object' argument. - - :param timestamp_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'timestamp_protobuf_object' argument. - """ - return Timestamp( - timestamp_protobuf_object.seconds, timestamp_protobuf_object.nanos - ) - - def __eq__(self, other) -> bool: - """Compare with another object.""" - return ( - isinstance(other, Timestamp) - and self.seconds == other.seconds - and self.nanos == other.nanos - ) - - -class PublicKey: - """This class represents an instance of PublicKey.""" - - class PublicKeyType(Enum): - """Enumeration of public key types supported by Tendermint.""" - - ed25519 = "ed25519" - secp256k1 = "secp256k1" - - def __init__(self, data: bytes, key_type: PublicKeyType) -> None: - """ - Initialize the public key object. - - :param data: the data of the public key. - :param key_type: the type of the public key. - """ - self.data = data - self.key_type = key_type - - @staticmethod - def encode(public_key_protobuf_object, public_key_object: "PublicKey") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the public_key_protobuf_object argument is matched with the instance of this class in the 'public_key_object' argument. - - :param public_key_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param public_key_object: an instance of this class to be encoded in the protocol buffer object. - """ - key_type_name = public_key_object.key_type.value - setattr(public_key_protobuf_object, key_type_name, public_key_object.data) - - @classmethod - def decode(cls, public_key_protobuf_object) -> "PublicKey": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'public_key_protobuf_object' argument. - - :param public_key_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'public_key_protobuf_object' argument. - """ - key_type_name = public_key_protobuf_object.WhichOneof("sum") - key_type = PublicKey.PublicKeyType(key_type_name) - data = getattr(public_key_protobuf_object, key_type_name) - return PublicKey(data, key_type) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, PublicKey) - and self.data == other.data - and self.key_type == other.key_type - ) - - -class ValidatorUpdate: - """This class represents an instance of ValidatorUpdate.""" - - def __init__(self, pub_key: PublicKey, power: int): - """Initialise an instance of ValidatorUpdate.""" - self.pub_key = pub_key - self.power = power - - @staticmethod - def encode( - validator_update_protobuf_object, validator_update_object: "ValidatorUpdate" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the validator_update_protobuf_object argument is matched with the instance of this class in the 'validator_update_object' argument. - - :param validator_update_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param validator_update_object: an instance of this class to be encoded in the protocol buffer object. - """ - PublicKey.encode( - validator_update_protobuf_object.pub_key, validator_update_object.pub_key - ) - validator_update_protobuf_object.power = validator_update_object.power - - @classmethod - def decode(cls, validator_update_protobuf_object) -> "ValidatorUpdate": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'validator_update_protobuf_object' argument. - - :param validator_update_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'validator_update_protobuf_object' argument. - """ - pub_key = PublicKey.decode(validator_update_protobuf_object.pub_key) - return ValidatorUpdate( - pub_key, - validator_update_protobuf_object.power, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, ValidatorUpdate) - and self.pub_key == other.pub_key - and self.power == other.power - ) - - -class ValidatorUpdates: - """This class represents an instance of ValidatorUpdates.""" - - def __init__(self, validator_updates: List[ValidatorUpdate]): - """Initialise an instance of ValidatorUpdates.""" - self.validator_updates = validator_updates - - @staticmethod - def encode( - validator_updates_protobuf_object, validator_updates_object: "ValidatorUpdates" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the validator_updates_protobuf_object argument is matched with the instance of this class in the 'validator_updates_object' argument. - - :param validator_updates_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param validator_updates_object: an instance of this class to be encoded in the protocol buffer object. - """ - validator_updates = [] - for validator_update_object in validator_updates_object.validator_updates: - validator_update_protobuf_object = ( - abci_pb2.AbciMessage.ValidatorUpdates.ValidatorUpdate() - ) - ValidatorUpdate.encode( - validator_update_protobuf_object, validator_update_object - ) - validator_updates.append(validator_update_protobuf_object) - validator_updates_protobuf_object.validators.extend(validator_updates) - - @classmethod - def decode(cls, validator_updates_protobuf_object) -> "ValidatorUpdates": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'validator_updates_protobuf_object' argument. - - :param validator_updates_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'validator_updates_protobuf_object' argument. - """ - validator_updates_objects = [] - validator_updates_protobuf_objects = list( - validator_updates_protobuf_object.validators - ) - for validator_update_protobuf_object in validator_updates_protobuf_objects: - validator_update = ValidatorUpdate.decode(validator_update_protobuf_object) - validator_updates_objects.append(validator_update) - return ValidatorUpdates(validator_updates_objects) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, ValidatorUpdates) - and self.validator_updates == other.validator_updates - ) diff --git a/trader_backup/vendor/valory/protocols/abci/dialogues.py b/trader_backup/vendor/valory/protocols/abci/dialogues.py deleted file mode 100644 index 3126eef85..000000000 --- a/trader_backup/vendor/valory/protocols/abci/dialogues.py +++ /dev/null @@ -1,253 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for abci dialogue management. - -- AbciDialogue: The dialogue class maintains state of a dialogue and manages it. -- AbciDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.abci.message import AbciMessage - - -class AbciDialogue(Dialogue): - """The abci dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - AbciMessage.Performative.REQUEST_ECHO, - AbciMessage.Performative.REQUEST_FLUSH, - AbciMessage.Performative.REQUEST_INFO, - AbciMessage.Performative.REQUEST_SET_OPTION, - AbciMessage.Performative.REQUEST_INIT_CHAIN, - AbciMessage.Performative.REQUEST_QUERY, - AbciMessage.Performative.REQUEST_BEGIN_BLOCK, - AbciMessage.Performative.REQUEST_CHECK_TX, - AbciMessage.Performative.REQUEST_DELIVER_TX, - AbciMessage.Performative.REQUEST_END_BLOCK, - AbciMessage.Performative.REQUEST_COMMIT, - AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS, - AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT, - AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK, - AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK, - AbciMessage.Performative.DUMMY, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - AbciMessage.Performative.RESPONSE_EXCEPTION, - AbciMessage.Performative.RESPONSE_ECHO, - AbciMessage.Performative.RESPONSE_FLUSH, - AbciMessage.Performative.RESPONSE_INFO, - AbciMessage.Performative.RESPONSE_SET_OPTION, - AbciMessage.Performative.RESPONSE_INIT_CHAIN, - AbciMessage.Performative.RESPONSE_QUERY, - AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, - AbciMessage.Performative.RESPONSE_CHECK_TX, - AbciMessage.Performative.RESPONSE_DELIVER_TX, - AbciMessage.Performative.RESPONSE_END_BLOCK, - AbciMessage.Performative.RESPONSE_COMMIT, - AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, - AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, - AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, - AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, - AbciMessage.Performative.DUMMY, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - AbciMessage.Performative.DUMMY: frozenset(), - AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK: frozenset( - { - AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_BEGIN_BLOCK: frozenset( - { - AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_CHECK_TX: frozenset( - { - AbciMessage.Performative.RESPONSE_CHECK_TX, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_COMMIT: frozenset( - { - AbciMessage.Performative.RESPONSE_COMMIT, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_DELIVER_TX: frozenset( - { - AbciMessage.Performative.RESPONSE_DELIVER_TX, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_ECHO: frozenset( - { - AbciMessage.Performative.RESPONSE_ECHO, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_END_BLOCK: frozenset( - { - AbciMessage.Performative.RESPONSE_END_BLOCK, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_FLUSH: frozenset( - { - AbciMessage.Performative.RESPONSE_FLUSH, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_INFO: frozenset( - { - AbciMessage.Performative.RESPONSE_INFO, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_INIT_CHAIN: frozenset( - { - AbciMessage.Performative.RESPONSE_INIT_CHAIN, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS: frozenset( - { - AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK: frozenset( - { - AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT: frozenset( - { - AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_QUERY: frozenset( - { - AbciMessage.Performative.RESPONSE_QUERY, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_SET_OPTION: frozenset( - { - AbciMessage.Performative.RESPONSE_SET_OPTION, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK: frozenset(), - AbciMessage.Performative.RESPONSE_BEGIN_BLOCK: frozenset(), - AbciMessage.Performative.RESPONSE_CHECK_TX: frozenset(), - AbciMessage.Performative.RESPONSE_COMMIT: frozenset(), - AbciMessage.Performative.RESPONSE_DELIVER_TX: frozenset(), - AbciMessage.Performative.RESPONSE_ECHO: frozenset(), - AbciMessage.Performative.RESPONSE_END_BLOCK: frozenset(), - AbciMessage.Performative.RESPONSE_EXCEPTION: frozenset(), - AbciMessage.Performative.RESPONSE_FLUSH: frozenset(), - AbciMessage.Performative.RESPONSE_INFO: frozenset(), - AbciMessage.Performative.RESPONSE_INIT_CHAIN: frozenset(), - AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS: frozenset(), - AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK: frozenset(), - AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT: frozenset(), - AbciMessage.Performative.RESPONSE_QUERY: frozenset(), - AbciMessage.Performative.RESPONSE_SET_OPTION: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a abci dialogue.""" - - CLIENT = "client" - SERVER = "server" - - class EndState(Dialogue.EndState): - """This class defines the end states of a abci dialogue.""" - - SUCCESSFUL = 0 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[AbciMessage] = AbciMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class AbciDialogues(Dialogues, ABC): - """This class keeps track of all abci dialogues.""" - - END_STATES = frozenset({AbciDialogue.EndState.SUCCESSFUL}) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[AbciDialogue] = AbciDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=AbciMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_backup/vendor/valory/protocols/abci/message.py b/trader_backup/vendor/valory/protocols/abci/message.py deleted file mode 100644 index 7d0237d8b..000000000 --- a/trader_backup/vendor/valory/protocols/abci/message.py +++ /dev/null @@ -1,1273 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 abci's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Optional, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - -from packages.valory.protocols.abci.custom_types import CheckTxType as CustomCheckTxType -from packages.valory.protocols.abci.custom_types import ( - ConsensusParams as CustomConsensusParams, -) -from packages.valory.protocols.abci.custom_types import Events as CustomEvents -from packages.valory.protocols.abci.custom_types import Evidences as CustomEvidences -from packages.valory.protocols.abci.custom_types import Header as CustomHeader -from packages.valory.protocols.abci.custom_types import ( - LastCommitInfo as CustomLastCommitInfo, -) -from packages.valory.protocols.abci.custom_types import ProofOps as CustomProofOps -from packages.valory.protocols.abci.custom_types import Result as CustomResult -from packages.valory.protocols.abci.custom_types import SnapShots as CustomSnapShots -from packages.valory.protocols.abci.custom_types import Snapshot as CustomSnapshot -from packages.valory.protocols.abci.custom_types import Timestamp as CustomTimestamp -from packages.valory.protocols.abci.custom_types import ( - ValidatorUpdates as CustomValidatorUpdates, -) - - -_default_logger = logging.getLogger("aea.packages.valory.protocols.abci.message") - -DEFAULT_BODY_SIZE = 4 - - -class AbciMessage(Message): - """A protocol for ABCI requests and responses.""" - - protocol_id = PublicId.from_str("valory/abci:0.1.0") - protocol_specification_id = PublicId.from_str("valory/abci:0.1.0") - - CheckTxType = CustomCheckTxType - - ConsensusParams = CustomConsensusParams - - Events = CustomEvents - - Evidences = CustomEvidences - - Header = CustomHeader - - LastCommitInfo = CustomLastCommitInfo - - ProofOps = CustomProofOps - - Result = CustomResult - - SnapShots = CustomSnapShots - - Snapshot = CustomSnapshot - - Timestamp = CustomTimestamp - - ValidatorUpdates = CustomValidatorUpdates - - class Performative(Message.Performative): - """Performatives for the abci protocol.""" - - DUMMY = "dummy" - REQUEST_APPLY_SNAPSHOT_CHUNK = "request_apply_snapshot_chunk" - REQUEST_BEGIN_BLOCK = "request_begin_block" - REQUEST_CHECK_TX = "request_check_tx" - REQUEST_COMMIT = "request_commit" - REQUEST_DELIVER_TX = "request_deliver_tx" - REQUEST_ECHO = "request_echo" - REQUEST_END_BLOCK = "request_end_block" - REQUEST_FLUSH = "request_flush" - REQUEST_INFO = "request_info" - REQUEST_INIT_CHAIN = "request_init_chain" - REQUEST_LIST_SNAPSHOTS = "request_list_snapshots" - REQUEST_LOAD_SNAPSHOT_CHUNK = "request_load_snapshot_chunk" - REQUEST_OFFER_SNAPSHOT = "request_offer_snapshot" - REQUEST_QUERY = "request_query" - REQUEST_SET_OPTION = "request_set_option" - RESPONSE_APPLY_SNAPSHOT_CHUNK = "response_apply_snapshot_chunk" - RESPONSE_BEGIN_BLOCK = "response_begin_block" - RESPONSE_CHECK_TX = "response_check_tx" - RESPONSE_COMMIT = "response_commit" - RESPONSE_DELIVER_TX = "response_deliver_tx" - RESPONSE_ECHO = "response_echo" - RESPONSE_END_BLOCK = "response_end_block" - RESPONSE_EXCEPTION = "response_exception" - RESPONSE_FLUSH = "response_flush" - RESPONSE_INFO = "response_info" - RESPONSE_INIT_CHAIN = "response_init_chain" - RESPONSE_LIST_SNAPSHOTS = "response_list_snapshots" - RESPONSE_LOAD_SNAPSHOT_CHUNK = "response_load_snapshot_chunk" - RESPONSE_OFFER_SNAPSHOT = "response_offer_snapshot" - RESPONSE_QUERY = "response_query" - RESPONSE_SET_OPTION = "response_set_option" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = { - "dummy", - "request_apply_snapshot_chunk", - "request_begin_block", - "request_check_tx", - "request_commit", - "request_deliver_tx", - "request_echo", - "request_end_block", - "request_flush", - "request_info", - "request_init_chain", - "request_list_snapshots", - "request_load_snapshot_chunk", - "request_offer_snapshot", - "request_query", - "request_set_option", - "response_apply_snapshot_chunk", - "response_begin_block", - "response_check_tx", - "response_commit", - "response_deliver_tx", - "response_echo", - "response_end_block", - "response_exception", - "response_flush", - "response_info", - "response_init_chain", - "response_list_snapshots", - "response_load_snapshot_chunk", - "response_offer_snapshot", - "response_query", - "response_set_option", - } - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "app_hash", - "app_state_bytes", - "app_version", - "block_version", - "byzantine_validators", - "chain_id", - "chunk", - "chunk_index", - "chunk_sender", - "code", - "codespace", - "consensus_param_updates", - "consensus_params", - "data", - "dialogue_reference", - "dummy_consensus_params", - "error", - "events", - "format", - "gas_used", - "gas_wanted", - "hash", - "header", - "height", - "index", - "info", - "info_data", - "initial_height", - "key", - "last_block_app_hash", - "last_block_height", - "last_commit_info", - "log", - "message", - "message_id", - "option_key", - "option_value", - "p2p_version", - "path", - "performative", - "proof_ops", - "prove", - "query_data", - "refetch_chunks", - "reject_senders", - "result", - "retain_height", - "snapshot", - "snapshots", - "target", - "time", - "tx", - "type", - "validator_updates", - "validators", - "value", - "version", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of AbciMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=AbciMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(AbciMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def app_hash(self) -> bytes: - """Get the 'app_hash' content from the message.""" - enforce(self.is_set("app_hash"), "'app_hash' content is not set.") - return cast(bytes, self.get("app_hash")) - - @property - def app_state_bytes(self) -> bytes: - """Get the 'app_state_bytes' content from the message.""" - enforce(self.is_set("app_state_bytes"), "'app_state_bytes' content is not set.") - return cast(bytes, self.get("app_state_bytes")) - - @property - def app_version(self) -> int: - """Get the 'app_version' content from the message.""" - enforce(self.is_set("app_version"), "'app_version' content is not set.") - return cast(int, self.get("app_version")) - - @property - def block_version(self) -> int: - """Get the 'block_version' content from the message.""" - enforce(self.is_set("block_version"), "'block_version' content is not set.") - return cast(int, self.get("block_version")) - - @property - def byzantine_validators(self) -> CustomEvidences: - """Get the 'byzantine_validators' content from the message.""" - enforce( - self.is_set("byzantine_validators"), - "'byzantine_validators' content is not set.", - ) - return cast(CustomEvidences, self.get("byzantine_validators")) - - @property - def chain_id(self) -> str: - """Get the 'chain_id' content from the message.""" - enforce(self.is_set("chain_id"), "'chain_id' content is not set.") - return cast(str, self.get("chain_id")) - - @property - def chunk(self) -> bytes: - """Get the 'chunk' content from the message.""" - enforce(self.is_set("chunk"), "'chunk' content is not set.") - return cast(bytes, self.get("chunk")) - - @property - def chunk_index(self) -> int: - """Get the 'chunk_index' content from the message.""" - enforce(self.is_set("chunk_index"), "'chunk_index' content is not set.") - return cast(int, self.get("chunk_index")) - - @property - def chunk_sender(self) -> str: - """Get the 'chunk_sender' content from the message.""" - enforce(self.is_set("chunk_sender"), "'chunk_sender' content is not set.") - return cast(str, self.get("chunk_sender")) - - @property - def code(self) -> int: - """Get the 'code' content from the message.""" - enforce(self.is_set("code"), "'code' content is not set.") - return cast(int, self.get("code")) - - @property - def codespace(self) -> str: - """Get the 'codespace' content from the message.""" - enforce(self.is_set("codespace"), "'codespace' content is not set.") - return cast(str, self.get("codespace")) - - @property - def consensus_param_updates(self) -> Optional[CustomConsensusParams]: - """Get the 'consensus_param_updates' content from the message.""" - return cast( - Optional[CustomConsensusParams], self.get("consensus_param_updates") - ) - - @property - def consensus_params(self) -> Optional[CustomConsensusParams]: - """Get the 'consensus_params' content from the message.""" - return cast(Optional[CustomConsensusParams], self.get("consensus_params")) - - @property - def data(self) -> bytes: - """Get the 'data' content from the message.""" - enforce(self.is_set("data"), "'data' content is not set.") - return cast(bytes, self.get("data")) - - @property - def dummy_consensus_params(self) -> CustomConsensusParams: - """Get the 'dummy_consensus_params' content from the message.""" - enforce( - self.is_set("dummy_consensus_params"), - "'dummy_consensus_params' content is not set.", - ) - return cast(CustomConsensusParams, self.get("dummy_consensus_params")) - - @property - def error(self) -> str: - """Get the 'error' content from the message.""" - enforce(self.is_set("error"), "'error' content is not set.") - return cast(str, self.get("error")) - - @property - def events(self) -> CustomEvents: - """Get the 'events' content from the message.""" - enforce(self.is_set("events"), "'events' content is not set.") - return cast(CustomEvents, self.get("events")) - - @property - def format(self) -> int: - """Get the 'format' content from the message.""" - enforce(self.is_set("format"), "'format' content is not set.") - return cast(int, self.get("format")) - - @property - def gas_used(self) -> int: - """Get the 'gas_used' content from the message.""" - enforce(self.is_set("gas_used"), "'gas_used' content is not set.") - return cast(int, self.get("gas_used")) - - @property - def gas_wanted(self) -> int: - """Get the 'gas_wanted' content from the message.""" - enforce(self.is_set("gas_wanted"), "'gas_wanted' content is not set.") - return cast(int, self.get("gas_wanted")) - - @property - def hash(self) -> bytes: - """Get the 'hash' content from the message.""" - enforce(self.is_set("hash"), "'hash' content is not set.") - return cast(bytes, self.get("hash")) - - @property - def header(self) -> CustomHeader: - """Get the 'header' content from the message.""" - enforce(self.is_set("header"), "'header' content is not set.") - return cast(CustomHeader, self.get("header")) - - @property - def height(self) -> int: - """Get the 'height' content from the message.""" - enforce(self.is_set("height"), "'height' content is not set.") - return cast(int, self.get("height")) - - @property - def index(self) -> int: - """Get the 'index' content from the message.""" - enforce(self.is_set("index"), "'index' content is not set.") - return cast(int, self.get("index")) - - @property - def info(self) -> str: - """Get the 'info' content from the message.""" - enforce(self.is_set("info"), "'info' content is not set.") - return cast(str, self.get("info")) - - @property - def info_data(self) -> str: - """Get the 'info_data' content from the message.""" - enforce(self.is_set("info_data"), "'info_data' content is not set.") - return cast(str, self.get("info_data")) - - @property - def initial_height(self) -> int: - """Get the 'initial_height' content from the message.""" - enforce(self.is_set("initial_height"), "'initial_height' content is not set.") - return cast(int, self.get("initial_height")) - - @property - def key(self) -> bytes: - """Get the 'key' content from the message.""" - enforce(self.is_set("key"), "'key' content is not set.") - return cast(bytes, self.get("key")) - - @property - def last_block_app_hash(self) -> bytes: - """Get the 'last_block_app_hash' content from the message.""" - enforce( - self.is_set("last_block_app_hash"), - "'last_block_app_hash' content is not set.", - ) - return cast(bytes, self.get("last_block_app_hash")) - - @property - def last_block_height(self) -> int: - """Get the 'last_block_height' content from the message.""" - enforce( - self.is_set("last_block_height"), "'last_block_height' content is not set." - ) - return cast(int, self.get("last_block_height")) - - @property - def last_commit_info(self) -> CustomLastCommitInfo: - """Get the 'last_commit_info' content from the message.""" - enforce( - self.is_set("last_commit_info"), "'last_commit_info' content is not set." - ) - return cast(CustomLastCommitInfo, self.get("last_commit_info")) - - @property - def log(self) -> str: - """Get the 'log' content from the message.""" - enforce(self.is_set("log"), "'log' content is not set.") - return cast(str, self.get("log")) - - @property - def message(self) -> str: - """Get the 'message' content from the message.""" - enforce(self.is_set("message"), "'message' content is not set.") - return cast(str, self.get("message")) - - @property - def option_key(self) -> str: - """Get the 'option_key' content from the message.""" - enforce(self.is_set("option_key"), "'option_key' content is not set.") - return cast(str, self.get("option_key")) - - @property - def option_value(self) -> str: - """Get the 'option_value' content from the message.""" - enforce(self.is_set("option_value"), "'option_value' content is not set.") - return cast(str, self.get("option_value")) - - @property - def p2p_version(self) -> int: - """Get the 'p2p_version' content from the message.""" - enforce(self.is_set("p2p_version"), "'p2p_version' content is not set.") - return cast(int, self.get("p2p_version")) - - @property - def path(self) -> str: - """Get the 'path' content from the message.""" - enforce(self.is_set("path"), "'path' content is not set.") - return cast(str, self.get("path")) - - @property - def proof_ops(self) -> CustomProofOps: - """Get the 'proof_ops' content from the message.""" - enforce(self.is_set("proof_ops"), "'proof_ops' content is not set.") - return cast(CustomProofOps, self.get("proof_ops")) - - @property - def prove(self) -> bool: - """Get the 'prove' content from the message.""" - enforce(self.is_set("prove"), "'prove' content is not set.") - return cast(bool, self.get("prove")) - - @property - def query_data(self) -> bytes: - """Get the 'query_data' content from the message.""" - enforce(self.is_set("query_data"), "'query_data' content is not set.") - return cast(bytes, self.get("query_data")) - - @property - def refetch_chunks(self) -> Tuple[int, ...]: - """Get the 'refetch_chunks' content from the message.""" - enforce(self.is_set("refetch_chunks"), "'refetch_chunks' content is not set.") - return cast(Tuple[int, ...], self.get("refetch_chunks")) - - @property - def reject_senders(self) -> Tuple[str, ...]: - """Get the 'reject_senders' content from the message.""" - enforce(self.is_set("reject_senders"), "'reject_senders' content is not set.") - return cast(Tuple[str, ...], self.get("reject_senders")) - - @property - def result(self) -> CustomResult: - """Get the 'result' content from the message.""" - enforce(self.is_set("result"), "'result' content is not set.") - return cast(CustomResult, self.get("result")) - - @property - def retain_height(self) -> int: - """Get the 'retain_height' content from the message.""" - enforce(self.is_set("retain_height"), "'retain_height' content is not set.") - return cast(int, self.get("retain_height")) - - @property - def snapshot(self) -> CustomSnapshot: - """Get the 'snapshot' content from the message.""" - enforce(self.is_set("snapshot"), "'snapshot' content is not set.") - return cast(CustomSnapshot, self.get("snapshot")) - - @property - def snapshots(self) -> CustomSnapShots: - """Get the 'snapshots' content from the message.""" - enforce(self.is_set("snapshots"), "'snapshots' content is not set.") - return cast(CustomSnapShots, self.get("snapshots")) - - @property - def time(self) -> CustomTimestamp: - """Get the 'time' content from the message.""" - enforce(self.is_set("time"), "'time' content is not set.") - return cast(CustomTimestamp, self.get("time")) - - @property - def tx(self) -> bytes: - """Get the 'tx' content from the message.""" - enforce(self.is_set("tx"), "'tx' content is not set.") - return cast(bytes, self.get("tx")) - - @property - def type(self) -> CustomCheckTxType: - """Get the 'type' content from the message.""" - enforce(self.is_set("type"), "'type' content is not set.") - return cast(CustomCheckTxType, self.get("type")) - - @property - def validator_updates(self) -> CustomValidatorUpdates: - """Get the 'validator_updates' content from the message.""" - enforce( - self.is_set("validator_updates"), "'validator_updates' content is not set." - ) - return cast(CustomValidatorUpdates, self.get("validator_updates")) - - @property - def validators(self) -> CustomValidatorUpdates: - """Get the 'validators' content from the message.""" - enforce(self.is_set("validators"), "'validators' content is not set.") - return cast(CustomValidatorUpdates, self.get("validators")) - - @property - def value(self) -> bytes: - """Get the 'value' content from the message.""" - enforce(self.is_set("value"), "'value' content is not set.") - return cast(bytes, self.get("value")) - - @property - def version(self) -> str: - """Get the 'version' content from the message.""" - enforce(self.is_set("version"), "'version' content is not set.") - return cast(str, self.get("version")) - - def _is_consistent(self) -> bool: - """Check that the message follows the abci protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, AbciMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == AbciMessage.Performative.REQUEST_ECHO: - expected_nb_of_contents = 1 - enforce( - isinstance(self.message, str), - "Invalid type for content 'message'. Expected 'str'. Found '{}'.".format( - type(self.message) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_FLUSH: - expected_nb_of_contents = 0 - elif self.performative == AbciMessage.Performative.REQUEST_INFO: - expected_nb_of_contents = 3 - enforce( - isinstance(self.version, str), - "Invalid type for content 'version'. Expected 'str'. Found '{}'.".format( - type(self.version) - ), - ) - enforce( - type(self.block_version) is int, - "Invalid type for content 'block_version'. Expected 'int'. Found '{}'.".format( - type(self.block_version) - ), - ) - enforce( - type(self.p2p_version) is int, - "Invalid type for content 'p2p_version'. Expected 'int'. Found '{}'.".format( - type(self.p2p_version) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_SET_OPTION: - expected_nb_of_contents = 2 - enforce( - isinstance(self.option_key, str), - "Invalid type for content 'option_key'. Expected 'str'. Found '{}'.".format( - type(self.option_key) - ), - ) - enforce( - isinstance(self.option_value, str), - "Invalid type for content 'option_value'. Expected 'str'. Found '{}'.".format( - type(self.option_value) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_INIT_CHAIN: - expected_nb_of_contents = 5 - enforce( - isinstance(self.time, CustomTimestamp), - "Invalid type for content 'time'. Expected 'Timestamp'. Found '{}'.".format( - type(self.time) - ), - ) - enforce( - isinstance(self.chain_id, str), - "Invalid type for content 'chain_id'. Expected 'str'. Found '{}'.".format( - type(self.chain_id) - ), - ) - if self.is_set("consensus_params"): - expected_nb_of_contents += 1 - consensus_params = cast( - CustomConsensusParams, self.consensus_params - ) - enforce( - isinstance(consensus_params, CustomConsensusParams), - "Invalid type for content 'consensus_params'. Expected 'ConsensusParams'. Found '{}'.".format( - type(consensus_params) - ), - ) - enforce( - isinstance(self.validators, CustomValidatorUpdates), - "Invalid type for content 'validators'. Expected 'ValidatorUpdates'. Found '{}'.".format( - type(self.validators) - ), - ) - enforce( - isinstance(self.app_state_bytes, bytes), - "Invalid type for content 'app_state_bytes'. Expected 'bytes'. Found '{}'.".format( - type(self.app_state_bytes) - ), - ) - enforce( - type(self.initial_height) is int, - "Invalid type for content 'initial_height'. Expected 'int'. Found '{}'.".format( - type(self.initial_height) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_QUERY: - expected_nb_of_contents = 4 - enforce( - isinstance(self.query_data, bytes), - "Invalid type for content 'query_data'. Expected 'bytes'. Found '{}'.".format( - type(self.query_data) - ), - ) - enforce( - isinstance(self.path, str), - "Invalid type for content 'path'. Expected 'str'. Found '{}'.".format( - type(self.path) - ), - ) - enforce( - type(self.height) is int, - "Invalid type for content 'height'. Expected 'int'. Found '{}'.".format( - type(self.height) - ), - ) - enforce( - isinstance(self.prove, bool), - "Invalid type for content 'prove'. Expected 'bool'. Found '{}'.".format( - type(self.prove) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_BEGIN_BLOCK: - expected_nb_of_contents = 4 - enforce( - isinstance(self.hash, bytes), - "Invalid type for content 'hash'. Expected 'bytes'. Found '{}'.".format( - type(self.hash) - ), - ) - enforce( - isinstance(self.header, CustomHeader), - "Invalid type for content 'header'. Expected 'Header'. Found '{}'.".format( - type(self.header) - ), - ) - enforce( - isinstance(self.last_commit_info, CustomLastCommitInfo), - "Invalid type for content 'last_commit_info'. Expected 'LastCommitInfo'. Found '{}'.".format( - type(self.last_commit_info) - ), - ) - enforce( - isinstance(self.byzantine_validators, CustomEvidences), - "Invalid type for content 'byzantine_validators'. Expected 'Evidences'. Found '{}'.".format( - type(self.byzantine_validators) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_CHECK_TX: - expected_nb_of_contents = 2 - enforce( - isinstance(self.tx, bytes), - "Invalid type for content 'tx'. Expected 'bytes'. Found '{}'.".format( - type(self.tx) - ), - ) - enforce( - isinstance(self.type, CustomCheckTxType), - "Invalid type for content 'type'. Expected 'CheckTxType'. Found '{}'.".format( - type(self.type) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_DELIVER_TX: - expected_nb_of_contents = 1 - enforce( - isinstance(self.tx, bytes), - "Invalid type for content 'tx'. Expected 'bytes'. Found '{}'.".format( - type(self.tx) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_END_BLOCK: - expected_nb_of_contents = 1 - enforce( - type(self.height) is int, - "Invalid type for content 'height'. Expected 'int'. Found '{}'.".format( - type(self.height) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_COMMIT: - expected_nb_of_contents = 0 - elif self.performative == AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS: - expected_nb_of_contents = 0 - elif self.performative == AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT: - expected_nb_of_contents = 2 - enforce( - isinstance(self.snapshot, CustomSnapshot), - "Invalid type for content 'snapshot'. Expected 'Snapshot'. Found '{}'.".format( - type(self.snapshot) - ), - ) - enforce( - isinstance(self.app_hash, bytes), - "Invalid type for content 'app_hash'. Expected 'bytes'. Found '{}'.".format( - type(self.app_hash) - ), - ) - elif ( - self.performative - == AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK - ): - expected_nb_of_contents = 3 - enforce( - type(self.height) is int, - "Invalid type for content 'height'. Expected 'int'. Found '{}'.".format( - type(self.height) - ), - ) - enforce( - type(self.format) is int, - "Invalid type for content 'format'. Expected 'int'. Found '{}'.".format( - type(self.format) - ), - ) - enforce( - type(self.chunk_index) is int, - "Invalid type for content 'chunk_index'. Expected 'int'. Found '{}'.".format( - type(self.chunk_index) - ), - ) - elif ( - self.performative - == AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK - ): - expected_nb_of_contents = 3 - enforce( - type(self.index) is int, - "Invalid type for content 'index'. Expected 'int'. Found '{}'.".format( - type(self.index) - ), - ) - enforce( - isinstance(self.chunk, bytes), - "Invalid type for content 'chunk'. Expected 'bytes'. Found '{}'.".format( - type(self.chunk) - ), - ) - enforce( - isinstance(self.chunk_sender, str), - "Invalid type for content 'chunk_sender'. Expected 'str'. Found '{}'.".format( - type(self.chunk_sender) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_EXCEPTION: - expected_nb_of_contents = 1 - enforce( - isinstance(self.error, str), - "Invalid type for content 'error'. Expected 'str'. Found '{}'.".format( - type(self.error) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_ECHO: - expected_nb_of_contents = 1 - enforce( - isinstance(self.message, str), - "Invalid type for content 'message'. Expected 'str'. Found '{}'.".format( - type(self.message) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_FLUSH: - expected_nb_of_contents = 0 - elif self.performative == AbciMessage.Performative.RESPONSE_INFO: - expected_nb_of_contents = 5 - enforce( - isinstance(self.info_data, str), - "Invalid type for content 'info_data'. Expected 'str'. Found '{}'.".format( - type(self.info_data) - ), - ) - enforce( - isinstance(self.version, str), - "Invalid type for content 'version'. Expected 'str'. Found '{}'.".format( - type(self.version) - ), - ) - enforce( - type(self.app_version) is int, - "Invalid type for content 'app_version'. Expected 'int'. Found '{}'.".format( - type(self.app_version) - ), - ) - enforce( - type(self.last_block_height) is int, - "Invalid type for content 'last_block_height'. Expected 'int'. Found '{}'.".format( - type(self.last_block_height) - ), - ) - enforce( - isinstance(self.last_block_app_hash, bytes), - "Invalid type for content 'last_block_app_hash'. Expected 'bytes'. Found '{}'.".format( - type(self.last_block_app_hash) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_SET_OPTION: - expected_nb_of_contents = 3 - enforce( - type(self.code) is int, - "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( - type(self.code) - ), - ) - enforce( - isinstance(self.log, str), - "Invalid type for content 'log'. Expected 'str'. Found '{}'.".format( - type(self.log) - ), - ) - enforce( - isinstance(self.info, str), - "Invalid type for content 'info'. Expected 'str'. Found '{}'.".format( - type(self.info) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_INIT_CHAIN: - expected_nb_of_contents = 2 - if self.is_set("consensus_params"): - expected_nb_of_contents += 1 - consensus_params = cast( - CustomConsensusParams, self.consensus_params - ) - enforce( - isinstance(consensus_params, CustomConsensusParams), - "Invalid type for content 'consensus_params'. Expected 'ConsensusParams'. Found '{}'.".format( - type(consensus_params) - ), - ) - enforce( - isinstance(self.validators, CustomValidatorUpdates), - "Invalid type for content 'validators'. Expected 'ValidatorUpdates'. Found '{}'.".format( - type(self.validators) - ), - ) - enforce( - isinstance(self.app_hash, bytes), - "Invalid type for content 'app_hash'. Expected 'bytes'. Found '{}'.".format( - type(self.app_hash) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_QUERY: - expected_nb_of_contents = 9 - enforce( - type(self.code) is int, - "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( - type(self.code) - ), - ) - enforce( - isinstance(self.log, str), - "Invalid type for content 'log'. Expected 'str'. Found '{}'.".format( - type(self.log) - ), - ) - enforce( - isinstance(self.info, str), - "Invalid type for content 'info'. Expected 'str'. Found '{}'.".format( - type(self.info) - ), - ) - enforce( - type(self.index) is int, - "Invalid type for content 'index'. Expected 'int'. Found '{}'.".format( - type(self.index) - ), - ) - enforce( - isinstance(self.key, bytes), - "Invalid type for content 'key'. Expected 'bytes'. Found '{}'.".format( - type(self.key) - ), - ) - enforce( - isinstance(self.value, bytes), - "Invalid type for content 'value'. Expected 'bytes'. Found '{}'.".format( - type(self.value) - ), - ) - enforce( - isinstance(self.proof_ops, CustomProofOps), - "Invalid type for content 'proof_ops'. Expected 'ProofOps'. Found '{}'.".format( - type(self.proof_ops) - ), - ) - enforce( - type(self.height) is int, - "Invalid type for content 'height'. Expected 'int'. Found '{}'.".format( - type(self.height) - ), - ) - enforce( - isinstance(self.codespace, str), - "Invalid type for content 'codespace'. Expected 'str'. Found '{}'.".format( - type(self.codespace) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_BEGIN_BLOCK: - expected_nb_of_contents = 1 - enforce( - isinstance(self.events, CustomEvents), - "Invalid type for content 'events'. Expected 'Events'. Found '{}'.".format( - type(self.events) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_CHECK_TX: - expected_nb_of_contents = 8 - enforce( - type(self.code) is int, - "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( - type(self.code) - ), - ) - enforce( - isinstance(self.data, bytes), - "Invalid type for content 'data'. Expected 'bytes'. Found '{}'.".format( - type(self.data) - ), - ) - enforce( - isinstance(self.log, str), - "Invalid type for content 'log'. Expected 'str'. Found '{}'.".format( - type(self.log) - ), - ) - enforce( - isinstance(self.info, str), - "Invalid type for content 'info'. Expected 'str'. Found '{}'.".format( - type(self.info) - ), - ) - enforce( - type(self.gas_wanted) is int, - "Invalid type for content 'gas_wanted'. Expected 'int'. Found '{}'.".format( - type(self.gas_wanted) - ), - ) - enforce( - type(self.gas_used) is int, - "Invalid type for content 'gas_used'. Expected 'int'. Found '{}'.".format( - type(self.gas_used) - ), - ) - enforce( - isinstance(self.events, CustomEvents), - "Invalid type for content 'events'. Expected 'Events'. Found '{}'.".format( - type(self.events) - ), - ) - enforce( - isinstance(self.codespace, str), - "Invalid type for content 'codespace'. Expected 'str'. Found '{}'.".format( - type(self.codespace) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_DELIVER_TX: - expected_nb_of_contents = 8 - enforce( - type(self.code) is int, - "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( - type(self.code) - ), - ) - enforce( - isinstance(self.data, bytes), - "Invalid type for content 'data'. Expected 'bytes'. Found '{}'.".format( - type(self.data) - ), - ) - enforce( - isinstance(self.log, str), - "Invalid type for content 'log'. Expected 'str'. Found '{}'.".format( - type(self.log) - ), - ) - enforce( - isinstance(self.info, str), - "Invalid type for content 'info'. Expected 'str'. Found '{}'.".format( - type(self.info) - ), - ) - enforce( - type(self.gas_wanted) is int, - "Invalid type for content 'gas_wanted'. Expected 'int'. Found '{}'.".format( - type(self.gas_wanted) - ), - ) - enforce( - type(self.gas_used) is int, - "Invalid type for content 'gas_used'. Expected 'int'. Found '{}'.".format( - type(self.gas_used) - ), - ) - enforce( - isinstance(self.events, CustomEvents), - "Invalid type for content 'events'. Expected 'Events'. Found '{}'.".format( - type(self.events) - ), - ) - enforce( - isinstance(self.codespace, str), - "Invalid type for content 'codespace'. Expected 'str'. Found '{}'.".format( - type(self.codespace) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_END_BLOCK: - expected_nb_of_contents = 2 - enforce( - isinstance(self.validator_updates, CustomValidatorUpdates), - "Invalid type for content 'validator_updates'. Expected 'ValidatorUpdates'. Found '{}'.".format( - type(self.validator_updates) - ), - ) - if self.is_set("consensus_param_updates"): - expected_nb_of_contents += 1 - consensus_param_updates = cast( - CustomConsensusParams, self.consensus_param_updates - ) - enforce( - isinstance(consensus_param_updates, CustomConsensusParams), - "Invalid type for content 'consensus_param_updates'. Expected 'ConsensusParams'. Found '{}'.".format( - type(consensus_param_updates) - ), - ) - enforce( - isinstance(self.events, CustomEvents), - "Invalid type for content 'events'. Expected 'Events'. Found '{}'.".format( - type(self.events) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_COMMIT: - expected_nb_of_contents = 2 - enforce( - isinstance(self.data, bytes), - "Invalid type for content 'data'. Expected 'bytes'. Found '{}'.".format( - type(self.data) - ), - ) - enforce( - type(self.retain_height) is int, - "Invalid type for content 'retain_height'. Expected 'int'. Found '{}'.".format( - type(self.retain_height) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS: - expected_nb_of_contents = 1 - enforce( - isinstance(self.snapshots, CustomSnapShots), - "Invalid type for content 'snapshots'. Expected 'SnapShots'. Found '{}'.".format( - type(self.snapshots) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT: - expected_nb_of_contents = 1 - enforce( - isinstance(self.result, CustomResult), - "Invalid type for content 'result'. Expected 'Result'. Found '{}'.".format( - type(self.result) - ), - ) - elif ( - self.performative - == AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK - ): - expected_nb_of_contents = 1 - enforce( - isinstance(self.chunk, bytes), - "Invalid type for content 'chunk'. Expected 'bytes'. Found '{}'.".format( - type(self.chunk) - ), - ) - elif ( - self.performative - == AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK - ): - expected_nb_of_contents = 3 - enforce( - isinstance(self.result, CustomResult), - "Invalid type for content 'result'. Expected 'Result'. Found '{}'.".format( - type(self.result) - ), - ) - enforce( - isinstance(self.refetch_chunks, tuple), - "Invalid type for content 'refetch_chunks'. Expected 'tuple'. Found '{}'.".format( - type(self.refetch_chunks) - ), - ) - enforce( - all(type(element) is int for element in self.refetch_chunks), - "Invalid type for tuple elements in content 'refetch_chunks'. Expected 'int'.", - ) - enforce( - isinstance(self.reject_senders, tuple), - "Invalid type for content 'reject_senders'. Expected 'tuple'. Found '{}'.".format( - type(self.reject_senders) - ), - ) - enforce( - all(isinstance(element, str) for element in self.reject_senders), - "Invalid type for tuple elements in content 'reject_senders'. Expected 'str'.", - ) - elif self.performative == AbciMessage.Performative.DUMMY: - expected_nb_of_contents = 1 - enforce( - isinstance(self.dummy_consensus_params, CustomConsensusParams), - "Invalid type for content 'dummy_consensus_params'. Expected 'ConsensusParams'. Found '{}'.".format( - type(self.dummy_consensus_params) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_backup/vendor/valory/protocols/abci/protocol.yaml b/trader_backup/vendor/valory/protocols/abci/protocol.yaml deleted file mode 100644 index 205cccc92..000000000 --- a/trader_backup/vendor/valory/protocols/abci/protocol.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: abci -author: valory -version: 0.1.0 -protocol_specification_id: valory/abci:0.1.0 -type: protocol -description: A protocol for ABCI requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeia5y34dgznojhabsw7js2auxzmwxoubs2yacvscvoqkmt323d3npq - __init__.py: bafybeigdywrj2szik3yvkpnouvsdwna2c3w6txzfyxqgqvmq3brhy2guqy - abci.proto: bafybeid2kv4fy6xx453apqxashnqfjymhbrvtxj3uq2vdtqr45lvlfjzm4 - abci_pb2.py: bafybeiamdsjnddab32gu3xxa2tj4hkuaor2aboqem5dpt4ug25hhejp2li - custom_types.py: bafybeihpkluue4c7cunrcaxze3pqexhmwxkybrv4c3bzmkkakze7n6v44a - dialogues.py: bafybeihllufuvxtzb6vtz7qbsxqoyboaxik7lacwrbqfl4wfdzkfiv35de - message.py: bafybeifyexp6v5ajzqtuneknamnhhcobnaekbsbo3uq2xlu6a2lpfavfjm - serialization.py: bafybeifbqcuyp6kjsditiprvujhlr5zyj67icjtceu2wrkmtun6icwfnre - tests/__init__.py: bafybeie4cd5xo7o4teyfjclaju3zoguuahjvkpsbshda3x23jcph53fdpi - tests/conftest.py: bafybeidomydt6bdji22rndrdb5w773vvdja55o5m5n4pbfslx7ey5euot4 - tests/test_abci.py: bafybeig4gex7e62uxca7riaetmr2pu5xekxg3d7xjvck72zjd3uxny4v64 - tests/test_abci_dialogues.py: bafybeiby6ahpj6dnvjagnyyew3hgncstay37tt3xqu5x2c2yx3nldwvzzi - tests/test_abci_messages.py: bafybeidbec7g3gvyr4jon57m6pfcobslj3nvnnynzeib3mgvm46d3ywdgi -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_backup/vendor/valory/protocols/abci/serialization.py b/trader_backup/vendor/valory/protocols/abci/serialization.py deleted file mode 100644 index f5fad05e4..000000000 --- a/trader_backup/vendor/valory/protocols/abci/serialization.py +++ /dev/null @@ -1,617 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for abci protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.abci import abci_pb2 # type: ignore -from packages.valory.protocols.abci.custom_types import ( # type: ignore - CheckTxType, - ConsensusParams, - Events, - Evidences, - Header, - LastCommitInfo, - ProofOps, - Result, - SnapShots, - Snapshot, - Timestamp, - ValidatorUpdates, -) -from packages.valory.protocols.abci.message import AbciMessage # type: ignore - - -class AbciSerializer(Serializer): - """Serialization for the 'abci' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'Abci' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(AbciMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - abci_msg = abci_pb2.AbciMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == AbciMessage.Performative.REQUEST_ECHO: - performative = abci_pb2.AbciMessage.Request_Echo_Performative() # type: ignore - message = msg.message - performative.message = message - abci_msg.request_echo.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_FLUSH: - performative = abci_pb2.AbciMessage.Request_Flush_Performative() # type: ignore - abci_msg.request_flush.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_INFO: - performative = abci_pb2.AbciMessage.Request_Info_Performative() # type: ignore - version = msg.version - performative.version = version - block_version = msg.block_version - performative.block_version = block_version - p2p_version = msg.p2p_version - performative.p2p_version = p2p_version - abci_msg.request_info.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_SET_OPTION: - performative = abci_pb2.AbciMessage.Request_Set_Option_Performative() # type: ignore - option_key = msg.option_key - performative.option_key = option_key - option_value = msg.option_value - performative.option_value = option_value - abci_msg.request_set_option.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_INIT_CHAIN: - performative = abci_pb2.AbciMessage.Request_Init_Chain_Performative() # type: ignore - time = msg.time - Timestamp.encode(performative.time, time) - chain_id = msg.chain_id - performative.chain_id = chain_id - if msg.is_set("consensus_params"): - performative.consensus_params_is_set = True - consensus_params = msg.consensus_params - ConsensusParams.encode(performative.consensus_params, consensus_params) - validators = msg.validators - ValidatorUpdates.encode(performative.validators, validators) - app_state_bytes = msg.app_state_bytes - performative.app_state_bytes = app_state_bytes - initial_height = msg.initial_height - performative.initial_height = initial_height - abci_msg.request_init_chain.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_QUERY: - performative = abci_pb2.AbciMessage.Request_Query_Performative() # type: ignore - query_data = msg.query_data - performative.query_data = query_data - path = msg.path - performative.path = path - height = msg.height - performative.height = height - prove = msg.prove - performative.prove = prove - abci_msg.request_query.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_BEGIN_BLOCK: - performative = abci_pb2.AbciMessage.Request_Begin_Block_Performative() # type: ignore - hash = msg.hash - performative.hash = hash - header = msg.header - Header.encode(performative.header, header) - last_commit_info = msg.last_commit_info - LastCommitInfo.encode(performative.last_commit_info, last_commit_info) - byzantine_validators = msg.byzantine_validators - Evidences.encode(performative.byzantine_validators, byzantine_validators) - abci_msg.request_begin_block.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_CHECK_TX: - performative = abci_pb2.AbciMessage.Request_Check_Tx_Performative() # type: ignore - tx = msg.tx - performative.tx = tx - type = msg.type - CheckTxType.encode(performative.type, type) - abci_msg.request_check_tx.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_DELIVER_TX: - performative = abci_pb2.AbciMessage.Request_Deliver_Tx_Performative() # type: ignore - tx = msg.tx - performative.tx = tx - abci_msg.request_deliver_tx.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_END_BLOCK: - performative = abci_pb2.AbciMessage.Request_End_Block_Performative() # type: ignore - height = msg.height - performative.height = height - abci_msg.request_end_block.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_COMMIT: - performative = abci_pb2.AbciMessage.Request_Commit_Performative() # type: ignore - abci_msg.request_commit.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS: - performative = abci_pb2.AbciMessage.Request_List_Snapshots_Performative() # type: ignore - abci_msg.request_list_snapshots.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT: - performative = abci_pb2.AbciMessage.Request_Offer_Snapshot_Performative() # type: ignore - snapshot = msg.snapshot - Snapshot.encode(performative.snapshot, snapshot) - app_hash = msg.app_hash - performative.app_hash = app_hash - abci_msg.request_offer_snapshot.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK: - performative = abci_pb2.AbciMessage.Request_Load_Snapshot_Chunk_Performative() # type: ignore - height = msg.height - performative.height = height - format = msg.format - performative.format = format - chunk_index = msg.chunk_index - performative.chunk_index = chunk_index - abci_msg.request_load_snapshot_chunk.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK: - performative = abci_pb2.AbciMessage.Request_Apply_Snapshot_Chunk_Performative() # type: ignore - index = msg.index - performative.index = index - chunk = msg.chunk - performative.chunk = chunk - chunk_sender = msg.chunk_sender - performative.chunk_sender = chunk_sender - abci_msg.request_apply_snapshot_chunk.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_EXCEPTION: - performative = abci_pb2.AbciMessage.Response_Exception_Performative() # type: ignore - error = msg.error - performative.error = error - abci_msg.response_exception.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_ECHO: - performative = abci_pb2.AbciMessage.Response_Echo_Performative() # type: ignore - message = msg.message - performative.message = message - abci_msg.response_echo.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_FLUSH: - performative = abci_pb2.AbciMessage.Response_Flush_Performative() # type: ignore - abci_msg.response_flush.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_INFO: - performative = abci_pb2.AbciMessage.Response_Info_Performative() # type: ignore - info_data = msg.info_data - performative.info_data = info_data - version = msg.version - performative.version = version - app_version = msg.app_version - performative.app_version = app_version - last_block_height = msg.last_block_height - performative.last_block_height = last_block_height - last_block_app_hash = msg.last_block_app_hash - performative.last_block_app_hash = last_block_app_hash - abci_msg.response_info.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_SET_OPTION: - performative = abci_pb2.AbciMessage.Response_Set_Option_Performative() # type: ignore - code = msg.code - performative.code = code - log = msg.log - performative.log = log - info = msg.info - performative.info = info - abci_msg.response_set_option.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_INIT_CHAIN: - performative = abci_pb2.AbciMessage.Response_Init_Chain_Performative() # type: ignore - if msg.is_set("consensus_params"): - performative.consensus_params_is_set = True - consensus_params = msg.consensus_params - ConsensusParams.encode(performative.consensus_params, consensus_params) - validators = msg.validators - ValidatorUpdates.encode(performative.validators, validators) - app_hash = msg.app_hash - performative.app_hash = app_hash - abci_msg.response_init_chain.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_QUERY: - performative = abci_pb2.AbciMessage.Response_Query_Performative() # type: ignore - code = msg.code - performative.code = code - log = msg.log - performative.log = log - info = msg.info - performative.info = info - index = msg.index - performative.index = index - key = msg.key - performative.key = key - value = msg.value - performative.value = value - proof_ops = msg.proof_ops - ProofOps.encode(performative.proof_ops, proof_ops) - height = msg.height - performative.height = height - codespace = msg.codespace - performative.codespace = codespace - abci_msg.response_query.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_BEGIN_BLOCK: - performative = abci_pb2.AbciMessage.Response_Begin_Block_Performative() # type: ignore - events = msg.events - Events.encode(performative.events, events) - abci_msg.response_begin_block.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_CHECK_TX: - performative = abci_pb2.AbciMessage.Response_Check_Tx_Performative() # type: ignore - code = msg.code - performative.code = code - data = msg.data - performative.data = data - log = msg.log - performative.log = log - info = msg.info - performative.info = info - gas_wanted = msg.gas_wanted - performative.gas_wanted = gas_wanted - gas_used = msg.gas_used - performative.gas_used = gas_used - events = msg.events - Events.encode(performative.events, events) - codespace = msg.codespace - performative.codespace = codespace - abci_msg.response_check_tx.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_DELIVER_TX: - performative = abci_pb2.AbciMessage.Response_Deliver_Tx_Performative() # type: ignore - code = msg.code - performative.code = code - data = msg.data - performative.data = data - log = msg.log - performative.log = log - info = msg.info - performative.info = info - gas_wanted = msg.gas_wanted - performative.gas_wanted = gas_wanted - gas_used = msg.gas_used - performative.gas_used = gas_used - events = msg.events - Events.encode(performative.events, events) - codespace = msg.codespace - performative.codespace = codespace - abci_msg.response_deliver_tx.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_END_BLOCK: - performative = abci_pb2.AbciMessage.Response_End_Block_Performative() # type: ignore - validator_updates = msg.validator_updates - ValidatorUpdates.encode(performative.validator_updates, validator_updates) - if msg.is_set("consensus_param_updates"): - performative.consensus_param_updates_is_set = True - consensus_param_updates = msg.consensus_param_updates - ConsensusParams.encode( - performative.consensus_param_updates, consensus_param_updates - ) - events = msg.events - Events.encode(performative.events, events) - abci_msg.response_end_block.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_COMMIT: - performative = abci_pb2.AbciMessage.Response_Commit_Performative() # type: ignore - data = msg.data - performative.data = data - retain_height = msg.retain_height - performative.retain_height = retain_height - abci_msg.response_commit.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS: - performative = abci_pb2.AbciMessage.Response_List_Snapshots_Performative() # type: ignore - snapshots = msg.snapshots - SnapShots.encode(performative.snapshots, snapshots) - abci_msg.response_list_snapshots.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT: - performative = abci_pb2.AbciMessage.Response_Offer_Snapshot_Performative() # type: ignore - result = msg.result - Result.encode(performative.result, result) - abci_msg.response_offer_snapshot.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK: - performative = abci_pb2.AbciMessage.Response_Load_Snapshot_Chunk_Performative() # type: ignore - chunk = msg.chunk - performative.chunk = chunk - abci_msg.response_load_snapshot_chunk.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK: - performative = abci_pb2.AbciMessage.Response_Apply_Snapshot_Chunk_Performative() # type: ignore - result = msg.result - Result.encode(performative.result, result) - refetch_chunks = msg.refetch_chunks - performative.refetch_chunks.extend(refetch_chunks) - reject_senders = msg.reject_senders - performative.reject_senders.extend(reject_senders) - abci_msg.response_apply_snapshot_chunk.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.DUMMY: - performative = abci_pb2.AbciMessage.Dummy_Performative() # type: ignore - dummy_consensus_params = msg.dummy_consensus_params - ConsensusParams.encode( - performative.dummy_consensus_params, dummy_consensus_params - ) - abci_msg.dummy.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = abci_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'Abci' message. - - :param obj: the bytes object. - :return: the 'Abci' message. - """ - message_pb = ProtobufMessage() - abci_pb = abci_pb2.AbciMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - abci_pb.ParseFromString(message_pb.dialogue_message.content) - performative = abci_pb.WhichOneof("performative") - performative_id = AbciMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == AbciMessage.Performative.REQUEST_ECHO: - message = abci_pb.request_echo.message - performative_content["message"] = message - elif performative_id == AbciMessage.Performative.REQUEST_FLUSH: - pass - elif performative_id == AbciMessage.Performative.REQUEST_INFO: - version = abci_pb.request_info.version - performative_content["version"] = version - block_version = abci_pb.request_info.block_version - performative_content["block_version"] = block_version - p2p_version = abci_pb.request_info.p2p_version - performative_content["p2p_version"] = p2p_version - elif performative_id == AbciMessage.Performative.REQUEST_SET_OPTION: - option_key = abci_pb.request_set_option.option_key - performative_content["option_key"] = option_key - option_value = abci_pb.request_set_option.option_value - performative_content["option_value"] = option_value - elif performative_id == AbciMessage.Performative.REQUEST_INIT_CHAIN: - pb2_time = abci_pb.request_init_chain.time - time = Timestamp.decode(pb2_time) - performative_content["time"] = time - chain_id = abci_pb.request_init_chain.chain_id - performative_content["chain_id"] = chain_id - if abci_pb.request_init_chain.consensus_params_is_set: - pb2_consensus_params = abci_pb.request_init_chain.consensus_params - consensus_params = ConsensusParams.decode(pb2_consensus_params) - performative_content["consensus_params"] = consensus_params - pb2_validators = abci_pb.request_init_chain.validators - validators = ValidatorUpdates.decode(pb2_validators) - performative_content["validators"] = validators - app_state_bytes = abci_pb.request_init_chain.app_state_bytes - performative_content["app_state_bytes"] = app_state_bytes - initial_height = abci_pb.request_init_chain.initial_height - performative_content["initial_height"] = initial_height - elif performative_id == AbciMessage.Performative.REQUEST_QUERY: - query_data = abci_pb.request_query.query_data - performative_content["query_data"] = query_data - path = abci_pb.request_query.path - performative_content["path"] = path - height = abci_pb.request_query.height - performative_content["height"] = height - prove = abci_pb.request_query.prove - performative_content["prove"] = prove - elif performative_id == AbciMessage.Performative.REQUEST_BEGIN_BLOCK: - hash = abci_pb.request_begin_block.hash - performative_content["hash"] = hash - pb2_header = abci_pb.request_begin_block.header - header = Header.decode(pb2_header) - performative_content["header"] = header - pb2_last_commit_info = abci_pb.request_begin_block.last_commit_info - last_commit_info = LastCommitInfo.decode(pb2_last_commit_info) - performative_content["last_commit_info"] = last_commit_info - pb2_byzantine_validators = abci_pb.request_begin_block.byzantine_validators - byzantine_validators = Evidences.decode(pb2_byzantine_validators) - performative_content["byzantine_validators"] = byzantine_validators - elif performative_id == AbciMessage.Performative.REQUEST_CHECK_TX: - tx = abci_pb.request_check_tx.tx - performative_content["tx"] = tx - pb2_type = abci_pb.request_check_tx.type - type = CheckTxType.decode(pb2_type) - performative_content["type"] = type - elif performative_id == AbciMessage.Performative.REQUEST_DELIVER_TX: - tx = abci_pb.request_deliver_tx.tx - performative_content["tx"] = tx - elif performative_id == AbciMessage.Performative.REQUEST_END_BLOCK: - height = abci_pb.request_end_block.height - performative_content["height"] = height - elif performative_id == AbciMessage.Performative.REQUEST_COMMIT: - pass - elif performative_id == AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS: - pass - elif performative_id == AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT: - pb2_snapshot = abci_pb.request_offer_snapshot.snapshot - snapshot = Snapshot.decode(pb2_snapshot) - performative_content["snapshot"] = snapshot - app_hash = abci_pb.request_offer_snapshot.app_hash - performative_content["app_hash"] = app_hash - elif performative_id == AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK: - height = abci_pb.request_load_snapshot_chunk.height - performative_content["height"] = height - format = abci_pb.request_load_snapshot_chunk.format - performative_content["format"] = format - chunk_index = abci_pb.request_load_snapshot_chunk.chunk_index - performative_content["chunk_index"] = chunk_index - elif performative_id == AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK: - index = abci_pb.request_apply_snapshot_chunk.index - performative_content["index"] = index - chunk = abci_pb.request_apply_snapshot_chunk.chunk - performative_content["chunk"] = chunk - chunk_sender = abci_pb.request_apply_snapshot_chunk.chunk_sender - performative_content["chunk_sender"] = chunk_sender - elif performative_id == AbciMessage.Performative.RESPONSE_EXCEPTION: - error = abci_pb.response_exception.error - performative_content["error"] = error - elif performative_id == AbciMessage.Performative.RESPONSE_ECHO: - message = abci_pb.response_echo.message - performative_content["message"] = message - elif performative_id == AbciMessage.Performative.RESPONSE_FLUSH: - pass - elif performative_id == AbciMessage.Performative.RESPONSE_INFO: - info_data = abci_pb.response_info.info_data - performative_content["info_data"] = info_data - version = abci_pb.response_info.version - performative_content["version"] = version - app_version = abci_pb.response_info.app_version - performative_content["app_version"] = app_version - last_block_height = abci_pb.response_info.last_block_height - performative_content["last_block_height"] = last_block_height - last_block_app_hash = abci_pb.response_info.last_block_app_hash - performative_content["last_block_app_hash"] = last_block_app_hash - elif performative_id == AbciMessage.Performative.RESPONSE_SET_OPTION: - code = abci_pb.response_set_option.code - performative_content["code"] = code - log = abci_pb.response_set_option.log - performative_content["log"] = log - info = abci_pb.response_set_option.info - performative_content["info"] = info - elif performative_id == AbciMessage.Performative.RESPONSE_INIT_CHAIN: - if abci_pb.response_init_chain.consensus_params_is_set: - pb2_consensus_params = abci_pb.response_init_chain.consensus_params - consensus_params = ConsensusParams.decode(pb2_consensus_params) - performative_content["consensus_params"] = consensus_params - pb2_validators = abci_pb.response_init_chain.validators - validators = ValidatorUpdates.decode(pb2_validators) - performative_content["validators"] = validators - app_hash = abci_pb.response_init_chain.app_hash - performative_content["app_hash"] = app_hash - elif performative_id == AbciMessage.Performative.RESPONSE_QUERY: - code = abci_pb.response_query.code - performative_content["code"] = code - log = abci_pb.response_query.log - performative_content["log"] = log - info = abci_pb.response_query.info - performative_content["info"] = info - index = abci_pb.response_query.index - performative_content["index"] = index - key = abci_pb.response_query.key - performative_content["key"] = key - value = abci_pb.response_query.value - performative_content["value"] = value - pb2_proof_ops = abci_pb.response_query.proof_ops - proof_ops = ProofOps.decode(pb2_proof_ops) - performative_content["proof_ops"] = proof_ops - height = abci_pb.response_query.height - performative_content["height"] = height - codespace = abci_pb.response_query.codespace - performative_content["codespace"] = codespace - elif performative_id == AbciMessage.Performative.RESPONSE_BEGIN_BLOCK: - pb2_events = abci_pb.response_begin_block.events - events = Events.decode(pb2_events) - performative_content["events"] = events - elif performative_id == AbciMessage.Performative.RESPONSE_CHECK_TX: - code = abci_pb.response_check_tx.code - performative_content["code"] = code - data = abci_pb.response_check_tx.data - performative_content["data"] = data - log = abci_pb.response_check_tx.log - performative_content["log"] = log - info = abci_pb.response_check_tx.info - performative_content["info"] = info - gas_wanted = abci_pb.response_check_tx.gas_wanted - performative_content["gas_wanted"] = gas_wanted - gas_used = abci_pb.response_check_tx.gas_used - performative_content["gas_used"] = gas_used - pb2_events = abci_pb.response_check_tx.events - events = Events.decode(pb2_events) - performative_content["events"] = events - codespace = abci_pb.response_check_tx.codespace - performative_content["codespace"] = codespace - elif performative_id == AbciMessage.Performative.RESPONSE_DELIVER_TX: - code = abci_pb.response_deliver_tx.code - performative_content["code"] = code - data = abci_pb.response_deliver_tx.data - performative_content["data"] = data - log = abci_pb.response_deliver_tx.log - performative_content["log"] = log - info = abci_pb.response_deliver_tx.info - performative_content["info"] = info - gas_wanted = abci_pb.response_deliver_tx.gas_wanted - performative_content["gas_wanted"] = gas_wanted - gas_used = abci_pb.response_deliver_tx.gas_used - performative_content["gas_used"] = gas_used - pb2_events = abci_pb.response_deliver_tx.events - events = Events.decode(pb2_events) - performative_content["events"] = events - codespace = abci_pb.response_deliver_tx.codespace - performative_content["codespace"] = codespace - elif performative_id == AbciMessage.Performative.RESPONSE_END_BLOCK: - pb2_validator_updates = abci_pb.response_end_block.validator_updates - validator_updates = ValidatorUpdates.decode(pb2_validator_updates) - performative_content["validator_updates"] = validator_updates - if abci_pb.response_end_block.consensus_param_updates_is_set: - pb2_consensus_param_updates = ( - abci_pb.response_end_block.consensus_param_updates - ) - consensus_param_updates = ConsensusParams.decode( - pb2_consensus_param_updates - ) - performative_content[ - "consensus_param_updates" - ] = consensus_param_updates - pb2_events = abci_pb.response_end_block.events - events = Events.decode(pb2_events) - performative_content["events"] = events - elif performative_id == AbciMessage.Performative.RESPONSE_COMMIT: - data = abci_pb.response_commit.data - performative_content["data"] = data - retain_height = abci_pb.response_commit.retain_height - performative_content["retain_height"] = retain_height - elif performative_id == AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS: - pb2_snapshots = abci_pb.response_list_snapshots.snapshots - snapshots = SnapShots.decode(pb2_snapshots) - performative_content["snapshots"] = snapshots - elif performative_id == AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT: - pb2_result = abci_pb.response_offer_snapshot.result - result = Result.decode(pb2_result) - performative_content["result"] = result - elif performative_id == AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK: - chunk = abci_pb.response_load_snapshot_chunk.chunk - performative_content["chunk"] = chunk - elif performative_id == AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK: - pb2_result = abci_pb.response_apply_snapshot_chunk.result - result = Result.decode(pb2_result) - performative_content["result"] = result - refetch_chunks = abci_pb.response_apply_snapshot_chunk.refetch_chunks - refetch_chunks_tuple = tuple(refetch_chunks) - performative_content["refetch_chunks"] = refetch_chunks_tuple - reject_senders = abci_pb.response_apply_snapshot_chunk.reject_senders - reject_senders_tuple = tuple(reject_senders) - performative_content["reject_senders"] = reject_senders_tuple - elif performative_id == AbciMessage.Performative.DUMMY: - pb2_dummy_consensus_params = abci_pb.dummy.dummy_consensus_params - dummy_consensus_params = ConsensusParams.decode(pb2_dummy_consensus_params) - performative_content["dummy_consensus_params"] = dummy_consensus_params - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return AbciMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_backup/vendor/valory/protocols/abci/tests/__init__.py b/trader_backup/vendor/valory/protocols/abci/tests/__init__.py deleted file mode 100644 index 5fe6a268e..000000000 --- a/trader_backup/vendor/valory/protocols/abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""ABCI protocol tests.""" diff --git a/trader_backup/vendor/valory/protocols/abci/tests/conftest.py b/trader_backup/vendor/valory/protocols/abci/tests/conftest.py deleted file mode 100644 index d3a5cfa36..000000000 --- a/trader_backup/vendor/valory/protocols/abci/tests/conftest.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Conftest module.""" diff --git a/trader_backup/vendor/valory/protocols/abci/tests/test_abci.py b/trader_backup/vendor/valory/protocols/abci/tests/test_abci.py deleted file mode 100644 index 156930d60..000000000 --- a/trader_backup/vendor/valory/protocols/abci/tests/test_abci.py +++ /dev/null @@ -1,910 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for the 'valory/abci' protocol.""" -import datetime -from abc import abstractmethod -from typing import Callable, Type -from unittest import mock - -import pytest -from aea.common import Address -from aea.exceptions import AEAEnforceError -from aea.mail.base import Envelope -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.abci import AbciMessage, message -from packages.valory.protocols.abci.custom_types import ( - BlockID, - BlockParams, - CheckTxType, - CheckTxTypeEnum, - ConsensusParams, - ConsensusVersion, - Duration, - Event, - EventAttribute, - Events, - Evidence, - EvidenceParams, - EvidenceType, - Evidences, - Header, - LastCommitInfo, - PartSetHeader, - ProofOp, - ProofOps, - PublicKey, - Result, - ResultType, - SnapShots, - Snapshot, - Timestamp, - Validator, - ValidatorParams, - ValidatorUpdate, - ValidatorUpdates, - VersionParams, - VoteInfo, -) -from packages.valory.protocols.abci.dialogues import AbciDialogue, AbciDialogues -from packages.valory.protocols.abci.message import ( - _default_logger as abci_message_logger, -) - - -class BaseTestMessageConstruction: - """Base class to test message construction for the ABCI protocol.""" - - @abstractmethod - def build_message(self) -> AbciMessage: - """Build the message to be used for testing.""" - - def test_run(self) -> None: - """Run the test.""" - msg = self.build_message() - msg.to = "receiver" - envelope = Envelope(to=msg.to, sender="sender", message=msg) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = AbciMessage.serializer.decode(actual_envelope.message_bytes) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - @classmethod - def _make_consensus_params(cls) -> ConsensusParams: - """Build a ConsensuParams object.""" - return ConsensusParams( - BlockParams(0, 0), - EvidenceParams(0, Duration(0, 0), 0), - ValidatorParams(["pub_key"]), - VersionParams(0), - ) - - @classmethod - def _make_snapshot(cls) -> Snapshot: - """Build a Snapshot object.""" - return Snapshot(0, 0, 0, b"hash", b"metadata") - - -class TestRequestEcho(BaseTestMessageConstruction): - """Test ABCI request abci.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_ECHO, # type: ignore - message="hello", - ) - - -class TestResponseEcho(BaseTestMessageConstruction): - """Test ABCI response abci.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_ECHO, # type: ignore - message="hello", - ) - - -class TestRequestFlush(BaseTestMessageConstruction): - """Test ABCI request flush.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_FLUSH, # type: ignore - ) - - -class TestResponseFlush(BaseTestMessageConstruction): - """Test ABCI response flush.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_FLUSH, # type: ignore - ) - - -class TestRequestInfo(BaseTestMessageConstruction): - """Test ABCI request info.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_INFO, # type: ignore - version="0.1.0", - block_version=1, - p2p_version=1, - ) - - -class TestResponseInfo(BaseTestMessageConstruction): - """Test ABCI response info.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_INFO, # type: ignore - info_data="info", - version="0.1.0", - app_version=1, - last_block_height=1, - last_block_app_hash=b"bytes", - ) - - -class TestRequestInitChain(BaseTestMessageConstruction): - """Test ABCI request init chain.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - consensus_params = super()._make_consensus_params() - - validators = ValidatorUpdates( - [ - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.ed25519), 1 - ), - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.secp256k1), 2 - ), - ] - ) - - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_INIT_CHAIN, # type: ignore - time=Timestamp(0, 0), - chain_id="1", - consensus_params=consensus_params, - validators=validators, - app_state_bytes=b"bytes", - initial_height=0, - ) - - -class TestResponseInitChain(BaseTestMessageConstruction): - """Test ABCI response init chain.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - consensus_params = super()._make_consensus_params() - - validators = ValidatorUpdates( - [ - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.ed25519), 1 - ), - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.secp256k1), 2 - ), - ] - ) - - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_INIT_CHAIN, # type: ignore - consensus_params=consensus_params, - validators=validators, - app_hash=b"app_hash", - ) - - -class TestRequestQuery(BaseTestMessageConstruction): - """Test ABCI response query.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_QUERY, # type: ignore - query_data=b"bytes", - path="", - height=0, - prove=False, - ) - - -class TestResponseQuery(BaseTestMessageConstruction): - """Test ABCI response query.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_QUERY, # type: ignore - code=0, - log="log", - info="info", - index=0, - key=b"key", - value=b"value", - proof_ops=ProofOps( - [ - ProofOp("type", b"key", b"data"), - ProofOp("type", b"key", b"data"), - ] - ), - height=0, - codespace="", - ) - - -class TestRequestBeginBlock(BaseTestMessageConstruction): - """Test ABCI request begin block.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - header = Header( - ConsensusVersion(0, 0), - "chain_id", - 0, - Timestamp(0, 0), - BlockID(b"hash", PartSetHeader(0, b"hash")), - b"last_commit_hash", - b"data_hash", - b"validators_hash", - b"next_validators_hash", - b"consensus_hash", - b"app_hash", - b"last_results_hash", - b"evidence_hash", - b"proposer_address", - ) - - assert header.timestamp == datetime.datetime.fromtimestamp(0) - - validator = Validator(b"address", 0) - last_commit_info = LastCommitInfo( - 0, - [ - VoteInfo(validator, True), - VoteInfo(validator, False), - ], - ) - - evidences = Evidences( - [ - Evidence(EvidenceType.UNKNOWN, validator, 0, Timestamp(0, 0), 0), - Evidence(EvidenceType.DUPLICATE_VOTE, validator, 0, Timestamp(0, 0), 0), - ] - ) - - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_BEGIN_BLOCK, # type: ignore - hash=b"hash", - header=header, - last_commit_info=last_commit_info, - byzantine_validators=evidences, - ) - - -class TestResponseBeginBlock(BaseTestMessageConstruction): - """Test ABCI response begin block.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - event = Event("type", [EventAttribute(b"key", b"value", True)]) - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, # type: ignore - events=Events([event, event]), - ) - - -class TestRequestCheckTx(BaseTestMessageConstruction): - """Test ABCI request check tx.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - tx = b"bytes" - type_ = CheckTxType(CheckTxTypeEnum.NEW) - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_CHECK_TX, # type: ignore - tx=tx, - type=type_, - ) - - -class TestResponseCheckTx(BaseTestMessageConstruction): - """Test ABCI response check tx.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - attribute = EventAttribute(b"key", b"value", True) - event = Event("type", attributes=[attribute, attribute]) - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, # type: ignore - code=0, - data=b"data", - log="log", - info="info", - gas_wanted=0, - gas_used=0, - events=Events([event, event]), - codespace="codespace", - ) - - -class TestRequestDeliverTx(BaseTestMessageConstruction): - """Test ABCI request deliver tx.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, # type: ignore - tx=b"tx", - ) - - -class TestResponseDeliverTx(BaseTestMessageConstruction): - """Test ABCI response deliver tx.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - attribute = EventAttribute(b"key", b"value", True) - event = Event("type", attributes=[attribute, attribute]) - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, # type: ignore - code=0, - data=b"data", - log="log", - info="info", - gas_wanted=0, - gas_used=0, - events=Events([event, event]), - codespace="codespace", - ) - - -class TestRequestEndBlock(BaseTestMessageConstruction): - """Test ABCI request end block.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_END_BLOCK, # type: ignore - height=0, - ) - - -class TestRequestSetOption(BaseTestMessageConstruction): - """Test ABCI request end block.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_SET_OPTION, # type: ignore - option_key="", - option_value="", - ) - - -class TestResponseEndBlock(BaseTestMessageConstruction): - """Test ABCI response end block.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - attribute = EventAttribute(b"key", b"value", True) - event = Event("type", attributes=[attribute, attribute]) - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_END_BLOCK, # type: ignore - validator_updates=ValidatorUpdates( - [ - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.ed25519), 1 - ), - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.secp256k1), - 2, - ), - ] - ), - consensus_param_updates=super()._make_consensus_params(), - events=Events([event, event]), - ) - - -class TestRequestCommit(BaseTestMessageConstruction): - """Test ABCI request commit.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_COMMIT, # type: ignore - ) - - -class TestResponseCommit(BaseTestMessageConstruction): - """Test ABCI response commit.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_COMMIT, # type: ignore - data=b"bytes", - retain_height=0, - ) - - -class TestRequestListSnapshots(BaseTestMessageConstruction): - """Test ABCI request list snapshots.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS, # type: ignore - ) - - -class TestResponseListSnapshots(BaseTestMessageConstruction): - """Test ABCI response list snapshots.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - snapshots = SnapShots( - [ - super()._make_snapshot(), - super()._make_snapshot(), - ] - ) - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, # type: ignore - snapshots=snapshots, - ) - - -class TestRequestOfferSnapshot(BaseTestMessageConstruction): - """Test ABCI request offer snapshot.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT, # type: ignore - snapshot=super()._make_snapshot(), - app_hash=b"app_hash", - ) - - -class TestResponseOfferSnapshot(BaseTestMessageConstruction): - """Test ABCI response offer snapshot.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, # type: ignore - result=Result(ResultType.UNKNOWN), - ) - - -class TestRequestLoadSnapshotChunk(BaseTestMessageConstruction): - """Test ABCI request load snapshot chunk.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK, # type: ignore - height=0, - format=0, - chunk_index=0, - ) - - -class TestResponseLoadSnapshotChunk(BaseTestMessageConstruction): - """Test ABCI response load snapshot chunk.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, # type: ignore - chunk=b"chunk", - ) - - -class TestRequestApplySnapshotChunk(BaseTestMessageConstruction): - """Test ABCI request load snapshot chunk.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK, # type: ignore - index=0, - chunk=b"chunk", - chunk_sender="sender", - ) - - -class TestResponseApplySnapshotChunk(BaseTestMessageConstruction): - """Test ABCI response apply snapshot chunk.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, # type: ignore - result=Result(ResultType.REJECT), - refetch_chunks=(0, 1, 2), - reject_senders=("sender_1", "sender_2"), - ) - - -class TestDummy(BaseTestMessageConstruction): - """Test ABCI request abci.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.DUMMY, # type: ignore - dummy_consensus_params=self._make_consensus_params(), - ) - - -class TestResponseException(BaseTestMessageConstruction): - """Test ABCI request abci.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_EXCEPTION, error="" # type: ignore - ) - - -class TestResponseSetOption(BaseTestMessageConstruction): - """Test ABCI request end block.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_SET_OPTION, # type: ignore - code=1, - log="", - info="", - ) - - -@mock.patch.object( - message, - "enforce", - side_effect=AEAEnforceError("some error"), -) -def test_incorrect_message( - mocked_enforce: Callable, # pylint: disable=unused-argument -) -> None: - """Test that we raise an exception when the message is incorrect.""" - with mock.patch.object(abci_message_logger, "error") as mock_logger: - AbciMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=AbciMessage.Performative.DUMMY, # type: ignore - ) - - mock_logger.assert_any_call("some error") - - -def test_performative_string_value() -> None: - """Test the string valoe of performatives.""" - - assert str(AbciMessage.Performative.DUMMY) == "dummy", "The str value must be dummy" - assert ( - str(AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK) - == "request_apply_snapshot_chunk" - ), "The str value must be request_apply_snapshot_chunk" - assert ( - str(AbciMessage.Performative.REQUEST_BEGIN_BLOCK) == "request_begin_block" - ), "The str value must be request_begin_block" - assert ( - str(AbciMessage.Performative.REQUEST_CHECK_TX) == "request_check_tx" - ), "The str value must be request_check_tx" - assert ( - str(AbciMessage.Performative.REQUEST_COMMIT) == "request_commit" - ), "The str value must be request_commit" - assert ( - str(AbciMessage.Performative.REQUEST_DELIVER_TX) == "request_deliver_tx" - ), "The str value must be request_deliver_tx" - assert ( - str(AbciMessage.Performative.REQUEST_ECHO) == "request_echo" - ), "The str value must be request_echo" - assert ( - str(AbciMessage.Performative.REQUEST_END_BLOCK) == "request_end_block" - ), "The str value must be request_end_block" - assert ( - str(AbciMessage.Performative.REQUEST_FLUSH) == "request_flush" - ), "The str value must be request_flush" - assert ( - str(AbciMessage.Performative.REQUEST_INFO) == "request_info" - ), "The str value must be request_info" - assert ( - str(AbciMessage.Performative.REQUEST_INIT_CHAIN) == "request_init_chain" - ), "The str value must be request_init_chain" - assert ( - str(AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS) == "request_list_snapshots" - ), "The str value must be request_list_snapshots" - assert ( - str(AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK) - == "request_load_snapshot_chunk" - ), "The str value must be request_load_snapshot_chunk" - assert ( - str(AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT) == "request_offer_snapshot" - ), "The str value must be request_offer_snapshot" - assert ( - str(AbciMessage.Performative.REQUEST_QUERY) == "request_query" - ), "The str value must be request_query" - assert ( - str(AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK) - == "response_apply_snapshot_chunk" - ), "The str value must be response_apply_snapshot_chunk" - assert ( - str(AbciMessage.Performative.RESPONSE_BEGIN_BLOCK) == "response_begin_block" - ), "The str value must be response_begin_block" - assert ( - str(AbciMessage.Performative.RESPONSE_CHECK_TX) == "response_check_tx" - ), "The str value must be response_check_tx" - assert ( - str(AbciMessage.Performative.RESPONSE_COMMIT) == "response_commit" - ), "The str value must be response_commit" - assert ( - str(AbciMessage.Performative.RESPONSE_DELIVER_TX) == "response_deliver_tx" - ), "The str value must be response_deliver_tx" - assert ( - str(AbciMessage.Performative.RESPONSE_ECHO) == "response_echo" - ), "The str value must be response_echo" - assert ( - str(AbciMessage.Performative.RESPONSE_END_BLOCK) == "response_end_block" - ), "The str value must be response_end_block" - assert ( - str(AbciMessage.Performative.RESPONSE_EXCEPTION) == "response_exception" - ), "The str value must be response_exception" - assert ( - str(AbciMessage.Performative.RESPONSE_FLUSH) == "response_flush" - ), "The str value must be response_flush" - assert ( - str(AbciMessage.Performative.RESPONSE_INFO) == "response_info" - ), "The str value must be response_info" - assert ( - str(AbciMessage.Performative.RESPONSE_INIT_CHAIN) == "response_init_chain" - ), "The str value must be response_init_chain" - assert ( - str(AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS) - == "response_list_snapshots" - ), "The str value must be response_list_snapshots" - assert ( - str(AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK) - == "response_load_snapshot_chunk" - ), "The str value must be response_load_snapshot_chunk" - assert ( - str(AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT) - == "response_offer_snapshot" - ), "The str value must be response_offer_snapshot" - assert ( - str(AbciMessage.Performative.RESPONSE_QUERY) == "response_query" - ), "The str value must be response_query" - assert ( - str(AbciMessage.Performative.RESPONSE_SET_OPTION) == "response_set_option" - ), "The str value must be response_set_option" - assert ( - str(AbciMessage.Performative.REQUEST_SET_OPTION) == "request_set_option" - ), "The str value must be request_set_option" - - -def test_encoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = AbciMessage( - performative=AbciMessage.Performative.REQUEST_ECHO, message="Hello" # type: ignore - ) - - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object(AbciMessage.Performative, "__eq__", return_value=False): - AbciMessage.serializer.encode(msg) - - -def test_decoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = AbciMessage( - performative=AbciMessage.Performative.REQUEST_ECHO, message="Hello" # type: ignore - ) - - encoded_msg = AbciMessage.serializer.encode(msg) - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object(AbciMessage.Performative, "__eq__", return_value=False): - AbciMessage.serializer.decode(encoded_msg) - - -class AgentDialogue(AbciDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[AbciMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - AbciDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class AgentDialogues(AbciDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.CLIENT - - AbciDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=AgentDialogue, - ) - - -class ServerDialogue(AbciDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[AbciMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - AbciDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class ServerDialogues(AbciDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.SERVER - - AbciDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=ServerDialogue, - ) - - -class TestDialogues: - """Tests abci dialogues.""" - - agent_addr: str - server_addr: str - agent_dialogues: AgentDialogues - server_dialogues: ServerDialogues - - @classmethod - def setup_class(cls) -> None: - """Set up the test.""" - cls.agent_addr = "agent address" - cls.server_addr = "server address" - cls.agent_dialogues = AgentDialogues(cls.agent_addr) - cls.server_dialogues = ServerDialogues(cls.server_addr) - - def test_create_self_initiated(self) -> None: - """Test the self initialisation of a dialogue.""" - result = self.agent_dialogues._create_self_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.server_addr, - dialogue_reference=(str(0), ""), - role=AbciDialogue.Role.CLIENT, - ) - assert isinstance(result, AbciDialogue) - assert result.role == AbciDialogue.Role.CLIENT, "The role must be client." - - def test_create_opponent_initiated(self) -> None: - """Test the opponent initialisation of a dialogue.""" - result = self.agent_dialogues._create_opponent_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.server_addr, - dialogue_reference=(str(0), ""), - role=AbciDialogue.Role.CLIENT, - ) - assert isinstance(result, AbciDialogue) - assert result.role == AbciDialogue.Role.CLIENT, "The role must be client." diff --git a/trader_backup/vendor/valory/protocols/abci/tests/test_abci_dialogues.py b/trader_backup/vendor/valory/protocols/abci/tests/test_abci_dialogues.py deleted file mode 100644 index e6055a9cf..000000000 --- a/trader_backup/vendor/valory/protocols/abci/tests/test_abci_dialogues.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for abci protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.abci.dialogues import AbciDialogue, AbciDialogues -from packages.valory.protocols.abci.message import AbciMessage - - -class TestDialoguesAbci(BaseProtocolDialoguesTestCase): - """Test for the 'abci' protocol dialogues.""" - - MESSAGE_CLASS = AbciMessage - - DIALOGUE_CLASS = AbciDialogue - - DIALOGUES_CLASS = AbciDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = AbciDialogue.Role.CLIENT # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=AbciMessage.Performative.REQUEST_ECHO, - message="some str", - ) diff --git a/trader_backup/vendor/valory/protocols/abci/tests/test_abci_messages.py b/trader_backup/vendor/valory/protocols/abci/tests/test_abci_messages.py deleted file mode 100644 index 40f3a799c..000000000 --- a/trader_backup/vendor/valory/protocols/abci/tests/test_abci_messages.py +++ /dev/null @@ -1,491 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for abci protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.abci.custom_types import ( - BlockID, - BlockParams, - CheckTxType, - CheckTxTypeEnum, - ConsensusParams, - ConsensusVersion, - Duration, - Event, - EventAttribute, - Events, - Evidence, - EvidenceParams, - EvidenceType, - Evidences, - Header, - LastCommitInfo, - PartSetHeader, - ProofOp, - ProofOps, - PublicKey, - Result, - ResultType, - SnapShots, - Snapshot, - Timestamp, - Validator, - ValidatorParams, - ValidatorUpdate, - ValidatorUpdates, - VersionParams, - VoteInfo, -) -from packages.valory.protocols.abci.message import AbciMessage - - -event = Event("type", [EventAttribute(b"key", b"value", True)]) -events = Events([event, event]) - -header = Header( - ConsensusVersion(0, 0), - "chain_id", - 0, - Timestamp(0, 0), - BlockID(b"hash", PartSetHeader(0, b"hash")), - b"last_commit_hash", - b"data_hash", - b"validators_hash", - b"next_validators_hash", - b"consensus_hash", - b"app_hash", - b"last_results_hash", - b"evidence_hash", - b"proposer_address", -) - -validator = Validator(b"address", 0) -last_commit_info = LastCommitInfo( - 0, - [ - VoteInfo(validator, True), - VoteInfo(validator, False), - ], -) - -consensus_params = ConsensusParams( - BlockParams(0, 0), - EvidenceParams(0, Duration(0, 0), 0), - ValidatorParams(["pub_key"]), - VersionParams(0), -) - -evidences = Evidences( - [ - Evidence(EvidenceType.UNKNOWN, validator, 0, Timestamp(0, 0), 0), - Evidence(EvidenceType.DUPLICATE_VOTE, validator, 0, Timestamp(0, 0), 0), - ] -) - - -validators = ValidatorUpdates( - [ - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.ed25519), 1 - ), - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.secp256k1), 2 - ), - ] -) -snapshot = Snapshot(0, 0, 0, b"hash", b"metadata") -snapshots = SnapShots([snapshot, snapshot]) -proof_ops = ( - ProofOps( - [ - ProofOp("type", b"key", b"data"), - ProofOp("type", b"key", b"data"), - ] - ), -) - - -class TestMessageAbci(BaseProtocolMessagesTestCase): - """Test for the 'abci' protocol message.""" - - MESSAGE_CLASS = AbciMessage - - def build_messages(self) -> List[AbciMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - AbciMessage( - performative=AbciMessage.Performative.REQUEST_ECHO, - message="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_FLUSH, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_INFO, - version="some str", - block_version=12, - p2p_version=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_SET_OPTION, - option_key="some str", - option_value="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_INIT_CHAIN, - time=Timestamp(seconds=1, nanos=1), - chain_id="some str", - consensus_params=consensus_params, - validators=validators, - app_state_bytes=b"some_bytes", - initial_height=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_QUERY, - query_data=b"some_bytes", - path="some str", - height=12, - prove=True, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_BEGIN_BLOCK, - hash=b"some_bytes", - header=header, - last_commit_info=last_commit_info, - byzantine_validators=evidences, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_CHECK_TX, - tx=b"some_bytes", - type=CheckTxType(CheckTxTypeEnum.NEW), - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - tx=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_END_BLOCK, - height=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_COMMIT, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT, - snapshot=Snapshot(0, 0, 0, b"hash", b"metadata"), - app_hash=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK, - height=12, - format=12, - chunk_index=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK, - index=12, - chunk=b"some_bytes", - chunk_sender="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_EXCEPTION, - error="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_ECHO, - message="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_FLUSH, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_INFO, - info_data="some str", - version="some str", - app_version=12, - last_block_height=12, - last_block_app_hash=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_SET_OPTION, - code=12, - log="some str", - info="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_INIT_CHAIN, - consensus_params=consensus_params, - validators=validators, - app_hash=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_QUERY, - code=12, - log="some str", - info="some str", - index=12, - key=b"some_bytes", - value=b"some_bytes", - proof_ops=ProofOps( - [ - ProofOp("type", b"key", b"data"), - ProofOp("type", b"key", b"data"), - ] - ), - height=12, - codespace="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, - events=events, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, - code=12, - data=b"some_bytes", - log="some str", - info="some str", - gas_wanted=12, - gas_used=12, - events=events, - codespace="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, - code=12, - data=b"some_bytes", - log="some str", - info="some str", - gas_wanted=12, - gas_used=12, - events=events, - codespace="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_END_BLOCK, - validator_updates=validators, - consensus_param_updates=consensus_params, - events=events, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_COMMIT, - data=b"some_bytes", - retain_height=12, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, - snapshots=snapshots, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, - result=Result(ResultType.UNKNOWN), - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, - chunk=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, - result=Result(ResultType.UNKNOWN), - refetch_chunks=(12,), - reject_senders=("some str",), - ), - AbciMessage( - performative=AbciMessage.Performative.DUMMY, - dummy_consensus_params=consensus_params, - ), - ] - - def build_inconsistent(self) -> List[AbciMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - AbciMessage( - performative=AbciMessage.Performative.REQUEST_ECHO, - # skip content: message - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_INFO, - # skip content: version - block_version=12, - p2p_version=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_SET_OPTION, - # skip content: option_key - option_value="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_INIT_CHAIN, - # skip content: time,app_state_bytes - chain_id="some str", - consensus_params=consensus_params, - validators=validators, - initial_height=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_QUERY, - # skip content: query_data - path="some str", - height=12, - prove=True, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_BEGIN_BLOCK, - # skip content: hash - header=header, - last_commit_info=last_commit_info, - byzantine_validators=evidences, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_CHECK_TX, - # skip content: tx - type=CheckTxType(CheckTxTypeEnum.NEW), - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - # skip content: tx - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_END_BLOCK, - # skip content: height - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT, - # skip content: snapshot - app_hash=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK, - # skip content: height - format=12, - chunk_index=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK, - # skip content: index - chunk=b"some_bytes", - chunk_sender="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_EXCEPTION, - # skip content: error - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_ECHO, - # skip content: message - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_INFO, - # skip content: info_data - version="some str", - app_version=12, - last_block_height=12, - last_block_app_hash=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_SET_OPTION, - # skip content: code - log="some str", - info="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_INIT_CHAIN, - # skip content: consensus_params, validators - app_hash=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_QUERY, - # skip content: code - log="some str", - info="some str", - index=12, - key=b"some_bytes", - value=b"some_bytes", - proof_ops=proof_ops, - height=12, - codespace="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, - # skip content: events - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, - # skip content: code - data=b"some_bytes", - log="some str", - info="some str", - gas_wanted=12, - gas_used=12, - events=events, - codespace="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, - # skip content: code - data=b"some_bytes", - log="some str", - info="some str", - gas_wanted=12, - gas_used=12, - events=events, - codespace="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_END_BLOCK, - # skip content: validator_updates - consensus_param_updates=consensus_params, - events=events, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_COMMIT, - # skip content: data - retain_height=12, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, - # skip content: snapshots - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, - # skip content: result - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, - # skip content: chunk - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, - # skip content: result - refetch_chunks=(12,), - reject_senders=("some str",), - ), - AbciMessage( - performative=AbciMessage.Performative.DUMMY, - # skip content: dummy_consensus_params - ), - ] diff --git a/trader_backup/vendor/valory/protocols/acn/README.md b/trader_backup/vendor/valory/protocols/acn/README.md deleted file mode 100644 index 7c44e6b2d..000000000 --- a/trader_backup/vendor/valory/protocols/acn/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# ACN Protocol - -## Description - -This is a protocol for ACN (agent communication network) envelope delivery. - -## Specification - -```yaml ---- -name: acn -author: valory -version: 1.1.0 -description: The protocol used for envelope delivery on the ACN. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: aea/acn:1.0.0 -speech_acts: - register: - record: ct:AgentRecord - lookup_request: - agent_address: pt:str - lookup_response: - record: ct:AgentRecord - aea_envelope: - envelope: pt:bytes - record: ct:AgentRecord - status: - body: ct:StatusBody -... ---- -ct:AgentRecord: - string service_id = 1; - string ledger_id = 2; - string address = 3; - string public_key = 4; - string peer_public_key = 5; - string signature = 6; - string not_before = 7; - string not_after = 8; -ct:StatusBody: | - enum StatusCodeEnum { - // common (0x) - SUCCESS = 0; - ERROR_UNSUPPORTED_VERSION = 1; - ERROR_UNEXPECTED_PAYLOAD = 2; - ERROR_GENERIC = 3; - ERROR_DECODE = 4; - // register (1x) - ERROR_WRONG_AGENT_ADDRESS = 10; - ERROR_WRONG_PUBLIC_KEY = 11; - ERROR_INVALID_PROOF = 12; - ERROR_UNSUPPORTED_LEDGER = 13; - // lookup & delivery (2x) - ERROR_UNKNOWN_AGENT_ADDRESS = 20; - ERROR_AGENT_NOT_READY = 21; - } - StatusCodeEnum code = 1; - repeated string msgs = 2; -... ---- -initiation: [register, lookup_request, aea_envelope] -reply: - register: [status] - lookup_request: [lookup_response, status] - aea_envelope: [status] - status: [] - lookup_response: [] -termination: [status, lookup_response] -roles: {node} -end_states: [successful, failed] -keep_terminal_state_dialogues: false -... -``` - -## Links diff --git a/trader_backup/vendor/valory/protocols/acn/__init__.py b/trader_backup/vendor/valory/protocols/acn/__init__.py deleted file mode 100644 index 6d72792dc..000000000 --- a/trader_backup/vendor/valory/protocols/acn/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the acn protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.acn.message import AcnMessage -from packages.valory.protocols.acn.serialization import AcnSerializer - - -AcnMessage.serializer = AcnSerializer diff --git a/trader_backup/vendor/valory/protocols/acn/acn.proto b/trader_backup/vendor/valory/protocols/acn/acn.proto deleted file mode 100644 index a2c2dc25d..000000000 --- a/trader_backup/vendor/valory/protocols/acn/acn.proto +++ /dev/null @@ -1,71 +0,0 @@ -syntax = "proto3"; - -package aea.aea.acn.v1_0_0; - -message AcnMessage{ - - // Custom Types - message AgentRecord{ - string service_id = 1; - string ledger_id = 2; - string address = 3; - string public_key = 4; - string peer_public_key = 5; - string signature = 6; - string not_before = 7; - string not_after = 8; - } - - message StatusBody{ - enum StatusCodeEnum { - // common (0x) - SUCCESS = 0; - ERROR_UNSUPPORTED_VERSION = 1; - ERROR_UNEXPECTED_PAYLOAD = 2; - ERROR_GENERIC = 3; - ERROR_DECODE = 4; - // register (1x) - ERROR_WRONG_AGENT_ADDRESS = 10; - ERROR_WRONG_PUBLIC_KEY = 11; - ERROR_INVALID_PROOF = 12; - ERROR_UNSUPPORTED_LEDGER = 13; - // lookup & delivery (2x) - ERROR_UNKNOWN_AGENT_ADDRESS = 20; - ERROR_AGENT_NOT_READY = 21; - } - StatusCodeEnum code = 1; - repeated string msgs = 2; - } - - - // Performatives and contents - message Register_Performative{ - AgentRecord record = 1; - } - - message Lookup_Request_Performative{ - string agent_address = 1; - } - - message Lookup_Response_Performative{ - AgentRecord record = 1; - } - - message Aea_Envelope_Performative{ - bytes envelope = 1; - AgentRecord record = 2; - } - - message Status_Performative{ - StatusBody body = 1; - } - - - oneof performative{ - Aea_Envelope_Performative aea_envelope = 5; - Lookup_Request_Performative lookup_request = 6; - Lookup_Response_Performative lookup_response = 7; - Register_Performative register = 8; - Status_Performative status = 9; - } -} diff --git a/trader_backup/vendor/valory/protocols/acn/acn_pb2.py b/trader_backup/vendor/valory/protocols/acn/acn_pb2.py deleted file mode 100644 index 9047a16ea..000000000 --- a/trader_backup/vendor/valory/protocols/acn/acn_pb2.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: acn.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\tacn.proto\x12\x12\x61\x65\x61.aea.acn.v1_0_0"\x92\x0b\n\nAcnMessage\x12P\n\x0c\x61\x65\x61_envelope\x18\x05 \x01(\x0b\x32\x38.aea.aea.acn.v1_0_0.AcnMessage.Aea_Envelope_PerformativeH\x00\x12T\n\x0elookup_request\x18\x06 \x01(\x0b\x32:.aea.aea.acn.v1_0_0.AcnMessage.Lookup_Request_PerformativeH\x00\x12V\n\x0flookup_response\x18\x07 \x01(\x0b\x32;.aea.aea.acn.v1_0_0.AcnMessage.Lookup_Response_PerformativeH\x00\x12H\n\x08register\x18\x08 \x01(\x0b\x32\x34.aea.aea.acn.v1_0_0.AcnMessage.Register_PerformativeH\x00\x12\x44\n\x06status\x18\t \x01(\x0b\x32\x32.aea.aea.acn.v1_0_0.AcnMessage.Status_PerformativeH\x00\x1a\xac\x01\n\x0b\x41gentRecord\x12\x12\n\nservice_id\x18\x01 \x01(\t\x12\x11\n\tledger_id\x18\x02 \x01(\t\x12\x0f\n\x07\x61\x64\x64ress\x18\x03 \x01(\t\x12\x12\n\npublic_key\x18\x04 \x01(\t\x12\x17\n\x0fpeer_public_key\x18\x05 \x01(\t\x12\x11\n\tsignature\x18\x06 \x01(\t\x12\x12\n\nnot_before\x18\x07 \x01(\t\x12\x11\n\tnot_after\x18\x08 \x01(\t\x1a\x92\x03\n\nStatusBody\x12\x46\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x38.aea.aea.acn.v1_0_0.AcnMessage.StatusBody.StatusCodeEnum\x12\x0c\n\x04msgs\x18\x02 \x03(\t"\xad\x02\n\x0eStatusCodeEnum\x12\x0b\n\x07SUCCESS\x10\x00\x12\x1d\n\x19\x45RROR_UNSUPPORTED_VERSION\x10\x01\x12\x1c\n\x18\x45RROR_UNEXPECTED_PAYLOAD\x10\x02\x12\x11\n\rERROR_GENERIC\x10\x03\x12\x10\n\x0c\x45RROR_DECODE\x10\x04\x12\x1d\n\x19\x45RROR_WRONG_AGENT_ADDRESS\x10\n\x12\x1a\n\x16\x45RROR_WRONG_PUBLIC_KEY\x10\x0b\x12\x17\n\x13\x45RROR_INVALID_PROOF\x10\x0c\x12\x1c\n\x18\x45RROR_UNSUPPORTED_LEDGER\x10\r\x12\x1f\n\x1b\x45RROR_UNKNOWN_AGENT_ADDRESS\x10\x14\x12\x19\n\x15\x45RROR_AGENT_NOT_READY\x10\x15\x1aS\n\x15Register_Performative\x12:\n\x06record\x18\x01 \x01(\x0b\x32*.aea.aea.acn.v1_0_0.AcnMessage.AgentRecord\x1a\x34\n\x1bLookup_Request_Performative\x12\x15\n\ragent_address\x18\x01 \x01(\t\x1aZ\n\x1cLookup_Response_Performative\x12:\n\x06record\x18\x01 \x01(\x0b\x32*.aea.aea.acn.v1_0_0.AcnMessage.AgentRecord\x1ai\n\x19\x41\x65\x61_Envelope_Performative\x12\x10\n\x08\x65nvelope\x18\x01 \x01(\x0c\x12:\n\x06record\x18\x02 \x01(\x0b\x32*.aea.aea.acn.v1_0_0.AcnMessage.AgentRecord\x1aN\n\x13Status_Performative\x12\x37\n\x04\x62ody\x18\x01 \x01(\x0b\x32).aea.aea.acn.v1_0_0.AcnMessage.StatusBodyB\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "acn_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals["_ACNMESSAGE"]._serialized_start = 34 - _globals["_ACNMESSAGE"]._serialized_end = 1460 - _globals["_ACNMESSAGE_AGENTRECORD"]._serialized_start = 449 - _globals["_ACNMESSAGE_AGENTRECORD"]._serialized_end = 621 - _globals["_ACNMESSAGE_STATUSBODY"]._serialized_start = 624 - _globals["_ACNMESSAGE_STATUSBODY"]._serialized_end = 1026 - _globals["_ACNMESSAGE_STATUSBODY_STATUSCODEENUM"]._serialized_start = 725 - _globals["_ACNMESSAGE_STATUSBODY_STATUSCODEENUM"]._serialized_end = 1026 - _globals["_ACNMESSAGE_REGISTER_PERFORMATIVE"]._serialized_start = 1028 - _globals["_ACNMESSAGE_REGISTER_PERFORMATIVE"]._serialized_end = 1111 - _globals["_ACNMESSAGE_LOOKUP_REQUEST_PERFORMATIVE"]._serialized_start = 1113 - _globals["_ACNMESSAGE_LOOKUP_REQUEST_PERFORMATIVE"]._serialized_end = 1165 - _globals["_ACNMESSAGE_LOOKUP_RESPONSE_PERFORMATIVE"]._serialized_start = 1167 - _globals["_ACNMESSAGE_LOOKUP_RESPONSE_PERFORMATIVE"]._serialized_end = 1257 - _globals["_ACNMESSAGE_AEA_ENVELOPE_PERFORMATIVE"]._serialized_start = 1259 - _globals["_ACNMESSAGE_AEA_ENVELOPE_PERFORMATIVE"]._serialized_end = 1364 - _globals["_ACNMESSAGE_STATUS_PERFORMATIVE"]._serialized_start = 1366 - _globals["_ACNMESSAGE_STATUS_PERFORMATIVE"]._serialized_end = 1444 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/protocols/acn/custom_types.py b/trader_backup/vendor/valory/protocols/acn/custom_types.py deleted file mode 100644 index bb7069c1c..000000000 --- a/trader_backup/vendor/valory/protocols/acn/custom_types.py +++ /dev/null @@ -1,224 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 class representations corresponding to every custom type in the protocol specification.""" -# pylint: disable-all -from enum import Enum -from typing import Any, List - -from aea.helpers.base import SimpleId, SimpleIdOrStr - - -class AgentRecord: - """ - This class represents an instance of AgentRecord. - - Eventually needs to be unified with `aea.helpers.acn.agent_record`. - """ - - __slots__ = ( - "_address", - "_public_key", - "_peer_public_key", - "_signature", - "_service_id", - "_ledger_id", - "_message_format", - "_message", - ) - - def __init__( - self, - address: str, - public_key: str, - peer_public_key: str, - signature: str, - service_id: SimpleIdOrStr, - ledger_id: SimpleIdOrStr, - ) -> None: - """Initialise an instance of AgentRecord.""" - self._address = address - self._public_key = public_key - self._peer_public_key = peer_public_key - self._signature = signature - self._service_id = str(SimpleId(service_id)) - self._ledger_id = str(SimpleId(ledger_id)) - - @property - def address(self) -> str: - """Get agent address""" - return self._address - - @property - def public_key(self) -> str: - """Get agent public key""" - return self._public_key - - @property - def peer_public_key(self) -> str: - """Get agent representative's public key""" - return self._peer_public_key - - @property - def signature(self) -> str: - """Get record signature""" - return self._signature - - @property - def service_id(self) -> SimpleIdOrStr: - """Get the identifier.""" - return self._service_id - - @property - def ledger_id(self) -> SimpleIdOrStr: - """Get ledger id.""" - return self._ledger_id - - @staticmethod - def encode( - agent_record_protobuf_object: Any, agent_record_object: "AgentRecord" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the agent_record_protobuf_object argument is matched with the instance of this class in the 'agent_record_object' argument. - - :param agent_record_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param agent_record_object: an instance of this class to be encoded in the protocol buffer object. - """ - agent_record_protobuf_object.address = agent_record_object.address - agent_record_protobuf_object.public_key = agent_record_object.public_key - agent_record_protobuf_object.peer_public_key = ( - agent_record_object.peer_public_key - ) - agent_record_protobuf_object.signature = agent_record_object.signature - agent_record_protobuf_object.service_id = agent_record_object.service_id - agent_record_protobuf_object.ledger_id = agent_record_object.ledger_id - - @classmethod - def decode(cls, agent_record_protobuf_object: Any) -> "AgentRecord": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'agent_record_protobuf_object' argument. - - :param agent_record_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'agent_record_protobuf_object' argument. - """ - record = cls( - address=agent_record_protobuf_object.address, - public_key=agent_record_protobuf_object.public_key, - peer_public_key=agent_record_protobuf_object.peer_public_key, - signature=agent_record_protobuf_object.signature, - service_id=agent_record_protobuf_object.service_id, - ledger_id=agent_record_protobuf_object.ledger_id, - ) - return record - - def __eq__(self, other: Any) -> bool: - """Compare to objects of this class.""" - return ( - isinstance(other, AgentRecord) - and self.address == other.address - and self.public_key == other.public_key - ) - - -class StatusBody: - """This class represents an instance of StatusBody.""" - - __slots__ = ( - "_status_code", - "_msgs", - ) - - class StatusCode(Enum): - """Status code enum.""" - - SUCCESS = 0 - ERROR_UNSUPPORTED_VERSION = 1 - ERROR_UNEXPECTED_PAYLOAD = 2 - ERROR_GENERIC = 3 - ERROR_DECODE = 4 - - ERROR_WRONG_AGENT_ADDRESS = 10 - ERROR_WRONG_PUBLIC_KEY = 11 - ERROR_INVALID_PROOF = 12 - ERROR_UNSUPPORTED_LEDGER = 13 - - ERROR_UNKNOWN_AGENT_ADDRESS = 20 - ERROR_AGENT_NOT_READY = 21 - - def __int__(self) -> int: - """Get string representation.""" - return self.value - - def __init__(self, status_code: StatusCode, msgs: List[str]) -> None: - """Initialise an instance of StatusBody.""" - self._status_code = status_code - self._msgs = msgs - - @property - def status_code(self) -> "StatusCode": - """Get the status code.""" - return self._status_code - - @property - def msgs(self) -> List[str]: - """Get the list of messages.""" - return self._msgs - - @staticmethod - def encode( - status_body_protobuf_object: Any, status_body_object: "StatusBody" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the status_body_protobuf_object argument is matched with the instance of this class in the 'status_body_object' argument. - - :param status_body_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param status_body_object: an instance of this class to be encoded in the protocol buffer object. - """ - status_body_protobuf_object.code = int(status_body_object.status_code) - status_body_protobuf_object.msgs.extend(status_body_object.msgs) - - @classmethod - def decode(cls, status_body_protobuf_object: Any) -> "StatusBody": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'status_body_protobuf_object' argument. - - :param status_body_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'status_body_protobuf_object' argument. - """ - status_body = cls( - status_code=cls.StatusCode(status_body_protobuf_object.code), - msgs=status_body_protobuf_object.msgs, - ) - return status_body - - def __eq__(self, other: Any) -> bool: - """Compare to objects of this class.""" - return ( - isinstance(other, StatusBody) - and self.status_code == other.status_code - and self.msgs == other.msgs - ) diff --git a/trader_backup/vendor/valory/protocols/acn/dialogues.py b/trader_backup/vendor/valory/protocols/acn/dialogues.py deleted file mode 100644 index 90b88ea30..000000000 --- a/trader_backup/vendor/valory/protocols/acn/dialogues.py +++ /dev/null @@ -1,126 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for acn dialogue management. - -- AcnDialogue: The dialogue class maintains state of a dialogue and manages it. -- AcnDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.acn.message import AcnMessage - - -class AcnDialogue(Dialogue): - """The acn dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - AcnMessage.Performative.REGISTER, - AcnMessage.Performative.LOOKUP_REQUEST, - AcnMessage.Performative.AEA_ENVELOPE, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - {AcnMessage.Performative.STATUS, AcnMessage.Performative.LOOKUP_RESPONSE} - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - AcnMessage.Performative.AEA_ENVELOPE: frozenset( - {AcnMessage.Performative.STATUS} - ), - AcnMessage.Performative.LOOKUP_REQUEST: frozenset( - {AcnMessage.Performative.LOOKUP_RESPONSE, AcnMessage.Performative.STATUS} - ), - AcnMessage.Performative.LOOKUP_RESPONSE: frozenset(), - AcnMessage.Performative.REGISTER: frozenset({AcnMessage.Performative.STATUS}), - AcnMessage.Performative.STATUS: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a acn dialogue.""" - - NODE = "node" - - class EndState(Dialogue.EndState): - """This class defines the end states of a acn dialogue.""" - - SUCCESSFUL = 0 - FAILED = 1 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[AcnMessage] = AcnMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class AcnDialogues(Dialogues, ABC): - """This class keeps track of all acn dialogues.""" - - END_STATES = frozenset( - {AcnDialogue.EndState.SUCCESSFUL, AcnDialogue.EndState.FAILED} - ) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[AcnDialogue] = AcnDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=AcnMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_backup/vendor/valory/protocols/acn/message.py b/trader_backup/vendor/valory/protocols/acn/message.py deleted file mode 100644 index 5ef50253e..000000000 --- a/trader_backup/vendor/valory/protocols/acn/message.py +++ /dev/null @@ -1,274 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 acn's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - -from packages.valory.protocols.acn.custom_types import AgentRecord as CustomAgentRecord -from packages.valory.protocols.acn.custom_types import StatusBody as CustomStatusBody - - -_default_logger = logging.getLogger("aea.packages.valory.protocols.acn.message") - -DEFAULT_BODY_SIZE = 4 - - -class AcnMessage(Message): - """The protocol used for envelope delivery on the ACN.""" - - protocol_id = PublicId.from_str("valory/acn:1.1.0") - protocol_specification_id = PublicId.from_str("aea/acn:1.0.0") - - AgentRecord = CustomAgentRecord - - StatusBody = CustomStatusBody - - class Performative(Message.Performative): - """Performatives for the acn protocol.""" - - AEA_ENVELOPE = "aea_envelope" - LOOKUP_REQUEST = "lookup_request" - LOOKUP_RESPONSE = "lookup_response" - REGISTER = "register" - STATUS = "status" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = { - "aea_envelope", - "lookup_request", - "lookup_response", - "register", - "status", - } - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "agent_address", - "body", - "dialogue_reference", - "envelope", - "message_id", - "performative", - "record", - "target", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of AcnMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=AcnMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(AcnMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def agent_address(self) -> str: - """Get the 'agent_address' content from the message.""" - enforce(self.is_set("agent_address"), "'agent_address' content is not set.") - return cast(str, self.get("agent_address")) - - @property - def body(self) -> CustomStatusBody: - """Get the 'body' content from the message.""" - enforce(self.is_set("body"), "'body' content is not set.") - return cast(CustomStatusBody, self.get("body")) - - @property - def envelope(self) -> bytes: - """Get the 'envelope' content from the message.""" - enforce(self.is_set("envelope"), "'envelope' content is not set.") - return cast(bytes, self.get("envelope")) - - @property - def record(self) -> CustomAgentRecord: - """Get the 'record' content from the message.""" - enforce(self.is_set("record"), "'record' content is not set.") - return cast(CustomAgentRecord, self.get("record")) - - def _is_consistent(self) -> bool: - """Check that the message follows the acn protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, AcnMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == AcnMessage.Performative.REGISTER: - expected_nb_of_contents = 1 - enforce( - isinstance(self.record, CustomAgentRecord), - "Invalid type for content 'record'. Expected 'AgentRecord'. Found '{}'.".format( - type(self.record) - ), - ) - elif self.performative == AcnMessage.Performative.LOOKUP_REQUEST: - expected_nb_of_contents = 1 - enforce( - isinstance(self.agent_address, str), - "Invalid type for content 'agent_address'. Expected 'str'. Found '{}'.".format( - type(self.agent_address) - ), - ) - elif self.performative == AcnMessage.Performative.LOOKUP_RESPONSE: - expected_nb_of_contents = 1 - enforce( - isinstance(self.record, CustomAgentRecord), - "Invalid type for content 'record'. Expected 'AgentRecord'. Found '{}'.".format( - type(self.record) - ), - ) - elif self.performative == AcnMessage.Performative.AEA_ENVELOPE: - expected_nb_of_contents = 2 - enforce( - isinstance(self.envelope, bytes), - "Invalid type for content 'envelope'. Expected 'bytes'. Found '{}'.".format( - type(self.envelope) - ), - ) - enforce( - isinstance(self.record, CustomAgentRecord), - "Invalid type for content 'record'. Expected 'AgentRecord'. Found '{}'.".format( - type(self.record) - ), - ) - elif self.performative == AcnMessage.Performative.STATUS: - expected_nb_of_contents = 1 - enforce( - isinstance(self.body, CustomStatusBody), - "Invalid type for content 'body'. Expected 'StatusBody'. Found '{}'.".format( - type(self.body) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_backup/vendor/valory/protocols/acn/protocol.yaml b/trader_backup/vendor/valory/protocols/acn/protocol.yaml deleted file mode 100644 index 2062cfb93..000000000 --- a/trader_backup/vendor/valory/protocols/acn/protocol.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: acn -author: valory -version: 1.1.0 -protocol_specification_id: aea/acn:1.0.0 -type: protocol -description: The protocol used for envelope delivery on the ACN. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeie7paijucvzemlfhwfmmhorypwuhzbeimgoitlkokdio5c3ne4pjq - __init__.py: bafybeicqlp4gkeeef5osp6zopjztlgat24nxrzq43cy7wbwxk5omf2sc2m - acn.proto: bafybeidkun7o75sxpyk2sixt7dsykgty62f6dnixnes2irbunyamilqsh4 - acn_pb2.py: bafybeialafz3yomunwa3g5xgrdqwodzl7zg5dncvzuetv7xoew4zhw76ni - custom_types.py: bafybeigpueuq6mdeyjyayzv3menkmemutfgfiwlozlpl64t67cfnnom24q - dialogues.py: bafybeidjpyk7s3getyfegjdrgrt5blf2yutzqclohaktjehwcj3sqx2ole - message.py: bafybeiai7kond3rcbtwnr5xgpwzuauf5tusuep6ikopi4cqvp2wa5qfz3e - serialization.py: bafybeidu7fzixk6sm3iprhph4shbiq5qgvg56lg4yiryfaf3unuqk34bwi - tests/__init__.py: bafybeidteufp2npjd77ekcftk5e4gbaquq3gike5nxtk5xfmnusls56keu - tests/test_acn.py: bafybeignjgdtlfdnj25hc5necmg7zl3kvngsmzkjgcwfm5qg36liqa63ki - tests/test_acn_dialogues.py: bafybeia2kndutaokjpogo4wlb5pf4gkqacvcbngqromf4g4mzu6wyetz7q - tests/test_acn_messages.py: bafybeigriniqu3tfzeok7rjx3widzclyjqgjhkunkgt657lpng23mo7oxa -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_backup/vendor/valory/protocols/acn/serialization.py b/trader_backup/vendor/valory/protocols/acn/serialization.py deleted file mode 100644 index 4bf68c321..000000000 --- a/trader_backup/vendor/valory/protocols/acn/serialization.py +++ /dev/null @@ -1,149 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for acn protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.acn import acn_pb2 # type: ignore -from packages.valory.protocols.acn.custom_types import ( # type: ignore - AgentRecord, - StatusBody, -) -from packages.valory.protocols.acn.message import AcnMessage # type: ignore - - -class AcnSerializer(Serializer): - """Serialization for the 'acn' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'Acn' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(AcnMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - acn_msg = acn_pb2.AcnMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == AcnMessage.Performative.REGISTER: - performative = acn_pb2.AcnMessage.Register_Performative() # type: ignore - record = msg.record - AgentRecord.encode(performative.record, record) - acn_msg.register.CopyFrom(performative) - elif performative_id == AcnMessage.Performative.LOOKUP_REQUEST: - performative = acn_pb2.AcnMessage.Lookup_Request_Performative() # type: ignore - agent_address = msg.agent_address - performative.agent_address = agent_address - acn_msg.lookup_request.CopyFrom(performative) - elif performative_id == AcnMessage.Performative.LOOKUP_RESPONSE: - performative = acn_pb2.AcnMessage.Lookup_Response_Performative() # type: ignore - record = msg.record - AgentRecord.encode(performative.record, record) - acn_msg.lookup_response.CopyFrom(performative) - elif performative_id == AcnMessage.Performative.AEA_ENVELOPE: - performative = acn_pb2.AcnMessage.Aea_Envelope_Performative() # type: ignore - envelope = msg.envelope - performative.envelope = envelope - record = msg.record - AgentRecord.encode(performative.record, record) - acn_msg.aea_envelope.CopyFrom(performative) - elif performative_id == AcnMessage.Performative.STATUS: - performative = acn_pb2.AcnMessage.Status_Performative() # type: ignore - body = msg.body - StatusBody.encode(performative.body, body) - acn_msg.status.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = acn_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'Acn' message. - - :param obj: the bytes object. - :return: the 'Acn' message. - """ - message_pb = ProtobufMessage() - acn_pb = acn_pb2.AcnMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - acn_pb.ParseFromString(message_pb.dialogue_message.content) - performative = acn_pb.WhichOneof("performative") - performative_id = AcnMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == AcnMessage.Performative.REGISTER: - pb2_record = acn_pb.register.record - record = AgentRecord.decode(pb2_record) - performative_content["record"] = record - elif performative_id == AcnMessage.Performative.LOOKUP_REQUEST: - agent_address = acn_pb.lookup_request.agent_address - performative_content["agent_address"] = agent_address - elif performative_id == AcnMessage.Performative.LOOKUP_RESPONSE: - pb2_record = acn_pb.lookup_response.record - record = AgentRecord.decode(pb2_record) - performative_content["record"] = record - elif performative_id == AcnMessage.Performative.AEA_ENVELOPE: - envelope = acn_pb.aea_envelope.envelope - performative_content["envelope"] = envelope - pb2_record = acn_pb.aea_envelope.record - record = AgentRecord.decode(pb2_record) - performative_content["record"] = record - elif performative_id == AcnMessage.Performative.STATUS: - pb2_body = acn_pb.status.body - body = StatusBody.decode(pb2_body) - performative_content["body"] = body - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return AcnMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_backup/vendor/valory/protocols/acn/tests/__init__.py b/trader_backup/vendor/valory/protocols/acn/tests/__init__.py deleted file mode 100644 index 0ca8df4d2..000000000 --- a/trader_backup/vendor/valory/protocols/acn/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""The tests module contains the tests of the acn protocol.""" diff --git a/trader_backup/vendor/valory/protocols/acn/tests/test_acn.py b/trader_backup/vendor/valory/protocols/acn/tests/test_acn.py deleted file mode 100644 index efd8dfa95..000000000 --- a/trader_backup/vendor/valory/protocols/acn/tests/test_acn.py +++ /dev/null @@ -1,256 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 the tests of the messages module.""" - -from typing import Type -from unittest import mock -from unittest.mock import patch - -import pytest - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.acn.dialogues import AcnDialogue as BaseAcnDialogue -from packages.valory.protocols.acn.dialogues import AcnDialogues as BaseAcnDialogues -from packages.valory.protocols.acn.message import AcnMessage - - -def test_acn_aea_envelope_serialization(): - """Test that the serialization for the 'simple' protocol works for the AEA_ENVELOPE message.""" - expected_msg = AcnMessage( - dialogue_reference=("", ""), - message_id=1, - target=0, - performative=AcnMessage.Performative.AEA_ENVELOPE, - envelope=b"envelope", - record=AcnMessage.AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ) - msg_bytes = AcnMessage.serializer.encode(expected_msg) - actual_msg = AcnMessage.serializer.decode(msg_bytes) - assert expected_msg == actual_msg - - -def test_acn_lookup_request_serialization(): - """Test that the serialization for the 'simple' protocol works for the LOOKUP_REQUEST message.""" - msg = AcnMessage( - dialogue_reference=("", ""), - message_id=1, - target=0, - performative=AcnMessage.Performative.LOOKUP_REQUEST, - agent_address="some_address", - ) - msg_bytes = AcnMessage.serializer.encode(msg) - actual_msg = AcnMessage.serializer.decode(msg_bytes) - expected_msg = msg - assert expected_msg == actual_msg - - -def test_acn_lookup_response_serialization(): - """Test that the serialization for the 'simple' protocol works for the LOOKUP_RESPONSE message.""" - msg = AcnMessage( - dialogue_reference=("", ""), - message_id=1, - target=0, - performative=AcnMessage.Performative.LOOKUP_RESPONSE, - record=AcnMessage.AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ) - msg_bytes = AcnMessage.serializer.encode(msg) - actual_msg = AcnMessage.serializer.decode(msg_bytes) - expected_msg = msg - assert expected_msg == actual_msg - - -def test_acn_record_serialization(): - """Test that the serialization for the 'simple' protocol works for the REGISTER message.""" - msg = AcnMessage( - dialogue_reference=("", ""), - message_id=1, - target=0, - performative=AcnMessage.Performative.REGISTER, - record=AcnMessage.AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ) - msg_bytes = AcnMessage.serializer.encode(msg) - actual_msg = AcnMessage.serializer.decode(msg_bytes) - expected_msg = msg - assert expected_msg == actual_msg - - -def test_acn_status_serialization(): - """Test that the serialization for the 'simple' protocol works for the STATUS message.""" - msg = AcnMessage( - dialogue_reference=("", ""), - message_id=1, - target=0, - performative=AcnMessage.Performative.STATUS, - body=AcnMessage.StatusBody( - status_code=AcnMessage.StatusBody.StatusCode.ERROR_UNSUPPORTED_VERSION, - msgs=["pbk"], - ), - ) - msg_bytes = AcnMessage.serializer.encode(msg) - actual_msg = AcnMessage.serializer.decode(msg_bytes) - expected_msg = msg - assert expected_msg == actual_msg - - -def test_acn_message_str_values(): - """Tests the returned string values of acn Message.""" - assert ( - str(AcnMessage.Performative.LOOKUP_REQUEST) == "lookup_request" - ), "AcnMessage.Performative.LOOKUP_REQUEST must be lookup_request" - - -def test_encoding_unknown_performative(): - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = AcnMessage( - performative=AcnMessage.Performative.LOOKUP_REQUEST, - agent_address="address", - ) - - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object(AcnMessage.Performative, "__eq__", return_value=False): - AcnMessage.serializer.encode(msg) - - -def test_check_consistency_raises_exception_when_type_not_recognized(): - """Test that we raise exception when the type of the message is not recognized.""" - message = AcnMessage( - dialogue_reference=("", ""), - message_id=1, - target=0, - performative=AcnMessage.Performative.LOOKUP_REQUEST, - agent_address="address", - ) - # mock the __eq__ method such that any kind of matching is going to fail. - with mock.patch.object(AcnMessage.Performative, "__eq__", return_value=False): - assert not message._is_consistent() # pylint: disable=protected-access - - -def test_acn_valid_performatives(): - """Test 'valid_performatives' getter.""" - msg = AcnMessage(AcnMessage.Performative.LOOKUP_REQUEST, agent_address="address") - assert msg.valid_performatives == set( - map(lambda x: x.value, iter(AcnMessage.Performative)) - ) - - -def test_serializer_performative_not_found(): - """Test the serializer when the performative is not found.""" - message = AcnMessage( - message_id=1, - target=0, - performative=AcnMessage.Performative.LOOKUP_REQUEST, - agent_address="address", - ) - message_bytes = message.serializer.encode(message) - with patch.object(AcnMessage.Performative, "__eq__", return_value=False): - with pytest.raises(ValueError, match="Performative not valid: .*"): - message.serializer.decode(message_bytes) - - -def test_dialogues(): - """Test intiaontiation of dialogues.""" - acn_dialogues = AcnDialogues("agent_addr") - _, dialogue = acn_dialogues.create( - counterparty="abc", - performative=AcnMessage.Performative.LOOKUP_REQUEST, - agent_address="address", - ) - assert dialogue is not None - - -class AcnDialogue(BaseAcnDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[AcnMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - BaseAcnDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class AcnDialogues(BaseAcnDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity that this dialogues is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AcnDialogue.Role.NODE - - BaseAcnDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=AcnDialogue, - ) diff --git a/trader_backup/vendor/valory/protocols/acn/tests/test_acn_dialogues.py b/trader_backup/vendor/valory/protocols/acn/tests/test_acn_dialogues.py deleted file mode 100644 index 825bc14c0..000000000 --- a/trader_backup/vendor/valory/protocols/acn/tests/test_acn_dialogues.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for acn protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.acn.custom_types import AgentRecord -from packages.valory.protocols.acn.dialogues import AcnDialogue, AcnDialogues -from packages.valory.protocols.acn.message import AcnMessage - - -class TestDialoguesAcn(BaseProtocolDialoguesTestCase): - """Test for the 'acn' protocol dialogues.""" - - MESSAGE_CLASS = AcnMessage - - DIALOGUE_CLASS = AcnDialogue - - DIALOGUES_CLASS = AcnDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = AcnDialogue.Role.NODE # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=AcnMessage.Performative.REGISTER, - record=AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ) diff --git a/trader_backup/vendor/valory/protocols/acn/tests/test_acn_messages.py b/trader_backup/vendor/valory/protocols/acn/tests/test_acn_messages.py deleted file mode 100644 index 35dedd070..000000000 --- a/trader_backup/vendor/valory/protocols/acn/tests/test_acn_messages.py +++ /dev/null @@ -1,117 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for acn protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.acn.custom_types import AgentRecord, StatusBody -from packages.valory.protocols.acn.message import AcnMessage - - -class TestMessageAcn(BaseProtocolMessagesTestCase): - """Test for the 'acn' protocol message.""" - - MESSAGE_CLASS = AcnMessage - - def build_messages(self) -> List[AcnMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - AcnMessage( - performative=AcnMessage.Performative.REGISTER, - record=AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ), - AcnMessage( - performative=AcnMessage.Performative.LOOKUP_REQUEST, - agent_address="some str", - ), - AcnMessage( - performative=AcnMessage.Performative.LOOKUP_RESPONSE, - record=AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ), - AcnMessage( - performative=AcnMessage.Performative.AEA_ENVELOPE, - envelope=b"some_bytes", - record=AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ), - AcnMessage( - performative=AcnMessage.Performative.STATUS, - body=StatusBody( - status_code=AcnMessage.StatusBody.StatusCode.ERROR_UNSUPPORTED_VERSION, - msgs=["pbk"], - ), - ), - ] - - def build_inconsistent(self) -> List[AcnMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - AcnMessage( - performative=AcnMessage.Performative.REGISTER, - # skip content: record - ), - AcnMessage( - performative=AcnMessage.Performative.LOOKUP_REQUEST, - # skip content: agent_address - ), - AcnMessage( - performative=AcnMessage.Performative.LOOKUP_RESPONSE, - # skip content: record - ), - AcnMessage( - performative=AcnMessage.Performative.AEA_ENVELOPE, - # skip content: envelope - record=AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ), - AcnMessage( - performative=AcnMessage.Performative.STATUS, - # skip content: body - ), - ] diff --git a/trader_backup/vendor/valory/protocols/contract_api/README.md b/trader_backup/vendor/valory/protocols/contract_api/README.md deleted file mode 100644 index 5aff863d1..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# Contract API Protocol - -## Description - -This is a protocol for contract APIs' requests and responses. - -## Specification - -```yaml ---- -name: contract_api -author: valory -version: 1.0.0 -description: A protocol for contract APIs requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: valory/contract_api:1.0.0 -speech_acts: - get_deploy_transaction: - ledger_id: pt:str - contract_id: pt:str - callable: pt:str - kwargs: ct:Kwargs - get_raw_transaction: - ledger_id: pt:str - contract_id: pt:str - contract_address: pt:str - callable: pt:str - kwargs: ct:Kwargs - get_raw_message: - ledger_id: pt:str - contract_id: pt:str - contract_address: pt:str - callable: pt:str - kwargs: ct:Kwargs - get_state: - ledger_id: pt:str - contract_id: pt:str - contract_address: pt:str - callable: pt:str - kwargs: ct:Kwargs - state: - state: ct:State - raw_transaction: - raw_transaction: ct:RawTransaction - raw_message: - raw_message: ct:RawMessage - error: - code: pt:optional[pt:int] - message: pt:optional[pt:str] - data: pt:bytes -... ---- -ct:Kwargs: - bytes kwargs = 1; -ct:State: - bytes state = 1; -ct:RawTransaction: - bytes raw_transaction = 1; -ct:RawMessage: - bytes raw_message = 1; -... ---- -initiation: [get_deploy_transaction, get_raw_transaction, get_raw_message, get_state] -reply: - get_deploy_transaction: [raw_transaction, error] - get_raw_transaction: [raw_transaction, error] - get_raw_message: [raw_message, error] - get_state: [state, error] - raw_transaction: [] - raw_message: [] - state: [] - error: [] -termination: [state, raw_transaction, raw_message, error] -roles: {agent, ledger} -end_states: [successful, failed] -keep_terminal_state_dialogues: false -... -``` - -## Links diff --git a/trader_backup/vendor/valory/protocols/contract_api/__init__.py b/trader_backup/vendor/valory/protocols/contract_api/__init__.py deleted file mode 100644 index 700b8ef27..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the contract_api protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.contract_api.message import ContractApiMessage -from packages.valory.protocols.contract_api.serialization import ContractApiSerializer - - -ContractApiMessage.serializer = ContractApiSerializer diff --git a/trader_backup/vendor/valory/protocols/contract_api/contract_api.proto b/trader_backup/vendor/valory/protocols/contract_api/contract_api.proto deleted file mode 100644 index f330d75bb..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/contract_api.proto +++ /dev/null @@ -1,88 +0,0 @@ -syntax = "proto3"; - -package aea.valory.contract_api.v1_0_0; - -message ContractApiMessage{ - - // Custom Types - message Kwargs{ - bytes kwargs = 1; - } - - message RawMessage{ - bytes raw_message = 1; - } - - message RawTransaction{ - bytes raw_transaction = 1; - } - - message State{ - bytes state = 1; - } - - - // Performatives and contents - message Get_Deploy_Transaction_Performative{ - string ledger_id = 1; - string contract_id = 2; - string callable = 3; - Kwargs kwargs = 4; - } - - message Get_Raw_Transaction_Performative{ - string ledger_id = 1; - string contract_id = 2; - string contract_address = 3; - string callable = 4; - Kwargs kwargs = 5; - } - - message Get_Raw_Message_Performative{ - string ledger_id = 1; - string contract_id = 2; - string contract_address = 3; - string callable = 4; - Kwargs kwargs = 5; - } - - message Get_State_Performative{ - string ledger_id = 1; - string contract_id = 2; - string contract_address = 3; - string callable = 4; - Kwargs kwargs = 5; - } - - message State_Performative{ - State state = 1; - } - - message Raw_Transaction_Performative{ - RawTransaction raw_transaction = 1; - } - - message Raw_Message_Performative{ - RawMessage raw_message = 1; - } - - message Error_Performative{ - int32 code = 1; - bool code_is_set = 2; - string message = 3; - bool message_is_set = 4; - bytes data = 5; - } - - - oneof performative{ - Error_Performative error = 5; - Get_Deploy_Transaction_Performative get_deploy_transaction = 6; - Get_Raw_Message_Performative get_raw_message = 7; - Get_Raw_Transaction_Performative get_raw_transaction = 8; - Get_State_Performative get_state = 9; - Raw_Message_Performative raw_message = 10; - Raw_Transaction_Performative raw_transaction = 11; - State_Performative state = 12; - } -} diff --git a/trader_backup/vendor/valory/protocols/contract_api/contract_api_pb2.py b/trader_backup/vendor/valory/protocols/contract_api/contract_api_pb2.py deleted file mode 100644 index f09367621..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/contract_api_pb2.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: contract_api.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x12\x63ontract_api.proto\x12\x1e\x61\x65\x61.valory.contract_api.v1_0_0"\x84\x11\n\x12\x43ontractApiMessage\x12V\n\x05\x65rror\x18\x05 \x01(\x0b\x32\x45.aea.valory.contract_api.v1_0_0.ContractApiMessage.Error_PerformativeH\x00\x12x\n\x16get_deploy_transaction\x18\x06 \x01(\x0b\x32V.aea.valory.contract_api.v1_0_0.ContractApiMessage.Get_Deploy_Transaction_PerformativeH\x00\x12j\n\x0fget_raw_message\x18\x07 \x01(\x0b\x32O.aea.valory.contract_api.v1_0_0.ContractApiMessage.Get_Raw_Message_PerformativeH\x00\x12r\n\x13get_raw_transaction\x18\x08 \x01(\x0b\x32S.aea.valory.contract_api.v1_0_0.ContractApiMessage.Get_Raw_Transaction_PerformativeH\x00\x12^\n\tget_state\x18\t \x01(\x0b\x32I.aea.valory.contract_api.v1_0_0.ContractApiMessage.Get_State_PerformativeH\x00\x12\x62\n\x0braw_message\x18\n \x01(\x0b\x32K.aea.valory.contract_api.v1_0_0.ContractApiMessage.Raw_Message_PerformativeH\x00\x12j\n\x0fraw_transaction\x18\x0b \x01(\x0b\x32O.aea.valory.contract_api.v1_0_0.ContractApiMessage.Raw_Transaction_PerformativeH\x00\x12V\n\x05state\x18\x0c \x01(\x0b\x32\x45.aea.valory.contract_api.v1_0_0.ContractApiMessage.State_PerformativeH\x00\x1a\x18\n\x06Kwargs\x12\x0e\n\x06kwargs\x18\x01 \x01(\x0c\x1a!\n\nRawMessage\x12\x13\n\x0braw_message\x18\x01 \x01(\x0c\x1a)\n\x0eRawTransaction\x12\x17\n\x0fraw_transaction\x18\x01 \x01(\x0c\x1a\x16\n\x05State\x12\r\n\x05state\x18\x01 \x01(\x0c\x1a\xaa\x01\n#Get_Deploy_Transaction_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x13\n\x0b\x63ontract_id\x18\x02 \x01(\t\x12\x10\n\x08\x63\x61llable\x18\x03 \x01(\t\x12I\n\x06kwargs\x18\x04 \x01(\x0b\x32\x39.aea.valory.contract_api.v1_0_0.ContractApiMessage.Kwargs\x1a\xc1\x01\n Get_Raw_Transaction_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x13\n\x0b\x63ontract_id\x18\x02 \x01(\t\x12\x18\n\x10\x63ontract_address\x18\x03 \x01(\t\x12\x10\n\x08\x63\x61llable\x18\x04 \x01(\t\x12I\n\x06kwargs\x18\x05 \x01(\x0b\x32\x39.aea.valory.contract_api.v1_0_0.ContractApiMessage.Kwargs\x1a\xbd\x01\n\x1cGet_Raw_Message_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x13\n\x0b\x63ontract_id\x18\x02 \x01(\t\x12\x18\n\x10\x63ontract_address\x18\x03 \x01(\t\x12\x10\n\x08\x63\x61llable\x18\x04 \x01(\t\x12I\n\x06kwargs\x18\x05 \x01(\x0b\x32\x39.aea.valory.contract_api.v1_0_0.ContractApiMessage.Kwargs\x1a\xb7\x01\n\x16Get_State_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x13\n\x0b\x63ontract_id\x18\x02 \x01(\t\x12\x18\n\x10\x63ontract_address\x18\x03 \x01(\t\x12\x10\n\x08\x63\x61llable\x18\x04 \x01(\t\x12I\n\x06kwargs\x18\x05 \x01(\x0b\x32\x39.aea.valory.contract_api.v1_0_0.ContractApiMessage.Kwargs\x1a]\n\x12State_Performative\x12G\n\x05state\x18\x01 \x01(\x0b\x32\x38.aea.valory.contract_api.v1_0_0.ContractApiMessage.State\x1az\n\x1cRaw_Transaction_Performative\x12Z\n\x0fraw_transaction\x18\x01 \x01(\x0b\x32\x41.aea.valory.contract_api.v1_0_0.ContractApiMessage.RawTransaction\x1an\n\x18Raw_Message_Performative\x12R\n\x0braw_message\x18\x01 \x01(\x0b\x32=.aea.valory.contract_api.v1_0_0.ContractApiMessage.RawMessage\x1an\n\x12\x45rror_Performative\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x13\n\x0b\x63ode_is_set\x18\x02 \x01(\x08\x12\x0f\n\x07message\x18\x03 \x01(\t\x12\x16\n\x0emessage_is_set\x18\x04 \x01(\x08\x12\x0c\n\x04\x64\x61ta\x18\x05 \x01(\x0c\x42\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "contract_api_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals["_CONTRACTAPIMESSAGE"]._serialized_start = 55 - _globals["_CONTRACTAPIMESSAGE"]._serialized_end = 2235 - _globals["_CONTRACTAPIMESSAGE_KWARGS"]._serialized_start = 903 - _globals["_CONTRACTAPIMESSAGE_KWARGS"]._serialized_end = 927 - _globals["_CONTRACTAPIMESSAGE_RAWMESSAGE"]._serialized_start = 929 - _globals["_CONTRACTAPIMESSAGE_RAWMESSAGE"]._serialized_end = 962 - _globals["_CONTRACTAPIMESSAGE_RAWTRANSACTION"]._serialized_start = 964 - _globals["_CONTRACTAPIMESSAGE_RAWTRANSACTION"]._serialized_end = 1005 - _globals["_CONTRACTAPIMESSAGE_STATE"]._serialized_start = 1007 - _globals["_CONTRACTAPIMESSAGE_STATE"]._serialized_end = 1029 - _globals[ - "_CONTRACTAPIMESSAGE_GET_DEPLOY_TRANSACTION_PERFORMATIVE" - ]._serialized_start = 1032 - _globals[ - "_CONTRACTAPIMESSAGE_GET_DEPLOY_TRANSACTION_PERFORMATIVE" - ]._serialized_end = 1202 - _globals[ - "_CONTRACTAPIMESSAGE_GET_RAW_TRANSACTION_PERFORMATIVE" - ]._serialized_start = 1205 - _globals[ - "_CONTRACTAPIMESSAGE_GET_RAW_TRANSACTION_PERFORMATIVE" - ]._serialized_end = 1398 - _globals[ - "_CONTRACTAPIMESSAGE_GET_RAW_MESSAGE_PERFORMATIVE" - ]._serialized_start = 1401 - _globals["_CONTRACTAPIMESSAGE_GET_RAW_MESSAGE_PERFORMATIVE"]._serialized_end = 1590 - _globals["_CONTRACTAPIMESSAGE_GET_STATE_PERFORMATIVE"]._serialized_start = 1593 - _globals["_CONTRACTAPIMESSAGE_GET_STATE_PERFORMATIVE"]._serialized_end = 1776 - _globals["_CONTRACTAPIMESSAGE_STATE_PERFORMATIVE"]._serialized_start = 1778 - _globals["_CONTRACTAPIMESSAGE_STATE_PERFORMATIVE"]._serialized_end = 1871 - _globals[ - "_CONTRACTAPIMESSAGE_RAW_TRANSACTION_PERFORMATIVE" - ]._serialized_start = 1873 - _globals["_CONTRACTAPIMESSAGE_RAW_TRANSACTION_PERFORMATIVE"]._serialized_end = 1995 - _globals["_CONTRACTAPIMESSAGE_RAW_MESSAGE_PERFORMATIVE"]._serialized_start = 1997 - _globals["_CONTRACTAPIMESSAGE_RAW_MESSAGE_PERFORMATIVE"]._serialized_end = 2107 - _globals["_CONTRACTAPIMESSAGE_ERROR_PERFORMATIVE"]._serialized_start = 2109 - _globals["_CONTRACTAPIMESSAGE_ERROR_PERFORMATIVE"]._serialized_end = 2219 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/protocols/contract_api/custom_types.py b/trader_backup/vendor/valory/protocols/contract_api/custom_types.py deleted file mode 100644 index fb1ffa8b5..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/custom_types.py +++ /dev/null @@ -1,96 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2020 valory -# -# 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 class representations corresponding to every custom type in the protocol specification.""" - -from typing import Any - -from aea.common import JSONLike -from aea.exceptions import enforce -from aea.helpers.serializers import DictProtobufStructSerializer -from aea.helpers.transaction.base import RawMessage as BaseRawMessage -from aea.helpers.transaction.base import RawTransaction as BaseRawTransaction -from aea.helpers.transaction.base import State as BaseState - - -RawMessage = BaseRawMessage -RawTransaction = BaseRawTransaction -State = BaseState - - -class Kwargs: - """This class represents an instance of Kwargs.""" - - __slots__ = ("_body",) - - def __init__( - self, - body: JSONLike, - ): - """Initialise an instance of RawTransaction.""" - self._body = body - self._check_consistency() - - def _check_consistency(self) -> None: - """Check consistency of the object.""" - enforce( - isinstance(self._body, dict) - and all([isinstance(key, str) for key in self._body.keys()]), - "Body must be dict and keys must be str.", - ) - - @property - def body(self) -> JSONLike: - """Get the body.""" - return self._body - - @staticmethod - def encode(kwargs_protobuf_object: Any, kwargs_object: "Kwargs") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the kwargs_protobuf_object argument is matched with the instance of this class in the 'kwargs_object' argument. - - :param kwargs_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param kwargs_object: an instance of this class to be encoded in the protocol buffer object. - """ - kwargs_protobuf_object.kwargs = DictProtobufStructSerializer.encode( - kwargs_object.body - ) - - @classmethod - def decode(cls, kwargs_protobuf_object: Any) -> "Kwargs": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'kwargs_protobuf_object' argument. - - :param kwargs_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'kwargs_protobuf_object' argument. - """ - kwargs = DictProtobufStructSerializer.decode(kwargs_protobuf_object.kwargs) - return cls(kwargs) - - def __eq__(self, other: Any) -> bool: - """Check equality.""" - return isinstance(other, Kwargs) and self.body == other.body - - def __str__(self) -> str: - """Get string representation.""" - return "Kwargs: body={}".format(self.body) diff --git a/trader_backup/vendor/valory/protocols/contract_api/dialogues.py b/trader_backup/vendor/valory/protocols/contract_api/dialogues.py deleted file mode 100644 index 5b9f534f6..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/dialogues.py +++ /dev/null @@ -1,152 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for contract_api dialogue management. - -- ContractApiDialogue: The dialogue class maintains state of a dialogue and manages it. -- ContractApiDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.contract_api.message import ContractApiMessage - - -class ContractApiDialogue(Dialogue): - """The contract_api dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ContractApiMessage.Performative.GET_RAW_MESSAGE, - ContractApiMessage.Performative.GET_STATE, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - ContractApiMessage.Performative.STATE, - ContractApiMessage.Performative.RAW_TRANSACTION, - ContractApiMessage.Performative.RAW_MESSAGE, - ContractApiMessage.Performative.ERROR, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - ContractApiMessage.Performative.ERROR: frozenset(), - ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION: frozenset( - { - ContractApiMessage.Performative.RAW_TRANSACTION, - ContractApiMessage.Performative.ERROR, - } - ), - ContractApiMessage.Performative.GET_RAW_MESSAGE: frozenset( - { - ContractApiMessage.Performative.RAW_MESSAGE, - ContractApiMessage.Performative.ERROR, - } - ), - ContractApiMessage.Performative.GET_RAW_TRANSACTION: frozenset( - { - ContractApiMessage.Performative.RAW_TRANSACTION, - ContractApiMessage.Performative.ERROR, - } - ), - ContractApiMessage.Performative.GET_STATE: frozenset( - { - ContractApiMessage.Performative.STATE, - ContractApiMessage.Performative.ERROR, - } - ), - ContractApiMessage.Performative.RAW_MESSAGE: frozenset(), - ContractApiMessage.Performative.RAW_TRANSACTION: frozenset(), - ContractApiMessage.Performative.STATE: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a contract_api dialogue.""" - - AGENT = "agent" - LEDGER = "ledger" - - class EndState(Dialogue.EndState): - """This class defines the end states of a contract_api dialogue.""" - - SUCCESSFUL = 0 - FAILED = 1 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[ContractApiMessage] = ContractApiMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class ContractApiDialogues(Dialogues, ABC): - """This class keeps track of all contract_api dialogues.""" - - END_STATES = frozenset( - {ContractApiDialogue.EndState.SUCCESSFUL, ContractApiDialogue.EndState.FAILED} - ) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[ContractApiDialogue] = ContractApiDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=ContractApiMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_backup/vendor/valory/protocols/contract_api/message.py b/trader_backup/vendor/valory/protocols/contract_api/message.py deleted file mode 100644 index 1b68bc22e..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/message.py +++ /dev/null @@ -1,472 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 contract_api's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Optional, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - -from packages.valory.protocols.contract_api.custom_types import Kwargs as CustomKwargs -from packages.valory.protocols.contract_api.custom_types import ( - RawMessage as CustomRawMessage, -) -from packages.valory.protocols.contract_api.custom_types import ( - RawTransaction as CustomRawTransaction, -) -from packages.valory.protocols.contract_api.custom_types import State as CustomState - - -_default_logger = logging.getLogger( - "aea.packages.valory.protocols.contract_api.message" -) - -DEFAULT_BODY_SIZE = 4 - - -class ContractApiMessage(Message): - """A protocol for contract APIs requests and responses.""" - - protocol_id = PublicId.from_str("valory/contract_api:1.0.0") - protocol_specification_id = PublicId.from_str("valory/contract_api:1.0.0") - - Kwargs = CustomKwargs - - RawMessage = CustomRawMessage - - RawTransaction = CustomRawTransaction - - State = CustomState - - class Performative(Message.Performative): - """Performatives for the contract_api protocol.""" - - ERROR = "error" - GET_DEPLOY_TRANSACTION = "get_deploy_transaction" - GET_RAW_MESSAGE = "get_raw_message" - GET_RAW_TRANSACTION = "get_raw_transaction" - GET_STATE = "get_state" - RAW_MESSAGE = "raw_message" - RAW_TRANSACTION = "raw_transaction" - STATE = "state" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = { - "error", - "get_deploy_transaction", - "get_raw_message", - "get_raw_transaction", - "get_state", - "raw_message", - "raw_transaction", - "state", - } - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "callable", - "code", - "contract_address", - "contract_id", - "data", - "dialogue_reference", - "kwargs", - "ledger_id", - "message", - "message_id", - "performative", - "raw_message", - "raw_transaction", - "state", - "target", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of ContractApiMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=ContractApiMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(ContractApiMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def callable(self) -> str: - """Get the 'callable' content from the message.""" - enforce(self.is_set("callable"), "'callable' content is not set.") - return cast(str, self.get("callable")) - - @property - def code(self) -> Optional[int]: - """Get the 'code' content from the message.""" - return cast(Optional[int], self.get("code")) - - @property - def contract_address(self) -> str: - """Get the 'contract_address' content from the message.""" - enforce( - self.is_set("contract_address"), "'contract_address' content is not set." - ) - return cast(str, self.get("contract_address")) - - @property - def contract_id(self) -> str: - """Get the 'contract_id' content from the message.""" - enforce(self.is_set("contract_id"), "'contract_id' content is not set.") - return cast(str, self.get("contract_id")) - - @property - def data(self) -> bytes: - """Get the 'data' content from the message.""" - enforce(self.is_set("data"), "'data' content is not set.") - return cast(bytes, self.get("data")) - - @property - def kwargs(self) -> CustomKwargs: - """Get the 'kwargs' content from the message.""" - enforce(self.is_set("kwargs"), "'kwargs' content is not set.") - return cast(CustomKwargs, self.get("kwargs")) - - @property - def ledger_id(self) -> str: - """Get the 'ledger_id' content from the message.""" - enforce(self.is_set("ledger_id"), "'ledger_id' content is not set.") - return cast(str, self.get("ledger_id")) - - @property - def message(self) -> Optional[str]: - """Get the 'message' content from the message.""" - return cast(Optional[str], self.get("message")) - - @property - def raw_message(self) -> CustomRawMessage: - """Get the 'raw_message' content from the message.""" - enforce(self.is_set("raw_message"), "'raw_message' content is not set.") - return cast(CustomRawMessage, self.get("raw_message")) - - @property - def raw_transaction(self) -> CustomRawTransaction: - """Get the 'raw_transaction' content from the message.""" - enforce(self.is_set("raw_transaction"), "'raw_transaction' content is not set.") - return cast(CustomRawTransaction, self.get("raw_transaction")) - - @property - def state(self) -> CustomState: - """Get the 'state' content from the message.""" - enforce(self.is_set("state"), "'state' content is not set.") - return cast(CustomState, self.get("state")) - - def _is_consistent(self) -> bool: - """Check that the message follows the contract_api protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, ContractApiMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if ( - self.performative - == ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION - ): - expected_nb_of_contents = 4 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.contract_id, str), - "Invalid type for content 'contract_id'. Expected 'str'. Found '{}'.".format( - type(self.contract_id) - ), - ) - enforce( - isinstance(self.callable, str), - "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( - type(self.callable) - ), - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif ( - self.performative == ContractApiMessage.Performative.GET_RAW_TRANSACTION - ): - expected_nb_of_contents = 5 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.contract_id, str), - "Invalid type for content 'contract_id'. Expected 'str'. Found '{}'.".format( - type(self.contract_id) - ), - ) - enforce( - isinstance(self.contract_address, str), - "Invalid type for content 'contract_address'. Expected 'str'. Found '{}'.".format( - type(self.contract_address) - ), - ) - enforce( - isinstance(self.callable, str), - "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( - type(self.callable) - ), - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif self.performative == ContractApiMessage.Performative.GET_RAW_MESSAGE: - expected_nb_of_contents = 5 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.contract_id, str), - "Invalid type for content 'contract_id'. Expected 'str'. Found '{}'.".format( - type(self.contract_id) - ), - ) - enforce( - isinstance(self.contract_address, str), - "Invalid type for content 'contract_address'. Expected 'str'. Found '{}'.".format( - type(self.contract_address) - ), - ) - enforce( - isinstance(self.callable, str), - "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( - type(self.callable) - ), - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif self.performative == ContractApiMessage.Performative.GET_STATE: - expected_nb_of_contents = 5 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.contract_id, str), - "Invalid type for content 'contract_id'. Expected 'str'. Found '{}'.".format( - type(self.contract_id) - ), - ) - enforce( - isinstance(self.contract_address, str), - "Invalid type for content 'contract_address'. Expected 'str'. Found '{}'.".format( - type(self.contract_address) - ), - ) - enforce( - isinstance(self.callable, str), - "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( - type(self.callable) - ), - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif self.performative == ContractApiMessage.Performative.STATE: - expected_nb_of_contents = 1 - enforce( - isinstance(self.state, CustomState), - "Invalid type for content 'state'. Expected 'State'. Found '{}'.".format( - type(self.state) - ), - ) - elif self.performative == ContractApiMessage.Performative.RAW_TRANSACTION: - expected_nb_of_contents = 1 - enforce( - isinstance(self.raw_transaction, CustomRawTransaction), - "Invalid type for content 'raw_transaction'. Expected 'RawTransaction'. Found '{}'.".format( - type(self.raw_transaction) - ), - ) - elif self.performative == ContractApiMessage.Performative.RAW_MESSAGE: - expected_nb_of_contents = 1 - enforce( - isinstance(self.raw_message, CustomRawMessage), - "Invalid type for content 'raw_message'. Expected 'RawMessage'. Found '{}'.".format( - type(self.raw_message) - ), - ) - elif self.performative == ContractApiMessage.Performative.ERROR: - expected_nb_of_contents = 1 - if self.is_set("code"): - expected_nb_of_contents += 1 - code = cast(int, self.code) - enforce( - type(code) is int, - "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( - type(code) - ), - ) - if self.is_set("message"): - expected_nb_of_contents += 1 - message = cast(str, self.message) - enforce( - isinstance(message, str), - "Invalid type for content 'message'. Expected 'str'. Found '{}'.".format( - type(message) - ), - ) - enforce( - isinstance(self.data, bytes), - "Invalid type for content 'data'. Expected 'bytes'. Found '{}'.".format( - type(self.data) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_backup/vendor/valory/protocols/contract_api/protocol.yaml b/trader_backup/vendor/valory/protocols/contract_api/protocol.yaml deleted file mode 100644 index 8938192bd..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/protocol.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: contract_api -author: valory -version: 1.0.0 -protocol_specification_id: valory/contract_api:1.0.0 -type: protocol -description: A protocol for contract APIs requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeigaihpzixjv56vbuch6yqk5shzevt3rlpvchgqudmztid5mgchlqy - __init__.py: bafybeifxn7w75gxufl4ekvk27qo3tkxetdvxxnqmhq5gtnhjyvlhn3i6yu - contract_api.proto: bafybeiafpnyivdogs7omw2bxxxkmnbqcl3n32oqbzug65p7jimbeubgljy - contract_api_pb2.py: bafybeibjspkls7zjf7x4on2sm2274r355xzodgv3e54ueopz4vgpvg5owa - custom_types.py: bafybeiawof5bblaefwui5wgsou2ohvrxi2zrkdthehiet57qguplzsgrhu - dialogues.py: bafybeictadz75pczogizyglzklbk4mf76zoh6we66ras4stntz5dwzi7du - message.py: bafybeid75ybjywwslz7jwsng4aosfejutesj6jffkmrpdy5jg4oluwn5hm - serialization.py: bafybeie56ahly26zco47a7dg6umysqy6ygle65lebmwekstbiwmym62p7i - tests/__init__.py: bafybeicc5zmsziu4r5dwjnhckfbgnwbgydn7ekeyqsestutq2tusajqzmu - tests/test_contract_api.py: bafybeigszksq7bxi3skvw3zvpatkltgbnvnfatofjn63xnd5xds33iyni4 - tests/test_contract_api_dialogues.py: bafybeifalicqk4g44sl5dpeuvls5dqtyfdgc6nwyuf5cl4fofis7fr3mnq - tests/test_contract_api_messages.py: bafybeigjdnyyxpzfje4ok7sxi6a3gstbgaryzjm2izoxmn4x5twsec35fa -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_backup/vendor/valory/protocols/contract_api/serialization.py b/trader_backup/vendor/valory/protocols/contract_api/serialization.py deleted file mode 100644 index c8aeaad9d..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/serialization.py +++ /dev/null @@ -1,250 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for contract_api protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.contract_api import contract_api_pb2 # type: ignore -from packages.valory.protocols.contract_api.custom_types import ( # type: ignore - Kwargs, - RawMessage, - RawTransaction, - State, -) -from packages.valory.protocols.contract_api.message import ( # type: ignore - ContractApiMessage, -) - - -class ContractApiSerializer(Serializer): - """Serialization for the 'contract_api' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'ContractApi' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(ContractApiMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - contract_api_msg = contract_api_pb2.ContractApiMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION: - performative = contract_api_pb2.ContractApiMessage.Get_Deploy_Transaction_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - contract_id = msg.contract_id - performative.contract_id = contract_id - callable = msg.callable - performative.callable = callable - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - contract_api_msg.get_deploy_transaction.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.GET_RAW_TRANSACTION: - performative = contract_api_pb2.ContractApiMessage.Get_Raw_Transaction_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - contract_id = msg.contract_id - performative.contract_id = contract_id - contract_address = msg.contract_address - performative.contract_address = contract_address - callable = msg.callable - performative.callable = callable - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - contract_api_msg.get_raw_transaction.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.GET_RAW_MESSAGE: - performative = contract_api_pb2.ContractApiMessage.Get_Raw_Message_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - contract_id = msg.contract_id - performative.contract_id = contract_id - contract_address = msg.contract_address - performative.contract_address = contract_address - callable = msg.callable - performative.callable = callable - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - contract_api_msg.get_raw_message.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.GET_STATE: - performative = contract_api_pb2.ContractApiMessage.Get_State_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - contract_id = msg.contract_id - performative.contract_id = contract_id - contract_address = msg.contract_address - performative.contract_address = contract_address - callable = msg.callable - performative.callable = callable - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - contract_api_msg.get_state.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.STATE: - performative = contract_api_pb2.ContractApiMessage.State_Performative() # type: ignore - state = msg.state - State.encode(performative.state, state) - contract_api_msg.state.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.RAW_TRANSACTION: - performative = contract_api_pb2.ContractApiMessage.Raw_Transaction_Performative() # type: ignore - raw_transaction = msg.raw_transaction - RawTransaction.encode(performative.raw_transaction, raw_transaction) - contract_api_msg.raw_transaction.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.RAW_MESSAGE: - performative = contract_api_pb2.ContractApiMessage.Raw_Message_Performative() # type: ignore - raw_message = msg.raw_message - RawMessage.encode(performative.raw_message, raw_message) - contract_api_msg.raw_message.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.ERROR: - performative = contract_api_pb2.ContractApiMessage.Error_Performative() # type: ignore - if msg.is_set("code"): - performative.code_is_set = True - code = msg.code - performative.code = code - if msg.is_set("message"): - performative.message_is_set = True - message = msg.message - performative.message = message - data = msg.data - performative.data = data - contract_api_msg.error.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = contract_api_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'ContractApi' message. - - :param obj: the bytes object. - :return: the 'ContractApi' message. - """ - message_pb = ProtobufMessage() - contract_api_pb = contract_api_pb2.ContractApiMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - contract_api_pb.ParseFromString(message_pb.dialogue_message.content) - performative = contract_api_pb.WhichOneof("performative") - performative_id = ContractApiMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION: - ledger_id = contract_api_pb.get_deploy_transaction.ledger_id - performative_content["ledger_id"] = ledger_id - contract_id = contract_api_pb.get_deploy_transaction.contract_id - performative_content["contract_id"] = contract_id - callable = contract_api_pb.get_deploy_transaction.callable - performative_content["callable"] = callable - pb2_kwargs = contract_api_pb.get_deploy_transaction.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == ContractApiMessage.Performative.GET_RAW_TRANSACTION: - ledger_id = contract_api_pb.get_raw_transaction.ledger_id - performative_content["ledger_id"] = ledger_id - contract_id = contract_api_pb.get_raw_transaction.contract_id - performative_content["contract_id"] = contract_id - contract_address = contract_api_pb.get_raw_transaction.contract_address - performative_content["contract_address"] = contract_address - callable = contract_api_pb.get_raw_transaction.callable - performative_content["callable"] = callable - pb2_kwargs = contract_api_pb.get_raw_transaction.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == ContractApiMessage.Performative.GET_RAW_MESSAGE: - ledger_id = contract_api_pb.get_raw_message.ledger_id - performative_content["ledger_id"] = ledger_id - contract_id = contract_api_pb.get_raw_message.contract_id - performative_content["contract_id"] = contract_id - contract_address = contract_api_pb.get_raw_message.contract_address - performative_content["contract_address"] = contract_address - callable = contract_api_pb.get_raw_message.callable - performative_content["callable"] = callable - pb2_kwargs = contract_api_pb.get_raw_message.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == ContractApiMessage.Performative.GET_STATE: - ledger_id = contract_api_pb.get_state.ledger_id - performative_content["ledger_id"] = ledger_id - contract_id = contract_api_pb.get_state.contract_id - performative_content["contract_id"] = contract_id - contract_address = contract_api_pb.get_state.contract_address - performative_content["contract_address"] = contract_address - callable = contract_api_pb.get_state.callable - performative_content["callable"] = callable - pb2_kwargs = contract_api_pb.get_state.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == ContractApiMessage.Performative.STATE: - pb2_state = contract_api_pb.state.state - state = State.decode(pb2_state) - performative_content["state"] = state - elif performative_id == ContractApiMessage.Performative.RAW_TRANSACTION: - pb2_raw_transaction = contract_api_pb.raw_transaction.raw_transaction - raw_transaction = RawTransaction.decode(pb2_raw_transaction) - performative_content["raw_transaction"] = raw_transaction - elif performative_id == ContractApiMessage.Performative.RAW_MESSAGE: - pb2_raw_message = contract_api_pb.raw_message.raw_message - raw_message = RawMessage.decode(pb2_raw_message) - performative_content["raw_message"] = raw_message - elif performative_id == ContractApiMessage.Performative.ERROR: - if contract_api_pb.error.code_is_set: - code = contract_api_pb.error.code - performative_content["code"] = code - if contract_api_pb.error.message_is_set: - message = contract_api_pb.error.message - performative_content["message"] = message - data = contract_api_pb.error.data - performative_content["data"] = data - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return ContractApiMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_backup/vendor/valory/protocols/contract_api/tests/__init__.py b/trader_backup/vendor/valory/protocols/contract_api/tests/__init__.py deleted file mode 100644 index f0a0d0f83..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/contract_api protocol.""" diff --git a/trader_backup/vendor/valory/protocols/contract_api/tests/test_contract_api.py b/trader_backup/vendor/valory/protocols/contract_api/tests/test_contract_api.py deleted file mode 100644 index 919358c2d..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/tests/test_contract_api.py +++ /dev/null @@ -1,734 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for the 'valory/contract_api' protocol.""" -from abc import abstractmethod -from typing import Callable, Type -from unittest import mock - -import pytest - -from aea.common import Address -from aea.exceptions import AEAEnforceError -from aea.mail.base import Envelope -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.contract_api import ContractApiMessage, message -from packages.valory.protocols.contract_api.custom_types import Kwargs -from packages.valory.protocols.contract_api.dialogues import ( - ContractApiDialogue, - ContractApiDialogues, -) -from packages.valory.protocols.contract_api.message import ( - _default_logger as contract_api_message_logger, -) - - -LEDGER_ID = "ethereum" -CONTRACT_ID = "contract_id_stub" -CALLABLE = "callable_stub" -CONTRACT_ADDRESS = "contract_address_stub" - - -def test_get_deploy_transaction_serialization(): - """Test the serialization for 'get_deploy_transaction' speech-act works.""" - kwargs_arg = ContractApiMessage.Kwargs({"key_1": 1, "key_2": 2}) - msg = ContractApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - ledger_id="some_ledger_id", - contract_id="some_contract_id", - callable="some_callable", - kwargs=kwargs_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_get_raw_transaction_serialization(): - """Test the serialization for 'get_raw_transaction' speech-act works.""" - kwargs_arg = ContractApiMessage.Kwargs({"key_1": 1, "key_2": 2}) - msg = ContractApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ledger_id="some_ledger_id", - contract_id="some_contract_id", - contract_address="some_contract_address", - callable="some_callable", - kwargs=kwargs_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_get_raw_message_serialization(): - """Test the serialization for 'get_raw_message' speech-act works.""" - kwargs_arg = ContractApiMessage.Kwargs({"key_1": 1, "key_2": 2}) - msg = ContractApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=ContractApiMessage.Performative.GET_RAW_MESSAGE, - ledger_id="some_ledger_id", - contract_id="some_contract_id", - contract_address="some_contract_address", - callable="some_callable", - kwargs=kwargs_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_get_state_serialization(): - """Test the serialization for 'get_state' speech-act works.""" - kwargs_arg = ContractApiMessage.Kwargs({"key_1": 1, "key_2": 2}) - msg = ContractApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=ContractApiMessage.Performative.GET_STATE, - ledger_id="some_ledger_id", - contract_id="some_contract_id", - contract_address="some_contract_address", - callable="some_callable", - kwargs=kwargs_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_state_serialization(): - """Test the serialization for 'state' speech-act works.""" - state_arg = ContractApiMessage.State("some_ledger_id", {"key": "some_body"}) - msg = ContractApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=ContractApiMessage.Performative.STATE, - state=state_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_raw_transaction_serialization(): - """Test the serialization for 'raw_transaction' speech-act works.""" - raw_transaction_arg = ContractApiMessage.RawTransaction( - "some_ledger_id", {"body": "some_body"} - ) - msg = ContractApiMessage( - message_id=2, - target=1, - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=raw_transaction_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_raw_message_serialization(): - """Test the serialization for 'raw_message' speech-act works.""" - raw_message_arg = ContractApiMessage.RawMessage("some_ledger_id", b"some_body") - msg = ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_MESSAGE, - raw_message=raw_message_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_error_serialization(): - """Test the serialization for 'error' speech-act works.""" - msg = ContractApiMessage( - performative=ContractApiMessage.Performative.ERROR, - code=7, - message="some_error_message", - data=b"some_error_data", - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_performative_string_value() -> None: - """Test the string value of the performatives.""" - assert ( - str(ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION) - == "get_deploy_transaction" - ), "The str value must be get_deploy_transaction" - assert ( - str(ContractApiMessage.Performative.GET_RAW_TRANSACTION) - == "get_raw_transaction" - ), "The str value must be get_raw_transaction" - assert ( - str(ContractApiMessage.Performative.GET_RAW_MESSAGE) == "get_raw_message" - ), "The str value must be get_raw_message" - assert ( - str(ContractApiMessage.Performative.GET_STATE) == "get_state" - ), "The str value must be get_state" - assert ( - str(ContractApiMessage.Performative.STATE) == "state" - ), "The str value must be state" - assert ( - str(ContractApiMessage.Performative.RAW_TRANSACTION) == "raw_transaction" - ), "The str value must be raw_transaction" - assert ( - str(ContractApiMessage.Performative.RAW_MESSAGE) == "raw_message" - ), "The str value must be raw_message" - assert ( - str(ContractApiMessage.Performative.ERROR) == "error" - ), "The str value must be error" - - -def test_encoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = ContractApiMessage( - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, # type: ignore - ledger_id=LEDGER_ID, - contract_id=CONTRACT_ID, - callable=CALLABLE, - kwargs=Kwargs({}), - ) - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object( - ContractApiMessage.Performative, "__eq__", return_value=False - ): - ContractApiMessage.serializer.encode(msg) - - -def test_decoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = ContractApiMessage( - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, # type: ignore - ledger_id=LEDGER_ID, - contract_id=CONTRACT_ID, - callable=CALLABLE, - kwargs=Kwargs({}), - ) - - encoded_msg = ContractApiMessage.serializer.encode(msg) - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object( - ContractApiMessage.Performative, "__eq__", return_value=False - ): - ContractApiMessage.serializer.decode(encoded_msg) - - -@mock.patch.object( - message, - "enforce", - side_effect=AEAEnforceError("some error"), -) -def test_incorrect_message( - mocked_enforce: Callable, # pylint: disable=unused-argument -) -> None: - """Test that we raise an exception when the message is incorrect.""" - with mock.patch.object(contract_api_message_logger, "error") as mock_logger: - ContractApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=ContractApiMessage.Performative.RAW_MESSAGE, # type: ignore - raw_message=ContractApiMessage.RawMessage("some_ledger_id", b"some_body"), - ) - - mock_logger.assert_any_call("some error") - - -def test_kwargs(): - """Test the kwargs custom type.""" - body = {"key_1": 1, "key_2": 2} - kwargs = ContractApiMessage.Kwargs(body) - assert str(kwargs) == "Kwargs: body={}".format(body) - - -class BaseTestMessageConstruction: - """Base class to test message construction for the ABCI protocol.""" - - ledger_id = LEDGER_ID - contract_id = CONTRACT_ID - callable_ = CALLABLE - msg_class = ContractApiMessage - contract_address = CONTRACT_ADDRESS - - @abstractmethod - def build_message(self) -> ContractApiMessage: - """Build the message to be used for testing.""" - - def test_run(self) -> None: - """Run the test.""" - msg = self.build_message() - msg.to = "receiver" - envelope = Envelope(to=msg.to, sender="sender", message=msg) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = self.msg_class.serializer.decode(actual_envelope.message_bytes) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - @classmethod - def _make_kwargs(cls) -> Kwargs: - """Build a ConsensuParams object.""" - return Kwargs(body={}) - - -class TestGetDeployTransaction(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - assert str(self._make_kwargs()) == "Kwargs: body={}" - return ContractApiMessage( - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, # type: ignore - ledger_id=self.ledger_id, - contract_id=self.contract_id, - callable=self.callable_, - kwargs=self._make_kwargs(), - ) - - -class TestError(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.ERROR, # type: ignore - code=1, - message="", - data=b"", - ) - - -class TestGetRawTransaction(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - ledger_id=self.ledger_id, - contract_id=self.contract_id, - contract_address=self.contract_address, - callable=self.callable_, - kwargs=self._make_kwargs(), - ) - - -class TestRawTransaction(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, # type: ignore - raw_transaction=ContractApiMessage.RawTransaction( - ledger_id=LEDGER_ID, body={} - ), - ) - - -class TestGetRawMessage(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.GET_RAW_MESSAGE, # type: ignore - ledger_id=self.ledger_id, - contract_id=self.contract_id, - contract_address=self.contract_address, - callable=self.callable_, - kwargs=self._make_kwargs(), - ) - - -class TestRawMessage(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_MESSAGE, # type: ignore - raw_message=ContractApiMessage.RawMessage(ledger_id=LEDGER_ID, body=b""), - ) - - -class TestGetState(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - ledger_id=self.ledger_id, - contract_id=self.contract_id, - contract_address=self.contract_address, - callable=self.callable_, - kwargs=self._make_kwargs(), - ) - - -class TestState(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.STATE, # type: ignore - state=ContractApiMessage.State(ledger_id=LEDGER_ID, body={}), - ) - - -class AgentDialogue(ContractApiDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[ContractApiMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - ContractApiDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class AgentDialogues(ContractApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return ContractApiDialogue.Role.AGENT - - ContractApiDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=AgentDialogue, - ) - - -class LedgerDialogue(ContractApiDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[ContractApiMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - ContractApiDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class LedgerDialogues(ContractApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return ContractApiDialogue.Role.LEDGER - - ContractApiDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=LedgerDialogue, - ) - - -class TestDialogues: - """Tests abci dialogues.""" - - agent_addr: str - ledger_addr: str - agent_dialogues: AgentDialogues - ledger_dialogues: LedgerDialogues - - @classmethod - def setup_class(cls) -> None: - """Set up the test.""" - cls.agent_addr = "agent address" - cls.ledger_addr = "ledger address" - cls.agent_dialogues = AgentDialogues(cls.agent_addr) - cls.ledger_dialogues = LedgerDialogues(cls.ledger_addr) - - def test_create_self_initiated(self) -> None: - """Test the self initialisation of a dialogue.""" - result = self.agent_dialogues._create_self_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.ledger_addr, - dialogue_reference=(str(0), ""), - role=ContractApiDialogue.Role.AGENT, - ) - assert isinstance(result, ContractApiDialogue) - assert result.role == ContractApiDialogue.Role.AGENT, "The role must be agent." - - def test_create_opponent_initiated(self) -> None: - """Test the opponent initialisation of a dialogue.""" - result = self.agent_dialogues._create_opponent_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.ledger_addr, - dialogue_reference=(str(0), ""), - role=ContractApiDialogue.Role.AGENT, - ) - assert isinstance(result, ContractApiDialogue) - assert result.role == ContractApiDialogue.Role.AGENT, "The role must be agent." diff --git a/trader_backup/vendor/valory/protocols/contract_api/tests/test_contract_api_dialogues.py b/trader_backup/vendor/valory/protocols/contract_api/tests/test_contract_api_dialogues.py deleted file mode 100644 index dd07d1c34..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/tests/test_contract_api_dialogues.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for contract_api protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.contract_api.custom_types import Kwargs -from packages.valory.protocols.contract_api.dialogues import ( - ContractApiDialogue, - ContractApiDialogues, -) -from packages.valory.protocols.contract_api.message import ContractApiMessage - - -class TestDialoguesContractApi(BaseProtocolDialoguesTestCase): - """Test for the 'contract_api' protocol dialogues.""" - - MESSAGE_CLASS = ContractApiMessage - - DIALOGUE_CLASS = ContractApiDialogue - - DIALOGUES_CLASS = ContractApiDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = ContractApiDialogue.Role.AGENT # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - ledger_id="some str", - contract_id="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ) diff --git a/trader_backup/vendor/valory/protocols/contract_api/tests/test_contract_api_messages.py b/trader_backup/vendor/valory/protocols/contract_api/tests/test_contract_api_messages.py deleted file mode 100644 index 09600e3c1..000000000 --- a/trader_backup/vendor/valory/protocols/contract_api/tests/test_contract_api_messages.py +++ /dev/null @@ -1,147 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for contract_api protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.contract_api.custom_types import ( - Kwargs, - RawMessage, - RawTransaction, - State, -) -from packages.valory.protocols.contract_api.message import ContractApiMessage - - -class TestMessageContractApi(BaseProtocolMessagesTestCase): - """Test for the 'contract_api' protocol message.""" - - MESSAGE_CLASS = ContractApiMessage - - def build_messages(self) -> List[ContractApiMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - ledger_id="some str", - contract_id="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ledger_id="some str", - contract_id="some str", - contract_address="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_RAW_MESSAGE, - ledger_id="some str", - contract_id="some str", - contract_address="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_STATE, - ledger_id="some str", - contract_id="some str", - contract_address="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.STATE, - state=State("some_ledger_id", {"key": "some_body"}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=RawTransaction("some_ledger_id", {"body": "some_body"}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_MESSAGE, - raw_message=RawMessage("some_ledger_id", b"some_body"), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.ERROR, - code=12, - message="some str", - data=b"some_bytes", - ), - ] - - def build_inconsistent(self) -> List[ContractApiMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - # skip content: ledger_id - contract_id="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, - # skip content: ledger_id - contract_id="some str", - contract_address="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_RAW_MESSAGE, - # skip content: ledger_id - contract_id="some str", - contract_address="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_STATE, - # skip content: ledger_id - contract_id="some str", - contract_address="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.STATE, - # skip content: state - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - # skip content: raw_transaction - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_MESSAGE, - # skip content: raw_message - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.ERROR, - # skip content: code - message=["some str"], - data=b"some_bytes", - ), - ] diff --git a/trader_backup/vendor/valory/protocols/http/README.md b/trader_backup/vendor/valory/protocols/http/README.md deleted file mode 100644 index 446909ef6..000000000 --- a/trader_backup/vendor/valory/protocols/http/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# HTTP Protocol - -## Description - -This is a protocol for interacting with a client/server via HTTP requests and responses. - -## Specification - -```yaml ---- -name: http -author: valory -version: 1.0.0 -description: A protocol for HTTP requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: valory/http:1.0.0 -speech_acts: - request: - method: pt:str - url: pt:str - version: pt:str - headers: pt:str - body: pt:bytes - response: - version: pt:str - status_code: pt:int - status_text: pt:str - headers: pt:str - body: pt:bytes -... ---- -initiation: [request] -reply: - request: [response] - response: [] -termination: [response] -roles: {client, server} -end_states: [successful] -keep_terminal_state_dialogues: false -... -``` - -## Links - -* HTTP Specification diff --git a/trader_backup/vendor/valory/protocols/http/__init__.py b/trader_backup/vendor/valory/protocols/http/__init__.py deleted file mode 100644 index 73442b676..000000000 --- a/trader_backup/vendor/valory/protocols/http/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the http protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.http.message import HttpMessage -from packages.valory.protocols.http.serialization import HttpSerializer - - -HttpMessage.serializer = HttpSerializer diff --git a/trader_backup/vendor/valory/protocols/http/dialogues.py b/trader_backup/vendor/valory/protocols/http/dialogues.py deleted file mode 100644 index c8b68e416..000000000 --- a/trader_backup/vendor/valory/protocols/http/dialogues.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for http dialogue management. - -- HttpDialogue: The dialogue class maintains state of a dialogue and manages it. -- HttpDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.http.message import HttpMessage - - -class HttpDialogue(Dialogue): - """The http dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - {HttpMessage.Performative.REQUEST} - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - {HttpMessage.Performative.RESPONSE} - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - HttpMessage.Performative.REQUEST: frozenset( - {HttpMessage.Performative.RESPONSE} - ), - HttpMessage.Performative.RESPONSE: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a http dialogue.""" - - CLIENT = "client" - SERVER = "server" - - class EndState(Dialogue.EndState): - """This class defines the end states of a http dialogue.""" - - SUCCESSFUL = 0 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[HttpMessage] = HttpMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class HttpDialogues(Dialogues, ABC): - """This class keeps track of all http dialogues.""" - - END_STATES = frozenset({HttpDialogue.EndState.SUCCESSFUL}) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[HttpDialogue] = HttpDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=HttpMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_backup/vendor/valory/protocols/http/http.proto b/trader_backup/vendor/valory/protocols/http/http.proto deleted file mode 100644 index 02f606944..000000000 --- a/trader_backup/vendor/valory/protocols/http/http.proto +++ /dev/null @@ -1,29 +0,0 @@ -syntax = "proto3"; - -package aea.valory.http.v1_0_0; - -message HttpMessage{ - - // Performatives and contents - message Request_Performative{ - string method = 1; - string url = 2; - string version = 3; - string headers = 4; - bytes body = 5; - } - - message Response_Performative{ - string version = 1; - int32 status_code = 2; - string status_text = 3; - string headers = 4; - bytes body = 5; - } - - - oneof performative{ - Request_Performative request = 5; - Response_Performative response = 6; - } -} diff --git a/trader_backup/vendor/valory/protocols/http/http_pb2.py b/trader_backup/vendor/valory/protocols/http/http_pb2.py deleted file mode 100644 index 6c202f914..000000000 --- a/trader_backup/vendor/valory/protocols/http/http_pb2.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: http.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\nhttp.proto\x12\x16\x61\x65\x61.valory.http.v1_0_0"\x91\x03\n\x0bHttpMessage\x12K\n\x07request\x18\x05 \x01(\x0b\x32\x38.aea.valory.http.v1_0_0.HttpMessage.Request_PerformativeH\x00\x12M\n\x08response\x18\x06 \x01(\x0b\x32\x39.aea.valory.http.v1_0_0.HttpMessage.Response_PerformativeH\x00\x1a\x63\n\x14Request_Performative\x12\x0e\n\x06method\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\t\x12\x0f\n\x07headers\x18\x04 \x01(\t\x12\x0c\n\x04\x62ody\x18\x05 \x01(\x0c\x1aq\n\x15Response_Performative\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x13\n\x0bstatus_code\x18\x02 \x01(\x05\x12\x13\n\x0bstatus_text\x18\x03 \x01(\t\x12\x0f\n\x07headers\x18\x04 \x01(\t\x12\x0c\n\x04\x62ody\x18\x05 \x01(\x0c\x42\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "http_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals["_HTTPMESSAGE"]._serialized_start = 39 - _globals["_HTTPMESSAGE"]._serialized_end = 440 - _globals["_HTTPMESSAGE_REQUEST_PERFORMATIVE"]._serialized_start = 210 - _globals["_HTTPMESSAGE_REQUEST_PERFORMATIVE"]._serialized_end = 309 - _globals["_HTTPMESSAGE_RESPONSE_PERFORMATIVE"]._serialized_start = 311 - _globals["_HTTPMESSAGE_RESPONSE_PERFORMATIVE"]._serialized_end = 424 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/protocols/http/message.py b/trader_backup/vendor/valory/protocols/http/message.py deleted file mode 100644 index 44dcec3b1..000000000 --- a/trader_backup/vendor/valory/protocols/http/message.py +++ /dev/null @@ -1,297 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 http's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - - -_default_logger = logging.getLogger("aea.packages.valory.protocols.http.message") - -DEFAULT_BODY_SIZE = 4 - - -class HttpMessage(Message): - """A protocol for HTTP requests and responses.""" - - protocol_id = PublicId.from_str("valory/http:1.0.0") - protocol_specification_id = PublicId.from_str("valory/http:1.0.0") - - class Performative(Message.Performative): - """Performatives for the http protocol.""" - - REQUEST = "request" - RESPONSE = "response" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = {"request", "response"} - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "body", - "dialogue_reference", - "headers", - "message_id", - "method", - "performative", - "status_code", - "status_text", - "target", - "url", - "version", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of HttpMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=HttpMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(HttpMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def body(self) -> bytes: - """Get the 'body' content from the message.""" - enforce(self.is_set("body"), "'body' content is not set.") - return cast(bytes, self.get("body")) - - @property - def headers(self) -> str: - """Get the 'headers' content from the message.""" - enforce(self.is_set("headers"), "'headers' content is not set.") - return cast(str, self.get("headers")) - - @property - def method(self) -> str: - """Get the 'method' content from the message.""" - enforce(self.is_set("method"), "'method' content is not set.") - return cast(str, self.get("method")) - - @property - def status_code(self) -> int: - """Get the 'status_code' content from the message.""" - enforce(self.is_set("status_code"), "'status_code' content is not set.") - return cast(int, self.get("status_code")) - - @property - def status_text(self) -> str: - """Get the 'status_text' content from the message.""" - enforce(self.is_set("status_text"), "'status_text' content is not set.") - return cast(str, self.get("status_text")) - - @property - def url(self) -> str: - """Get the 'url' content from the message.""" - enforce(self.is_set("url"), "'url' content is not set.") - return cast(str, self.get("url")) - - @property - def version(self) -> str: - """Get the 'version' content from the message.""" - enforce(self.is_set("version"), "'version' content is not set.") - return cast(str, self.get("version")) - - def _is_consistent(self) -> bool: - """Check that the message follows the http protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, HttpMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == HttpMessage.Performative.REQUEST: - expected_nb_of_contents = 5 - enforce( - isinstance(self.method, str), - "Invalid type for content 'method'. Expected 'str'. Found '{}'.".format( - type(self.method) - ), - ) - enforce( - isinstance(self.url, str), - "Invalid type for content 'url'. Expected 'str'. Found '{}'.".format( - type(self.url) - ), - ) - enforce( - isinstance(self.version, str), - "Invalid type for content 'version'. Expected 'str'. Found '{}'.".format( - type(self.version) - ), - ) - enforce( - isinstance(self.headers, str), - "Invalid type for content 'headers'. Expected 'str'. Found '{}'.".format( - type(self.headers) - ), - ) - enforce( - isinstance(self.body, bytes), - "Invalid type for content 'body'. Expected 'bytes'. Found '{}'.".format( - type(self.body) - ), - ) - elif self.performative == HttpMessage.Performative.RESPONSE: - expected_nb_of_contents = 5 - enforce( - isinstance(self.version, str), - "Invalid type for content 'version'. Expected 'str'. Found '{}'.".format( - type(self.version) - ), - ) - enforce( - type(self.status_code) is int, - "Invalid type for content 'status_code'. Expected 'int'. Found '{}'.".format( - type(self.status_code) - ), - ) - enforce( - isinstance(self.status_text, str), - "Invalid type for content 'status_text'. Expected 'str'. Found '{}'.".format( - type(self.status_text) - ), - ) - enforce( - isinstance(self.headers, str), - "Invalid type for content 'headers'. Expected 'str'. Found '{}'.".format( - type(self.headers) - ), - ) - enforce( - isinstance(self.body, bytes), - "Invalid type for content 'body'. Expected 'bytes'. Found '{}'.".format( - type(self.body) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_backup/vendor/valory/protocols/http/protocol.yaml b/trader_backup/vendor/valory/protocols/http/protocol.yaml deleted file mode 100644 index 0246138d0..000000000 --- a/trader_backup/vendor/valory/protocols/http/protocol.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: http -author: valory -version: 1.0.0 -protocol_specification_id: valory/http:1.0.0 -type: protocol -description: A protocol for HTTP requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeihkatpicz56ofrvu5fgks7ecrsfzw5toz23o23yvoymhk6l6hl7dy - __init__.py: bafybeidjcefjfitptbesnqxuq2yyl3v6eh3ng7qx3xk5wlpjbg6pzoca7q - dialogues.py: bafybeiepab5wdmdfevelxcpaky6znmc3wjb6kezwe7c55dp6d4lpiw7zuy - http.proto: bafybeigq6ykgxdqi4m65x3rcj4ehdm3usaisejzl2oisn6kzkjits3fzkq - http_pb2.py: bafybeibvqp664j4iaozk2hyotmd7gzsyknk4dt3mcddniuzdvdxhtkjcoq - message.py: bafybeifnffq6yjisyew6oodtbpaiqsmiruiljr4ihydhlqvlhgwl2hx7qe - serialization.py: bafybeidujjt46tdrooo6fjppax7b2qstmb62gfafd6r6uydb7mpnw6ukyi - tests/__init__.py: bafybeifitr3wqclw3kammd2fw5zww6gvzbvu6s72di2p7544qfisuslhpq - tests/test_http.py: bafybeibbz5zcqmqsvtwp2rucj2ubbbazmqt3shpjnkt5bdhnlclqy4fseq - tests/test_http_dialogues.py: bafybeic22z3aatytdx3cxrtzt3hqwwhxlnaal6sn7grm3cn5k7ycq5v46y - tests/test_http_messages.py: bafybeihp6qmanjxpcfwuq6fngxcjvcogyzrxguax4lcollkbujq542mlv4 -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_backup/vendor/valory/protocols/http/serialization.py b/trader_backup/vendor/valory/protocols/http/serialization.py deleted file mode 100644 index 7dd42a23d..000000000 --- a/trader_backup/vendor/valory/protocols/http/serialization.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for http protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.http import http_pb2 # type: ignore -from packages.valory.protocols.http.message import HttpMessage # type: ignore - - -class HttpSerializer(Serializer): - """Serialization for the 'http' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'Http' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(HttpMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - http_msg = http_pb2.HttpMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == HttpMessage.Performative.REQUEST: - performative = http_pb2.HttpMessage.Request_Performative() # type: ignore - method = msg.method - performative.method = method - url = msg.url - performative.url = url - version = msg.version - performative.version = version - headers = msg.headers - performative.headers = headers - body = msg.body - performative.body = body - http_msg.request.CopyFrom(performative) - elif performative_id == HttpMessage.Performative.RESPONSE: - performative = http_pb2.HttpMessage.Response_Performative() # type: ignore - version = msg.version - performative.version = version - status_code = msg.status_code - performative.status_code = status_code - status_text = msg.status_text - performative.status_text = status_text - headers = msg.headers - performative.headers = headers - body = msg.body - performative.body = body - http_msg.response.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = http_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'Http' message. - - :param obj: the bytes object. - :return: the 'Http' message. - """ - message_pb = ProtobufMessage() - http_pb = http_pb2.HttpMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - http_pb.ParseFromString(message_pb.dialogue_message.content) - performative = http_pb.WhichOneof("performative") - performative_id = HttpMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == HttpMessage.Performative.REQUEST: - method = http_pb.request.method - performative_content["method"] = method - url = http_pb.request.url - performative_content["url"] = url - version = http_pb.request.version - performative_content["version"] = version - headers = http_pb.request.headers - performative_content["headers"] = headers - body = http_pb.request.body - performative_content["body"] = body - elif performative_id == HttpMessage.Performative.RESPONSE: - version = http_pb.response.version - performative_content["version"] = version - status_code = http_pb.response.status_code - performative_content["status_code"] = status_code - status_text = http_pb.response.status_text - performative_content["status_text"] = status_text - headers = http_pb.response.headers - performative_content["headers"] = headers - body = http_pb.response.body - performative_content["body"] = body - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return HttpMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_backup/vendor/valory/protocols/http/tests/__init__.py b/trader_backup/vendor/valory/protocols/http/tests/__init__.py deleted file mode 100644 index 4864c2102..000000000 --- a/trader_backup/vendor/valory/protocols/http/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/http protocol.""" diff --git a/trader_backup/vendor/valory/protocols/http/tests/test_http.py b/trader_backup/vendor/valory/protocols/http/tests/test_http.py deleted file mode 100644 index caaf7da6c..000000000 --- a/trader_backup/vendor/valory/protocols/http/tests/test_http.py +++ /dev/null @@ -1,394 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for the 'valory/http' protocol.""" -from abc import abstractmethod -from typing import Callable, Type -from unittest import mock - -import pytest - -from aea.common import Address -from aea.exceptions import AEAEnforceError -from aea.mail.base import Envelope -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.http import HttpMessage, message -from packages.valory.protocols.http.dialogues import HttpDialogue, HttpDialogues -from packages.valory.protocols.http.message import ( - _default_logger as http_message_logger, -) - - -LEDGER_ID = "ethereum" - - -def test_request_serialization(): - """Test the serialization for 'request' speech-act works.""" - msg = HttpMessage( - performative=HttpMessage.Performative.REQUEST, - method="some_method", - url="url", - version="some_version", - headers="some_headers", - body=b"some_body", - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = HttpMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_response_serialization(): - """Test the serialization for 'response' speech-act works.""" - msg = HttpMessage( - message_id=2, - target=1, - performative=HttpMessage.Performative.RESPONSE, - version="some_version", - status_code=1, - status_text="some_status_text", - headers="some_headers", - body=b"some_body", - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = HttpMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_performative_string_value() -> None: - """Test the string valoe of performatives.""" - - assert ( - str(HttpMessage.Performative.REQUEST) == "request" - ), "The str value must be request" - assert ( - str(HttpMessage.Performative.RESPONSE) == "response" - ), "The str value must be response" - - -def test_encoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = HttpMessage( - performative=HttpMessage.Performative.REQUEST, # type: ignore - method="GET", - url="http://example.com", - version="", - headers="", - body=b"", - ) - - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object(HttpMessage.Performative, "__eq__", return_value=False): - HttpMessage.serializer.encode(msg) - - -def test_decoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = HttpMessage( - performative=HttpMessage.Performative.REQUEST, # type: ignore - method="GET", - url="http://example.com", - version="", - headers="", - body=b"", - ) - - encoded_msg = HttpMessage.serializer.encode(msg) - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object(HttpMessage.Performative, "__eq__", return_value=False): - HttpMessage.serializer.decode(encoded_msg) - - -class BaseTestMessageConstruction: - """Base class to test message construction for the ABCI protocol.""" - - msg_class = HttpMessage - - @abstractmethod - def build_message(self) -> HttpMessage: - """Build the message to be used for testing.""" - - def test_run(self) -> None: - """Run the test.""" - msg = self.build_message() - msg.to = "receiver" - envelope = Envelope(to=msg.to, sender="sender", message=msg) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = self.msg_class.serializer.decode(actual_envelope.message_bytes) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -class TestRequest(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> HttpMessage: - """Build the message.""" - return HttpMessage( - performative=HttpMessage.Performative.REQUEST, # type: ignore - method="GET", - url="http://example.com", - version="", - headers="", - body=b"", - ) - - -class TestResponse(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> HttpMessage: - """Build the message.""" - return HttpMessage( - performative=HttpMessage.Performative.RESPONSE, # type: ignore - version="", - status_code=200, - status_text="OK", - headers="", - body=b"", - ) - - -@mock.patch.object( - message, - "enforce", - side_effect=AEAEnforceError("some error"), -) -def test_incorrect_message( - mocked_enforce: Callable, # pylint: disable=unused-argument -) -> None: - """Test that we raise an exception when the message is incorrect.""" - with mock.patch.object(http_message_logger, "error") as mock_logger: - HttpMessage( - performative=HttpMessage.Performative.REQUEST, # type: ignore - method="GET", - url="http://example.com", - version="", - headers="", - body=b"", - ) - mock_logger.assert_any_call("some error") - - -class AgentDialogue(HttpDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[HttpMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - HttpDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class AgentDialogues(HttpDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return HttpDialogue.Role.CLIENT - - HttpDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=AgentDialogue, - ) - - -class LedgerDialogue(HttpDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[HttpMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - HttpDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class LedgerDialogues(HttpDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return HttpDialogue.Role.SERVER - - HttpDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=LedgerDialogue, - ) - - -class TestDialogues: - """Tests abci dialogues.""" - - agent_addr: str - ledger_addr: str - agent_dialogues: AgentDialogues - ledger_dialogues: LedgerDialogues - - @classmethod - def setup_class(cls) -> None: - """Set up the test.""" - cls.agent_addr = "agent address" - cls.ledger_addr = "ledger address" - cls.agent_dialogues = AgentDialogues(cls.agent_addr) - cls.ledger_dialogues = LedgerDialogues(cls.ledger_addr) - - def test_create_self_initiated(self) -> None: - """Test the self initialisation of a dialogue.""" - result = self.agent_dialogues._create_self_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.ledger_addr, - dialogue_reference=(str(0), ""), - role=HttpDialogue.Role.CLIENT, - ) - assert isinstance(result, HttpDialogue) - assert result.role == HttpDialogue.Role.CLIENT, "The role must be agent." - - def test_create_opponent_initiated(self) -> None: - """Test the opponent initialisation of a dialogue.""" - result = self.agent_dialogues._create_opponent_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.ledger_addr, - dialogue_reference=(str(0), ""), - role=HttpDialogue.Role.CLIENT, - ) - assert isinstance(result, HttpDialogue) - assert result.role == HttpDialogue.Role.CLIENT, "The role must be agent." diff --git a/trader_backup/vendor/valory/protocols/http/tests/test_http_dialogues.py b/trader_backup/vendor/valory/protocols/http/tests/test_http_dialogues.py deleted file mode 100644 index 6a2224e79..000000000 --- a/trader_backup/vendor/valory/protocols/http/tests/test_http_dialogues.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for http protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.http.dialogues import HttpDialogue, HttpDialogues -from packages.valory.protocols.http.message import HttpMessage - - -class TestDialoguesHttp(BaseProtocolDialoguesTestCase): - """Test for the 'http' protocol dialogues.""" - - MESSAGE_CLASS = HttpMessage - - DIALOGUE_CLASS = HttpDialogue - - DIALOGUES_CLASS = HttpDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = HttpDialogue.Role.CLIENT # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=HttpMessage.Performative.REQUEST, - method="some str", - url="some str", - version="some str", - headers="some str", - body=b"some_bytes", - ) diff --git a/trader_backup/vendor/valory/protocols/http/tests/test_http_messages.py b/trader_backup/vendor/valory/protocols/http/tests/test_http_messages.py deleted file mode 100644 index 817f9928e..000000000 --- a/trader_backup/vendor/valory/protocols/http/tests/test_http_messages.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for http protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.http.message import HttpMessage - - -class TestMessageHttp(BaseProtocolMessagesTestCase): - """Test for the 'http' protocol message.""" - - MESSAGE_CLASS = HttpMessage - - def build_messages(self) -> List[HttpMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - HttpMessage( - performative=HttpMessage.Performative.REQUEST, - method="some str", - url="some str", - version="some str", - headers="some str", - body=b"some_bytes", - ), - HttpMessage( - performative=HttpMessage.Performative.RESPONSE, - version="some str", - status_code=12, - status_text="some str", - headers="some str", - body=b"some_bytes", - ), - ] - - def build_inconsistent(self) -> List[HttpMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - HttpMessage( - performative=HttpMessage.Performative.REQUEST, - # skip content: method - url="some str", - version="some str", - headers="some str", - body=b"some_bytes", - ), - HttpMessage( - performative=HttpMessage.Performative.RESPONSE, - # skip content: version - status_code=12, - status_text="some str", - headers="some str", - body=b"some_bytes", - ), - ] diff --git a/trader_backup/vendor/valory/protocols/ipfs/README.md b/trader_backup/vendor/valory/protocols/ipfs/README.md deleted file mode 100644 index 72ddf37a3..000000000 --- a/trader_backup/vendor/valory/protocols/ipfs/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# IPFS Protocol - -## Description - -This is a protocol for interacting with IPFS. - -## Specification - -```yaml ---- -name: ipfs -author: valory -version: 0.1.0 -description: A protocol specification for IPFS requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: valory/ipfs:0.1.0 -speech_acts: - store_files: - files: pt:dict[pt:str, pt:str] - timeout: pt:optional[pt:float] - ipfs_hash: - ipfs_hash: pt:str - get_files: - ipfs_hash: pt:str - timeout: pt:optional[pt:float] - files: - files: pt:dict[pt:str, pt:str] - error: - reason: pt:str ---- -initiation: [get_files, store_files] -reply: - store_files: [ipfs_hash, error] - ipfs_hash: [] - get_files: [files, error] - files: [] - error: [] -termination: [ipfs_hash, files, error] -roles: {skill, connection} -end_states: [ok, error] -keep_terminal_state_dialogues: false -... -``` - -## Links - diff --git a/trader_backup/vendor/valory/protocols/ipfs/__init__.py b/trader_backup/vendor/valory/protocols/ipfs/__init__.py deleted file mode 100644 index 5e2342280..000000000 --- a/trader_backup/vendor/valory/protocols/ipfs/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the ipfs protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.ipfs.message import IpfsMessage -from packages.valory.protocols.ipfs.serialization import IpfsSerializer - - -IpfsMessage.serializer = IpfsSerializer diff --git a/trader_backup/vendor/valory/protocols/ipfs/dialogues.py b/trader_backup/vendor/valory/protocols/ipfs/dialogues.py deleted file mode 100644 index 46bb54e81..000000000 --- a/trader_backup/vendor/valory/protocols/ipfs/dialogues.py +++ /dev/null @@ -1,125 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for ipfs dialogue management. - -- IpfsDialogue: The dialogue class maintains state of a dialogue and manages it. -- IpfsDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.ipfs.message import IpfsMessage - - -class IpfsDialogue(Dialogue): - """The ipfs dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - {IpfsMessage.Performative.GET_FILES, IpfsMessage.Performative.STORE_FILES} - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - IpfsMessage.Performative.IPFS_HASH, - IpfsMessage.Performative.FILES, - IpfsMessage.Performative.ERROR, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - IpfsMessage.Performative.ERROR: frozenset(), - IpfsMessage.Performative.FILES: frozenset(), - IpfsMessage.Performative.GET_FILES: frozenset( - {IpfsMessage.Performative.FILES, IpfsMessage.Performative.ERROR} - ), - IpfsMessage.Performative.IPFS_HASH: frozenset(), - IpfsMessage.Performative.STORE_FILES: frozenset( - {IpfsMessage.Performative.IPFS_HASH, IpfsMessage.Performative.ERROR} - ), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a ipfs dialogue.""" - - CONNECTION = "connection" - SKILL = "skill" - - class EndState(Dialogue.EndState): - """This class defines the end states of a ipfs dialogue.""" - - OK = 0 - ERROR = 1 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[IpfsMessage] = IpfsMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class IpfsDialogues(Dialogues, ABC): - """This class keeps track of all ipfs dialogues.""" - - END_STATES = frozenset({IpfsDialogue.EndState.OK, IpfsDialogue.EndState.ERROR}) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[IpfsDialogue] = IpfsDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=IpfsMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_backup/vendor/valory/protocols/ipfs/ipfs.proto b/trader_backup/vendor/valory/protocols/ipfs/ipfs.proto deleted file mode 100644 index ae5311eb2..000000000 --- a/trader_backup/vendor/valory/protocols/ipfs/ipfs.proto +++ /dev/null @@ -1,40 +0,0 @@ -syntax = "proto3"; - -package aea.valory.ipfs.v0_1_0; - -message IpfsMessage{ - - // Performatives and contents - message Store_Files_Performative{ - map files = 1; - double timeout = 2; - bool timeout_is_set = 3; - } - - message Ipfs_Hash_Performative{ - string ipfs_hash = 1; - } - - message Get_Files_Performative{ - string ipfs_hash = 1; - double timeout = 2; - bool timeout_is_set = 3; - } - - message Files_Performative{ - map files = 1; - } - - message Error_Performative{ - string reason = 1; - } - - - oneof performative{ - Error_Performative error = 5; - Files_Performative files = 6; - Get_Files_Performative get_files = 7; - Ipfs_Hash_Performative ipfs_hash = 8; - Store_Files_Performative store_files = 9; - } -} diff --git a/trader_backup/vendor/valory/protocols/ipfs/ipfs_pb2.py b/trader_backup/vendor/valory/protocols/ipfs/ipfs_pb2.py deleted file mode 100644 index c69233ef6..000000000 --- a/trader_backup/vendor/valory/protocols/ipfs/ipfs_pb2.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: ipfs.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\nipfs.proto\x12\x16\x61\x65\x61.valory.ipfs.v0_1_0"\xb2\x07\n\x0bIpfsMessage\x12G\n\x05\x65rror\x18\x05 \x01(\x0b\x32\x36.aea.valory.ipfs.v0_1_0.IpfsMessage.Error_PerformativeH\x00\x12G\n\x05\x66iles\x18\x06 \x01(\x0b\x32\x36.aea.valory.ipfs.v0_1_0.IpfsMessage.Files_PerformativeH\x00\x12O\n\tget_files\x18\x07 \x01(\x0b\x32:.aea.valory.ipfs.v0_1_0.IpfsMessage.Get_Files_PerformativeH\x00\x12O\n\tipfs_hash\x18\x08 \x01(\x0b\x32:.aea.valory.ipfs.v0_1_0.IpfsMessage.Ipfs_Hash_PerformativeH\x00\x12S\n\x0bstore_files\x18\t \x01(\x0b\x32<.aea.valory.ipfs.v0_1_0.IpfsMessage.Store_Files_PerformativeH\x00\x1a\xc9\x01\n\x18Store_Files_Performative\x12V\n\x05\x66iles\x18\x01 \x03(\x0b\x32G.aea.valory.ipfs.v0_1_0.IpfsMessage.Store_Files_Performative.FilesEntry\x12\x0f\n\x07timeout\x18\x02 \x01(\x01\x12\x16\n\x0etimeout_is_set\x18\x03 \x01(\x08\x1a,\n\nFilesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a+\n\x16Ipfs_Hash_Performative\x12\x11\n\tipfs_hash\x18\x01 \x01(\t\x1aT\n\x16Get_Files_Performative\x12\x11\n\tipfs_hash\x18\x01 \x01(\t\x12\x0f\n\x07timeout\x18\x02 \x01(\x01\x12\x16\n\x0etimeout_is_set\x18\x03 \x01(\x08\x1a\x94\x01\n\x12\x46iles_Performative\x12P\n\x05\x66iles\x18\x01 \x03(\x0b\x32\x41.aea.valory.ipfs.v0_1_0.IpfsMessage.Files_Performative.FilesEntry\x1a,\n\nFilesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a$\n\x12\x45rror_Performative\x12\x0e\n\x06reason\x18\x01 \x01(\tB\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "ipfs_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _IPFSMESSAGE_STORE_FILES_PERFORMATIVE_FILESENTRY._options = None - _IPFSMESSAGE_STORE_FILES_PERFORMATIVE_FILESENTRY._serialized_options = b"8\001" - _IPFSMESSAGE_FILES_PERFORMATIVE_FILESENTRY._options = None - _IPFSMESSAGE_FILES_PERFORMATIVE_FILESENTRY._serialized_options = b"8\001" - _globals["_IPFSMESSAGE"]._serialized_start = 39 - _globals["_IPFSMESSAGE"]._serialized_end = 985 - _globals["_IPFSMESSAGE_STORE_FILES_PERFORMATIVE"]._serialized_start = 448 - _globals["_IPFSMESSAGE_STORE_FILES_PERFORMATIVE"]._serialized_end = 649 - _globals["_IPFSMESSAGE_STORE_FILES_PERFORMATIVE_FILESENTRY"]._serialized_start = 605 - _globals["_IPFSMESSAGE_STORE_FILES_PERFORMATIVE_FILESENTRY"]._serialized_end = 649 - _globals["_IPFSMESSAGE_IPFS_HASH_PERFORMATIVE"]._serialized_start = 651 - _globals["_IPFSMESSAGE_IPFS_HASH_PERFORMATIVE"]._serialized_end = 694 - _globals["_IPFSMESSAGE_GET_FILES_PERFORMATIVE"]._serialized_start = 696 - _globals["_IPFSMESSAGE_GET_FILES_PERFORMATIVE"]._serialized_end = 780 - _globals["_IPFSMESSAGE_FILES_PERFORMATIVE"]._serialized_start = 783 - _globals["_IPFSMESSAGE_FILES_PERFORMATIVE"]._serialized_end = 931 - _globals["_IPFSMESSAGE_FILES_PERFORMATIVE_FILESENTRY"]._serialized_start = 605 - _globals["_IPFSMESSAGE_FILES_PERFORMATIVE_FILESENTRY"]._serialized_end = 649 - _globals["_IPFSMESSAGE_ERROR_PERFORMATIVE"]._serialized_start = 933 - _globals["_IPFSMESSAGE_ERROR_PERFORMATIVE"]._serialized_end = 969 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/protocols/ipfs/message.py b/trader_backup/vendor/valory/protocols/ipfs/message.py deleted file mode 100644 index 93aa55baa..000000000 --- a/trader_backup/vendor/valory/protocols/ipfs/message.py +++ /dev/null @@ -1,298 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 ipfs's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Dict, Optional, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - - -_default_logger = logging.getLogger("aea.packages.valory.protocols.ipfs.message") - -DEFAULT_BODY_SIZE = 4 - - -class IpfsMessage(Message): - """A protocol specification for IPFS requests and responses.""" - - protocol_id = PublicId.from_str("valory/ipfs:0.1.0") - protocol_specification_id = PublicId.from_str("valory/ipfs:0.1.0") - - class Performative(Message.Performative): - """Performatives for the ipfs protocol.""" - - ERROR = "error" - FILES = "files" - GET_FILES = "get_files" - IPFS_HASH = "ipfs_hash" - STORE_FILES = "store_files" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = {"error", "files", "get_files", "ipfs_hash", "store_files"} - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "dialogue_reference", - "files", - "ipfs_hash", - "message_id", - "performative", - "reason", - "target", - "timeout", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of IpfsMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=IpfsMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(IpfsMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def files(self) -> Dict[str, str]: - """Get the 'files' content from the message.""" - enforce(self.is_set("files"), "'files' content is not set.") - return cast(Dict[str, str], self.get("files")) - - @property - def ipfs_hash(self) -> str: - """Get the 'ipfs_hash' content from the message.""" - enforce(self.is_set("ipfs_hash"), "'ipfs_hash' content is not set.") - return cast(str, self.get("ipfs_hash")) - - @property - def reason(self) -> str: - """Get the 'reason' content from the message.""" - enforce(self.is_set("reason"), "'reason' content is not set.") - return cast(str, self.get("reason")) - - @property - def timeout(self) -> Optional[float]: - """Get the 'timeout' content from the message.""" - return cast(Optional[float], self.get("timeout")) - - def _is_consistent(self) -> bool: - """Check that the message follows the ipfs protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, IpfsMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == IpfsMessage.Performative.STORE_FILES: - expected_nb_of_contents = 1 - enforce( - isinstance(self.files, dict), - "Invalid type for content 'files'. Expected 'dict'. Found '{}'.".format( - type(self.files) - ), - ) - for key_of_files, value_of_files in self.files.items(): - enforce( - isinstance(key_of_files, str), - "Invalid type for dictionary keys in content 'files'. Expected 'str'. Found '{}'.".format( - type(key_of_files) - ), - ) - enforce( - isinstance(value_of_files, str), - "Invalid type for dictionary values in content 'files'. Expected 'str'. Found '{}'.".format( - type(value_of_files) - ), - ) - if self.is_set("timeout"): - expected_nb_of_contents += 1 - timeout = cast(float, self.timeout) - enforce( - isinstance(timeout, float), - "Invalid type for content 'timeout'. Expected 'float'. Found '{}'.".format( - type(timeout) - ), - ) - elif self.performative == IpfsMessage.Performative.IPFS_HASH: - expected_nb_of_contents = 1 - enforce( - isinstance(self.ipfs_hash, str), - "Invalid type for content 'ipfs_hash'. Expected 'str'. Found '{}'.".format( - type(self.ipfs_hash) - ), - ) - elif self.performative == IpfsMessage.Performative.GET_FILES: - expected_nb_of_contents = 1 - enforce( - isinstance(self.ipfs_hash, str), - "Invalid type for content 'ipfs_hash'. Expected 'str'. Found '{}'.".format( - type(self.ipfs_hash) - ), - ) - if self.is_set("timeout"): - expected_nb_of_contents += 1 - timeout = cast(float, self.timeout) - enforce( - isinstance(timeout, float), - "Invalid type for content 'timeout'. Expected 'float'. Found '{}'.".format( - type(timeout) - ), - ) - elif self.performative == IpfsMessage.Performative.FILES: - expected_nb_of_contents = 1 - enforce( - isinstance(self.files, dict), - "Invalid type for content 'files'. Expected 'dict'. Found '{}'.".format( - type(self.files) - ), - ) - for key_of_files, value_of_files in self.files.items(): - enforce( - isinstance(key_of_files, str), - "Invalid type for dictionary keys in content 'files'. Expected 'str'. Found '{}'.".format( - type(key_of_files) - ), - ) - enforce( - isinstance(value_of_files, str), - "Invalid type for dictionary values in content 'files'. Expected 'str'. Found '{}'.".format( - type(value_of_files) - ), - ) - elif self.performative == IpfsMessage.Performative.ERROR: - expected_nb_of_contents = 1 - enforce( - isinstance(self.reason, str), - "Invalid type for content 'reason'. Expected 'str'. Found '{}'.".format( - type(self.reason) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_backup/vendor/valory/protocols/ipfs/protocol.yaml b/trader_backup/vendor/valory/protocols/ipfs/protocol.yaml deleted file mode 100644 index 6e5a91883..000000000 --- a/trader_backup/vendor/valory/protocols/ipfs/protocol.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: ipfs -author: valory -version: 0.1.0 -protocol_specification_id: valory/ipfs:0.1.0 -type: protocol -description: A protocol specification for IPFS requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeidv64ed7ljvsggruwj3onb7dj7b5nyx4ngohacztdreujjztsuns4 - __init__.py: bafybeigvsifgesa6mc7dikvjdhyr3nsfksn5f73eryfk5imj47xvdbtqam - dialogues.py: bafybeidjf3k6pg6qgtgrzu2iothckvx2wuprx4ft4bqocz6mni63feptl4 - ipfs.proto: bafybeifpe6szd3m2zjlvn5zwiy7mbimur7pu46lobxvyyarozabxpmhcs4 - ipfs_pb2.py: bafybeihzspjtj2zoy3owb5itbz2lrintf7odanhvsi4qooxuqxu3ar6qpu - message.py: bafybeicxtql2e72atkcdsxc4ni4blffywconumyvh3mlsvb7o2dljqk7oy - serialization.py: bafybeicvvind4q6gqfwcmrjttlsm74pz7lc7z2uciyc2vghxckmmuh3dze - tests/test_ipfs_dialogues.py: bafybeigqi2cal5m252qf3ry75mldfd5kyqj3bgstvyzpjgpjgxhi2otpoa - tests/test_ipfs_messages.py: bafybeiasgajluoijzuln3s4gcbv5xenzazejt5kgbs54momozsntzrudw4 -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_backup/vendor/valory/protocols/ipfs/serialization.py b/trader_backup/vendor/valory/protocols/ipfs/serialization.py deleted file mode 100644 index faa999a7c..000000000 --- a/trader_backup/vendor/valory/protocols/ipfs/serialization.py +++ /dev/null @@ -1,153 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for ipfs protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.ipfs import ipfs_pb2 # type: ignore -from packages.valory.protocols.ipfs.message import IpfsMessage # type: ignore - - -class IpfsSerializer(Serializer): - """Serialization for the 'ipfs' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'Ipfs' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(IpfsMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - ipfs_msg = ipfs_pb2.IpfsMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == IpfsMessage.Performative.STORE_FILES: - performative = ipfs_pb2.IpfsMessage.Store_Files_Performative() # type: ignore - files = msg.files - performative.files.update(files) - if msg.is_set("timeout"): - performative.timeout_is_set = True - timeout = msg.timeout - performative.timeout = timeout - ipfs_msg.store_files.CopyFrom(performative) - elif performative_id == IpfsMessage.Performative.IPFS_HASH: - performative = ipfs_pb2.IpfsMessage.Ipfs_Hash_Performative() # type: ignore - ipfs_hash = msg.ipfs_hash - performative.ipfs_hash = ipfs_hash - ipfs_msg.ipfs_hash.CopyFrom(performative) - elif performative_id == IpfsMessage.Performative.GET_FILES: - performative = ipfs_pb2.IpfsMessage.Get_Files_Performative() # type: ignore - ipfs_hash = msg.ipfs_hash - performative.ipfs_hash = ipfs_hash - if msg.is_set("timeout"): - performative.timeout_is_set = True - timeout = msg.timeout - performative.timeout = timeout - ipfs_msg.get_files.CopyFrom(performative) - elif performative_id == IpfsMessage.Performative.FILES: - performative = ipfs_pb2.IpfsMessage.Files_Performative() # type: ignore - files = msg.files - performative.files.update(files) - ipfs_msg.files.CopyFrom(performative) - elif performative_id == IpfsMessage.Performative.ERROR: - performative = ipfs_pb2.IpfsMessage.Error_Performative() # type: ignore - reason = msg.reason - performative.reason = reason - ipfs_msg.error.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = ipfs_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'Ipfs' message. - - :param obj: the bytes object. - :return: the 'Ipfs' message. - """ - message_pb = ProtobufMessage() - ipfs_pb = ipfs_pb2.IpfsMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - ipfs_pb.ParseFromString(message_pb.dialogue_message.content) - performative = ipfs_pb.WhichOneof("performative") - performative_id = IpfsMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == IpfsMessage.Performative.STORE_FILES: - files = ipfs_pb.store_files.files - files_dict = dict(files) - performative_content["files"] = files_dict - if ipfs_pb.store_files.timeout_is_set: - timeout = ipfs_pb.store_files.timeout - performative_content["timeout"] = timeout - elif performative_id == IpfsMessage.Performative.IPFS_HASH: - ipfs_hash = ipfs_pb.ipfs_hash.ipfs_hash - performative_content["ipfs_hash"] = ipfs_hash - elif performative_id == IpfsMessage.Performative.GET_FILES: - ipfs_hash = ipfs_pb.get_files.ipfs_hash - performative_content["ipfs_hash"] = ipfs_hash - if ipfs_pb.get_files.timeout_is_set: - timeout = ipfs_pb.get_files.timeout - performative_content["timeout"] = timeout - elif performative_id == IpfsMessage.Performative.FILES: - files = ipfs_pb.files.files - files_dict = dict(files) - performative_content["files"] = files_dict - elif performative_id == IpfsMessage.Performative.ERROR: - reason = ipfs_pb.error.reason - performative_content["reason"] = reason - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return IpfsMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_backup/vendor/valory/protocols/ipfs/tests/test_ipfs_dialogues.py b/trader_backup/vendor/valory/protocols/ipfs/tests/test_ipfs_dialogues.py deleted file mode 100644 index 8a515a22b..000000000 --- a/trader_backup/vendor/valory/protocols/ipfs/tests/test_ipfs_dialogues.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for ipfs protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.ipfs.dialogues import IpfsDialogue, IpfsDialogues -from packages.valory.protocols.ipfs.message import IpfsMessage - - -class TestDialoguesIpfs(BaseProtocolDialoguesTestCase): - """Test for the 'ipfs' protocol dialogues.""" - - MESSAGE_CLASS = IpfsMessage - - DIALOGUE_CLASS = IpfsDialogue - - DIALOGUES_CLASS = IpfsDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = IpfsDialogue.Role.CONNECTION # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=IpfsMessage.Performative.GET_FILES, - ipfs_hash="some str", - timeout=1.0, - ) diff --git a/trader_backup/vendor/valory/protocols/ipfs/tests/test_ipfs_messages.py b/trader_backup/vendor/valory/protocols/ipfs/tests/test_ipfs_messages.py deleted file mode 100644 index 075918486..000000000 --- a/trader_backup/vendor/valory/protocols/ipfs/tests/test_ipfs_messages.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for ipfs protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.ipfs.message import IpfsMessage - - -class TestMessageIpfs(BaseProtocolMessagesTestCase): - """Test for the 'ipfs' protocol message.""" - - MESSAGE_CLASS = IpfsMessage - - def build_messages(self) -> List[IpfsMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - IpfsMessage( - performative=IpfsMessage.Performative.STORE_FILES, - files={"some str": "some str"}, - timeout=1.0, - ), - IpfsMessage( - performative=IpfsMessage.Performative.IPFS_HASH, - ipfs_hash="some str", - ), - IpfsMessage( - performative=IpfsMessage.Performative.GET_FILES, - ipfs_hash="some str", - timeout=1.0, - ), - IpfsMessage( - performative=IpfsMessage.Performative.FILES, - files={"some str": "some str"}, - ), - IpfsMessage( - performative=IpfsMessage.Performative.ERROR, - reason="some str", - ), - ] - - def build_inconsistent(self) -> List[IpfsMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - IpfsMessage( - performative=IpfsMessage.Performative.STORE_FILES, - # skip content: files - timeout=1.0, - ), - IpfsMessage( - performative=IpfsMessage.Performative.IPFS_HASH, - # skip content: ipfs_hash - ), - IpfsMessage( - performative=IpfsMessage.Performative.GET_FILES, - # skip content: ipfs_hash - timeout=1.0, - ), - IpfsMessage( - performative=IpfsMessage.Performative.FILES, - # skip content: files - ), - IpfsMessage( - performative=IpfsMessage.Performative.ERROR, - # skip content: reason - ), - ] diff --git a/trader_backup/vendor/valory/protocols/ledger_api/README.md b/trader_backup/vendor/valory/protocols/ledger_api/README.md deleted file mode 100644 index 09303f9aa..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/README.md +++ /dev/null @@ -1,103 +0,0 @@ -# Ledger API Protocol - -## Description - -This is a protocol for interacting with ledger APIs. - -## Specification - -```yaml ---- -name: ledger_api -author: valory -version: 1.0.0 -description: A protocol for ledger APIs requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: valory/ledger_api:1.0.0 -speech_acts: - get_balance: - ledger_id: pt:str - address: pt:str - get_raw_transaction: - terms: ct:Terms - send_signed_transaction: - signed_transaction: ct:SignedTransaction - kwargs: ct:Kwargs - send_signed_transactions: - signed_transactions: ct:SignedTransactions - kwargs: ct:Kwargs - get_transaction_receipt: - transaction_digest: ct:TransactionDigest - retry_timeout: pt:optional[pt:int] - retry_attempts: pt:optional[pt:int] - balance: - ledger_id: pt:str - balance: pt:int - raw_transaction: - raw_transaction: ct:RawTransaction - transaction_digest: - transaction_digest: ct:TransactionDigest - transaction_digests: - transaction_digests: ct:TransactionDigests - transaction_receipt: - transaction_receipt: ct:TransactionReceipt - get_state: - ledger_id: pt:str - callable: pt:str - args: pt:list[pt:str] - kwargs: ct:Kwargs - state: - ledger_id: pt:str - state: ct:State - error: - code: pt:int - message: pt:optional[pt:str] - data: pt:optional[pt:bytes] -... ---- -ct:Terms: | - bytes terms = 1; -ct:Kwargs: | - bytes kwargs = 1; -ct:State: | - bytes state = 1; -ct:SignedTransaction: | - bytes signed_transaction = 1; -ct:SignedTransactions: | - string ledger_id = 1; - repeated bytes signed_transactions = 2; -ct:RawTransaction: | - bytes raw_transaction = 1; -ct:TransactionDigest: | - bytes transaction_digest = 1; -ct:TransactionDigests: | - string ledger_id = 1; - repeated string transaction_digests = 2; -ct:TransactionReceipt: | - bytes transaction_receipt = 1; -... ---- -initiation: [get_balance, get_state, get_raw_transaction, send_signed_transaction, send_signed_transactions, get_transaction_receipt] -reply: - get_balance: [balance, error] - balance: [] - get_state: [state, error] - state: [] - get_raw_transaction: [raw_transaction, error] - raw_transaction: [] - send_signed_transaction: [transaction_digest, error] - send_signed_transactions: [transaction_digests, error] - transaction_digest: [] - transaction_digests: [] - get_transaction_receipt: [transaction_receipt, error] - transaction_receipt: [] - error: [] -termination: [balance, state, raw_transaction, transaction_digest, transaction_digests, transaction_receipt, error] -roles: {agent, ledger} -end_states: [successful] -keep_terminal_state_dialogues: false -... -``` - -## Links diff --git a/trader_backup/vendor/valory/protocols/ledger_api/__init__.py b/trader_backup/vendor/valory/protocols/ledger_api/__init__.py deleted file mode 100644 index 21b4d2592..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the ledger_api protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.protocols.ledger_api.serialization import LedgerApiSerializer - - -LedgerApiMessage.serializer = LedgerApiSerializer diff --git a/trader_backup/vendor/valory/protocols/ledger_api/custom_types.py b/trader_backup/vendor/valory/protocols/ledger_api/custom_types.py deleted file mode 100644 index ba2e11140..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/custom_types.py +++ /dev/null @@ -1,284 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2020-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 class representations corresponding to every custom type in the protocol specification.""" - -from typing import Any, List - -from aea.common import JSONLike -from aea.exceptions import enforce -from aea.helpers.serializers import DictProtobufStructSerializer -from aea.helpers.transaction.base import RawTransaction as BaseRawTransaction -from aea.helpers.transaction.base import SignedTransaction as BaseSignedTransaction -from aea.helpers.transaction.base import State as BaseState -from aea.helpers.transaction.base import Terms as BaseTerms -from aea.helpers.transaction.base import TransactionDigest as BaseTransactionDigest -from aea.helpers.transaction.base import TransactionReceipt as BaseTransactionReceipt - - -RawTransaction = BaseRawTransaction -SignedTransaction = BaseSignedTransaction -State = BaseState -Terms = BaseTerms -TransactionDigest = BaseTransactionDigest -TransactionReceipt = BaseTransactionReceipt - - -class Kwargs: - """This class represents an instance of Kwargs.""" - - __slots__ = ("_body",) - - def __init__( - self, - body: JSONLike, - ): - """Initialise an instance of RawTransaction.""" - self._body = body - self._check_consistency() - - def _check_consistency(self) -> None: - """Check consistency of the object.""" - enforce( - isinstance(self._body, dict) - and all([isinstance(key, str) for key in self._body.keys()]), - "Body must be dict and keys must be str.", - ) - - @property - def body(self) -> JSONLike: - """Get the body.""" - return self._body - - @staticmethod - def encode(kwargs_protobuf_object: Any, kwargs_object: "Kwargs") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the kwargs_protobuf_object argument is matched with the instance of this class in the 'kwargs_object' argument. - - :param kwargs_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param kwargs_object: an instance of this class to be encoded in the protocol buffer object. - """ - kwargs_protobuf_object.kwargs = DictProtobufStructSerializer.encode( - kwargs_object.body - ) - - @classmethod - def decode(cls, kwargs_protobuf_object: Any) -> "Kwargs": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'kwargs_protobuf_object' argument. - - :param kwargs_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'kwargs_protobuf_object' argument. - """ - kwargs = DictProtobufStructSerializer.decode(kwargs_protobuf_object.kwargs) - return cls(kwargs) - - def __eq__(self, other: Any) -> bool: - """Check equality.""" - return isinstance(other, Kwargs) and self.body == other.body - - def __str__(self) -> str: - """Get string representation.""" - return "Kwargs: body={}".format(self.body) - - -class SignedTransactions: - """This class represents an instance of SignedTransactions.""" - - __slots__ = ( - "_ledger_id", - "_signed_transactions", - ) - - def __init__( - self, - ledger_id: str, - signed_transactions: List[JSONLike], - ): - """Initialise an instance of SignedTransactions.""" - self._ledger_id = ledger_id - self._signed_transactions = signed_transactions - self._check_consistency() - - def _check_consistency(self) -> None: - """Check consistency of the object.""" - enforce(isinstance(self._ledger_id, str), "ledger_id must be str.") - enforce( - isinstance(self._signed_transactions, list), - "signed_transactions must be list.", - ) - - @property - def ledger_id(self) -> str: - """Get the body.""" - return self._ledger_id - - @property - def signed_transactions(self) -> List[JSONLike]: - """Get the body.""" - return self._signed_transactions - - @staticmethod - def encode( - signed_transactions_protobuf_object: Any, - signed_transactions_object: "SignedTransactions", - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the signed_transactions_protobuf_object argument is matched with the instance of this class in the 'signed_transactions_object' argument. - - :param signed_transactions_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param signed_transactions_object: an instance of this class to be encoded in the protocol buffer object. - """ - encoded_transactions = [ - DictProtobufStructSerializer.encode(tx) - for tx in signed_transactions_object.signed_transactions - ] - signed_transactions_protobuf_object.signed_transactions.extend( - encoded_transactions - ) - signed_transactions_protobuf_object.ledger_id = ( - signed_transactions_object.ledger_id - ) - - @classmethod - def decode(cls, signed_transactions_protobuf_object: Any) -> "SignedTransactions": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'signed_transactions_protobuf_object' argument. - - :param signed_transactions_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'signed_transactions_protobuf_object' argument. - """ - decoded_transactions = [ - DictProtobufStructSerializer.decode(tx) - for tx in signed_transactions_protobuf_object.signed_transactions - ] - return cls( - ledger_id=signed_transactions_protobuf_object.ledger_id, - signed_transactions=decoded_transactions, - ) - - def __eq__(self, other: Any) -> bool: - """Check equality.""" - return ( - isinstance(other, SignedTransactions) - and self.ledger_id == other.ledger_id - and self.signed_transactions == other.signed_transactions - ) - - def __str__(self) -> str: - """Get string representation.""" - return "SignedTransactions: ledger_id={} signed_transactions={}".format( - self.ledger_id, self.signed_transactions - ) - - -class TransactionDigests: - """This class represents an instance of TransactionDigests.""" - - __slots__ = ( - "_ledger_id", - "_transaction_digests", - ) - - def __init__( - self, - ledger_id: str, - transaction_digests: List[str], - ): - """Initialise an instance of TransactionDigests.""" - self._ledger_id = ledger_id - self._transaction_digests = transaction_digests - self._check_consistency() - - def _check_consistency(self) -> None: - """Check consistency of the object.""" - enforce(isinstance(self._ledger_id, str), "ledger_id must be str.") - enforce( - isinstance(self._transaction_digests, list), - "transaction_digests must be list.", - ) - - @property - def ledger_id(self) -> str: - """Get the body.""" - return self._ledger_id - - @property - def transaction_digests(self) -> List[str]: - """Get the body.""" - return self._transaction_digests - - @staticmethod - def encode( - transaction_digests_protobuf_object: Any, - transaction_digests_object: "TransactionDigests", - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the transaction_digests_protobuf_object argument is matched with the instance of this class in the 'transaction_digests_object' argument. - - :param transaction_digests_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param transaction_digests_object: an instance of this class to be encoded in the protocol buffer object. - """ - transaction_digests_protobuf_object.transaction_digests.extend( - transaction_digests_object.transaction_digests - ) - transaction_digests_protobuf_object.ledger_id = ( - transaction_digests_object.ledger_id - ) - - @classmethod - def decode(cls, transaction_digests_protobuf_object: Any) -> "TransactionDigests": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'transaction_digests_protobuf_object' argument. - - :param transaction_digests_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'transaction_digests_protobuf_object' argument. - """ - return cls( - ledger_id=transaction_digests_protobuf_object.ledger_id, - transaction_digests=list( - transaction_digests_protobuf_object.transaction_digests - ), - ) - - def __eq__(self, other: Any) -> bool: - """Check equality.""" - return ( - isinstance(other, TransactionDigests) - and self.ledger_id == other.ledger_id - and self.transaction_digests == other.transaction_digests - ) - - def __str__(self) -> str: - """Get string representation.""" - return "TransactionDigests: ledger_id={} transaction_digests={}".format( - self.ledger_id, self.transaction_digests - ) diff --git a/trader_backup/vendor/valory/protocols/ledger_api/dialogues.py b/trader_backup/vendor/valory/protocols/ledger_api/dialogues.py deleted file mode 100644 index d08650274..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/dialogues.py +++ /dev/null @@ -1,163 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for ledger_api dialogue management. - -- LedgerApiDialogue: The dialogue class maintains state of a dialogue and manages it. -- LedgerApiDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.ledger_api.message import LedgerApiMessage - - -class LedgerApiDialogue(Dialogue): - """The ledger_api dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - LedgerApiMessage.Performative.GET_BALANCE, - LedgerApiMessage.Performative.GET_STATE, - LedgerApiMessage.Performative.GET_RAW_TRANSACTION, - LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, - LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS, - LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - LedgerApiMessage.Performative.BALANCE, - LedgerApiMessage.Performative.STATE, - LedgerApiMessage.Performative.RAW_TRANSACTION, - LedgerApiMessage.Performative.TRANSACTION_DIGEST, - LedgerApiMessage.Performative.TRANSACTION_DIGESTS, - LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - LedgerApiMessage.Performative.ERROR, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - LedgerApiMessage.Performative.BALANCE: frozenset(), - LedgerApiMessage.Performative.ERROR: frozenset(), - LedgerApiMessage.Performative.GET_BALANCE: frozenset( - {LedgerApiMessage.Performative.BALANCE, LedgerApiMessage.Performative.ERROR} - ), - LedgerApiMessage.Performative.GET_RAW_TRANSACTION: frozenset( - { - LedgerApiMessage.Performative.RAW_TRANSACTION, - LedgerApiMessage.Performative.ERROR, - } - ), - LedgerApiMessage.Performative.GET_STATE: frozenset( - {LedgerApiMessage.Performative.STATE, LedgerApiMessage.Performative.ERROR} - ), - LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT: frozenset( - { - LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - LedgerApiMessage.Performative.ERROR, - } - ), - LedgerApiMessage.Performative.RAW_TRANSACTION: frozenset(), - LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION: frozenset( - { - LedgerApiMessage.Performative.TRANSACTION_DIGEST, - LedgerApiMessage.Performative.ERROR, - } - ), - LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS: frozenset( - { - LedgerApiMessage.Performative.TRANSACTION_DIGESTS, - LedgerApiMessage.Performative.ERROR, - } - ), - LedgerApiMessage.Performative.STATE: frozenset(), - LedgerApiMessage.Performative.TRANSACTION_DIGEST: frozenset(), - LedgerApiMessage.Performative.TRANSACTION_DIGESTS: frozenset(), - LedgerApiMessage.Performative.TRANSACTION_RECEIPT: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a ledger_api dialogue.""" - - AGENT = "agent" - LEDGER = "ledger" - - class EndState(Dialogue.EndState): - """This class defines the end states of a ledger_api dialogue.""" - - SUCCESSFUL = 0 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[LedgerApiMessage] = LedgerApiMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class LedgerApiDialogues(Dialogues, ABC): - """This class keeps track of all ledger_api dialogues.""" - - END_STATES = frozenset({LedgerApiDialogue.EndState.SUCCESSFUL}) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[LedgerApiDialogue] = LedgerApiDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=LedgerApiMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_backup/vendor/valory/protocols/ledger_api/ledger_api.proto b/trader_backup/vendor/valory/protocols/ledger_api/ledger_api.proto deleted file mode 100644 index e0441b4f0..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/ledger_api.proto +++ /dev/null @@ -1,132 +0,0 @@ -syntax = "proto3"; - -package aea.valory.ledger_api.v1_0_0; - -message LedgerApiMessage{ - - // Custom Types - message Kwargs{ - bytes kwargs = 1; - } - - message RawTransaction{ - bytes raw_transaction = 1; - } - - message SignedTransaction{ - bytes signed_transaction = 1; - } - - message SignedTransactions{ - string ledger_id = 1; - repeated bytes signed_transactions = 2; - } - - message State{ - bytes state = 1; - } - - message Terms{ - bytes terms = 1; - } - - message TransactionDigest{ - bytes transaction_digest = 1; - } - - message TransactionDigests{ - string ledger_id = 1; - repeated string transaction_digests = 2; - } - - message TransactionReceipt{ - bytes transaction_receipt = 1; - } - - - // Performatives and contents - message Get_Balance_Performative{ - string ledger_id = 1; - string address = 2; - } - - message Get_Raw_Transaction_Performative{ - Terms terms = 1; - } - - message Send_Signed_Transaction_Performative{ - SignedTransaction signed_transaction = 1; - Kwargs kwargs = 2; - } - - message Send_Signed_Transactions_Performative{ - SignedTransactions signed_transactions = 1; - Kwargs kwargs = 2; - } - - message Get_Transaction_Receipt_Performative{ - TransactionDigest transaction_digest = 1; - int32 retry_timeout = 2; - bool retry_timeout_is_set = 3; - int32 retry_attempts = 4; - bool retry_attempts_is_set = 5; - } - - message Balance_Performative{ - string ledger_id = 1; - int32 balance = 2; - } - - message Raw_Transaction_Performative{ - RawTransaction raw_transaction = 1; - } - - message Transaction_Digest_Performative{ - TransactionDigest transaction_digest = 1; - } - - message Transaction_Digests_Performative{ - TransactionDigests transaction_digests = 1; - } - - message Transaction_Receipt_Performative{ - TransactionReceipt transaction_receipt = 1; - } - - message Get_State_Performative{ - string ledger_id = 1; - string callable = 2; - repeated string args = 3; - Kwargs kwargs = 4; - } - - message State_Performative{ - string ledger_id = 1; - State state = 2; - } - - message Error_Performative{ - int32 code = 1; - string message = 2; - bool message_is_set = 3; - bytes data = 4; - bool data_is_set = 5; - } - - - oneof performative{ - Balance_Performative balance = 5; - Error_Performative error = 6; - Get_Balance_Performative get_balance = 7; - Get_Raw_Transaction_Performative get_raw_transaction = 8; - Get_State_Performative get_state = 9; - Get_Transaction_Receipt_Performative get_transaction_receipt = 10; - Raw_Transaction_Performative raw_transaction = 11; - Send_Signed_Transaction_Performative send_signed_transaction = 12; - Send_Signed_Transactions_Performative send_signed_transactions = 13; - State_Performative state = 14; - Transaction_Digest_Performative transaction_digest = 15; - Transaction_Digests_Performative transaction_digests = 16; - Transaction_Receipt_Performative transaction_receipt = 17; - } -} diff --git a/trader_backup/vendor/valory/protocols/ledger_api/ledger_api_pb2.py b/trader_backup/vendor/valory/protocols/ledger_api/ledger_api_pb2.py deleted file mode 100644 index 38cc5978e..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/ledger_api_pb2.py +++ /dev/null @@ -1,96 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: ledger_api.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x10ledger_api.proto\x12\x1c\x61\x65\x61.valory.ledger_api.v1_0_0"\xf1\x1b\n\x10LedgerApiMessage\x12V\n\x07\x62\x61lance\x18\x05 \x01(\x0b\x32\x43.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Balance_PerformativeH\x00\x12R\n\x05\x65rror\x18\x06 \x01(\x0b\x32\x41.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Error_PerformativeH\x00\x12^\n\x0bget_balance\x18\x07 \x01(\x0b\x32G.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Get_Balance_PerformativeH\x00\x12n\n\x13get_raw_transaction\x18\x08 \x01(\x0b\x32O.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Get_Raw_Transaction_PerformativeH\x00\x12Z\n\tget_state\x18\t \x01(\x0b\x32\x45.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Get_State_PerformativeH\x00\x12v\n\x17get_transaction_receipt\x18\n \x01(\x0b\x32S.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Get_Transaction_Receipt_PerformativeH\x00\x12\x66\n\x0fraw_transaction\x18\x0b \x01(\x0b\x32K.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Raw_Transaction_PerformativeH\x00\x12v\n\x17send_signed_transaction\x18\x0c \x01(\x0b\x32S.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Send_Signed_Transaction_PerformativeH\x00\x12x\n\x18send_signed_transactions\x18\r \x01(\x0b\x32T.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Send_Signed_Transactions_PerformativeH\x00\x12R\n\x05state\x18\x0e \x01(\x0b\x32\x41.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.State_PerformativeH\x00\x12l\n\x12transaction_digest\x18\x0f \x01(\x0b\x32N.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Transaction_Digest_PerformativeH\x00\x12n\n\x13transaction_digests\x18\x10 \x01(\x0b\x32O.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Transaction_Digests_PerformativeH\x00\x12n\n\x13transaction_receipt\x18\x11 \x01(\x0b\x32O.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Transaction_Receipt_PerformativeH\x00\x1a\x18\n\x06Kwargs\x12\x0e\n\x06kwargs\x18\x01 \x01(\x0c\x1a)\n\x0eRawTransaction\x12\x17\n\x0fraw_transaction\x18\x01 \x01(\x0c\x1a/\n\x11SignedTransaction\x12\x1a\n\x12signed_transaction\x18\x01 \x01(\x0c\x1a\x44\n\x12SignedTransactions\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x1b\n\x13signed_transactions\x18\x02 \x03(\x0c\x1a\x16\n\x05State\x12\r\n\x05state\x18\x01 \x01(\x0c\x1a\x16\n\x05Terms\x12\r\n\x05terms\x18\x01 \x01(\x0c\x1a/\n\x11TransactionDigest\x12\x1a\n\x12transaction_digest\x18\x01 \x01(\x0c\x1a\x44\n\x12TransactionDigests\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x1b\n\x13transaction_digests\x18\x02 \x03(\t\x1a\x31\n\x12TransactionReceipt\x12\x1b\n\x13transaction_receipt\x18\x01 \x01(\x0c\x1a>\n\x18Get_Balance_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x1ag\n Get_Raw_Transaction_Performative\x12\x43\n\x05terms\x18\x01 \x01(\x0b\x32\x34.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Terms\x1a\xcb\x01\n$Send_Signed_Transaction_Performative\x12\\\n\x12signed_transaction\x18\x01 \x01(\x0b\x32@.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.SignedTransaction\x12\x45\n\x06kwargs\x18\x02 \x01(\x0b\x32\x35.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Kwargs\x1a\xce\x01\n%Send_Signed_Transactions_Performative\x12^\n\x13signed_transactions\x18\x01 \x01(\x0b\x32\x41.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.SignedTransactions\x12\x45\n\x06kwargs\x18\x02 \x01(\x0b\x32\x35.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Kwargs\x1a\xf0\x01\n$Get_Transaction_Receipt_Performative\x12\\\n\x12transaction_digest\x18\x01 \x01(\x0b\x32@.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.TransactionDigest\x12\x15\n\rretry_timeout\x18\x02 \x01(\x05\x12\x1c\n\x14retry_timeout_is_set\x18\x03 \x01(\x08\x12\x16\n\x0eretry_attempts\x18\x04 \x01(\x05\x12\x1d\n\x15retry_attempts_is_set\x18\x05 \x01(\x08\x1a:\n\x14\x42\x61lance_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x0f\n\x07\x62\x61lance\x18\x02 \x01(\x05\x1av\n\x1cRaw_Transaction_Performative\x12V\n\x0fraw_transaction\x18\x01 \x01(\x0b\x32=.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.RawTransaction\x1a\x7f\n\x1fTransaction_Digest_Performative\x12\\\n\x12transaction_digest\x18\x01 \x01(\x0b\x32@.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.TransactionDigest\x1a\x82\x01\n Transaction_Digests_Performative\x12^\n\x13transaction_digests\x18\x01 \x01(\x0b\x32\x41.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.TransactionDigests\x1a\x82\x01\n Transaction_Receipt_Performative\x12^\n\x13transaction_receipt\x18\x01 \x01(\x0b\x32\x41.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.TransactionReceipt\x1a\x92\x01\n\x16Get_State_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x10\n\x08\x63\x61llable\x18\x02 \x01(\t\x12\x0c\n\x04\x61rgs\x18\x03 \x03(\t\x12\x45\n\x06kwargs\x18\x04 \x01(\x0b\x32\x35.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Kwargs\x1al\n\x12State_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x43\n\x05state\x18\x02 \x01(\x0b\x32\x34.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.State\x1an\n\x12\x45rror_Performative\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x16\n\x0emessage_is_set\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\x0c\x12\x13\n\x0b\x64\x61ta_is_set\x18\x05 \x01(\x08\x42\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "ledger_api_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals["_LEDGERAPIMESSAGE"]._serialized_start = 51 - _globals["_LEDGERAPIMESSAGE"]._serialized_end = 3620 - _globals["_LEDGERAPIMESSAGE_KWARGS"]._serialized_start = 1427 - _globals["_LEDGERAPIMESSAGE_KWARGS"]._serialized_end = 1451 - _globals["_LEDGERAPIMESSAGE_RAWTRANSACTION"]._serialized_start = 1453 - _globals["_LEDGERAPIMESSAGE_RAWTRANSACTION"]._serialized_end = 1494 - _globals["_LEDGERAPIMESSAGE_SIGNEDTRANSACTION"]._serialized_start = 1496 - _globals["_LEDGERAPIMESSAGE_SIGNEDTRANSACTION"]._serialized_end = 1543 - _globals["_LEDGERAPIMESSAGE_SIGNEDTRANSACTIONS"]._serialized_start = 1545 - _globals["_LEDGERAPIMESSAGE_SIGNEDTRANSACTIONS"]._serialized_end = 1613 - _globals["_LEDGERAPIMESSAGE_STATE"]._serialized_start = 1615 - _globals["_LEDGERAPIMESSAGE_STATE"]._serialized_end = 1637 - _globals["_LEDGERAPIMESSAGE_TERMS"]._serialized_start = 1639 - _globals["_LEDGERAPIMESSAGE_TERMS"]._serialized_end = 1661 - _globals["_LEDGERAPIMESSAGE_TRANSACTIONDIGEST"]._serialized_start = 1663 - _globals["_LEDGERAPIMESSAGE_TRANSACTIONDIGEST"]._serialized_end = 1710 - _globals["_LEDGERAPIMESSAGE_TRANSACTIONDIGESTS"]._serialized_start = 1712 - _globals["_LEDGERAPIMESSAGE_TRANSACTIONDIGESTS"]._serialized_end = 1780 - _globals["_LEDGERAPIMESSAGE_TRANSACTIONRECEIPT"]._serialized_start = 1782 - _globals["_LEDGERAPIMESSAGE_TRANSACTIONRECEIPT"]._serialized_end = 1831 - _globals["_LEDGERAPIMESSAGE_GET_BALANCE_PERFORMATIVE"]._serialized_start = 1833 - _globals["_LEDGERAPIMESSAGE_GET_BALANCE_PERFORMATIVE"]._serialized_end = 1895 - _globals[ - "_LEDGERAPIMESSAGE_GET_RAW_TRANSACTION_PERFORMATIVE" - ]._serialized_start = 1897 - _globals[ - "_LEDGERAPIMESSAGE_GET_RAW_TRANSACTION_PERFORMATIVE" - ]._serialized_end = 2000 - _globals[ - "_LEDGERAPIMESSAGE_SEND_SIGNED_TRANSACTION_PERFORMATIVE" - ]._serialized_start = 2003 - _globals[ - "_LEDGERAPIMESSAGE_SEND_SIGNED_TRANSACTION_PERFORMATIVE" - ]._serialized_end = 2206 - _globals[ - "_LEDGERAPIMESSAGE_SEND_SIGNED_TRANSACTIONS_PERFORMATIVE" - ]._serialized_start = 2209 - _globals[ - "_LEDGERAPIMESSAGE_SEND_SIGNED_TRANSACTIONS_PERFORMATIVE" - ]._serialized_end = 2415 - _globals[ - "_LEDGERAPIMESSAGE_GET_TRANSACTION_RECEIPT_PERFORMATIVE" - ]._serialized_start = 2418 - _globals[ - "_LEDGERAPIMESSAGE_GET_TRANSACTION_RECEIPT_PERFORMATIVE" - ]._serialized_end = 2658 - _globals["_LEDGERAPIMESSAGE_BALANCE_PERFORMATIVE"]._serialized_start = 2660 - _globals["_LEDGERAPIMESSAGE_BALANCE_PERFORMATIVE"]._serialized_end = 2718 - _globals["_LEDGERAPIMESSAGE_RAW_TRANSACTION_PERFORMATIVE"]._serialized_start = 2720 - _globals["_LEDGERAPIMESSAGE_RAW_TRANSACTION_PERFORMATIVE"]._serialized_end = 2838 - _globals[ - "_LEDGERAPIMESSAGE_TRANSACTION_DIGEST_PERFORMATIVE" - ]._serialized_start = 2840 - _globals["_LEDGERAPIMESSAGE_TRANSACTION_DIGEST_PERFORMATIVE"]._serialized_end = 2967 - _globals[ - "_LEDGERAPIMESSAGE_TRANSACTION_DIGESTS_PERFORMATIVE" - ]._serialized_start = 2970 - _globals[ - "_LEDGERAPIMESSAGE_TRANSACTION_DIGESTS_PERFORMATIVE" - ]._serialized_end = 3100 - _globals[ - "_LEDGERAPIMESSAGE_TRANSACTION_RECEIPT_PERFORMATIVE" - ]._serialized_start = 3103 - _globals[ - "_LEDGERAPIMESSAGE_TRANSACTION_RECEIPT_PERFORMATIVE" - ]._serialized_end = 3233 - _globals["_LEDGERAPIMESSAGE_GET_STATE_PERFORMATIVE"]._serialized_start = 3236 - _globals["_LEDGERAPIMESSAGE_GET_STATE_PERFORMATIVE"]._serialized_end = 3382 - _globals["_LEDGERAPIMESSAGE_STATE_PERFORMATIVE"]._serialized_start = 3384 - _globals["_LEDGERAPIMESSAGE_STATE_PERFORMATIVE"]._serialized_end = 3492 - _globals["_LEDGERAPIMESSAGE_ERROR_PERFORMATIVE"]._serialized_start = 3494 - _globals["_LEDGERAPIMESSAGE_ERROR_PERFORMATIVE"]._serialized_end = 3604 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/protocols/ledger_api/message.py b/trader_backup/vendor/valory/protocols/ledger_api/message.py deleted file mode 100644 index 37e5606a7..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/message.py +++ /dev/null @@ -1,594 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 ledger_api's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Optional, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - -from packages.valory.protocols.ledger_api.custom_types import Kwargs as CustomKwargs -from packages.valory.protocols.ledger_api.custom_types import ( - RawTransaction as CustomRawTransaction, -) -from packages.valory.protocols.ledger_api.custom_types import ( - SignedTransaction as CustomSignedTransaction, -) -from packages.valory.protocols.ledger_api.custom_types import ( - SignedTransactions as CustomSignedTransactions, -) -from packages.valory.protocols.ledger_api.custom_types import State as CustomState -from packages.valory.protocols.ledger_api.custom_types import Terms as CustomTerms -from packages.valory.protocols.ledger_api.custom_types import ( - TransactionDigest as CustomTransactionDigest, -) -from packages.valory.protocols.ledger_api.custom_types import ( - TransactionDigests as CustomTransactionDigests, -) -from packages.valory.protocols.ledger_api.custom_types import ( - TransactionReceipt as CustomTransactionReceipt, -) - - -_default_logger = logging.getLogger("aea.packages.valory.protocols.ledger_api.message") - -DEFAULT_BODY_SIZE = 4 - - -class LedgerApiMessage(Message): - """A protocol for ledger APIs requests and responses.""" - - protocol_id = PublicId.from_str("valory/ledger_api:1.0.0") - protocol_specification_id = PublicId.from_str("valory/ledger_api:1.0.0") - - Kwargs = CustomKwargs - - RawTransaction = CustomRawTransaction - - SignedTransaction = CustomSignedTransaction - - SignedTransactions = CustomSignedTransactions - - State = CustomState - - Terms = CustomTerms - - TransactionDigest = CustomTransactionDigest - - TransactionDigests = CustomTransactionDigests - - TransactionReceipt = CustomTransactionReceipt - - class Performative(Message.Performative): - """Performatives for the ledger_api protocol.""" - - BALANCE = "balance" - ERROR = "error" - GET_BALANCE = "get_balance" - GET_RAW_TRANSACTION = "get_raw_transaction" - GET_STATE = "get_state" - GET_TRANSACTION_RECEIPT = "get_transaction_receipt" - RAW_TRANSACTION = "raw_transaction" - SEND_SIGNED_TRANSACTION = "send_signed_transaction" - SEND_SIGNED_TRANSACTIONS = "send_signed_transactions" - STATE = "state" - TRANSACTION_DIGEST = "transaction_digest" - TRANSACTION_DIGESTS = "transaction_digests" - TRANSACTION_RECEIPT = "transaction_receipt" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = { - "balance", - "error", - "get_balance", - "get_raw_transaction", - "get_state", - "get_transaction_receipt", - "raw_transaction", - "send_signed_transaction", - "send_signed_transactions", - "state", - "transaction_digest", - "transaction_digests", - "transaction_receipt", - } - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "address", - "args", - "balance", - "callable", - "code", - "data", - "dialogue_reference", - "kwargs", - "ledger_id", - "message", - "message_id", - "performative", - "raw_transaction", - "retry_attempts", - "retry_timeout", - "signed_transaction", - "signed_transactions", - "state", - "target", - "terms", - "transaction_digest", - "transaction_digests", - "transaction_receipt", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of LedgerApiMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=LedgerApiMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(LedgerApiMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def address(self) -> str: - """Get the 'address' content from the message.""" - enforce(self.is_set("address"), "'address' content is not set.") - return cast(str, self.get("address")) - - @property - def args(self) -> Tuple[str, ...]: - """Get the 'args' content from the message.""" - enforce(self.is_set("args"), "'args' content is not set.") - return cast(Tuple[str, ...], self.get("args")) - - @property - def balance(self) -> int: - """Get the 'balance' content from the message.""" - enforce(self.is_set("balance"), "'balance' content is not set.") - return cast(int, self.get("balance")) - - @property - def callable(self) -> str: - """Get the 'callable' content from the message.""" - enforce(self.is_set("callable"), "'callable' content is not set.") - return cast(str, self.get("callable")) - - @property - def code(self) -> int: - """Get the 'code' content from the message.""" - enforce(self.is_set("code"), "'code' content is not set.") - return cast(int, self.get("code")) - - @property - def data(self) -> Optional[bytes]: - """Get the 'data' content from the message.""" - return cast(Optional[bytes], self.get("data")) - - @property - def kwargs(self) -> CustomKwargs: - """Get the 'kwargs' content from the message.""" - enforce(self.is_set("kwargs"), "'kwargs' content is not set.") - return cast(CustomKwargs, self.get("kwargs")) - - @property - def ledger_id(self) -> str: - """Get the 'ledger_id' content from the message.""" - enforce(self.is_set("ledger_id"), "'ledger_id' content is not set.") - return cast(str, self.get("ledger_id")) - - @property - def message(self) -> Optional[str]: - """Get the 'message' content from the message.""" - return cast(Optional[str], self.get("message")) - - @property - def raw_transaction(self) -> CustomRawTransaction: - """Get the 'raw_transaction' content from the message.""" - enforce(self.is_set("raw_transaction"), "'raw_transaction' content is not set.") - return cast(CustomRawTransaction, self.get("raw_transaction")) - - @property - def retry_attempts(self) -> Optional[int]: - """Get the 'retry_attempts' content from the message.""" - return cast(Optional[int], self.get("retry_attempts")) - - @property - def retry_timeout(self) -> Optional[int]: - """Get the 'retry_timeout' content from the message.""" - return cast(Optional[int], self.get("retry_timeout")) - - @property - def signed_transaction(self) -> CustomSignedTransaction: - """Get the 'signed_transaction' content from the message.""" - enforce( - self.is_set("signed_transaction"), - "'signed_transaction' content is not set.", - ) - return cast(CustomSignedTransaction, self.get("signed_transaction")) - - @property - def signed_transactions(self) -> CustomSignedTransactions: - """Get the 'signed_transactions' content from the message.""" - enforce( - self.is_set("signed_transactions"), - "'signed_transactions' content is not set.", - ) - return cast(CustomSignedTransactions, self.get("signed_transactions")) - - @property - def state(self) -> CustomState: - """Get the 'state' content from the message.""" - enforce(self.is_set("state"), "'state' content is not set.") - return cast(CustomState, self.get("state")) - - @property - def terms(self) -> CustomTerms: - """Get the 'terms' content from the message.""" - enforce(self.is_set("terms"), "'terms' content is not set.") - return cast(CustomTerms, self.get("terms")) - - @property - def transaction_digest(self) -> CustomTransactionDigest: - """Get the 'transaction_digest' content from the message.""" - enforce( - self.is_set("transaction_digest"), - "'transaction_digest' content is not set.", - ) - return cast(CustomTransactionDigest, self.get("transaction_digest")) - - @property - def transaction_digests(self) -> CustomTransactionDigests: - """Get the 'transaction_digests' content from the message.""" - enforce( - self.is_set("transaction_digests"), - "'transaction_digests' content is not set.", - ) - return cast(CustomTransactionDigests, self.get("transaction_digests")) - - @property - def transaction_receipt(self) -> CustomTransactionReceipt: - """Get the 'transaction_receipt' content from the message.""" - enforce( - self.is_set("transaction_receipt"), - "'transaction_receipt' content is not set.", - ) - return cast(CustomTransactionReceipt, self.get("transaction_receipt")) - - def _is_consistent(self) -> bool: - """Check that the message follows the ledger_api protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, LedgerApiMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == LedgerApiMessage.Performative.GET_BALANCE: - expected_nb_of_contents = 2 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.address, str), - "Invalid type for content 'address'. Expected 'str'. Found '{}'.".format( - type(self.address) - ), - ) - elif self.performative == LedgerApiMessage.Performative.GET_RAW_TRANSACTION: - expected_nb_of_contents = 1 - enforce( - isinstance(self.terms, CustomTerms), - "Invalid type for content 'terms'. Expected 'Terms'. Found '{}'.".format( - type(self.terms) - ), - ) - elif ( - self.performative - == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION - ): - expected_nb_of_contents = 2 - enforce( - isinstance(self.signed_transaction, CustomSignedTransaction), - "Invalid type for content 'signed_transaction'. Expected 'SignedTransaction'. Found '{}'.".format( - type(self.signed_transaction) - ), - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif ( - self.performative - == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS - ): - expected_nb_of_contents = 2 - enforce( - isinstance(self.signed_transactions, CustomSignedTransactions), - "Invalid type for content 'signed_transactions'. Expected 'SignedTransactions'. Found '{}'.".format( - type(self.signed_transactions) - ), - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif ( - self.performative - == LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT - ): - expected_nb_of_contents = 1 - enforce( - isinstance(self.transaction_digest, CustomTransactionDigest), - "Invalid type for content 'transaction_digest'. Expected 'TransactionDigest'. Found '{}'.".format( - type(self.transaction_digest) - ), - ) - if self.is_set("retry_timeout"): - expected_nb_of_contents += 1 - retry_timeout = cast(int, self.retry_timeout) - enforce( - type(retry_timeout) is int, - "Invalid type for content 'retry_timeout'. Expected 'int'. Found '{}'.".format( - type(retry_timeout) - ), - ) - if self.is_set("retry_attempts"): - expected_nb_of_contents += 1 - retry_attempts = cast(int, self.retry_attempts) - enforce( - type(retry_attempts) is int, - "Invalid type for content 'retry_attempts'. Expected 'int'. Found '{}'.".format( - type(retry_attempts) - ), - ) - elif self.performative == LedgerApiMessage.Performative.BALANCE: - expected_nb_of_contents = 2 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - type(self.balance) is int, - "Invalid type for content 'balance'. Expected 'int'. Found '{}'.".format( - type(self.balance) - ), - ) - elif self.performative == LedgerApiMessage.Performative.RAW_TRANSACTION: - expected_nb_of_contents = 1 - enforce( - isinstance(self.raw_transaction, CustomRawTransaction), - "Invalid type for content 'raw_transaction'. Expected 'RawTransaction'. Found '{}'.".format( - type(self.raw_transaction) - ), - ) - elif self.performative == LedgerApiMessage.Performative.TRANSACTION_DIGEST: - expected_nb_of_contents = 1 - enforce( - isinstance(self.transaction_digest, CustomTransactionDigest), - "Invalid type for content 'transaction_digest'. Expected 'TransactionDigest'. Found '{}'.".format( - type(self.transaction_digest) - ), - ) - elif self.performative == LedgerApiMessage.Performative.TRANSACTION_DIGESTS: - expected_nb_of_contents = 1 - enforce( - isinstance(self.transaction_digests, CustomTransactionDigests), - "Invalid type for content 'transaction_digests'. Expected 'TransactionDigests'. Found '{}'.".format( - type(self.transaction_digests) - ), - ) - elif self.performative == LedgerApiMessage.Performative.TRANSACTION_RECEIPT: - expected_nb_of_contents = 1 - enforce( - isinstance(self.transaction_receipt, CustomTransactionReceipt), - "Invalid type for content 'transaction_receipt'. Expected 'TransactionReceipt'. Found '{}'.".format( - type(self.transaction_receipt) - ), - ) - elif self.performative == LedgerApiMessage.Performative.GET_STATE: - expected_nb_of_contents = 4 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.callable, str), - "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( - type(self.callable) - ), - ) - enforce( - isinstance(self.args, tuple), - "Invalid type for content 'args'. Expected 'tuple'. Found '{}'.".format( - type(self.args) - ), - ) - enforce( - all(isinstance(element, str) for element in self.args), - "Invalid type for tuple elements in content 'args'. Expected 'str'.", - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif self.performative == LedgerApiMessage.Performative.STATE: - expected_nb_of_contents = 2 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.state, CustomState), - "Invalid type for content 'state'. Expected 'State'. Found '{}'.".format( - type(self.state) - ), - ) - elif self.performative == LedgerApiMessage.Performative.ERROR: - expected_nb_of_contents = 1 - enforce( - type(self.code) is int, - "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( - type(self.code) - ), - ) - if self.is_set("message"): - expected_nb_of_contents += 1 - message = cast(str, self.message) - enforce( - isinstance(message, str), - "Invalid type for content 'message'. Expected 'str'. Found '{}'.".format( - type(message) - ), - ) - if self.is_set("data"): - expected_nb_of_contents += 1 - data = cast(bytes, self.data) - enforce( - isinstance(data, bytes), - "Invalid type for content 'data'. Expected 'bytes'. Found '{}'.".format( - type(data) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_backup/vendor/valory/protocols/ledger_api/protocol.yaml b/trader_backup/vendor/valory/protocols/ledger_api/protocol.yaml deleted file mode 100644 index 5d767dca8..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/protocol.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: ledger_api -author: valory -version: 1.0.0 -protocol_specification_id: valory/ledger_api:1.0.0 -type: protocol -description: A protocol for ledger APIs requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeieviyxw7rq2fxq74c2fq2vv4qsyvxvioyke6wlz3m7ubfgxvebica - __init__.py: bafybeigxgphnez54c6elal3mfgdxwv3el36srmvblkec6sfpt6hcrcexsq - custom_types.py: bafybeiefoqbszkmctw6fep4pot6rdlm4irfy2dydoihlcb7g6i3v47gu4m - dialogues.py: bafybeiaeulvhvizadautscwbf2mi4uw6gdyh3fe36mixgoyy4wnofexebu - ledger_api.proto: bafybeidsmls6jcbeqv4kokizh3kvwzrlae2penr7ntungtosk6m4lxzd4u - ledger_api_pb2.py: bafybeib6kxlzndw5766nxmwfaqurybwjkw3u3uvowe7vn5h4ljsik2l3xu - message.py: bafybeietvabblvsj4nd3zkf2wtnyt2a7bijjygtjxbzndf3h7ng4sfvb44 - serialization.py: bafybeicbpsrxxk5zohsm642gtryhyebdn7lvrfrgika74lg3w6vxns7afq - tests/__init__.py: bafybeih2pvd62uql4qcvrrzqx6evsuu3apqok6wu63qq4r5qm3rikbfsmy - tests/test_ledger_api.py: bafybeiayvznmhqqy66rfqffyurysjc5jfp3bywhcv4zfvwr7kdwj25qjpa - tests/test_ledger_api_dialogues.py: bafybeiaq4ia6kvbwblyyuq7l64vwlluf57lpdkfddohbkbf2osiolrjeku - tests/test_ledger_api_messages.py: bafybeif4abvermxrxcqqfp65blbajadzl5ymnfjmwx62obj6n45emnlzuu -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_backup/vendor/valory/protocols/ledger_api/serialization.py b/trader_backup/vendor/valory/protocols/ledger_api/serialization.py deleted file mode 100644 index ebc2e6132..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/serialization.py +++ /dev/null @@ -1,309 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for ledger_api protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.ledger_api import ledger_api_pb2 # type: ignore -from packages.valory.protocols.ledger_api.custom_types import ( # type: ignore - Kwargs, - RawTransaction, - SignedTransaction, - SignedTransactions, - State, - Terms, - TransactionDigest, - TransactionDigests, - TransactionReceipt, -) -from packages.valory.protocols.ledger_api.message import ( # type: ignore - LedgerApiMessage, -) - - -class LedgerApiSerializer(Serializer): - """Serialization for the 'ledger_api' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'LedgerApi' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(LedgerApiMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - ledger_api_msg = ledger_api_pb2.LedgerApiMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == LedgerApiMessage.Performative.GET_BALANCE: - performative = ledger_api_pb2.LedgerApiMessage.Get_Balance_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - address = msg.address - performative.address = address - ledger_api_msg.get_balance.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.GET_RAW_TRANSACTION: - performative = ledger_api_pb2.LedgerApiMessage.Get_Raw_Transaction_Performative() # type: ignore - terms = msg.terms - Terms.encode(performative.terms, terms) - ledger_api_msg.get_raw_transaction.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION: - performative = ledger_api_pb2.LedgerApiMessage.Send_Signed_Transaction_Performative() # type: ignore - signed_transaction = msg.signed_transaction - SignedTransaction.encode( - performative.signed_transaction, signed_transaction - ) - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - ledger_api_msg.send_signed_transaction.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS: - performative = ledger_api_pb2.LedgerApiMessage.Send_Signed_Transactions_Performative() # type: ignore - signed_transactions = msg.signed_transactions - SignedTransactions.encode( - performative.signed_transactions, signed_transactions - ) - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - ledger_api_msg.send_signed_transactions.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT: - performative = ledger_api_pb2.LedgerApiMessage.Get_Transaction_Receipt_Performative() # type: ignore - transaction_digest = msg.transaction_digest - TransactionDigest.encode( - performative.transaction_digest, transaction_digest - ) - if msg.is_set("retry_timeout"): - performative.retry_timeout_is_set = True - retry_timeout = msg.retry_timeout - performative.retry_timeout = retry_timeout - if msg.is_set("retry_attempts"): - performative.retry_attempts_is_set = True - retry_attempts = msg.retry_attempts - performative.retry_attempts = retry_attempts - ledger_api_msg.get_transaction_receipt.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.BALANCE: - performative = ledger_api_pb2.LedgerApiMessage.Balance_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - balance = msg.balance - performative.balance = balance - ledger_api_msg.balance.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.RAW_TRANSACTION: - performative = ledger_api_pb2.LedgerApiMessage.Raw_Transaction_Performative() # type: ignore - raw_transaction = msg.raw_transaction - RawTransaction.encode(performative.raw_transaction, raw_transaction) - ledger_api_msg.raw_transaction.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.TRANSACTION_DIGEST: - performative = ledger_api_pb2.LedgerApiMessage.Transaction_Digest_Performative() # type: ignore - transaction_digest = msg.transaction_digest - TransactionDigest.encode( - performative.transaction_digest, transaction_digest - ) - ledger_api_msg.transaction_digest.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.TRANSACTION_DIGESTS: - performative = ledger_api_pb2.LedgerApiMessage.Transaction_Digests_Performative() # type: ignore - transaction_digests = msg.transaction_digests - TransactionDigests.encode( - performative.transaction_digests, transaction_digests - ) - ledger_api_msg.transaction_digests.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.TRANSACTION_RECEIPT: - performative = ledger_api_pb2.LedgerApiMessage.Transaction_Receipt_Performative() # type: ignore - transaction_receipt = msg.transaction_receipt - TransactionReceipt.encode( - performative.transaction_receipt, transaction_receipt - ) - ledger_api_msg.transaction_receipt.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.GET_STATE: - performative = ledger_api_pb2.LedgerApiMessage.Get_State_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - callable = msg.callable - performative.callable = callable - args = msg.args - performative.args.extend(args) - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - ledger_api_msg.get_state.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.STATE: - performative = ledger_api_pb2.LedgerApiMessage.State_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - state = msg.state - State.encode(performative.state, state) - ledger_api_msg.state.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.ERROR: - performative = ledger_api_pb2.LedgerApiMessage.Error_Performative() # type: ignore - code = msg.code - performative.code = code - if msg.is_set("message"): - performative.message_is_set = True - message = msg.message - performative.message = message - if msg.is_set("data"): - performative.data_is_set = True - data = msg.data - performative.data = data - ledger_api_msg.error.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = ledger_api_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'LedgerApi' message. - - :param obj: the bytes object. - :return: the 'LedgerApi' message. - """ - message_pb = ProtobufMessage() - ledger_api_pb = ledger_api_pb2.LedgerApiMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - ledger_api_pb.ParseFromString(message_pb.dialogue_message.content) - performative = ledger_api_pb.WhichOneof("performative") - performative_id = LedgerApiMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == LedgerApiMessage.Performative.GET_BALANCE: - ledger_id = ledger_api_pb.get_balance.ledger_id - performative_content["ledger_id"] = ledger_id - address = ledger_api_pb.get_balance.address - performative_content["address"] = address - elif performative_id == LedgerApiMessage.Performative.GET_RAW_TRANSACTION: - pb2_terms = ledger_api_pb.get_raw_transaction.terms - terms = Terms.decode(pb2_terms) - performative_content["terms"] = terms - elif performative_id == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION: - pb2_signed_transaction = ( - ledger_api_pb.send_signed_transaction.signed_transaction - ) - signed_transaction = SignedTransaction.decode(pb2_signed_transaction) - performative_content["signed_transaction"] = signed_transaction - pb2_kwargs = ledger_api_pb.send_signed_transaction.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS: - pb2_signed_transactions = ( - ledger_api_pb.send_signed_transactions.signed_transactions - ) - signed_transactions = SignedTransactions.decode(pb2_signed_transactions) - performative_content["signed_transactions"] = signed_transactions - pb2_kwargs = ledger_api_pb.send_signed_transactions.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT: - pb2_transaction_digest = ( - ledger_api_pb.get_transaction_receipt.transaction_digest - ) - transaction_digest = TransactionDigest.decode(pb2_transaction_digest) - performative_content["transaction_digest"] = transaction_digest - if ledger_api_pb.get_transaction_receipt.retry_timeout_is_set: - retry_timeout = ledger_api_pb.get_transaction_receipt.retry_timeout - performative_content["retry_timeout"] = retry_timeout - if ledger_api_pb.get_transaction_receipt.retry_attempts_is_set: - retry_attempts = ledger_api_pb.get_transaction_receipt.retry_attempts - performative_content["retry_attempts"] = retry_attempts - elif performative_id == LedgerApiMessage.Performative.BALANCE: - ledger_id = ledger_api_pb.balance.ledger_id - performative_content["ledger_id"] = ledger_id - balance = ledger_api_pb.balance.balance - performative_content["balance"] = balance - elif performative_id == LedgerApiMessage.Performative.RAW_TRANSACTION: - pb2_raw_transaction = ledger_api_pb.raw_transaction.raw_transaction - raw_transaction = RawTransaction.decode(pb2_raw_transaction) - performative_content["raw_transaction"] = raw_transaction - elif performative_id == LedgerApiMessage.Performative.TRANSACTION_DIGEST: - pb2_transaction_digest = ledger_api_pb.transaction_digest.transaction_digest - transaction_digest = TransactionDigest.decode(pb2_transaction_digest) - performative_content["transaction_digest"] = transaction_digest - elif performative_id == LedgerApiMessage.Performative.TRANSACTION_DIGESTS: - pb2_transaction_digests = ( - ledger_api_pb.transaction_digests.transaction_digests - ) - transaction_digests = TransactionDigests.decode(pb2_transaction_digests) - performative_content["transaction_digests"] = transaction_digests - elif performative_id == LedgerApiMessage.Performative.TRANSACTION_RECEIPT: - pb2_transaction_receipt = ( - ledger_api_pb.transaction_receipt.transaction_receipt - ) - transaction_receipt = TransactionReceipt.decode(pb2_transaction_receipt) - performative_content["transaction_receipt"] = transaction_receipt - elif performative_id == LedgerApiMessage.Performative.GET_STATE: - ledger_id = ledger_api_pb.get_state.ledger_id - performative_content["ledger_id"] = ledger_id - callable = ledger_api_pb.get_state.callable - performative_content["callable"] = callable - args = ledger_api_pb.get_state.args - args_tuple = tuple(args) - performative_content["args"] = args_tuple - pb2_kwargs = ledger_api_pb.get_state.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == LedgerApiMessage.Performative.STATE: - ledger_id = ledger_api_pb.state.ledger_id - performative_content["ledger_id"] = ledger_id - pb2_state = ledger_api_pb.state.state - state = State.decode(pb2_state) - performative_content["state"] = state - elif performative_id == LedgerApiMessage.Performative.ERROR: - code = ledger_api_pb.error.code - performative_content["code"] = code - if ledger_api_pb.error.message_is_set: - message = ledger_api_pb.error.message - performative_content["message"] = message - if ledger_api_pb.error.data_is_set: - data = ledger_api_pb.error.data - performative_content["data"] = data - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return LedgerApiMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_backup/vendor/valory/protocols/ledger_api/tests/__init__.py b/trader_backup/vendor/valory/protocols/ledger_api/tests/__init__.py deleted file mode 100644 index 42ad6b368..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/ledger_api protocol.""" diff --git a/trader_backup/vendor/valory/protocols/ledger_api/tests/test_ledger_api.py b/trader_backup/vendor/valory/protocols/ledger_api/tests/test_ledger_api.py deleted file mode 100644 index 8ef6ef00a..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/tests/test_ledger_api.py +++ /dev/null @@ -1,963 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for the 'valory/ledger_api' protocol.""" -from abc import abstractmethod -from typing import Callable, Type -from unittest import mock - -import pytest - -from aea.common import Address -from aea.exceptions import AEAEnforceError -from aea.mail.base import Envelope -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.ledger_api import LedgerApiMessage, message -from packages.valory.protocols.ledger_api.custom_types import ( - Kwargs, - SignedTransactions, - State, - Terms, - TransactionDigests, -) -from packages.valory.protocols.ledger_api.dialogues import ( - LedgerApiDialogue, - LedgerApiDialogues, -) -from packages.valory.protocols.ledger_api.message import ( - _default_logger as ledger_api_message_logger, -) - - -LEDGER_ID = "ethereum" -CONTRACT_ID = "contract_id_stub" -CALLABLE = "callable_stub" -CONTRACT_ADDRESS = "contract_address_stub" - - -def test_get_balance_serialization(): - """Test the serialization for 'get_balance' speech-act works.""" - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, - ledger_id="some_ledger_id", - address="some_address", - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_get_state_serialization(): - """Test the serialization for 'get_state' speech-act works.""" - - args = ("arg1", "arg2") - kwargs = Kwargs({"key": "value"}) - - assert str(kwargs) == "Kwargs: body={'key': 'value'}" - - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_STATE, - ledger_id="some_ledger_id", - callable="some_function", - args=args, - kwargs=kwargs, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_get_raw_transaction_serialization(): - """Test the serialization for 'get_raw_transaction' speech-act works.""" - terms_arg = LedgerApiMessage.Terms( - ledger_id="some_ledger_id", - sender_address="some_sender_address", - counterparty_address="some_counterparty_address", - amount_by_currency_id={"currency_id_1": 1}, - quantities_by_good_id={"good_id_1": -1, "good_id_2": -2}, - nonce="some_nonce", - is_sender_payable_tx_fee=False, - fee_by_currency_id={"currency_id_1": 1}, - is_strict=True, - ) - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, - terms=terms_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_send_signed_transaction_serialization(): - """Test the serialization for 'send_signed_transaction' speech-act works.""" - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, - signed_transaction=LedgerApiMessage.SignedTransaction( - "some_ledger_id", {"body": "some_body"} - ), - kwargs=Kwargs({}), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_get_transaction_receipt_serialization(): - """Test the serialization for 'get_transaction_receipt' speech-act works.""" - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, - transaction_digest=LedgerApiMessage.TransactionDigest( - "some_ledger_id", "some_body" - ), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_balance_serialization(): - """Test the serialization for 'balance' speech-act works.""" - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.BALANCE, - ledger_id="some_ledger_id", - balance=125, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_state_serialization(): - """Test the serialization for 'state' speech-act works.""" - - ledger_id = "some_ledger_id" - state = State(ledger_id, {"key": "some_state"}) - - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.STATE, - ledger_id=ledger_id, - state=state, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_raw_transaction_serialization(): - """Test the serialization for 'raw_transaction' speech-act works.""" - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=LedgerApiMessage.RawTransaction( - "some_ledger_id", {"body": "some_body"} - ), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_transaction_digest_serialization(): - """Test the serialization for 'transaction_digest' speech-act works.""" - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, - transaction_digest=LedgerApiMessage.TransactionDigest( - "some_ledger_id", "some_body" - ), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_transaction_receipt_serialization(): - """Test the serialization for 'transaction_receipt' speech-act works.""" - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - transaction_receipt=LedgerApiMessage.TransactionReceipt( - "some_ledger_id", {"key": "some_receipt"}, {"key": "some_transaction"} - ), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_error_serialization(): - """Test the serialization for 'error' speech-act works.""" - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.ERROR, - code=7, - message="some_error_message", - data=b"some_error_data", - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_performative_string_value() -> None: - """Test the string value of the performatives.""" - assert ( - str(LedgerApiMessage.Performative.GET_BALANCE) == "get_balance" - ), "The str value must be get_balance" - assert ( - str(LedgerApiMessage.Performative.GET_RAW_TRANSACTION) == "get_raw_transaction" - ), "The str value must be get_raw_transaction" - assert ( - str(LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION) - == "send_signed_transaction" - ), "The str value must be send_signed_transaction" - assert ( - str(LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT) - == "get_transaction_receipt" - ), "The str value must be get_transaction_receipt" - assert ( - str(LedgerApiMessage.Performative.BALANCE) == "balance" - ), "The str value must be balance" - assert ( - str(LedgerApiMessage.Performative.RAW_TRANSACTION) == "raw_transaction" - ), "The str value must be raw_transaction" - assert ( - str(LedgerApiMessage.Performative.TRANSACTION_DIGEST) == "transaction_digest" - ), "The str value must be transaction_digest" - assert ( - str(LedgerApiMessage.Performative.TRANSACTION_RECEIPT) == "transaction_receipt" - ), "The str value must be transaction_receipt" - assert ( - str(LedgerApiMessage.Performative.ERROR) == "error" - ), "The str value must be error" - - -def test_encoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, # type: ignore - ledger_id=LEDGER_ID, - address="address", - ) - - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object( - LedgerApiMessage.Performative, "__eq__", return_value=False - ): - LedgerApiMessage.serializer.encode(msg) - - -def test_decoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, # type: ignore - ledger_id=LEDGER_ID, - address="address", - ) - - encoded_msg = LedgerApiMessage.serializer.encode(msg) - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object( - LedgerApiMessage.Performative, "__eq__", return_value=False - ): - LedgerApiMessage.serializer.decode(encoded_msg) - - -@mock.patch.object( - message, - "enforce", - side_effect=AEAEnforceError("some error"), -) -def test_incorrect_message( - mocked_enforce: Callable, # pylint: disable=unused-argument -) -> None: - """Test that we raise an exception when the message is incorrect.""" - with mock.patch.object(ledger_api_message_logger, "error") as mock_logger: - LedgerApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=LedgerApiMessage.Performative.STATE, # type: ignore - ledger_id=LEDGER_ID, - state=LedgerApiMessage.State("some_ledger_id", {}), - ) - - mock_logger.assert_any_call("some error") - - -def test_send_signed_transactions_serialization() -> None: - """Test that the serialization for 'send_signed_transactions' works.""" - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS, - signed_transactions=SignedTransactions( - ledger_id=LEDGER_ID, signed_transactions=[dict(), dict(), dict(), dict()] - ), - kwargs=Kwargs(body={}), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_transaction_digests_serialization() -> None: - """Test that the serialization for 'transaction_digests' works.""" - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGESTS, - transaction_digests=TransactionDigests( - ledger_id=LEDGER_ID, transaction_digests=["", "", "", ""] - ), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -class BaseTestMessageConstruction: - """Base class to test message construction for the ABCI protocol.""" - - ledger_id = LEDGER_ID - address = "address_stub" - contract_id = CONTRACT_ID - callable_ = CALLABLE - msg_class = LedgerApiMessage - contract_address = CONTRACT_ADDRESS - - @abstractmethod - def build_message(self) -> LedgerApiMessage: - """Build the message to be used for testing.""" - - def test_run(self) -> None: - """Run the test.""" - msg = self.build_message() - msg.to = "receiver" - envelope = Envelope(to=msg.to, sender="sender", message=msg) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = self.msg_class.serializer.decode(actual_envelope.message_bytes) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - @classmethod - def _make_terms(cls) -> Terms: - """Build a Terms object.""" - return LedgerApiMessage.Terms( - ledger_id=cls.ledger_id, - sender_address="sender_address", - counterparty_address="counterparty_address", - amount_by_currency_id={}, - quantities_by_good_id={}, - nonce="nonce_stub", - ) - - -class TestGetBalance(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, # type: ignore - ledger_id=self.ledger_id, - address=self.address, - ) - - -class TestBalance(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - assert str(LedgerApiMessage.Kwargs({})) == "Kwargs: body={}" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.BALANCE, # type: ignore - ledger_id=self.ledger_id, - balance=0, - ) - - -class TestGetRawTransaction(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - terms=self._make_terms(), - ) - - -class TestRawTransaction(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.RAW_TRANSACTION, # type: ignore - raw_transaction=LedgerApiMessage.RawTransaction( - ledger_id=LEDGER_ID, body={} - ), - ) - - -class TestSendSignedTransaction(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, # type: ignore - signed_transaction=LedgerApiMessage.SignedTransaction( - ledger_id=self.ledger_id, body={} - ), - kwargs=Kwargs({}), - ) - - -class TestTransactionDigest(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, # type: ignore - transaction_digest=LedgerApiMessage.TransactionDigest( - ledger_id=LEDGER_ID, body="" - ), - ) - - -class TestGetTransactionReceipt(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, # type: ignore - transaction_digest=LedgerApiMessage.TransactionDigest( - ledger_id=LEDGER_ID, body="" - ), - ) - - -class TestGetTransactionReceiptWithParams(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, # type: ignore - transaction_digest=LedgerApiMessage.TransactionDigest( - ledger_id=LEDGER_ID, body="" - ), - retry_timeout=3, - retry_attempts=1, - ) - - -class TestTransactionReceipt(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT, # type: ignore - transaction_receipt=LedgerApiMessage.TransactionReceipt( - ledger_id=LEDGER_ID, receipt={}, transaction={} - ), - ) - - -class TestGetState(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_STATE, # type: ignore - ledger_id=self.ledger_id, - callable="cabllable", - args=("",), - kwargs=LedgerApiMessage.Kwargs({}), - ) - - -class TestState(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.STATE, # type: ignore - ledger_id=self.ledger_id, - state=LedgerApiMessage.State(ledger_id=LEDGER_ID, body={}), - ) - - -class TestError(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.ERROR, # type: ignore - code=1, - message="", - data=b"", - ) - - -class AgentDialogue(LedgerApiDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[LedgerApiMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - LedgerApiDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class AgentDialogues(LedgerApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return LedgerApiDialogue.Role.AGENT - - LedgerApiDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=AgentDialogue, - ) - - -class LedgerDialogue(LedgerApiDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[LedgerApiMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - LedgerApiDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class LedgerDialogues(LedgerApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return LedgerApiDialogue.Role.LEDGER - - LedgerApiDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=LedgerDialogue, - ) - - -class TestDialogues: - """Tests abci dialogues.""" - - agent_addr: str - ledger_addr: str - agent_dialogues: AgentDialogues - ledger_dialogues: LedgerDialogues - - @classmethod - def setup_class(cls) -> None: - """Set up the test.""" - cls.agent_addr = "agent address" - cls.ledger_addr = "ledger address" - cls.agent_dialogues = AgentDialogues(cls.agent_addr) - cls.ledger_dialogues = LedgerDialogues(cls.ledger_addr) - - def test_create_self_initiated(self) -> None: - """Test the self initialisation of a dialogue.""" - result = self.agent_dialogues._create_self_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.ledger_addr, - dialogue_reference=(str(0), ""), - role=LedgerApiDialogue.Role.AGENT, - ) - assert isinstance(result, LedgerApiDialogue) - assert result.role == LedgerApiDialogue.Role.AGENT, "The role must be agent." - - def test_create_opponent_initiated(self) -> None: - """Test the opponent initialisation of a dialogue.""" - result = self.agent_dialogues._create_opponent_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.ledger_addr, - dialogue_reference=(str(0), ""), - role=LedgerApiDialogue.Role.AGENT, - ) - assert isinstance(result, LedgerApiDialogue) - assert result.role == LedgerApiDialogue.Role.AGENT, "The role must be agent." diff --git a/trader_backup/vendor/valory/protocols/ledger_api/tests/test_ledger_api_dialogues.py b/trader_backup/vendor/valory/protocols/ledger_api/tests/test_ledger_api_dialogues.py deleted file mode 100644 index 55cdea143..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/tests/test_ledger_api_dialogues.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for ledger_api protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.ledger_api.dialogues import ( - LedgerApiDialogue, - LedgerApiDialogues, -) -from packages.valory.protocols.ledger_api.message import LedgerApiMessage - - -class TestDialoguesLedgerApi(BaseProtocolDialoguesTestCase): - """Test for the 'ledger_api' protocol dialogues.""" - - MESSAGE_CLASS = LedgerApiMessage - - DIALOGUE_CLASS = LedgerApiDialogue - - DIALOGUES_CLASS = LedgerApiDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = LedgerApiDialogue.Role.AGENT # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=LedgerApiMessage.Performative.GET_BALANCE, - ledger_id="some str", - address="some str", - ) diff --git a/trader_backup/vendor/valory/protocols/ledger_api/tests/test_ledger_api_messages.py b/trader_backup/vendor/valory/protocols/ledger_api/tests/test_ledger_api_messages.py deleted file mode 100644 index 3bdbf1c4a..000000000 --- a/trader_backup/vendor/valory/protocols/ledger_api/tests/test_ledger_api_messages.py +++ /dev/null @@ -1,180 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for ledger_api protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.ledger_api.custom_types import ( - Kwargs, - RawTransaction, - SignedTransaction, - State, - Terms, - TransactionDigest, - TransactionReceipt, -) -from packages.valory.protocols.ledger_api.message import LedgerApiMessage - - -LEDGER_ID = "ethereum" - - -class TestMessageLedgerApi(BaseProtocolMessagesTestCase): - """Test for the 'ledger_api' protocol message.""" - - MESSAGE_CLASS = LedgerApiMessage - - ledger_id = LEDGER_ID - terms = Terms( - ledger_id=ledger_id, - sender_address="sender_address", - counterparty_address="counterparty_address", - amount_by_currency_id={}, - quantities_by_good_id={}, - nonce="nonce_stub", - ) - - def build_messages(self) -> List[LedgerApiMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, - ledger_id="some str", - address="some str", - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, - terms=self.terms, - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, - signed_transaction=SignedTransaction( - "some_ledger_id", {"body": "some_body"} - ), - kwargs=Kwargs({}), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, - transaction_digest=TransactionDigest("some_ledger_id", "some_body"), - retry_timeout=12, - retry_attempts=12, - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.BALANCE, - ledger_id="some str", - balance=12, - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=RawTransaction("some_ledger_id", {"body": "some_body"}), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, - transaction_digest=TransactionDigest("some_ledger_id", "some_body"), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - transaction_receipt=TransactionReceipt( - "some_ledger_id", - {"key": "some_receipt"}, - {"key": "some_transaction"}, - ), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_STATE, - ledger_id="some str", - callable="some str", - args=("some str",), - kwargs=Kwargs({}), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.STATE, - ledger_id="some str", - state=State(ledger_id=LEDGER_ID, body={}), # check it please! - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.ERROR, - code=12, - message="some str", - data=b"some_bytes", - ), - ] - - def build_inconsistent(self) -> List[LedgerApiMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, - # skip content: ledger_id - address="some str", - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, - # skip content: terms - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, - # skip content: signed_transaction - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, - # skip content: transaction_digest - retry_timeout=12, - retry_attempts=12, - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.BALANCE, - # skip content: ledger_id - balance=12, - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.RAW_TRANSACTION, - # skip content: raw_transaction - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, - # skip content: transaction_digest - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - # skip content: transaction_receipt - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_STATE, - # skip content: ledger_id - callable="some str", - args=("some str",), - kwargs=Kwargs({}), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.STATE, - # skip content: ledger_id - state=State(ledger_id=LEDGER_ID, body={}), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.ERROR, - # skip content: code - message="some str", - data=b"some_bytes", - ), - ] diff --git a/trader_backup/vendor/valory/protocols/tendermint/README.md b/trader_backup/vendor/valory/protocols/tendermint/README.md deleted file mode 100644 index c10d0ad13..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Tendermint Protocol - -## Description - -This is a protocol for communication between AEAs for sharing their tendermint configuration details. - -## Specification - -```yaml ---- -name: tendermint -author: valory -version: 0.1.0 -protocol_specification_id: valory/tendermint:0.1.0 -description: A protocol for communication between two AEAs to share tendermint configuration details. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -speech_acts: - get_genesis_info: - query: pt:optional[pt:str] - get_recovery_params: - query: pt:optional[pt:str] - genesis_info: - info: pt:str - recovery_params: - params: pt:str - error: - error_code: ct:ErrorCode - error_msg: pt:str - error_data: pt:dict[pt:str, pt:str] -... ---- -ct:ErrorCode: | - enum ErrorCodeEnum { - INVALID_REQUEST = 0; - } - ErrorCodeEnum error_code = 1; -... ---- -initiation: [get_genesis_info, get_recovery_params] -reply: - get_genesis_info: [genesis_info, error] - get_recovery_params: [recovery_params, error] - genesis_info: [] - recovery_params: [] - error: [] -roles: {agent} -termination: [genesis_info, recovery_params, error] -end_states: [communicated, not_communicated] -keep_terminal_state_dialogues: true -... -``` - -## Links - diff --git a/trader_backup/vendor/valory/protocols/tendermint/__init__.py b/trader_backup/vendor/valory/protocols/tendermint/__init__.py deleted file mode 100644 index 90ee9b950..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the tendermint protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.tendermint.message import TendermintMessage -from packages.valory.protocols.tendermint.serialization import TendermintSerializer - - -TendermintMessage.serializer = TendermintSerializer diff --git a/trader_backup/vendor/valory/protocols/tendermint/custom_types.py b/trader_backup/vendor/valory/protocols/tendermint/custom_types.py deleted file mode 100644 index e3dc43c8b..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/custom_types.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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 class representations corresponding to every custom type in the protocol specification.""" - -from enum import Enum -from typing import Any - - -class ErrorCode(Enum): - """This class represents an instance of ErrorCode.""" - - INVALID_REQUEST = 0 - - @staticmethod - def encode(error_code_protobuf_object: Any, error_code_object: "ErrorCode") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the error_code_protobuf_object argument is matched with the instance of this class in the 'error_code_object' argument. - - :param error_code_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param error_code_object: an instance of this class to be encoded in the protocol buffer object. - """ - error_code_protobuf_object.error_code = error_code_object.value - - @classmethod - def decode(cls, error_code_protobuf_object: Any) -> "ErrorCode": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'error_code_protobuf_object' argument. - - :param error_code_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'error_code_protobuf_object' argument. - """ - enum_value_from_pb2 = error_code_protobuf_object.error_code - return ErrorCode(enum_value_from_pb2) diff --git a/trader_backup/vendor/valory/protocols/tendermint/dialogues.py b/trader_backup/vendor/valory/protocols/tendermint/dialogues.py deleted file mode 100644 index c2bcb42a8..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/dialogues.py +++ /dev/null @@ -1,138 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for tendermint dialogue management. - -- TendermintDialogue: The dialogue class maintains state of a dialogue and manages it. -- TendermintDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.tendermint.message import TendermintMessage - - -class TendermintDialogue(Dialogue): - """The tendermint dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - TendermintMessage.Performative.GET_GENESIS_INFO, - TendermintMessage.Performative.GET_RECOVERY_PARAMS, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - TendermintMessage.Performative.GENESIS_INFO, - TendermintMessage.Performative.RECOVERY_PARAMS, - TendermintMessage.Performative.ERROR, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - TendermintMessage.Performative.ERROR: frozenset(), - TendermintMessage.Performative.GENESIS_INFO: frozenset(), - TendermintMessage.Performative.GET_GENESIS_INFO: frozenset( - { - TendermintMessage.Performative.GENESIS_INFO, - TendermintMessage.Performative.ERROR, - } - ), - TendermintMessage.Performative.GET_RECOVERY_PARAMS: frozenset( - { - TendermintMessage.Performative.RECOVERY_PARAMS, - TendermintMessage.Performative.ERROR, - } - ), - TendermintMessage.Performative.RECOVERY_PARAMS: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a tendermint dialogue.""" - - AGENT = "agent" - - class EndState(Dialogue.EndState): - """This class defines the end states of a tendermint dialogue.""" - - COMMUNICATED = 0 - NOT_COMMUNICATED = 1 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[TendermintMessage] = TendermintMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class TendermintDialogues(Dialogues, ABC): - """This class keeps track of all tendermint dialogues.""" - - END_STATES = frozenset( - { - TendermintDialogue.EndState.COMMUNICATED, - TendermintDialogue.EndState.NOT_COMMUNICATED, - } - ) - - _keep_terminal_state_dialogues = True - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[TendermintDialogue] = TendermintDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=TendermintMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_backup/vendor/valory/protocols/tendermint/message.py b/trader_backup/vendor/valory/protocols/tendermint/message.py deleted file mode 100644 index a6e633d98..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/message.py +++ /dev/null @@ -1,313 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 tendermint's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Dict, Optional, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - -from packages.valory.protocols.tendermint.custom_types import ( - ErrorCode as CustomErrorCode, -) - - -_default_logger = logging.getLogger("aea.packages.valory.protocols.tendermint.message") - -DEFAULT_BODY_SIZE = 4 - - -class TendermintMessage(Message): - """A protocol for communication between two AEAs to share tendermint configuration details.""" - - protocol_id = PublicId.from_str("valory/tendermint:0.1.0") - protocol_specification_id = PublicId.from_str("valory/tendermint:0.1.0") - - ErrorCode = CustomErrorCode - - class Performative(Message.Performative): - """Performatives for the tendermint protocol.""" - - ERROR = "error" - GENESIS_INFO = "genesis_info" - GET_GENESIS_INFO = "get_genesis_info" - GET_RECOVERY_PARAMS = "get_recovery_params" - RECOVERY_PARAMS = "recovery_params" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = { - "error", - "genesis_info", - "get_genesis_info", - "get_recovery_params", - "recovery_params", - } - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "dialogue_reference", - "error_code", - "error_data", - "error_msg", - "info", - "message_id", - "params", - "performative", - "query", - "target", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of TendermintMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=TendermintMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(TendermintMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def error_code(self) -> CustomErrorCode: - """Get the 'error_code' content from the message.""" - enforce(self.is_set("error_code"), "'error_code' content is not set.") - return cast(CustomErrorCode, self.get("error_code")) - - @property - def error_data(self) -> Dict[str, str]: - """Get the 'error_data' content from the message.""" - enforce(self.is_set("error_data"), "'error_data' content is not set.") - return cast(Dict[str, str], self.get("error_data")) - - @property - def error_msg(self) -> str: - """Get the 'error_msg' content from the message.""" - enforce(self.is_set("error_msg"), "'error_msg' content is not set.") - return cast(str, self.get("error_msg")) - - @property - def info(self) -> str: - """Get the 'info' content from the message.""" - enforce(self.is_set("info"), "'info' content is not set.") - return cast(str, self.get("info")) - - @property - def params(self) -> str: - """Get the 'params' content from the message.""" - enforce(self.is_set("params"), "'params' content is not set.") - return cast(str, self.get("params")) - - @property - def query(self) -> Optional[str]: - """Get the 'query' content from the message.""" - return cast(Optional[str], self.get("query")) - - def _is_consistent(self) -> bool: - """Check that the message follows the tendermint protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, TendermintMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == TendermintMessage.Performative.GET_GENESIS_INFO: - expected_nb_of_contents = 0 - if self.is_set("query"): - expected_nb_of_contents += 1 - query = cast(str, self.query) - enforce( - isinstance(query, str), - "Invalid type for content 'query'. Expected 'str'. Found '{}'.".format( - type(query) - ), - ) - elif ( - self.performative == TendermintMessage.Performative.GET_RECOVERY_PARAMS - ): - expected_nb_of_contents = 0 - if self.is_set("query"): - expected_nb_of_contents += 1 - query = cast(str, self.query) - enforce( - isinstance(query, str), - "Invalid type for content 'query'. Expected 'str'. Found '{}'.".format( - type(query) - ), - ) - elif self.performative == TendermintMessage.Performative.GENESIS_INFO: - expected_nb_of_contents = 1 - enforce( - isinstance(self.info, str), - "Invalid type for content 'info'. Expected 'str'. Found '{}'.".format( - type(self.info) - ), - ) - elif self.performative == TendermintMessage.Performative.RECOVERY_PARAMS: - expected_nb_of_contents = 1 - enforce( - isinstance(self.params, str), - "Invalid type for content 'params'. Expected 'str'. Found '{}'.".format( - type(self.params) - ), - ) - elif self.performative == TendermintMessage.Performative.ERROR: - expected_nb_of_contents = 3 - enforce( - isinstance(self.error_code, CustomErrorCode), - "Invalid type for content 'error_code'. Expected 'ErrorCode'. Found '{}'.".format( - type(self.error_code) - ), - ) - enforce( - isinstance(self.error_msg, str), - "Invalid type for content 'error_msg'. Expected 'str'. Found '{}'.".format( - type(self.error_msg) - ), - ) - enforce( - isinstance(self.error_data, dict), - "Invalid type for content 'error_data'. Expected 'dict'. Found '{}'.".format( - type(self.error_data) - ), - ) - for key_of_error_data, value_of_error_data in self.error_data.items(): - enforce( - isinstance(key_of_error_data, str), - "Invalid type for dictionary keys in content 'error_data'. Expected 'str'. Found '{}'.".format( - type(key_of_error_data) - ), - ) - enforce( - isinstance(value_of_error_data, str), - "Invalid type for dictionary values in content 'error_data'. Expected 'str'. Found '{}'.".format( - type(value_of_error_data) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_backup/vendor/valory/protocols/tendermint/protocol.yaml b/trader_backup/vendor/valory/protocols/tendermint/protocol.yaml deleted file mode 100644 index c9adaab40..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/protocol.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: tendermint -author: valory -version: 0.1.0 -protocol_specification_id: valory/tendermint:0.1.0 -type: protocol -description: A protocol for communication between two AEAs to share tendermint configuration - details. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeib23wtp5el2lu4vpq3uap7jiyhm5fmoofvv4sz54cvvqq6vsksra4 - __init__.py: bafybeibaei6te5zbqkbcknl2rjh3nryamz6boe4gvvzbaxwi6ynq5uxqfa - custom_types.py: bafybeidbqm4h4fv24o3w6ueu4o3lyn5yaleyukahq7suvk6m2b6ydw4w3a - dialogues.py: bafybeih3kwv3hqnc7qe7gwvsxj755e3pridoesfashknt3i4z7sra7mm6m - message.py: bafybeiguo2x2vx5m3u6li4dl4fxomdjrtz63qkvpor22e2oq4hcj7r5pve - serialization.py: bafybeigs3sxcgyv5qrvltwzjvqq3suxcj2dmvrptvvnfopfpcar3v3evj4 - tendermint.proto: bafybeiaqoltnijwje7iog7s3r4nbtly6rbfp6zwb2btnrw7xuenoxtobui - tendermint_pb2.py: bafybeiay3q3pcvlitnhifh63vqkzvdyu4ywbbwj6vnoe5omqxmxg6gu25a - tests/__init__.py: bafybeiguds53xs5tmygjd26a7xxilzdrgi2x262relfagdlvdzymacumie - tests/test_tendermint.py: bafybeihnjxpkvgsclevn4bwi4qepw56vz554wox7gmhnjwobelbee7xpce - tests/test_tendermint_dialogues.py: bafybeieoviq62cv62h4nglyr7qflzb32bjcvjbepmytgfpycuypnz3mriy - tests/test_tendermint_messages.py: bafybeifqebxh5x5i5luiiypi6mqtcroejmb7ov6foj37ipfgqm7h5f5yve -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_backup/vendor/valory/protocols/tendermint/serialization.py b/trader_backup/vendor/valory/protocols/tendermint/serialization.py deleted file mode 100644 index 86d1f1218..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/serialization.py +++ /dev/null @@ -1,156 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for tendermint protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.tendermint import tendermint_pb2 # type: ignore -from packages.valory.protocols.tendermint.custom_types import ErrorCode # type: ignore -from packages.valory.protocols.tendermint.message import ( # type: ignore - TendermintMessage, -) - - -class TendermintSerializer(Serializer): - """Serialization for the 'tendermint' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'Tendermint' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(TendermintMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - tendermint_msg = tendermint_pb2.TendermintMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == TendermintMessage.Performative.GET_GENESIS_INFO: - performative = tendermint_pb2.TendermintMessage.Get_Genesis_Info_Performative() # type: ignore - if msg.is_set("query"): - performative.query_is_set = True - query = msg.query - performative.query = query - tendermint_msg.get_genesis_info.CopyFrom(performative) - elif performative_id == TendermintMessage.Performative.GET_RECOVERY_PARAMS: - performative = tendermint_pb2.TendermintMessage.Get_Recovery_Params_Performative() # type: ignore - if msg.is_set("query"): - performative.query_is_set = True - query = msg.query - performative.query = query - tendermint_msg.get_recovery_params.CopyFrom(performative) - elif performative_id == TendermintMessage.Performative.GENESIS_INFO: - performative = tendermint_pb2.TendermintMessage.Genesis_Info_Performative() # type: ignore - info = msg.info - performative.info = info - tendermint_msg.genesis_info.CopyFrom(performative) - elif performative_id == TendermintMessage.Performative.RECOVERY_PARAMS: - performative = tendermint_pb2.TendermintMessage.Recovery_Params_Performative() # type: ignore - params = msg.params - performative.params = params - tendermint_msg.recovery_params.CopyFrom(performative) - elif performative_id == TendermintMessage.Performative.ERROR: - performative = tendermint_pb2.TendermintMessage.Error_Performative() # type: ignore - error_code = msg.error_code - ErrorCode.encode(performative.error_code, error_code) - error_msg = msg.error_msg - performative.error_msg = error_msg - error_data = msg.error_data - performative.error_data.update(error_data) - tendermint_msg.error.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = tendermint_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'Tendermint' message. - - :param obj: the bytes object. - :return: the 'Tendermint' message. - """ - message_pb = ProtobufMessage() - tendermint_pb = tendermint_pb2.TendermintMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - tendermint_pb.ParseFromString(message_pb.dialogue_message.content) - performative = tendermint_pb.WhichOneof("performative") - performative_id = TendermintMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == TendermintMessage.Performative.GET_GENESIS_INFO: - if tendermint_pb.get_genesis_info.query_is_set: - query = tendermint_pb.get_genesis_info.query - performative_content["query"] = query - elif performative_id == TendermintMessage.Performative.GET_RECOVERY_PARAMS: - if tendermint_pb.get_recovery_params.query_is_set: - query = tendermint_pb.get_recovery_params.query - performative_content["query"] = query - elif performative_id == TendermintMessage.Performative.GENESIS_INFO: - info = tendermint_pb.genesis_info.info - performative_content["info"] = info - elif performative_id == TendermintMessage.Performative.RECOVERY_PARAMS: - params = tendermint_pb.recovery_params.params - performative_content["params"] = params - elif performative_id == TendermintMessage.Performative.ERROR: - pb2_error_code = tendermint_pb.error.error_code - error_code = ErrorCode.decode(pb2_error_code) - performative_content["error_code"] = error_code - error_msg = tendermint_pb.error.error_msg - performative_content["error_msg"] = error_msg - error_data = tendermint_pb.error.error_data - error_data_dict = dict(error_data) - performative_content["error_data"] = error_data_dict - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return TendermintMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_backup/vendor/valory/protocols/tendermint/tendermint.proto b/trader_backup/vendor/valory/protocols/tendermint/tendermint.proto deleted file mode 100644 index bfd922020..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/tendermint.proto +++ /dev/null @@ -1,49 +0,0 @@ -syntax = "proto3"; - -package aea.valory.tendermint.v0_1_0; - -message TendermintMessage{ - - // Custom Types - message ErrorCode{ - enum ErrorCodeEnum { - INVALID_REQUEST = 0; - } - ErrorCodeEnum error_code = 1; - } - - - // Performatives and contents - message Get_Genesis_Info_Performative{ - string query = 1; - bool query_is_set = 2; - } - - message Get_Recovery_Params_Performative{ - string query = 1; - bool query_is_set = 2; - } - - message Genesis_Info_Performative{ - string info = 1; - } - - message Recovery_Params_Performative{ - string params = 1; - } - - message Error_Performative{ - ErrorCode error_code = 1; - string error_msg = 2; - map error_data = 3; - } - - - oneof performative{ - Error_Performative error = 5; - Genesis_Info_Performative genesis_info = 6; - Get_Genesis_Info_Performative get_genesis_info = 7; - Get_Recovery_Params_Performative get_recovery_params = 8; - Recovery_Params_Performative recovery_params = 9; - } -} diff --git a/trader_backup/vendor/valory/protocols/tendermint/tendermint_pb2.py b/trader_backup/vendor/valory/protocols/tendermint/tendermint_pb2.py deleted file mode 100644 index aa4355b03..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/tendermint_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x10tendermint.proto\x12\x1c\x61\x65\x61.valory.tendermint.v0_1_0"\xad\t\n\x11TendermintMessage\x12S\n\x05\x65rror\x18\x05 \x01(\x0b\x32\x42.aea.valory.tendermint.v0_1_0.TendermintMessage.Error_PerformativeH\x00\x12\x61\n\x0cgenesis_info\x18\x06 \x01(\x0b\x32I.aea.valory.tendermint.v0_1_0.TendermintMessage.Genesis_Info_PerformativeH\x00\x12i\n\x10get_genesis_info\x18\x07 \x01(\x0b\x32M.aea.valory.tendermint.v0_1_0.TendermintMessage.Get_Genesis_Info_PerformativeH\x00\x12o\n\x13get_recovery_params\x18\x08 \x01(\x0b\x32P.aea.valory.tendermint.v0_1_0.TendermintMessage.Get_Recovery_Params_PerformativeH\x00\x12g\n\x0frecovery_params\x18\t \x01(\x0b\x32L.aea.valory.tendermint.v0_1_0.TendermintMessage.Recovery_Params_PerformativeH\x00\x1a\x8e\x01\n\tErrorCode\x12[\n\nerror_code\x18\x01 \x01(\x0e\x32G.aea.valory.tendermint.v0_1_0.TendermintMessage.ErrorCode.ErrorCodeEnum"$\n\rErrorCodeEnum\x12\x13\n\x0fINVALID_REQUEST\x10\x00\x1a\x44\n\x1dGet_Genesis_Info_Performative\x12\r\n\x05query\x18\x01 \x01(\t\x12\x14\n\x0cquery_is_set\x18\x02 \x01(\x08\x1aG\n Get_Recovery_Params_Performative\x12\r\n\x05query\x18\x01 \x01(\t\x12\x14\n\x0cquery_is_set\x18\x02 \x01(\x08\x1a)\n\x19Genesis_Info_Performative\x12\x0c\n\x04info\x18\x01 \x01(\t\x1a.\n\x1cRecovery_Params_Performative\x12\x0e\n\x06params\x18\x01 \x01(\t\x1a\x8f\x02\n\x12\x45rror_Performative\x12M\n\nerror_code\x18\x01 \x01(\x0b\x32\x39.aea.valory.tendermint.v0_1_0.TendermintMessage.ErrorCode\x12\x11\n\terror_msg\x18\x02 \x01(\t\x12\x65\n\nerror_data\x18\x03 \x03(\x0b\x32Q.aea.valory.tendermint.v0_1_0.TendermintMessage.Error_Performative.ErrorDataEntry\x1a\x30\n\x0e\x45rrorDataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "tendermint_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _TENDERMINTMESSAGE_ERROR_PERFORMATIVE_ERRORDATAENTRY._options = None - _TENDERMINTMESSAGE_ERROR_PERFORMATIVE_ERRORDATAENTRY._serialized_options = b"8\001" - _globals["_TENDERMINTMESSAGE"]._serialized_start = 51 - _globals["_TENDERMINTMESSAGE"]._serialized_end = 1248 - _globals["_TENDERMINTMESSAGE_ERRORCODE"]._serialized_start = 582 - _globals["_TENDERMINTMESSAGE_ERRORCODE"]._serialized_end = 724 - _globals["_TENDERMINTMESSAGE_ERRORCODE_ERRORCODEENUM"]._serialized_start = 688 - _globals["_TENDERMINTMESSAGE_ERRORCODE_ERRORCODEENUM"]._serialized_end = 724 - _globals["_TENDERMINTMESSAGE_GET_GENESIS_INFO_PERFORMATIVE"]._serialized_start = 726 - _globals["_TENDERMINTMESSAGE_GET_GENESIS_INFO_PERFORMATIVE"]._serialized_end = 794 - _globals[ - "_TENDERMINTMESSAGE_GET_RECOVERY_PARAMS_PERFORMATIVE" - ]._serialized_start = 796 - _globals[ - "_TENDERMINTMESSAGE_GET_RECOVERY_PARAMS_PERFORMATIVE" - ]._serialized_end = 867 - _globals["_TENDERMINTMESSAGE_GENESIS_INFO_PERFORMATIVE"]._serialized_start = 869 - _globals["_TENDERMINTMESSAGE_GENESIS_INFO_PERFORMATIVE"]._serialized_end = 910 - _globals["_TENDERMINTMESSAGE_RECOVERY_PARAMS_PERFORMATIVE"]._serialized_start = 912 - _globals["_TENDERMINTMESSAGE_RECOVERY_PARAMS_PERFORMATIVE"]._serialized_end = 958 - _globals["_TENDERMINTMESSAGE_ERROR_PERFORMATIVE"]._serialized_start = 961 - _globals["_TENDERMINTMESSAGE_ERROR_PERFORMATIVE"]._serialized_end = 1232 - _globals[ - "_TENDERMINTMESSAGE_ERROR_PERFORMATIVE_ERRORDATAENTRY" - ]._serialized_start = 1184 - _globals[ - "_TENDERMINTMESSAGE_ERROR_PERFORMATIVE_ERRORDATAENTRY" - ]._serialized_end = 1232 -# @@protoc_insertion_point(module_scope) diff --git a/trader_backup/vendor/valory/protocols/tendermint/tests/__init__.py b/trader_backup/vendor/valory/protocols/tendermint/tests/__init__.py deleted file mode 100644 index 283e0f64c..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for tendermint protocol.""" diff --git a/trader_backup/vendor/valory/protocols/tendermint/tests/test_tendermint.py b/trader_backup/vendor/valory/protocols/tendermint/tests/test_tendermint.py deleted file mode 100644 index c133f7019..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/tests/test_tendermint.py +++ /dev/null @@ -1,217 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for the 'valory/tendermint' protocol.""" -import logging -from typing import Type -from unittest import mock - -import pytest -from _pytest.logging import LogCaptureFixture # type: ignore -from aea.common import Address -from aea.mail.base import Envelope -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.tendermint.custom_types import ErrorCode -from packages.valory.protocols.tendermint.dialogues import ( - TendermintDialogue, - TendermintDialogues, -) -from packages.valory.protocols.tendermint.message import ( - TendermintMessage, - _default_logger, -) - - -@pytest.mark.parametrize( - "msg", - [ - TendermintMessage( - performative=TendermintMessage.Performative.GET_GENESIS_INFO, # type: ignore - query="", - ), - TendermintMessage( - performative=TendermintMessage.Performative.GET_RECOVERY_PARAMS, # type: ignore - query="", - ), - TendermintMessage( - performative=TendermintMessage.Performative.GENESIS_INFO, # type: ignore - info="", - ), - TendermintMessage( - performative=TendermintMessage.Performative.RECOVERY_PARAMS, # type: ignore - params="", - ), - TendermintMessage( - performative=TendermintMessage.Performative.ERROR, # type: ignore - error_code=ErrorCode.INVALID_REQUEST, - error_msg="", - error_data=dict(message="dummy"), - ), - ], -) -def test_serialization(msg: TendermintMessage) -> None: - """Test the serialization of Tendermint speech-act messages.""" - - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = TendermintMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_incorrect_error_data_logged(caplog: LogCaptureFixture) -> None: - """Test incorrect error_data is logged""" - - expected = "Invalid type for dictionary values in content 'error_data'. Expected 'str'. Found ''." - with caplog.at_level(logging.ERROR, logger=_default_logger.name): - TendermintMessage( - performative=TendermintMessage.Performative.ERROR, # type: ignore - error_code=ErrorCode.INVALID_REQUEST, - error_msg="", - error_data=dict(message=1), # incorrect type - ) - assert expected in caplog.text - - -def test_serialization_performative_not_valid() -> None: - """Test serialization performative not valid""" - - msg = TendermintMessage( - performative=TendermintMessage.Performative.GET_GENESIS_INFO, # type: ignore - query="", - ) - encoded_msg = msg.encode() - - with mock.patch.object(TendermintMessage, "Performative"): - with pytest.raises(ValueError, match="Performative not valid: "): - msg.encode() - with pytest.raises(ValueError, match="Performative not valid: "): - msg.decode(encoded_msg) - - -class AgentDialogue(TendermintDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[TendermintMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - TendermintDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class AgentDialogues(TendermintDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return TendermintDialogue.Role.AGENT - - TendermintDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=AgentDialogue, - ) - - -class TestDialogues: - """Tests abci dialogues.""" - - agent_dialogues: AgentDialogues - - @classmethod - def setup_class(cls) -> None: - """Setup test class""" - - cls.agent_dialogues = AgentDialogues("agent_address") - - def test_create_self_initiated(self) -> None: - """Test the self initialisation of a dialogue.""" - - result = self.agent_dialogues._create_self_initiated( # pylint: disable=protected-access - dialogue_opponent_addr="dummy_address", - dialogue_reference=(str(0), ""), - role=TendermintDialogue.Role.AGENT, - ) - assert isinstance(result, TendermintDialogue) - assert result.role == TendermintDialogue.Role.AGENT, "The role must be agent." - - def test_create_opponent_initiated(self) -> None: - """Test the opponent initialisation of a dialogue.""" - - result = self.agent_dialogues._create_opponent_initiated( # pylint: disable=protected-access - dialogue_opponent_addr="dummy_address", - dialogue_reference=(str(0), ""), - role=TendermintDialogue.Role.AGENT, - ) - assert isinstance(result, TendermintDialogue) - assert result.role == TendermintDialogue.Role.AGENT, "The role must be agent." diff --git a/trader_backup/vendor/valory/protocols/tendermint/tests/test_tendermint_dialogues.py b/trader_backup/vendor/valory/protocols/tendermint/tests/test_tendermint_dialogues.py deleted file mode 100644 index 4a55efd92..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/tests/test_tendermint_dialogues.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for tendermint protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.tendermint.dialogues import ( - TendermintDialogue, - TendermintDialogues, -) -from packages.valory.protocols.tendermint.message import TendermintMessage - - -class TestDialoguesTendermint(BaseProtocolDialoguesTestCase): - """Test for the 'tendermint' protocol dialogues.""" - - MESSAGE_CLASS = TendermintMessage - - DIALOGUE_CLASS = TendermintDialogue - - DIALOGUES_CLASS = TendermintDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = TendermintDialogue.Role.AGENT # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=TendermintMessage.Performative.GET_GENESIS_INFO, - query="some str", - ) diff --git a/trader_backup/vendor/valory/protocols/tendermint/tests/test_tendermint_messages.py b/trader_backup/vendor/valory/protocols/tendermint/tests/test_tendermint_messages.py deleted file mode 100644 index a279cef0c..000000000 --- a/trader_backup/vendor/valory/protocols/tendermint/tests/test_tendermint_messages.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for tendermint protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.tendermint.custom_types import ErrorCode -from packages.valory.protocols.tendermint.message import TendermintMessage - - -class TestMessageTendermint(BaseProtocolMessagesTestCase): - """Test for the 'tendermint' protocol message.""" - - MESSAGE_CLASS = TendermintMessage - - def build_messages(self) -> List[TendermintMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - TendermintMessage( - performative=TendermintMessage.Performative.GET_GENESIS_INFO, - query="some str", - ), - TendermintMessage( - performative=TendermintMessage.Performative.GET_RECOVERY_PARAMS, - query="some str", - ), - TendermintMessage( - performative=TendermintMessage.Performative.GENESIS_INFO, - info="some str", - ), - TendermintMessage( - performative=TendermintMessage.Performative.RECOVERY_PARAMS, - params="some str", - ), - TendermintMessage( - performative=TendermintMessage.Performative.ERROR, - error_code=ErrorCode.INVALID_REQUEST, - error_msg="some str", - error_data={"some str": "some str"}, - ), - ] - - def build_inconsistent(self) -> List[TendermintMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - TendermintMessage( - performative=TendermintMessage.Performative.GENESIS_INFO, - # skip content: info - ), - TendermintMessage( - performative=TendermintMessage.Performative.RECOVERY_PARAMS, - # skip content: params - ), - TendermintMessage( - performative=TendermintMessage.Performative.ERROR, - # skip content: error_code - error_msg="some str", - error_data={"some str": "some str"}, - ), - ] diff --git a/trader_backup/vendor/valory/skills/__init__.py b/trader_backup/vendor/valory/skills/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_backup/vendor/valory/skills/abstract_abci/README.md b/trader_backup/vendor/valory/skills/abstract_abci/README.md deleted file mode 100644 index 4a99a118c..000000000 --- a/trader_backup/vendor/valory/skills/abstract_abci/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Abstract abci - -## Description - -This module contains an abstract ABCI skill template for an AEA. - -## Behaviours - -No behaviours (the skill is purely reactive). - -## Handlers - -* `ABCIHandler` - - This abstract skill provides a template of an ABCI application managed by an - AEA. This abstract Handler replies to ABCI requests with default responses. - In another skill, extend the class and override the request handlers - to implement a custom behaviour. - - diff --git a/trader_backup/vendor/valory/skills/abstract_abci/__init__.py b/trader_backup/vendor/valory/skills/abstract_abci/__init__.py deleted file mode 100644 index 8c9d1355f..000000000 --- a/trader_backup/vendor/valory/skills/abstract_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 an abstract ABCI skill template for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/abstract_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/abstract_abci/dialogues.py b/trader_backup/vendor/valory/skills/abstract_abci/dialogues.py deleted file mode 100644 index e38665b5f..000000000 --- a/trader_backup/vendor/valory/skills/abstract_abci/dialogues.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the classes required for dialogue management.""" - -from typing import Any - -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.skills.base import Model - -from packages.valory.protocols.abci.dialogues import AbciDialogue as BaseAbciDialogue -from packages.valory.protocols.abci.dialogues import AbciDialogues as BaseAbciDialogues - - -AbciDialogue = BaseAbciDialogue - - -class AbciDialogues(Model, BaseAbciDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.CLIENT - - BaseAbciDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - ) diff --git a/trader_backup/vendor/valory/skills/abstract_abci/handlers.py b/trader_backup/vendor/valory/skills/abstract_abci/handlers.py deleted file mode 100644 index 93e95e35d..000000000 --- a/trader_backup/vendor/valory/skills/abstract_abci/handlers.py +++ /dev/null @@ -1,408 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the handler for the 'abci' skill.""" -from typing import List, cast - -from aea.protocols.base import Message -from aea.skills.base import Handler - -from packages.valory.connections.abci.connection import PUBLIC_ID -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import ( - Events, - ProofOps, - Result, - ResultType, - SnapShots, - ValidatorUpdates, -) -from packages.valory.protocols.abci.dialogues import AbciDialogue, AbciDialogues - - -ERROR_CODE = 1 - - -class ABCIHandler(Handler): - """ - Default ABCI handler. - - This abstract skill provides a template of an ABCI application managed by an - AEA. This abstract Handler replies to ABCI requests with default responses. - In another skill, extend the class and override the request handlers - to implement a custom behaviour. - """ - - SUPPORTED_PROTOCOL = AbciMessage.protocol_id - - def setup(self) -> None: - """Set up the handler.""" - self.context.logger.debug( - f"ABCI Handler: setup method called. Using {PUBLIC_ID}." - ) - - def handle(self, message: Message) -> None: - """ - Handle the message. - - :param message: the message. - """ - abci_message = cast(AbciMessage, message) - - # recover dialogue - abci_dialogues = cast(AbciDialogues, self.context.abci_dialogues) - abci_dialogue = cast(AbciDialogue, abci_dialogues.update(message)) - - if abci_dialogue is None: - self.log_exception(abci_message, "Invalid dialogue.") - return - - performative = message.performative.value - - # handle message - request_type = performative.replace("request_", "") - self.context.logger.debug(f"Received ABCI request of type {request_type}") - handler = getattr(self, request_type, None) - if handler is None: # pragma: nocover - self.context.logger.warning( - f"Cannot handle request '{request_type}', ignoring..." - ) - return - - self.context.logger.debug( - "ABCI Handler: message={}, sender={}".format(message, message.sender) - ) - response = handler(message, abci_dialogue) - self.context.outbox.put_message(message=response) - - def teardown(self) -> None: - """Teardown the handler.""" - self.context.logger.debug("ABCI Handler: teardown method called.") - - def log_exception(self, message: AbciMessage, error_message: str) -> None: - """Log a response exception.""" - self.context.logger.error( - f"An exception occurred: {error_message} for message: {message}" - ) - - def echo( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_ECHO performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_ECHO, - target_message=message, - message=message.message, - ) - return cast(AbciMessage, reply) - - def info( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_INFO performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - info_data = "" - version = "" - app_version = 0 - last_block_height = 0 - last_block_app_hash = b"" - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_INFO, - target_message=message, - info_data=info_data, - version=version, - app_version=app_version, - last_block_height=last_block_height, - last_block_app_hash=last_block_app_hash, - ) - return cast(AbciMessage, reply) - - def flush( # pylint: disable=no-self-use - self, - message: AbciMessage, - dialogue: AbciDialogue, - ) -> AbciMessage: - """ - Handle a message of REQUEST_FLUSH performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_FLUSH, - target_message=message, - ) - return cast(AbciMessage, reply) - - def set_option( # pylint: disable=no-self-use - self, - message: AbciMessage, - dialogue: AbciDialogue, - ) -> AbciMessage: - """ - Handle a message of REQUEST_SET_OPTION performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_SET_OPTION, - target_message=message, - code=ERROR_CODE, - log="operation not supported", - info="operation not supported", - ) - return cast(AbciMessage, reply) - - def init_chain( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_INIT_CHAIN performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - validators: List = [] - app_hash = b"" - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_INIT_CHAIN, - target_message=message, - validators=ValidatorUpdates(validators), - app_hash=app_hash, - ) - return cast(AbciMessage, reply) - - def query( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_QUERY performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_QUERY, - target_message=message, - code=ERROR_CODE, - log="operation not supported", - info="operation not supported", - index=0, - key=b"", - value=b"", - proof_ops=ProofOps([]), - height=0, - codespace="", - ) - return cast(AbciMessage, reply) - - def check_tx( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_CHECK_TX performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, - target_message=message, - code=ERROR_CODE, - data=b"", - log="operation not supported", - info="operation not supported", - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, reply) - - def deliver_tx( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_DELIVER_TX performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, - target_message=message, - code=ERROR_CODE, - data=b"", - log="operation not supported", - info="operation not supported", - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, reply) - - def begin_block( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_BEGIN_BLOCK performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, - target_message=message, - events=Events([]), - ) - return cast(AbciMessage, reply) - - def end_block( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_END_BLOCK performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_END_BLOCK, - target_message=message, - validator_updates=ValidatorUpdates([]), - events=Events([]), - ) - return cast(AbciMessage, reply) - - def commit( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_COMMIT performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_COMMIT, - target_message=message, - data=b"", - retain_height=0, - ) - return cast(AbciMessage, reply) - - def list_snapshots( # pylint: disable=no-self-use - self, - message: AbciMessage, - dialogue: AbciDialogue, - ) -> AbciMessage: - """ - Handle a message of REQUEST_LIST_SNAPSHOT performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, - target_message=message, - snapshots=SnapShots([]), - ) - return cast(AbciMessage, reply) - - def offer_snapshot( # pylint: disable=no-self-use - self, - message: AbciMessage, - dialogue: AbciDialogue, - ) -> AbciMessage: - """ - Handle a message of REQUEST_OFFER_SNAPSHOT performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, - target_message=message, - result=Result(ResultType.REJECT), # by default, we reject - ) - return cast(AbciMessage, reply) - - def load_snapshot_chunk( # pylint: disable=no-self-use - self, - message: AbciMessage, - dialogue: AbciDialogue, - ) -> AbciMessage: - """ - Handle a message of REQUEST_LOAD_SNAPSHOT_CHUNK performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, - target_message=message, - chunk=b"", - ) - return cast(AbciMessage, reply) - - def apply_snapshot_chunk( # pylint: disable=no-self-use - self, - message: AbciMessage, - dialogue: AbciDialogue, - ) -> AbciMessage: - """ - Handle a message of REQUEST_APPLY_SNAPSHOT_CHUNK performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, - target_message=message, - result=Result(ResultType.REJECT), - refetch_chunks=tuple(), - reject_senders=tuple(), - ) - return cast(AbciMessage, reply) diff --git a/trader_backup/vendor/valory/skills/abstract_abci/skill.yaml b/trader_backup/vendor/valory/skills/abstract_abci/skill.yaml deleted file mode 100644 index 0ffadfd19..000000000 --- a/trader_backup/vendor/valory/skills/abstract_abci/skill.yaml +++ /dev/null @@ -1,34 +0,0 @@ -name: abstract_abci -author: valory -version: 0.1.0 -type: skill -description: The abci skill provides a template of an ABCI application. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeiezmhsokdhxat2gzxgau2zotd5nqjepg5lb2y7ypijuuq75xnxxrq - __init__.py: bafybeigdpqcsxpxp3akxdy5wcccfahom7pmbrnmututws2fmpcr7q6ryoe - dialogues.py: bafybeib6cex55nl57xe6boa4c3z4ynlxstnospqjehdb5owpgtvzsu5ucm - handlers.py: bafybeihb25swvt26vtqpnvldf6viizt34ophj6hijfpu5pevrlmvpvzkdq - tests/__init__.py: bafybeicnx4gezk2zrgz23mco2kv7ws3yd5yspku5e3ng4cb5tw7s2zexsu - tests/test_dialogues.py: bafybeig3kubiyq7bqmetrka67fjk7vymgtjwguyui3yubbvgtzzhfizsdu - tests/test_handlers.py: bafybeieeuwtu35ddaevr2wgnk33l7kdhrx7ruoeb5jiltiyn65ufdcnopu -fingerprint_ignore_patterns: [] -connections: -- valory/abci:0.1.0:bafybeia6etkacvqend7xj6viejkqgo7ozu3yn4yg3qezfthf2xhrjjwse4 -contracts: [] -protocols: -- valory/abci:0.1.0:bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u -skills: [] -behaviours: {} -handlers: - abci: - args: {} - class_name: ABCIHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues -dependencies: {} -is_abstract: true -customs: [] diff --git a/trader_backup/vendor/valory/skills/abstract_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/abstract_abci/tests/__init__.py deleted file mode 100644 index 499994e54..000000000 --- a/trader_backup/vendor/valory/skills/abstract_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/abstract_abci skill.""" diff --git a/trader_backup/vendor/valory/skills/abstract_abci/tests/test_dialogues.py b/trader_backup/vendor/valory/skills/abstract_abci/tests/test_dialogues.py deleted file mode 100644 index 4de0596ce..000000000 --- a/trader_backup/vendor/valory/skills/abstract_abci/tests/test_dialogues.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" -from enum import Enum -from typing import Type, cast -from unittest.mock import MagicMock - -import pytest -from aea.protocols.dialogue.base import Dialogues - -from packages.valory.skills.abstract_abci.dialogues import AbciDialogue, AbciDialogues - - -@pytest.mark.parametrize( - "dialogues_cls,expected_role_from_first_message", - [ - (AbciDialogues, AbciDialogue.Role.CLIENT), - ], -) -def test_dialogues_creation( - dialogues_cls: Type[AbciDialogues], expected_role_from_first_message: Enum -) -> None: - """Test XDialogues creations.""" - dialogues = cast(Dialogues, dialogues_cls(name="", skill_context=MagicMock())) - assert ( - expected_role_from_first_message - == dialogues._role_from_first_message( # pylint: disable=protected-access - MagicMock(), MagicMock() - ) - ) diff --git a/trader_backup/vendor/valory/skills/abstract_abci/tests/test_handlers.py b/trader_backup/vendor/valory/skills/abstract_abci/tests/test_handlers.py deleted file mode 100644 index c653c34d5..000000000 --- a/trader_backup/vendor/valory/skills/abstract_abci/tests/test_handlers.py +++ /dev/null @@ -1,398 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the handlers.py module of the skill.""" -import logging -from pathlib import Path -from typing import Any, cast -from unittest.mock import MagicMock, patch - -from aea.configurations.data_types import PublicId -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.test_tools.test_skill import BaseSkillTestCase - -from packages.valory.connections.abci.connection import PUBLIC_ID -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import ( - CheckTxType, - CheckTxTypeEnum, - Evidences, - Header, - LastCommitInfo, - PublicKey, - Result, - ResultType, - SnapShots, - Snapshot, - Timestamp, - ValidatorUpdate, - ValidatorUpdates, -) -from packages.valory.protocols.abci.dialogues import AbciDialogues as BaseAbciDialogues -from packages.valory.skills.abstract_abci.dialogues import AbciDialogue, AbciDialogues -from packages.valory.skills.abstract_abci.handlers import ABCIHandler, ERROR_CODE - - -PACKAGE_DIR = Path(__file__).parent.parent - - -class AbciDialoguesServer(BaseAbciDialogues): - """The dialogues class keeps track of all ABCI dialogues.""" - - def __init__(self, address: str) -> None: - """Initialize dialogues.""" - self.address = address - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.SERVER - - BaseAbciDialogues.__init__( - self, - self_address=self.address, - role_from_first_message=role_from_first_message, - dialogue_class=AbciDialogue, - ) - - -class TestABCIHandlerOld(BaseSkillTestCase): - """Test ABCIHandler methods.""" - - path_to_skill = PACKAGE_DIR - abci_handler: ABCIHandler - logger: logging.Logger - abci_dialogues: AbciDialogues - - @classmethod - def setup_class(cls, **kwargs: Any) -> None: - """Setup the test class.""" - super().setup_class() - cls.abci_handler = cast(ABCIHandler, cls._skill.skill_context.handlers.abci) - cls.logger = cls._skill.skill_context.logger - - cls.abci_dialogues = cast( - AbciDialogues, cls._skill.skill_context.abci_dialogues - ) - - def test_setup(self) -> None: - """Test the setup method of the echo handler.""" - with patch.object(self.logger, "log") as mock_logger: - self.abci_handler.setup() - - # after - self.assert_quantity_in_outbox(0) - - mock_logger.assert_any_call( - logging.DEBUG, f"ABCI Handler: setup method called. Using {PUBLIC_ID}." - ) - - def test_teardown(self) -> None: - """Test the teardown method of the echo handler.""" - with patch.object(self.logger, "log") as mock_logger: - self.abci_handler.teardown() - - # after - self.assert_quantity_in_outbox(0) - - mock_logger.assert_any_call( - logging.DEBUG, "ABCI Handler: teardown method called." - ) - - -class TestABCIHandler: - """Test 'ABCIHandler'.""" - - def setup(self) -> None: - """Set up the tests.""" - self.skill_id = ( # pylint: disable=attribute-defined-outside-init - PublicId.from_str("dummy/skill:0.1.0") - ) - self.context = MagicMock( # pylint: disable=attribute-defined-outside-init - skill_id=self.skill_id - ) - self.context.abci_dialogues = AbciDialogues(name="", skill_context=self.context) - self.dialogues = ( # pylint: disable=attribute-defined-outside-init - AbciDialoguesServer(address="server") - ) - self.handler = ABCIHandler( # pylint: disable=attribute-defined-outside-init - name="", skill_context=self.context - ) - - def test_setup(self) -> None: - """Test the setup method.""" - self.handler.setup() - - def test_teardown(self) -> None: - """Test the teardown method.""" - self.handler.teardown() - - def test_handle(self) -> None: - """Test the message gets handled.""" - message, _ = self.dialogues.create( - counterparty=str(self.skill_id), - performative=AbciMessage.Performative.REQUEST_INFO, - version="", - block_version=0, - p2p_version=0, - ) - self.handler.handle(cast(AbciMessage, message)) - - def test_handle_log_exception(self) -> None: - """Test the message gets handled.""" - message = AbciMessage( - dialogue_reference=("", ""), - performative=AbciMessage.Performative.REQUEST_INFO, # type: ignore - version="", - block_version=0, - p2p_version=0, - target=0, - message_id=1, - ) - message._sender = "server" # pylint: disable=protected-access - message._to = str(self.skill_id) # pylint: disable=protected-access - self.handler.handle(message) - - def test_info(self) -> None: - """Test the 'info' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_INFO, - version="", - block_version=0, - p2p_version=0, - ) - response = self.handler.info( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_INFO - - def test_echo(self) -> None: - """Test the 'echo' handler method.""" - expected_message = "message" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_ECHO, - message=expected_message, - ) - response = self.handler.echo( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_ECHO - assert response.message == expected_message - - def test_set_option(self) -> None: - """Test the 'set_option' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_SET_OPTION, - ) - response = self.handler.set_option( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_SET_OPTION - assert response.code == ERROR_CODE - - def test_begin_block(self) -> None: - """Test the 'begin_block' handler method.""" - header = Header(*(MagicMock() for _ in range(14))) - last_commit_info = LastCommitInfo(*(MagicMock() for _ in range(2))) - byzantine_validators = Evidences(MagicMock()) - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_BEGIN_BLOCK, - hash=b"", - header=header, - last_commit_info=last_commit_info, - byzantine_validators=byzantine_validators, - ) - response = self.handler.begin_block( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_BEGIN_BLOCK - - def test_check_tx(self, *_: Any) -> None: - """Test the 'check_tx' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_CHECK_TX, - tx=b"", - type=CheckTxType(CheckTxTypeEnum.NEW), - ) - response = self.handler.check_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_CHECK_TX - assert response.code == ERROR_CODE - - def test_deliver_tx(self, *_: Any) -> None: - """Test the 'deliver_tx' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - tx=b"", - ) - response = self.handler.deliver_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_DELIVER_TX - assert response.code == ERROR_CODE - - def test_end_block(self) -> None: - """Test the 'end_block' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_END_BLOCK, - height=1, - ) - response = self.handler.end_block( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_END_BLOCK - - def test_commit(self) -> None: - """Test the 'commit' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_COMMIT, - ) - response = self.handler.commit( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_COMMIT - - def test_flush(self) -> None: - """Test the 'flush' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_FLUSH, - ) - response = self.handler.flush( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_FLUSH - - def test_init_chain(self) -> None: - """Test the 'init_chain' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_INIT_CHAIN, - time=Timestamp(1, 1), - chain_id="", - validators=ValidatorUpdates( - [ - ValidatorUpdate( - PublicKey(data=b"", key_type=PublicKey.PublicKeyType.ed25519), 1 - ) - ] - ), - app_state_bytes=b"", - initial_height=0, - ) - response = self.handler.init_chain( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_INIT_CHAIN - - def test_query(self) -> None: - """Test the 'init_chain' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_QUERY, - query_data=b"", - path="", - height=0, - prove=True, - ) - response = self.handler.query( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_QUERY - assert response.code == ERROR_CODE - - def test_list_snapshots(self) -> None: - """Test the 'list_snapshots' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS, - ) - response = self.handler.list_snapshots( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS - assert response.snapshots == SnapShots([]) - - def test_offer_snapshot(self) -> None: - """Test the 'offer_snapshot' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT, - snapshot=Snapshot(0, 0, 0, b"", b""), - app_hash=b"", - ) - response = self.handler.offer_snapshot( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT - assert response.result == Result(ResultType.REJECT) - - def test_load_snapshot_chunk(self) -> None: - """Test the 'load_snapshot_chunk' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK, - height=0, - format=0, - chunk_index=0, - ) - response = self.handler.load_snapshot_chunk( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert ( - response.performative - == AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK - ) - assert response.chunk == b"" - - def test_apply_snapshot_chunk(self) -> None: - """Test the 'apply_snapshot_chunk' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK, - index=0, - chunk=b"", - chunk_sender="", - ) - response = self.handler.apply_snapshot_chunk( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert ( - response.performative - == AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK - ) - assert response.result == Result(ResultType.REJECT) - assert response.refetch_chunks == tuple() - assert response.reject_senders == tuple() diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/README.md b/trader_backup/vendor/valory/skills/abstract_round_abci/README.md deleted file mode 100644 index 4ee033ebd..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Abstract round abci - -## Description - -This module contains an abstract round ABCI skill template for an AEA. - -## Behaviours - -* `AbstractRoundBehaviour` - - This behaviour implements an abstract round behaviour. - -* `_MetaRoundBehaviour` - - A metaclass that validates AbstractRoundBehaviour's attributes. - - -## Handlers - -* `ABCIRoundHandler` - - ABCI handler. - -* `AbstractResponseHandler` - - The concrete classes must set the `allowed_response_performatives` - class attribute to the (frozen)set of performative the developer - wants the handler to handle. - -* `ContractApiHandler` - - Implement the contract api handler. - -* `HttpHandler` - - The HTTP response handler. - -* `LedgerApiHandler` - - Implement the ledger handler. - -* `SigningHandler` - - Implement the transaction handler. - - diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/__init__.py b/trader_backup/vendor/valory/skills/abstract_round_abci/__init__.py deleted file mode 100644 index 2bc8fd5fb..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 an abstract round ABCI skill template for an AEA.""" # pragma: nocover - -from aea.configurations.base import PublicId # pragma: nocover - - -PUBLIC_ID = PublicId.from_str("valory/abstract_round_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/abci_app_chain.py b/trader_backup/vendor/valory/skills/abstract_round_abci/abci_app_chain.py deleted file mode 100644 index 577fb8c33..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/abci_app_chain.py +++ /dev/null @@ -1,291 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 utilities for AbciApps.""" -import logging -from copy import deepcopy -from typing import Any, Dict, FrozenSet, List, Optional, Set, Tuple, Type - -from aea.exceptions import enforce - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AppState, - EventToTimeout, - EventType, -) - - -_default_logger = logging.getLogger( - "aea.packages.valory.skills.abstract_round_abci.abci_app_chain" -) - -AbciAppTransitionMapping = Dict[AppState, AppState] - - -def check_set_uniqueness(sets: Tuple) -> Optional[Any]: - """Checks that all elements in the set list are unique and not repeated among different sets""" - all_elements = set.union(*sets) - for element in all_elements: - # Count the number of sets that include this element - sets_in = [set_ for set_ in sets if element in set_] - if len(sets_in) > 1: - return element - return None - - -def chain( # pylint: disable=too-many-locals,too-many-statements - abci_apps: Tuple[Type[AbciApp], ...], - abci_app_transition_mapping: AbciAppTransitionMapping, -) -> Type[AbciApp]: - """ - Concatenate multiple AbciApp types. - - The consistency checks assume that the first element in - abci_apps is the entry-point abci_app (i.e. the associated round of - the initial_behaviour_cls of the AbstractRoundBehaviour in which - the chained AbciApp is used is one of the initial_states of the first element.) - """ - enforce( - len(abci_apps) > 1, - f"there must be a minimum of two AbciApps to chain, found ({len(abci_apps)})", - ) - enforce( - len(set(abci_apps)) == len(abci_apps), - "Found multiple occurrences of same Abci App", - ) - non_abstract_abci_apps = [ - abci_app.__name__ for abci_app in abci_apps if not abci_app.is_abstract() - ] - enforce( - len(non_abstract_abci_apps) == 0, - f"found non-abstract AbciApp during chaining: {non_abstract_abci_apps}", - ) - - # Get the apps rounds - rounds = tuple(app.get_all_rounds() for app in abci_apps) - round_ids = tuple( - {round_.auto_round_id() for round_ in app.get_all_rounds()} for app in abci_apps - ) - - # Ensure there are no common rounds - common_round_classes = check_set_uniqueness(rounds) - enforce( - not common_round_classes, - f"rounds in common between abci apps are not allowed ({common_round_classes})", - ) - - # Ensure there are no common round_ids - common_round_ids = check_set_uniqueness(round_ids) - enforce( - not common_round_ids, - f"round ids in common between abci apps are not allowed ({common_round_ids})", - ) - - # Ensure all states in app transition mapping (keys and values) are final states or initial states, respectively. - all_final_states = { - final_state for app in abci_apps for final_state in app.final_states - } - all_initial_states = { - initial_state for app in abci_apps for initial_state in app.initial_states - }.union({app.initial_round_cls for app in abci_apps}) - for key, value in abci_app_transition_mapping.items(): - if key not in all_final_states: - raise ValueError( - f"Found non-final state {key} specified in abci_app_transition_mapping." - ) - if value not in all_initial_states: - raise ValueError( - f"Found non-initial state {value} specified in abci_app_transition_mapping." - ) - - # Ensure all DB pre- and post-conditions are consistent - # Since we know which app is the "entry-point" we can - # simply work forward from there through all branches. When - # we loop back on an earlier node we stop. - initial_state_to_app: Dict[AppState, Type[AbciApp]] = {} - for value in abci_app_transition_mapping.values(): - for app in abci_apps: - if value in app.initial_states or value == app.initial_round_cls: - initial_state_to_app[value] = app - break - - def get_paths( - initial_state: AppState, - app: Type[AbciApp], - previous_apps: Optional[List[Type[AbciApp]]] = None, - ) -> List[List[Tuple[AppState, Type[AbciApp], Optional[AppState]]]]: - """Get paths.""" - previous_apps_: List[Type[AbciApp]] = ( - deepcopy(previous_apps) if previous_apps is not None else [] - ) - default: List[List[Tuple[AppState, Type[AbciApp], Optional[AppState]]]] = [ - [(initial_state, app, None)] - ] - if app.final_states == {}: - return default # pragma: no cover - paths: List[List[Tuple[AppState, Type[AbciApp], Optional[AppState]]]] = [] - for final_state in app.final_states: - element: Tuple[AppState, Type[AbciApp], Optional[AppState]] = ( - initial_state, - app, - final_state, - ) - if final_state not in abci_app_transition_mapping: - # no linkage defined - paths.append([element]) - continue - next_initial_state = abci_app_transition_mapping[final_state] - next_app = initial_state_to_app[next_initial_state] - if next_app in previous_apps_: - # self-loops do not require attention - # we don't append to path - continue - new_previous_apps = previous_apps_ + [app] - for path in get_paths(next_initial_state, next_app, new_previous_apps): - # if element not in path: - paths.append([element] + path) - return paths if paths else default - - all_paths: List[ - List[Tuple[AppState, Type[AbciApp], Optional[AppState]]] - ] = get_paths(abci_apps[0].initial_round_cls, abci_apps[0]) - new_db_post_conditions: Dict[AppState, Set[str]] = {} - for path in all_paths: - current_initial_state, current_app, current_final_state = path[0] - accumulated_post_conditions: Set[str] = current_app.db_pre_conditions.get( - current_initial_state, set() - ) - for next_initial_state, next_app, next_final_state in path[1:]: - if current_final_state is None: - # No outwards transition, nothing to check. - # we are at the end of a path where the last - # app has no final state and therefore no post conditions - break # pragma: no cover - accumulated_post_conditions = accumulated_post_conditions.union( - set(current_app.db_post_conditions[current_final_state]) - ) - # we now check that the pre conditions of the next app - # are compatible with the post conditions of the current apps. - if next_initial_state in next_app.db_pre_conditions: - diff = set.difference( - next_app.db_pre_conditions[next_initial_state], - accumulated_post_conditions, - ) - if len(diff) != 0: - raise ValueError( - f"Pre conditions '{diff}' of app '{next_app}' not a post condition of app '{current_app}' or any preceding app in path {path}." - ) - else: - raise ValueError( - f"No pre-conditions have been set for {next_initial_state}! " - f"You need to explicitly specify them as empty if there are no pre-conditions for this FSM." - ) - current_app = next_app - current_final_state = next_final_state - - if current_final_state is not None: - new_db_post_conditions[current_final_state] = accumulated_post_conditions - - # Warn about events duplicated in multiple apps - app_to_events = {app: app.get_all_events() for app in abci_apps} - all_events = set.union(*app_to_events.values()) - for event in all_events: - apps = [str(app) for app, events in app_to_events.items() if event in events] - if len(apps) > 1: - apps_str = "\n".join(apps) - _default_logger.warning( - f"The same event '{event}' has been found in several apps:\n{apps_str}\n" - "It will be interpreted as the same event. " - "If this is not the intended behaviour, please rename it to enforce its uniqueness." - ) - - new_initial_round_cls = abci_apps[0].initial_round_cls - new_initial_states = abci_apps[0].initial_states - new_db_pre_conditions = abci_apps[0].db_pre_conditions - - # Merge the transition functions, final states and events - potential_final_states = set.union(*(app.final_states for app in abci_apps)) - potential_events_to_timeout: EventToTimeout = {} - for app in abci_apps: - for e, t in app.event_to_timeout.items(): - if e in potential_events_to_timeout and potential_events_to_timeout[e] != t: - raise ValueError( - f"Event {e} defined in app {app} is defined with timeout {t} but it is already defined in a prior app with timeout {potential_events_to_timeout[e]}." - ) - potential_events_to_timeout[e] = t - - potential_transition_function: AbciAppTransitionFunction = {} - for app in abci_apps: - for state, events_to_rounds in app.transition_function.items(): - if state in abci_app_transition_mapping: - # we remove these final states - continue - # Update transition function according to the transition mapping - new_events_to_rounds = {} - for event, round_ in events_to_rounds.items(): - destination_round = abci_app_transition_mapping.get(round_, round_) - new_events_to_rounds[event] = destination_round - potential_transition_function[state] = new_events_to_rounds - - # Remove no longer used states from transition function and final states - destination_states: Set[AppState] = set() - for event_to_states in potential_transition_function.values(): - destination_states.update(event_to_states.values()) - new_transition_function: AbciAppTransitionFunction = { - state: events_to_rounds - for state, events_to_rounds in potential_transition_function.items() - if state in destination_states or state is new_initial_round_cls - } - new_final_states = { - state for state in potential_final_states if state in destination_states - } - - # Remove no longer used events - used_events: Set[str] = set() - for event_to_states in new_transition_function.values(): - used_events.update(event_to_states.keys()) - new_events_to_timeout = { - event: timeout - for event, timeout in potential_events_to_timeout.items() - if event in used_events - } - - # Collect keys to persist across periods from all abcis - new_cross_period_persisted_keys: Set[str] = set() - for app in abci_apps: - new_cross_period_persisted_keys.update(app.cross_period_persisted_keys) - - # Return the composed result - class ComposedAbciApp(AbciApp[EventType]): - """Composed abci app class.""" - - initial_round_cls: AppState = new_initial_round_cls - initial_states: Set[AppState] = new_initial_states - transition_function: AbciAppTransitionFunction = new_transition_function - final_states: Set[AppState] = new_final_states - event_to_timeout: EventToTimeout = new_events_to_timeout - cross_period_persisted_keys: FrozenSet[str] = frozenset( - new_cross_period_persisted_keys - ) - db_pre_conditions: Dict[AppState, Set[str]] = new_db_pre_conditions - db_post_conditions: Dict[AppState, Set[str]] = new_db_post_conditions - - return ComposedAbciApp diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/base.py b/trader_backup/vendor/valory/skills/abstract_round_abci/base.py deleted file mode 100644 index 9718c8e98..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/base.py +++ /dev/null @@ -1,3850 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the base classes for the models classes of the skill.""" - -import datetime -import hashlib -import heapq -import itertools -import json -import logging -import re -import sys -import textwrap -import uuid -from abc import ABC, ABCMeta, abstractmethod -from collections import Counter, deque -from copy import copy, deepcopy -from dataclasses import asdict, astuple, dataclass, field, is_dataclass -from enum import Enum -from inspect import isclass -from math import ceil -from typing import ( - Any, - Callable, - Deque, - Dict, - FrozenSet, - Generic, - Iterator, - List, - Mapping, - Optional, - Sequence, - Set, - Tuple, - Type, - TypeVar, - Union, - cast, -) - -from aea.crypto.ledger_apis import LedgerApis -from aea.exceptions import enforce -from aea.skills.base import SkillContext - -from packages.valory.connections.abci.connection import MAX_READ_IN_BYTES -from packages.valory.connections.ledger.connection import ( - PUBLIC_ID as LEDGER_CONNECTION_PUBLIC_ID, -) -from packages.valory.protocols.abci.custom_types import ( - EvidenceType, - Evidences, - Header, - LastCommitInfo, - Validator, -) -from packages.valory.skills.abstract_round_abci.utils import ( - consensus_threshold, - is_json_serializable, -) - - -_logger = logging.getLogger("aea.packages.valory.skills.abstract_round_abci.base") - -OK_CODE = 0 -ERROR_CODE = 1 -LEDGER_API_ADDRESS = str(LEDGER_CONNECTION_PUBLIC_ID) -ROUND_COUNT_DEFAULT = -1 -MIN_HISTORY_DEPTH = 1 -ADDRESS_LENGTH = 42 -MAX_INT_256 = 2**256 - 1 -RESET_COUNT_START = 0 -VALUE_NOT_PROVIDED = object() -# tolerance in seconds for new blocks not having arrived yet -BLOCKS_STALL_TOLERANCE = 60 -SERIOUS_OFFENCE_ENUM_MIN = 1000 -NUMBER_OF_BLOCKS_TRACKED = 10_000 -NUMBER_OF_ROUNDS_TRACKED = 50 - -EventType = TypeVar("EventType") - - -def get_name(prop: Any) -> str: - """Get the name of a property.""" - if not (isinstance(prop, property) and hasattr(prop, "fget")): - raise ValueError(f"{prop} is not a property") - if prop.fget is None: - raise ValueError(f"fget of {prop} is None") # pragma: nocover - return prop.fget.__name__ - - -class ABCIAppException(Exception): - """A parent class for all exceptions related to the ABCIApp.""" - - -class SignatureNotValidError(ABCIAppException): - """Error raised when a signature is invalid.""" - - -class AddBlockError(ABCIAppException): - """Exception raised when a block addition is not valid.""" - - -class ABCIAppInternalError(ABCIAppException): - """Internal error due to a bad implementation of the ABCIApp.""" - - def __init__(self, message: str, *args: Any) -> None: - """Initialize the error object.""" - super().__init__("internal error: " + message, *args) - - -class TransactionTypeNotRecognizedError(ABCIAppException): - """Error raised when a transaction type is not recognized.""" - - -class TransactionNotValidError(ABCIAppException): - """Error raised when a transaction is not valid.""" - - -class LateArrivingTransaction(ABCIAppException): - """Error raised when the transaction belongs to previous round.""" - - -class AbstractRoundInternalError(ABCIAppException): - """Internal error due to a bad implementation of the AbstractRound.""" - - def __init__(self, message: str, *args: Any) -> None: - """Initialize the error object.""" - super().__init__("internal error: " + message, *args) - - -class _MetaPayload(ABCMeta): - """ - Payload metaclass. - - The purpose of this metaclass is to remember the association - between the type of payload and the payload class to build it. - This is necessary to recover the right payload class to instantiate - at decoding time. - """ - - registry: Dict[str, Type["BaseTxPayload"]] = {} - - def __new__(mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any) -> Type: # type: ignore - """Create a new class object.""" - new_cls = super().__new__(mcs, name, bases, namespace, **kwargs) - - if new_cls.__module__ == mcs.__module__ and new_cls.__name__ == "BaseTxPayload": - return new_cls - if not issubclass(new_cls, BaseTxPayload): - raise ValueError( # pragma: no cover - f"class {name} must inherit from {BaseTxPayload.__name__}" - ) - new_cls = cast(Type[BaseTxPayload], new_cls) - # remember association from transaction type to payload class - _metaclass_registry_key = f"{new_cls.__module__}.{new_cls.__name__}" # type: ignore - mcs.registry[_metaclass_registry_key] = new_cls - - return new_cls - - -@dataclass(frozen=True) -class BaseTxPayload(metaclass=_MetaPayload): - """This class represents a base class for transaction payload classes.""" - - sender: str - round_count: int = field(default=ROUND_COUNT_DEFAULT, init=False) - id_: str = field(default_factory=lambda: uuid.uuid4().hex, init=False) - - @property - def data(self) -> Dict[str, Any]: - """Data""" - excluded = ["sender", "round_count", "id_"] - return {k: v for k, v in asdict(self).items() if k not in excluded} - - @property - def values(self) -> Tuple[Any, ...]: - """Data""" - excluded = 3 # refers to ["sender", "round_count", "id_"] - return astuple(self)[excluded:] - - @property - def json(self) -> Dict[str, Any]: - """Json""" - data, cls = asdict(self), self.__class__ - data["_metaclass_registry_key"] = f"{cls.__module__}.{cls.__name__}" - return data - - @classmethod - def from_json(cls, obj: Dict) -> "BaseTxPayload": - """Decode the payload.""" - data = copy(obj) - round_count, id_ = data.pop("round_count"), data.pop("id_") - payload_cls = _MetaPayload.registry[data.pop("_metaclass_registry_key")] - payload = payload_cls(**data) # type: ignore - object.__setattr__(payload, "round_count", round_count) - object.__setattr__(payload, "id_", id_) - return payload - - def with_new_id(self) -> "BaseTxPayload": - """Create a new payload with the same content but new id.""" - new = type(self)(sender=self.sender, **self.data) # type: ignore - object.__setattr__(new, "round_count", self.round_count) - return new - - def encode(self) -> bytes: - """Encode""" - encoded_data = json.dumps(self.json, sort_keys=True).encode() - if sys.getsizeof(encoded_data) > MAX_READ_IN_BYTES: - msg = f"{type(self)} must be smaller than {MAX_READ_IN_BYTES} bytes" - raise ValueError(msg) - return encoded_data - - @classmethod - def decode(cls, obj: bytes) -> "BaseTxPayload": - """Decode""" - return cls.from_json(json.loads(obj.decode())) - - -@dataclass(frozen=True) -class Transaction(ABC): - """Class to represent a transaction for the ephemeral chain of a period.""" - - payload: BaseTxPayload - signature: str - - def encode(self) -> bytes: - """Encode the transaction.""" - - data = dict(payload=self.payload.json, signature=self.signature) - encoded_data = json.dumps(data, sort_keys=True).encode() - if sys.getsizeof(encoded_data) > MAX_READ_IN_BYTES: - raise ValueError( - f"Transaction must be smaller than {MAX_READ_IN_BYTES} bytes" - ) - return encoded_data - - @classmethod - def decode(cls, obj: bytes) -> "Transaction": - """Decode the transaction.""" - - data = json.loads(obj.decode()) - signature = data["signature"] - payload = BaseTxPayload.from_json(data["payload"]) - return Transaction(payload, signature) - - def verify(self, ledger_id: str) -> None: - """ - Verify the signature is correct. - - :param ledger_id: the ledger id of the address - :raises: SignatureNotValidError: if the signature is not valid. - """ - payload_bytes = self.payload.encode() - addresses = LedgerApis.recover_message( - identifier=ledger_id, message=payload_bytes, signature=self.signature - ) - if self.payload.sender not in addresses: - raise SignatureNotValidError(f"Signature not valid on transaction: {self}") - - -class Block: # pylint: disable=too-few-public-methods - """Class to represent (a subset of) data of a Tendermint block.""" - - def __init__( - self, - header: Header, - transactions: Sequence[Transaction], - ) -> None: - """Initialize the block.""" - self.header = header - self._transactions: Tuple[Transaction, ...] = tuple(transactions) - - @property - def transactions(self) -> Tuple[Transaction, ...]: - """Get the transactions.""" - return self._transactions - - @property - def timestamp(self) -> datetime.datetime: - """Get the block timestamp.""" - return self.header.timestamp - - -class Blockchain: - """ - Class to represent a (naive) Tendermint blockchain. - - The consistency of the data in the blocks is guaranteed by Tendermint. - """ - - def __init__(self, height_offset: int = 0, is_init: bool = True) -> None: - """Initialize the blockchain.""" - self._blocks: List[Block] = [] - self._height_offset = height_offset - self._is_init = is_init - - @property - def is_init(self) -> bool: - """Returns true if the blockchain is initialized.""" - return self._is_init - - def add_block(self, block: Block) -> None: - """Add a block to the list.""" - expected_height = self.height + 1 - actual_height = block.header.height - if actual_height < self._height_offset: - # if the current block has a lower height than the - # initial height, ignore it - return - - if expected_height != actual_height: - raise AddBlockError( - f"expected height {expected_height}, got {actual_height}" - ) - self._blocks.append(block) - - @property - def height(self) -> int: - """ - Get the height. - - Tendermint's height starts from 1. A return value - equal to 0 means empty blockchain. - - :return: the height. - """ - return self.length + self._height_offset - - @property - def length(self) -> int: - """Get the blockchain length.""" - return len(self._blocks) - - @property - def blocks(self) -> Tuple[Block, ...]: - """Get the blocks.""" - return tuple(self._blocks) - - @property - def last_block( - self, - ) -> Block: - """Returns the last stored block.""" - return self._blocks[-1] - - -class BlockBuilder: - """Helper class to build a block.""" - - _current_header: Optional[Header] = None - _current_transactions: List[Transaction] = [] - - def __init__(self) -> None: - """Initialize the block builder.""" - self.reset() - - def reset(self) -> None: - """Reset the temporary data structures.""" - self._current_header = None - self._current_transactions = [] - - @property - def header(self) -> Header: - """ - Get the block header. - - :return: the block header - """ - if self._current_header is None: - raise ValueError("header not set") - return self._current_header - - @header.setter - def header(self, header: Header) -> None: - """Set the header.""" - if self._current_header is not None: - raise ValueError("header already set") - self._current_header = header - - @property - def transactions(self) -> Tuple[Transaction, ...]: - """Get the sequence of transactions.""" - return tuple(self._current_transactions) - - def add_transaction(self, transaction: Transaction) -> None: - """Add a transaction.""" - self._current_transactions.append(transaction) - - def get_block(self) -> Block: - """Get the block.""" - return Block( - self.header, - self._current_transactions, - ) - - -class AbciAppDB: - """Class to represent all data replicated across agents. - - This class stores all the data in self._data. Every entry on this dict represents an optional "period" within your app execution. - The concept of period is user-defined, so it might be something like a sequence of rounds that together conform a logical cycle of - its execution, or it might have no sense at all (thus its optionality) and therefore only period 0 will be used. - - Every "period" entry stores a dict where every key is a saved parameter and its corresponding value a list containing the history - of the parameter values. For instance, for period 0: - - 0: {"parameter_name": [parameter_history]} - - A complete database could look like this: - - data = { - 0: { - "participants": - [ - {"participant_a", "participant_b", "participant_c", "participant_d"}, - {"participant_a", "participant_b", "participant_c"}, - {"participant_a", "participant_b", "participant_c", "participant_d"}, - ] - }, - "other_parameter": [0, 2, 8] - }, - 1: { - "participants": - [ - {"participant_a", "participant_c", "participant_d"}, - {"participant_a", "participant_b", "participant_c", "participant_d"}, - {"participant_a", "participant_b", "participant_c"}, - {"participant_a", "participant_b", "participant_d"}, - {"participant_a", "participant_b", "participant_c", "participant_d"}, - ], - "other_parameter": [3, 19, 10, 32, 6] - }, - 2: ... - } - - # Adding and removing data from the current period - -------------------------------------------------- - To update the current period entry, just call update() on the class. The new values will be appended to the current list for each updated parameter. - - To clean up old data from the current period entry, call cleanup_current_histories(cleanup_history_depth_current), where cleanup_history_depth_current - is the amount of data that you want to keep after the cleanup. The newest cleanup_history_depth_current values will be kept for each parameter in the DB. - - # Creating and removing old periods - ----------------------------------- - To create a new period entry, call create() on the class. The new values will be stored in a new list for each updated parameter. - - To remove old periods, call cleanup(cleanup_history_depth, [cleanup_history_depth_current]), where cleanup_history_depth is the amount of periods - that you want to keep after the cleanup. The newest cleanup_history_depth periods will be kept. If you also specify cleanup_history_depth_current, - cleanup_current_histories will be also called (see previous point). - - The parameters cleanup_history_depth and cleanup_history_depth_current can also be configured in skill.yaml so they are used automatically - when the cleanup method is called from AbciApp.cleanup(). - - # Memory warning - ----------------------------------- - The database is implemented in such a way to avoid indirect modification of its contents. - It copies all the mutable data structures*, which means that it consumes more memory than expected. - This is necessary because otherwise it would risk chance of modification from the behaviour side, - which is a safety concern. - - The effect of this on the memory usage should not be a big concern, because: - - 1. The synchronized data of the agents are not intended to store large amount of data. - IPFS should be used in such cases, and only the hash should be synchronized in the db. - 2. The data are automatically wiped after a predefined `cleanup_history` depth as described above. - 3. The retrieved data are only meant to be used for a short amount of time, - e.g., to perform a decision on a behaviour, which means that the gc will collect them before they are noticed. - - * the in-built `copy` module is used, which automatically detects if an item is immutable and skips copying it. - For more information take a look at the `_deepcopy_atomic` method and its usage: - https://github.com/python/cpython/blob/3.10/Lib/copy.py#L182-L183 - """ - - DB_DATA_KEY = "db_data" - SLASHING_CONFIG_KEY = "slashing_config" - - # database keys which values are always set for the next period by default - default_cross_period_keys: FrozenSet[str] = frozenset( - { - "all_participants", - "participants", - "consensus_threshold", - "safe_contract_address", - } - ) - - def __init__( - self, - setup_data: Dict[str, List[Any]], - cross_period_persisted_keys: Optional[FrozenSet[str]] = None, - logger: Optional[logging.Logger] = None, - ) -> None: - """Initialize the AbciApp database. - - setup_data must be passed as a Dict[str, List[Any]] (the database internal format). - The staticmethod 'data_to_lists' can be used to convert from Dict[str, Any] to Dict[str, List[Any]] - before instantiating this class. - - :param setup_data: the setup data - :param cross_period_persisted_keys: data keys that will be kept after a new period starts - :param logger: the logger of the abci app - """ - self.logger = logger or _logger - AbciAppDB._check_data(setup_data) - self._setup_data = deepcopy(setup_data) - self._data: Dict[int, Dict[str, List[Any]]] = { - RESET_COUNT_START: self.setup_data # the key represents the reset index - } - self._round_count = ROUND_COUNT_DEFAULT # ensures first round is indexed at 0! - - self._cross_period_persisted_keys = self.default_cross_period_keys.union( - cross_period_persisted_keys or frozenset() - ) - self._cross_period_check() - self.slashing_config: str = "" - - def _cross_period_check(self) -> None: - """Check the cross period keys against the setup data.""" - not_in_cross_period = set(self._setup_data).difference( - self.cross_period_persisted_keys - ) - if not_in_cross_period: - self.logger.warning( - f"The setup data ({self._setup_data.keys()}) contain keys that are not in the " - f"cross period persisted keys ({self.cross_period_persisted_keys}): {not_in_cross_period}" - ) - - @staticmethod - def normalize(value: Any) -> str: - """Attempt to normalize a non-primitive type to insert it into the db.""" - if is_json_serializable(value): - return value - - if isinstance(value, Enum): - return value.value - - if isinstance(value, bytes): - return value.hex() - - if isinstance(value, set): - try: - return json.dumps(list(value)) - except TypeError: - pass - - raise ValueError(f"Cannot normalize {value} to insert it in the db!") - - @property - def setup_data(self) -> Dict[str, Any]: - """ - Get the setup_data without entries which have empty values. - - :return: the setup_data - """ - # do not return data if no value has been set - return {k: v for k, v in deepcopy(self._setup_data).items() if len(v)} - - @staticmethod - def _check_data(data: Any) -> None: - """Check that all fields in setup data were passed as a list, and that the data can be accepted into the db.""" - if ( - not isinstance(data, dict) - or not all((isinstance(k, str) for k in data.keys())) - or not all((isinstance(v, list) for v in data.values())) - ): - raise ValueError( - f"AbciAppDB data must be `Dict[str, List[Any]]`, found `{type(data)}` instead." - ) - - AbciAppDB.validate(data) - - @property - def reset_index(self) -> int: - """Get the current reset index.""" - # should return the last key or 0 if we have no data - return list(self._data)[-1] if self._data else 0 - - @property - def round_count(self) -> int: - """Get the round count.""" - return self._round_count - - @round_count.setter - def round_count(self, round_count: int) -> None: - """Set the round count.""" - self._round_count = round_count - - @property - def cross_period_persisted_keys(self) -> FrozenSet[str]: - """Keys in the database which are persistent across periods.""" - return self._cross_period_persisted_keys - - def get(self, key: str, default: Any = VALUE_NOT_PROVIDED) -> Optional[Any]: - """Given a key, get its last for the current reset index.""" - if key in self._data[self.reset_index]: - return deepcopy(self._data[self.reset_index][key][-1]) - if default != VALUE_NOT_PROVIDED: - return default - raise ValueError( - f"'{key}' field is not set for this period [{self.reset_index}] and no default value was provided." - ) - - def get_strict(self, key: str) -> Any: - """Get a value from the data dictionary and raise if it is None.""" - return self.get(key) - - @staticmethod - def validate(data: Any) -> None: - """Validate if the given data are json serializable and therefore can be accepted into the database. - - :param data: the data to check. - :raises ABCIAppInternalError: If the data are not serializable. - """ - if not is_json_serializable(data): - raise ABCIAppInternalError( - f"`AbciAppDB` data must be json-serializable. Please convert non-serializable data in `{data}`. " - "You may use `AbciAppDB.validate(your_data)` to validate your data for the `AbciAppDB`." - ) - - def update(self, **kwargs: Any) -> None: - """Update the current data.""" - self.validate(kwargs) - - # Append new data to the key history - data = self._data[self.reset_index] - for key, value in deepcopy(kwargs).items(): - data.setdefault(key, []).append(value) - - def create(self, **kwargs: Any) -> None: - """Add a new entry to the data. - - Passes automatically the values of the `cross_period_persisted_keys` to the next period. - - :param kwargs: keyword arguments - """ - for key in self.cross_period_persisted_keys.union(kwargs.keys()): - value = kwargs.get(key, VALUE_NOT_PROVIDED) - if value is VALUE_NOT_PROVIDED: - value = self.get_latest().get(key, VALUE_NOT_PROVIDED) - if value is VALUE_NOT_PROVIDED: - raise ABCIAppInternalError( - f"Cross period persisted key `{key}` was not found in the db but was required for the next period." - ) - if isinstance(value, (set, frozenset)): - value = tuple(sorted(value)) - kwargs[key] = value - - data = self.data_to_lists(kwargs) - self._create_from_keys(**data) - - def _create_from_keys(self, **kwargs: Any) -> None: - """Add a new entry to the data using the provided key-value pairs.""" - AbciAppDB._check_data(kwargs) - self._data[self.reset_index + 1] = deepcopy(kwargs) - - def get_latest_from_reset_index(self, reset_index: int) -> Dict[str, Any]: - """Get the latest key-value pairs from the data dictionary for the specified period.""" - return { - key: values[-1] - for key, values in deepcopy(self._data.get(reset_index, {})).items() - } - - def get_latest(self) -> Dict[str, Any]: - """Get the latest key-value pairs from the data dictionary for the current period.""" - return self.get_latest_from_reset_index(self.reset_index) - - def increment_round_count(self) -> None: - """Increment the round count.""" - self._round_count += 1 - - def __repr__(self) -> str: - """Return a string representation of the data.""" - return f"AbciAppDB({self._data})" - - def cleanup( - self, - cleanup_history_depth: int, - cleanup_history_depth_current: Optional[int] = None, - ) -> None: - """Reset the db, keeping only the latest entries (periods). - - If cleanup_history_depth_current has been also set, also clear oldest historic values in the current entry. - - :param cleanup_history_depth: depth to clean up history - :param cleanup_history_depth_current: whether or not to clean up current entry too. - """ - cleanup_history_depth = max(cleanup_history_depth, MIN_HISTORY_DEPTH) - self._data = { - key: self._data[key] - for key in sorted(self._data.keys())[-cleanup_history_depth:] - } - if cleanup_history_depth_current: - self.cleanup_current_histories(cleanup_history_depth_current) - - def cleanup_current_histories(self, cleanup_history_depth_current: int) -> None: - """Reset the parameter histories for the current entry (period), keeping only the latest values for each parameter.""" - cleanup_history_depth_current = max( - cleanup_history_depth_current, MIN_HISTORY_DEPTH - ) - self._data[self.reset_index] = { - key: history[-cleanup_history_depth_current:] - for key, history in self._data[self.reset_index].items() - } - - def serialize(self) -> str: - """Serialize the data of the database to a string.""" - db = { - self.DB_DATA_KEY: self._data, - self.SLASHING_CONFIG_KEY: self.slashing_config, - } - return json.dumps(db, sort_keys=True) - - @staticmethod - def _as_abci_data(data: Dict) -> Dict[int, Any]: - """Hook to load serialized data as `AbciAppDB` data.""" - return {int(index): content for index, content in data.items()} - - def sync(self, serialized_data: str) -> None: - """Synchronize the data using a serialized object. - - :param serialized_data: the serialized data to use in order to sync the db. - :raises ABCIAppInternalError: if the given data cannot be deserialized. - """ - try: - loaded_data = json.loads(serialized_data) - except json.JSONDecodeError as exc: - raise ABCIAppInternalError( - f"Could not decode data using {serialized_data}: {exc}" - ) from exc - - input_report = f"\nThe following serialized data were given: {serialized_data}" - try: - db_data = loaded_data[self.DB_DATA_KEY] - slashing_config = loaded_data[self.SLASHING_CONFIG_KEY] - except KeyError as exc: - raise ABCIAppInternalError( - "Mandatory keys `db_data`, `slashing_config` are missing from the deserialized data: " - f"{loaded_data}{input_report}" - ) from exc - - try: - db_data = self._as_abci_data(db_data) - except AttributeError as exc: - raise ABCIAppInternalError( - f"Could not decode db data with an invalid format: {db_data}{input_report}" - ) from exc - except ValueError as exc: - raise ABCIAppInternalError( - f"An invalid index was found while trying to sync the db using data: {db_data}{input_report}" - ) from exc - - self._check_data(dict(tuple(db_data.values())[0])) - self._data = db_data - self.slashing_config = slashing_config - - def hash(self) -> bytes: - """Create a hash of the data.""" - # Compute the sha256 hash of the serialized data - sha256 = hashlib.sha256() - data = self.serialize() - sha256.update(data.encode("utf-8")) - hash_ = sha256.digest() - self.logger.debug(f"root hash: {hash_.hex()}; data: {data}") - return hash_ - - @staticmethod - def data_to_lists(data: Dict[str, Any]) -> Dict[str, List[Any]]: - """Convert Dict[str, Any] to Dict[str, List[Any]].""" - return {k: [v] for k, v in data.items()} - - -SerializedCollection = Dict[str, Dict[str, Any]] -DeserializedCollection = Mapping[str, BaseTxPayload] - - -class BaseSynchronizedData: - """ - Class to represent the synchronized data. - - This is the relevant data constructed and replicated by the agents. - """ - - # Keys always set by default - # `round_count` and `period_count` need to be guaranteed to be synchronized too: - # - # * `round_count` is only incremented when scheduling a new round, - # which is by definition always a synchronized action. - # * `period_count` comes from the `reset_index` which is the last key of the `self._data`. - # The `self._data` keys are only updated on create, and cleanup operations, - # which are also meant to be synchronized since they are used at the rounds. - default_db_keys: Set[str] = { - "round_count", - "period_count", - "all_participants", - "nb_participants", - "max_participants", - "consensus_threshold", - "safe_contract_address", - } - - def __init__( - self, - db: AbciAppDB, - ) -> None: - """Initialize the synchronized data.""" - self._db = db - - @property - def db(self) -> AbciAppDB: - """Get DB.""" - return self._db - - @property - def round_count(self) -> int: - """Get the round count.""" - return self.db.round_count - - @property - def period_count(self) -> int: - """Get the period count. - - Periods are executions between calls to AbciAppDB.create(), so as soon as it is called, - a new period begins. It is useful to have a logical subdivision of the FSM execution. - For example, if AbciAppDB.create() is called during reset, then a period will be the - execution between resets. - - :return: the period count - """ - return self.db.reset_index - - @property - def participants(self) -> FrozenSet[str]: - """Get the currently active participants.""" - participants = frozenset(self.db.get_strict("participants")) - if len(participants) == 0: - raise ValueError("List participants cannot be empty.") - return cast(FrozenSet[str], participants) - - @property - def all_participants(self) -> FrozenSet[str]: - """Get all registered participants.""" - all_participants = frozenset(self.db.get_strict("all_participants")) - if len(all_participants) == 0: - raise ValueError("List participants cannot be empty.") - return cast(FrozenSet[str], all_participants) - - @property - def max_participants(self) -> int: - """Get the number of all the participants.""" - return len(self.all_participants) - - @property - def consensus_threshold(self) -> int: - """Get the consensus threshold.""" - threshold = self.db.get_strict("consensus_threshold") - min_threshold = consensus_threshold(self.max_participants) - - if threshold is None: - return min_threshold - - threshold = int(threshold) - max_threshold = len(self.all_participants) - - if min_threshold <= threshold <= max_threshold: - return threshold - - expected_range = ( - f"can only be {min_threshold}" - if min_threshold == max_threshold - else f"not in [{min_threshold}, {max_threshold}]" - ) - raise ValueError(f"Consensus threshold {threshold} {expected_range}.") - - @property - def sorted_participants(self) -> Sequence[str]: - """ - Get the sorted participants' addresses. - - The addresses are sorted according to their hexadecimal value; - this is the reason we use key=str.lower as comparator. - - This property is useful when interacting with the Safe contract. - - :return: the sorted participants' addresses - """ - return sorted(self.participants, key=str.lower) - - @property - def nb_participants(self) -> int: - """Get the number of participants.""" - participants = cast(List, self.db.get("participants", [])) - return len(participants) - - @property - def slashing_config(self) -> str: - """Get the slashing configuration.""" - return self.db.slashing_config - - @slashing_config.setter - def slashing_config(self, config: str) -> None: - """Set the slashing configuration.""" - self.db.slashing_config = config - - def update( - self, - synchronized_data_class: Optional[Type] = None, - **kwargs: Any, - ) -> "BaseSynchronizedData": - """Copy and update the current data.""" - self.db.update(**kwargs) - - class_ = ( - type(self) if synchronized_data_class is None else synchronized_data_class - ) - return class_(db=self.db) - - def create( - self, - synchronized_data_class: Optional[Type] = None, - ) -> "BaseSynchronizedData": - """Copy and update with new data. Set values are stored as sorted tuples to the db for determinism.""" - self.db.create() - class_ = ( - type(self) if synchronized_data_class is None else synchronized_data_class - ) - return class_(db=self.db) - - def __repr__(self) -> str: - """Return a string representation of the data.""" - return f"{self.__class__.__name__}(db={self._db})" - - @property - def keeper_randomness(self) -> float: - """Get the keeper's random number [0-1].""" - return ( - int(self.most_voted_randomness, base=16) / MAX_INT_256 - ) # DRAND uses sha256 values - - @property - def most_voted_randomness(self) -> str: - """Get the most_voted_randomness.""" - return cast(str, self.db.get_strict("most_voted_randomness")) - - @property - def most_voted_keeper_address(self) -> str: - """Get the most_voted_keeper_address.""" - return cast(str, self.db.get_strict("most_voted_keeper_address")) - - @property - def is_keeper_set(self) -> bool: - """Check whether keeper is set.""" - return self.db.get("most_voted_keeper_address", None) is not None - - @property - def blacklisted_keepers(self) -> Set[str]: - """Get the current cycle's blacklisted keepers who cannot submit a transaction.""" - raw = cast(str, self.db.get("blacklisted_keepers", "")) - return set(textwrap.wrap(raw, ADDRESS_LENGTH)) - - @property - def participant_to_selection(self) -> DeserializedCollection: - """Check whether keeper is set.""" - serialized = self.db.get_strict("participant_to_selection") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(DeserializedCollection, deserialized) - - @property - def participant_to_randomness(self) -> DeserializedCollection: - """Check whether keeper is set.""" - serialized = self.db.get_strict("participant_to_randomness") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(DeserializedCollection, deserialized) - - @property - def participant_to_votes(self) -> DeserializedCollection: - """Check whether keeper is set.""" - serialized = self.db.get_strict("participant_to_votes") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(DeserializedCollection, deserialized) - - @property - def safe_contract_address(self) -> str: - """Get the safe contract address.""" - return cast(str, self.db.get_strict("safe_contract_address")) - - -class _MetaAbstractRound(ABCMeta): - """A metaclass that validates AbstractRound's attributes.""" - - def __new__(mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any) -> Type: # type: ignore - """Initialize the class.""" - new_cls = super().__new__(mcs, name, bases, namespace, **kwargs) - - if ABC in bases: - # abstract class, return - return new_cls - if not issubclass(new_cls, AbstractRound): - # the check only applies to AbstractRound subclasses - return new_cls - - mcs._check_consistency(cast(Type[AbstractRound], new_cls)) - return new_cls - - @classmethod - def _check_consistency(mcs, abstract_round_cls: Type["AbstractRound"]) -> None: - """Check consistency of class attributes.""" - mcs._check_required_class_attributes(abstract_round_cls) - - @classmethod - def _check_required_class_attributes( - mcs, abstract_round_cls: Type["AbstractRound"] - ) -> None: - """Check that required class attributes are set.""" - if not hasattr(abstract_round_cls, "synchronized_data_class"): - raise AbstractRoundInternalError( - f"'synchronized_data_class' not set on {abstract_round_cls}" - ) - if not hasattr(abstract_round_cls, "payload_class"): - raise AbstractRoundInternalError( - f"'payload_class' not set on {abstract_round_cls}" - ) - - -class AbstractRound(Generic[EventType], ABC, metaclass=_MetaAbstractRound): - """ - This class represents an abstract round. - - A round is a state of the FSM App execution. It usually involves - interactions between participants in the FSM App, - although this is not enforced at this level of abstraction. - - Concrete classes must set: - - synchronized_data_class: the data class associated with this round; - - payload_class: the payload type that is allowed for this round; - - Optionally, round_id can be defined, although it is recommended to use the autogenerated id. - """ - - __pattern = re.compile(r"(? None: - """Initialize the round.""" - self._synchronized_data = synchronized_data - self.block_confirmations = 0 - self._previous_round_payload_class = previous_round_payload_class - self.context = context - - @classmethod - def auto_round_id(cls) -> str: - """ - Get round id automatically. - - This method returns the auto generated id from the class name if the - class variable behaviour_id is not set on the child class. - Otherwise, it returns the class variable behaviour_id. - """ - return ( - cls.round_id - if isinstance(cls.round_id, str) - else cls.__pattern.sub("_", cls.__name__).lower() - ) - - @property # type: ignore - def round_id(self) -> str: - """Get round id.""" - return self.auto_round_id() - - @property - def synchronized_data(self) -> BaseSynchronizedData: - """Get the synchronized data.""" - return self._synchronized_data - - def check_transaction(self, transaction: Transaction) -> None: - """ - Check transaction against the current state. - - :param transaction: the transaction - """ - self.check_payload_type(transaction) - self.check_payload(transaction.payload) - - def process_transaction(self, transaction: Transaction) -> None: - """ - Process a transaction. - - By convention, the payload handler should be a method - of the class that is named '{payload_name}'. - - :param transaction: the transaction. - """ - self.check_payload_type(transaction) - self.process_payload(transaction.payload) - - @abstractmethod - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """ - Process the end of the block. - - The role of this method is check whether the round - is considered ended. - - If the round is ended, the return value is - - the final result of the round. - - the event that triggers a transition. If None, the period - in which the round was executed is considered ended. - - This is done after each block because we consider the consensus engine's - block, and not the transaction, as the smallest unit - on which the consensus is reached; in other words, - each read operation on the state should be done - only after each block, and not after each transaction. - """ - - def check_payload_type(self, transaction: Transaction) -> None: - """ - Check the transaction is of the allowed transaction type. - - :param transaction: the transaction - :raises: TransactionTypeNotRecognizedError if the transaction can be - applied to the current state. - """ - if self.payload_class is None: - raise TransactionTypeNotRecognizedError( - "current round does not allow transactions" - ) - - payload_class = type(transaction.payload) - - if payload_class is self._previous_round_payload_class: - raise LateArrivingTransaction( - f"request '{transaction.payload}' is from previous round; skipping" - ) - - if payload_class is not self.payload_class: - raise TransactionTypeNotRecognizedError( - f"request '{payload_class}' not recognized; only {self.payload_class} is supported" - ) - - def check_majority_possible_with_new_voter( - self, - votes_by_participant: Dict[str, BaseTxPayload], - new_voter: str, - new_vote: BaseTxPayload, - nb_participants: int, - exception_cls: Type[ABCIAppException] = ABCIAppException, - ) -> None: - """ - Check that a Byzantine majority is achievable, once a new vote is added. - - :param votes_by_participant: a mapping from a participant to its vote, - before the new vote is added - :param new_voter: the new voter - :param new_vote: the new vote - :param nb_participants: the total number of participants - :param exception_cls: the class of the exception to raise in case the - check fails. - :raises: exception_cls: in case the check does not pass. - """ - # check preconditions - enforce( - new_voter not in votes_by_participant, - "voter has already voted", - ABCIAppInternalError, - ) - enforce( - len(votes_by_participant) <= nb_participants - 1, - "nb_participants not consistent with votes_by_participants", - ABCIAppInternalError, - ) - - # copy the input dictionary to avoid side effects - votes_by_participant = copy(votes_by_participant) - - # add the new vote - votes_by_participant[new_voter] = new_vote - - self.check_majority_possible( - votes_by_participant, nb_participants, exception_cls=exception_cls - ) - - def check_majority_possible( - self, - votes_by_participant: Dict[str, BaseTxPayload], - nb_participants: int, - exception_cls: Type[ABCIAppException] = ABCIAppException, - ) -> None: - """ - Check that a Byzantine majority is still achievable. - - The idea is that, even if all the votes have not been delivered yet, - it can be deduced whether a quorum cannot be reached due to - divergent preferences among the voters and due to a too small - number of other participants whose vote has not been delivered yet. - - The check fails iff: - - nb_remaining_votes + largest_nb_votes < quorum - - That is, if the number of remaining votes is not enough to make - the most voted item so far to exceed the quorum. - - Preconditions on the input: - - the size of votes_by_participant should not be greater than - "nb_participants - 1" voters - - new voter must not be in the current votes_by_participant - - :param votes_by_participant: a mapping from a participant to its vote - :param nb_participants: the total number of participants - :param exception_cls: the class of the exception to raise in case the - check fails. - :raises exception_cls: in case the check does not pass. - """ - enforce( - nb_participants > 0 and len(votes_by_participant) <= nb_participants, - "nb_participants not consistent with votes_by_participants", - ABCIAppInternalError, - ) - if len(votes_by_participant) == 0: - return - - votes = votes_by_participant.values() - vote_count = Counter(tuple(sorted(v.data.items())) for v in votes) - largest_nb_votes = max(vote_count.values()) - nb_votes_received = sum(vote_count.values()) - nb_remaining_votes = nb_participants - nb_votes_received - - if ( - nb_remaining_votes + largest_nb_votes - < self.synchronized_data.consensus_threshold - ): - raise exception_cls( - f"cannot reach quorum={self.synchronized_data.consensus_threshold}, " - f"number of remaining votes={nb_remaining_votes}, number of most voted item's votes={largest_nb_votes}" - ) - - def is_majority_possible( - self, votes_by_participant: Dict[str, BaseTxPayload], nb_participants: int - ) -> bool: - """ - Return true if a Byzantine majority is achievable, false otherwise. - - :param votes_by_participant: a mapping from a participant to its vote - :param nb_participants: the total number of participants - :return: True if the majority is still possible, false otherwise. - """ - try: - self.check_majority_possible(votes_by_participant, nb_participants) - except ABCIAppException: - return False - return True - - @abstractmethod - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - - @abstractmethod - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - - -class DegenerateRound(AbstractRound, ABC): - """ - This class represents the finished round during operation. - - It is a sink round. - """ - - payload_class = None - synchronized_data_class = BaseSynchronizedData - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - raise NotImplementedError( # pragma: nocover - "DegenerateRound should not be used in operation." - ) - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - raise NotImplementedError( # pragma: nocover - "DegenerateRound should not be used in operation." - ) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """End block.""" - raise NotImplementedError( # pragma: nocover - "DegenerateRound should not be used in operation." - ) - - -class CollectionRound(AbstractRound, ABC): - """ - CollectionRound. - - This class represents abstract logic for collection based rounds where - the round object needs to collect data from different agents. The data - might for example be from a voting round or estimation round. - - `_allow_rejoin_payloads` is used to allow agents not currently active to - deliver a payload. - """ - - _allow_rejoin_payloads: bool = False - - def __init__(self, *args: Any, **kwargs: Any): - """Initialize the collection round.""" - super().__init__(*args, **kwargs) - self.collection: Dict[str, BaseTxPayload] = {} - - @staticmethod - def serialize_collection( - collection: DeserializedCollection, - ) -> SerializedCollection: - """Deserialize a serialized collection.""" - return {address: payload.json for address, payload in collection.items()} - - @staticmethod - def deserialize_collection( - serialized: SerializedCollection, - ) -> DeserializedCollection: - """Deserialize a serialized collection.""" - return { - address: BaseTxPayload.from_json(payload_json) - for address, payload_json in serialized.items() - } - - @property - def serialized_collection(self) -> SerializedCollection: - """A collection with the addresses mapped to serialized payloads.""" - return self.serialize_collection(self.collection) - - @property - def accepting_payloads_from(self) -> FrozenSet[str]: - """Accepting from the active set, or also from (re)joiners""" - if self._allow_rejoin_payloads: - return self.synchronized_data.all_participants - return self.synchronized_data.participants - - @property - def payloads(self) -> List[BaseTxPayload]: - """Get all agent payloads""" - return list(self.collection.values()) - - @property - def payload_values_count(self) -> Counter: - """Get count of payload values.""" - return Counter(map(lambda p: p.values, self.payloads)) - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - if payload.round_count != self.synchronized_data.round_count: - raise ABCIAppInternalError( - f"Expected round count {self.synchronized_data.round_count} and got {payload.round_count}." - ) - - sender = payload.sender - if sender not in self.accepting_payloads_from: - raise ABCIAppInternalError( - f"{sender} not in list of participants: {sorted(self.accepting_payloads_from)}" - ) - - if sender in self.collection: - raise ABCIAppInternalError( - f"sender {sender} has already sent value for round: {self.round_id}" - ) - - self.collection[sender] = payload - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check Payload""" - - # NOTE: the TransactionNotValidError is intercepted in ABCIRoundHandler.deliver_tx - # which means it will be logged instead of raised - if payload.round_count != self.synchronized_data.round_count: - raise TransactionNotValidError( - f"Expected round count {self.synchronized_data.round_count} and got {payload.round_count}." - ) - - sender_in_participant_set = payload.sender in self.accepting_payloads_from - if not sender_in_participant_set: - raise TransactionNotValidError( - f"{payload.sender} not in list of participants: {sorted(self.accepting_payloads_from)}" - ) - - if payload.sender in self.collection: - raise TransactionNotValidError( - f"sender {payload.sender} has already sent value for round: {self.round_id}" - ) - - -class _CollectUntilAllRound(CollectionRound, ABC): - """ - _CollectUntilAllRound - - This class represents abstract logic for when rounds need to collect payloads from all agents. - - This round should only be used when non-BFT behaviour is acceptable. - """ - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check Payload""" - if payload.round_count != self.synchronized_data.round_count: - raise TransactionNotValidError( - f"Expected round count {self.synchronized_data.round_count} and got {payload.round_count}." - ) - - if payload.sender in self.collection: - raise TransactionNotValidError( - f"sender {payload.sender} has already sent value for round: {self.round_id}" - ) - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - try: - self.check_payload(payload) - except TransactionNotValidError as e: - raise ABCIAppInternalError(e.args[0]) from e - - self.collection[payload.sender] = payload - - @property - def collection_threshold_reached( - self, - ) -> bool: - """Check that the collection threshold has been reached.""" - return len(self.collection) >= self.synchronized_data.max_participants - - -class CollectDifferentUntilAllRound(_CollectUntilAllRound, ABC): - """ - CollectDifferentUntilAllRound - - This class represents logic for rounds where a round needs to collect - different payloads from each agent. - - This round should only be used for registration of new agents when there is synchronization of the db. - """ - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check Payload""" - new = payload.values - existing = [payload_.values for payload_ in self.collection.values()] - - if payload.sender not in self.collection and new in existing: - raise TransactionNotValidError( - f"`CollectDifferentUntilAllRound` encountered a value '{new}' that already exists. " - f"All values: {existing}" - ) - - super().check_payload(payload) - - -class CollectSameUntilAllRound(_CollectUntilAllRound, ABC): - """ - This class represents logic for when a round needs to collect the same payload from all the agents. - - This round should only be used for registration of new agents when there is no synchronization of the db. - """ - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check Payload""" - new = payload.values - existing_ = [payload_.values for payload_ in self.collection.values()] - - if ( - payload.sender not in self.collection - and len(self.collection) - and new not in existing_ - ): - raise TransactionNotValidError( - f"`CollectSameUntilAllRound` encountered a value '{new}' " - f"which is not the same as the already existing one: '{existing_[0]}'" - ) - - super().check_payload(payload) - - @property - def common_payload( - self, - ) -> Any: - """Get the common payload among the agents.""" - return self.common_payload_values[0] - - @property - def common_payload_values( - self, - ) -> Tuple[Any, ...]: - """Get the common payload among the agents.""" - most_common_payload_values, max_votes = self.payload_values_count.most_common( - 1 - )[0] - if max_votes < self.synchronized_data.max_participants: - raise ABCIAppInternalError( - f"{max_votes} votes are not enough for `CollectSameUntilAllRound`. Expected: " - f"`n_votes = max_participants = {self.synchronized_data.max_participants}`" - ) - return most_common_payload_values - - -class CollectSameUntilThresholdRound(CollectionRound, ABC): - """ - CollectSameUntilThresholdRound - - This class represents logic for rounds where a round needs to collect - same payload from k of n agents. - - `done_event` is emitted when a) the collection threshold (k of n) is reached, - and b) the most voted payload has non-empty attributes. In this case all - payloads are saved under `collection_key` and the most voted payload attributes - are saved under `selection_key`. - - `none_event` is emitted when a) the collection threshold (k of n) is reached, - and b) the most voted payload has only empty attributes. - - `no_majority_event` is emitted when it is impossible to reach a k of n majority. - """ - - done_event: Any - no_majority_event: Any - none_event: Any - collection_key: str - selection_key: Union[str, Tuple[str, ...]] - - @property - def threshold_reached( - self, - ) -> bool: - """Check if the threshold has been reached.""" - counts = self.payload_values_count.values() - return any( - count >= self.synchronized_data.consensus_threshold for count in counts - ) - - @property - def most_voted_payload( - self, - ) -> Any: - """ - Get the most voted payload value. - - Kept for backward compatibility. - """ - return self.most_voted_payload_values[0] - - @property - def most_voted_payload_values( - self, - ) -> Tuple[Any, ...]: - """Get the most voted payload values.""" - most_voted_payload_values, max_votes = self.payload_values_count.most_common()[ - 0 - ] - if max_votes < self.synchronized_data.consensus_threshold: - raise ABCIAppInternalError("not enough votes") - return most_voted_payload_values - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.threshold_reached and any( - [val is not None for val in self.most_voted_payload_values] - ): - if isinstance(self.selection_key, tuple): - data = dict(zip(self.selection_key, self.most_voted_payload_values)) - data[self.collection_key] = self.serialized_collection - else: - data = { - self.collection_key: self.serialized_collection, - self.selection_key: self.most_voted_payload, - } - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **data, - ) - return synchronized_data, self.done_event - if self.threshold_reached and not any( - [val is not None for val in self.most_voted_payload_values] - ): - return self.synchronized_data, self.none_event - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, self.no_majority_event - return None - - -class OnlyKeeperSendsRound(AbstractRound, ABC): - """ - OnlyKeeperSendsRound - - This class represents logic for rounds where only one agent sends a - payload. - - `done_event` is emitted when a) the keeper payload has been received and b) - the keeper payload has non-empty attributes. In this case all attributes are saved - under `payload_key`. - - `fail_event` is emitted when a) the keeper payload has been received and b) - the keeper payload has only empty attributes - """ - - keeper_payload: Optional[BaseTxPayload] = None - done_event: Any - fail_event: Any - payload_key: Union[str, Tuple[str, ...]] - - def process_payload(self, payload: BaseTxPayload) -> None: - """Handle a deploy safe payload.""" - if payload.round_count != self.synchronized_data.round_count: - raise ABCIAppInternalError( - f"Expected round count {self.synchronized_data.round_count} and got {payload.round_count}." - ) - - sender = payload.sender - - if sender not in self.synchronized_data.participants: - raise ABCIAppInternalError( - f"{sender} not in list of participants: {sorted(self.synchronized_data.participants)}" - ) - - if sender != self.synchronized_data.most_voted_keeper_address: - raise ABCIAppInternalError(f"{sender} not elected as keeper.") - - if self.keeper_payload is not None: - raise ABCIAppInternalError("keeper already set the payload.") - - self.keeper_payload = payload - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check a deploy safe payload can be applied to the current state.""" - if payload.round_count != self.synchronized_data.round_count: - raise TransactionNotValidError( - f"Expected round count {self.synchronized_data.round_count} and got {payload.round_count}." - ) - - sender = payload.sender - sender_in_participant_set = sender in self.synchronized_data.participants - if not sender_in_participant_set: - raise TransactionNotValidError( - f"{sender} not in list of participants: {sorted(self.synchronized_data.participants)}" - ) - - sender_is_elected_sender = ( - sender == self.synchronized_data.most_voted_keeper_address - ) - if not sender_is_elected_sender: - raise TransactionNotValidError(f"{sender} not elected as keeper.") - - if self.keeper_payload is not None: - raise TransactionNotValidError("keeper payload value already set.") - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.keeper_payload is not None and any( - [val is not None for val in self.keeper_payload.values] - ): - if isinstance(self.payload_key, tuple): - data = dict(zip(self.payload_key, self.keeper_payload.values)) - else: - data = { - self.payload_key: self.keeper_payload.values[0], - } - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **data, - ) - return synchronized_data, self.done_event - if self.keeper_payload is not None and not any( - [val is not None for val in self.keeper_payload.values] - ): - return self.synchronized_data, self.fail_event - return None - - -class VotingRound(CollectionRound, ABC): - """ - VotingRound - - This class represents logic for rounds where a round needs votes from - agents. Votes are in the form of `True` (positive), `False` (negative) - and `None` (abstain). The round ends when k of n agents make the same vote. - - `done_event` is emitted when a) the collection threshold (k of n) is reached - with k positive votes. In this case all payloads are saved under `collection_key`. - - `negative_event` is emitted when a) the collection threshold (k of n) is reached - with k negative votes. - - `none_event` is emitted when a) the collection threshold (k of n) is reached - with k abstain votes. - - `no_majority_event` is emitted when it is impossible to reach a k of n majority for - either of the options. - """ - - done_event: Any - negative_event: Any - none_event: Any - no_majority_event: Any - collection_key: str - - @property - def vote_count(self) -> Counter: - """Get agent payload vote count""" - - def parse_payload(payload: Any) -> Optional[bool]: - if not hasattr(payload, "vote"): - raise ValueError(f"payload {payload} has no attribute `vote`") - return payload.vote - - return Counter(parse_payload(payload) for payload in self.collection.values()) - - @property - def positive_vote_threshold_reached(self) -> bool: - """Check that the vote threshold has been reached.""" - return self.vote_count[True] >= self.synchronized_data.consensus_threshold - - @property - def negative_vote_threshold_reached(self) -> bool: - """Check that the vote threshold has been reached.""" - return self.vote_count[False] >= self.synchronized_data.consensus_threshold - - @property - def none_vote_threshold_reached(self) -> bool: - """Check that the vote threshold has been reached.""" - return self.vote_count[None] >= self.synchronized_data.consensus_threshold - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.positive_vote_threshold_reached: - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{self.collection_key: self.serialized_collection}, - ) - return synchronized_data, self.done_event - if self.negative_vote_threshold_reached: - return self.synchronized_data, self.negative_event - if self.none_vote_threshold_reached: - return self.synchronized_data, self.none_event - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, self.no_majority_event - return None - - -class CollectDifferentUntilThresholdRound(CollectionRound, ABC): - """ - CollectDifferentUntilThresholdRound - - This class represents logic for rounds where a round needs to collect - different payloads from k of n agents. - - `done_event` is emitted when a) the required block confirmations - have been met, and b) the collection threshold (k of n) is reached. In - this case all payloads are saved under `collection_key`. - - Extended `required_block_confirmations` to allow for arrival of more - payloads. - """ - - done_event: Any - collection_key: str - required_block_confirmations: int = 0 - - @property - def collection_threshold_reached( - self, - ) -> bool: - """Check if the threshold has been reached.""" - return len(self.collection) >= self.synchronized_data.consensus_threshold - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.collection_threshold_reached: - self.block_confirmations += 1 - if ( - self.collection_threshold_reached - and self.block_confirmations > self.required_block_confirmations - ): - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{ - self.collection_key: self.serialized_collection, - }, - ) - return synchronized_data, self.done_event - - return None - - -class CollectNonEmptyUntilThresholdRound(CollectDifferentUntilThresholdRound, ABC): - """ - CollectNonEmptyUntilThresholdRound - - This class represents logic for rounds where a round needs to collect - optionally different payloads from k of n agents, where we only keep the non-empty attributes. - - `done_event` is emitted when a) the required block confirmations - have been met, b) the collection threshold (k of n) is reached, and - c) some non-empty attribute values have been collected. In this case - all payloads are saved under `collection_key`. Under `selection_key` - the non-empty attribute values are stored. - - `none_event` is emitted when a) the required block confirmations - have been met, b) the collection threshold (k of n) is reached, and - c) no non-empty attribute values have been collected. - - Attention: A `none_event` might be triggered even though some of the - remaining n-k agents might send non-empty attributes! Extended - `required_block_confirmations` can alleviate this somewhat. - """ - - none_event: Any - selection_key: Union[str, Tuple[str, ...]] - - def _get_non_empty_values(self) -> Dict[str, Tuple[Any, ...]]: - """Get the non-empty values from the payload, for all attributes.""" - non_empty_values: Dict[str, List[List[Any]]] = {} - - for sender, payload in self.collection.items(): - if sender not in non_empty_values: - non_empty_values[sender] = [ - value for value in payload.values if value is not None - ] - if len(non_empty_values[sender]) == 0: - del non_empty_values[sender] - continue - non_empty_values_ = { - sender: tuple(li) for sender, li in non_empty_values.items() - } - return non_empty_values_ - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.collection_threshold_reached: - self.block_confirmations += 1 - if ( - self.collection_threshold_reached - and self.block_confirmations > self.required_block_confirmations - ): - non_empty_values = self._get_non_empty_values() - - if isinstance(self.selection_key, tuple): - data: Dict[str, Any] = { - sender: dict(zip(self.selection_key, values)) - for sender, values in non_empty_values.items() - } - else: - data = { - self.selection_key: { - sender: values[0] for sender, values in non_empty_values.items() - }, - } - data[self.collection_key] = self.serialized_collection - - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **data, - ) - - if all([len(tu) == 0 for tu in non_empty_values]): - return self.synchronized_data, self.none_event - return synchronized_data, self.done_event - return None - - -AppState = Type[AbstractRound] -AbciAppTransitionFunction = Dict[AppState, Dict[EventType, AppState]] -EventToTimeout = Dict[EventType, float] - - -@dataclass(order=True) -class TimeoutEvent(Generic[EventType]): - """Timeout event.""" - - deadline: datetime.datetime - entry_count: int - event: EventType = field(compare=False) - cancelled: bool = field(default=False, compare=False) - - -class Timeouts(Generic[EventType]): - """Class to keep track of pending timeouts.""" - - def __init__(self) -> None: - """Initialize.""" - # The entry count serves as a tie-breaker so that two tasks with - # the same priority are returned in the order they were added - self._counter = itertools.count() - - # The timeout priority queue keeps the earliest deadline at the top. - self._heap: List[TimeoutEvent[EventType]] = [] - - # Mapping from entry id to task - self._entry_finder: Dict[int, TimeoutEvent[EventType]] = {} - - @property - def size(self) -> int: - """Get the size of the timeout queue.""" - return len(self._heap) - - def add_timeout(self, deadline: datetime.datetime, event: EventType) -> int: - """Add a timeout.""" - entry_count = next(self._counter) - timeout_event = TimeoutEvent[EventType](deadline, entry_count, event) - heapq.heappush(self._heap, timeout_event) - self._entry_finder[entry_count] = timeout_event - return entry_count - - def cancel_timeout(self, entry_count: int) -> None: - """ - Remove a timeout. - - :param entry_count: the entry id to remove. - :raises: KeyError: if the entry count is not found. - """ - if entry_count in self._entry_finder: - self._entry_finder[entry_count].cancelled = True - - def pop_earliest_cancelled_timeouts(self) -> None: - """Pop earliest cancelled timeouts.""" - if self.size == 0: - return - entry = self._heap[0] # heap peak - while entry.cancelled: - self.pop_timeout() - if self.size == 0: - break - entry = self._heap[0] - - def get_earliest_timeout(self) -> Tuple[datetime.datetime, Any]: - """Get the earliest timeout-event pair.""" - entry = self._heap[0] - return entry.deadline, entry.event - - def pop_timeout(self) -> Tuple[datetime.datetime, Any]: - """Remove and return the earliest timeout-event pair.""" - entry = heapq.heappop(self._heap) - del self._entry_finder[entry.entry_count] - return entry.deadline, entry.event - - -class _MetaAbciApp(ABCMeta): - """A metaclass that validates AbciApp's attributes.""" - - bg_round_added: bool = False - - def __new__(mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any) -> Type: # type: ignore - """Initialize the class.""" - new_cls = super().__new__(mcs, name, bases, namespace, **kwargs) - - if ABC in bases: - # abstract class, return - return new_cls - if not issubclass(new_cls, AbciApp): - # the check only applies to AbciApp subclasses - return new_cls - - if not mcs.bg_round_added: - mcs._add_pending_offences_bg_round(new_cls) - mcs.bg_round_added = True - - mcs._check_consistency(cast(Type[AbciApp], new_cls)) - - return new_cls - - @classmethod - def _check_consistency(mcs, abci_app_cls: Type["AbciApp"]) -> None: - """Check consistency of class attributes.""" - mcs._check_required_class_attributes(abci_app_cls) - mcs._check_initial_states_and_final_states(abci_app_cls) - mcs._check_consistency_outgoing_transitions_from_non_final_states(abci_app_cls) - mcs._check_db_constraints_consistency(abci_app_cls) - - @classmethod - def _check_required_class_attributes(mcs, abci_app_cls: Type["AbciApp"]) -> None: - """Check that required class attributes are set.""" - if not hasattr(abci_app_cls, "initial_round_cls"): - raise ABCIAppInternalError("'initial_round_cls' field not set") - if not hasattr(abci_app_cls, "transition_function"): - raise ABCIAppInternalError("'transition_function' field not set") - - @classmethod - def _check_initial_states_and_final_states( - mcs, - abci_app_cls: Type["AbciApp"], - ) -> None: - """ - Check that initial states and final states are consistent. - - I.e.: - - check that all the initial states are in the set of states specified - by the transition function. - - check that the initial state has outgoing transitions - - check that the initial state does not trigger timeout events. This is - because we need at least one block/timestamp to start timeouts. - - check that initial states are not final states. - - check that the set of final states is a proper subset of the set of - states. - - check that a final state does not have outgoing transitions. - - :param abci_app_cls: the AbciApp class - """ - initial_round_cls = abci_app_cls.initial_round_cls - initial_states = abci_app_cls.initial_states - transition_function = abci_app_cls.transition_function - final_states = abci_app_cls.final_states - states = abci_app_cls.get_all_rounds() - - enforce( - initial_states == set() or initial_round_cls in initial_states, - f"initial round class {initial_round_cls} is not in the set of " - f"initial states: {initial_states}", - ) - enforce( - initial_round_cls in states - and all(initial_state in states for initial_state in initial_states), - "initial states must be in the set of states", - ) - - true_initial_states = ( - initial_states if initial_states != set() else {initial_round_cls} - ) - enforce( - all( - initial_state not in final_states - for initial_state in true_initial_states - ), - "initial states cannot be final states", - ) - - unknown_final_states = set.difference(final_states, states) - enforce( - len(unknown_final_states) == 0, - f"the following final states are not in the set of states:" - f" {unknown_final_states}", - ) - - enforce( - all( - len(transition_function[final_state]) == 0 - for final_state in final_states - ), - "final states cannot have outgoing transitions", - ) - - enforce( - all( - issubclass(final_state, DegenerateRound) for final_state in final_states - ), - "final round classes must be subclasses of the DegenerateRound class", - ) - - @classmethod - def _check_db_constraints_consistency(mcs, abci_app_cls: Type["AbciApp"]) -> None: - """Check that the pre and post conditions on the db are consistent with the initial and final states.""" - expected = abci_app_cls.initial_states - actual = abci_app_cls.db_pre_conditions.keys() - is_pre_conditions_set = len(actual) != 0 - invalid_initial_states = ( - set.difference(expected, actual) if is_pre_conditions_set else set() - ) - enforce( - len(invalid_initial_states) == 0, - f"db pre conditions contain invalid initial states: {invalid_initial_states}", - ) - expected = abci_app_cls.final_states - actual = abci_app_cls.db_post_conditions.keys() - is_post_conditions_set = len(actual) != 0 - invalid_final_states = ( - set.difference(expected, actual) if is_post_conditions_set else set() - ) - enforce( - len(invalid_final_states) == 0, - f"db post conditions contain invalid final states: {invalid_final_states}", - ) - all_pre_conditions = { - value - for values in abci_app_cls.db_pre_conditions.values() - for value in values - } - all_post_conditions = { - value - for values in abci_app_cls.db_post_conditions.values() - for value in values - } - enforce( - len(all_pre_conditions.intersection(all_post_conditions)) == 0, - "db pre and post conditions intersect", - ) - intersection = abci_app_cls.default_db_preconditions.intersection( - all_pre_conditions - ) - enforce( - len(intersection) == 0, - f"db pre conditions contain value that is a default pre condition: {intersection}", - ) - intersection = abci_app_cls.default_db_preconditions.intersection( - all_post_conditions - ) - enforce( - len(intersection) == 0, - f"db post conditions contain value that is a default post condition: {intersection}", - ) - - @classmethod - def _check_consistency_outgoing_transitions_from_non_final_states( - mcs, abci_app_cls: Type["AbciApp"] - ) -> None: - """ - Check consistency of outgoing transitions from non-final states. - - In particular, check that all non-final states have: - - at least one non-timeout transition. - - at most one timeout transition - - :param abci_app_cls: the AbciApp class - """ - states = abci_app_cls.get_all_rounds() - event_to_timeout = abci_app_cls.event_to_timeout - - non_final_states = states.difference(abci_app_cls.final_states) - timeout_events = set(event_to_timeout.keys()) - for non_final_state in non_final_states: - outgoing_transitions = abci_app_cls.transition_function[non_final_state] - - outgoing_events = set(outgoing_transitions.keys()) - outgoing_timeout_events = set.intersection(outgoing_events, timeout_events) - outgoing_nontimeout_events = set.difference(outgoing_events, timeout_events) - - enforce( - len(outgoing_timeout_events) < 2, - f"non-final state {non_final_state} cannot have more than one " - f"outgoing timeout event, got: " - f"{', '.join(map(str, outgoing_timeout_events))}", - ) - enforce( - len(outgoing_nontimeout_events) > 0, - f"non-final state {non_final_state} must have at least one " - f"non-timeout transition", - ) - - @classmethod - def _add_pending_offences_bg_round(cls, abci_app_cls: Type["AbciApp"]) -> None: - """Add the pending offences synchronization background round.""" - config: BackgroundAppConfig = BackgroundAppConfig(PendingOffencesRound) - abci_app_cls.add_background_app(config) - - -class BackgroundAppType(Enum): - """ - The type of a background app. - - Please note that the values correspond to the priority in which the background apps should be processed - when updating rounds. - """ - - TERMINATING = 0 - EVER_RUNNING = 1 - NORMAL = 2 - INCORRECT = 3 - - @staticmethod - def correct_types() -> Set[str]: - """Return the correct types only.""" - return set(BackgroundAppType.__members__) - {BackgroundAppType.INCORRECT.name} - - -@dataclass(frozen=True) -class BackgroundAppConfig(Generic[EventType]): - """ - Necessary configuration for a background app. - - For a deeper understanding of the various types of background apps and how the config influences - the generated background app's type, please refer to the `BackgroundApp` class. - The `specify_type` method provides further insight on the subject matter. - """ - - # the class of the background round - round_cls: AppState - # the abci app of the background round - # the abci app must specify a valid transition function if the round is not of an ever-running type - abci_app: Optional[Type["AbciApp"]] = None - # the start event of the background round - # if no event or transition function is specified, then the round is running in the background forever - start_event: Optional[EventType] = None - # the end event of the background round - # if not specified, then the round is terminating the abci app - end_event: Optional[EventType] = None - - -class BackgroundApp(Generic[EventType]): - """A background app.""" - - def __init__( - self, - config: BackgroundAppConfig, - ) -> None: - """Initialize the BackgroundApp.""" - given_args = locals() - - self.config = config - self.round_cls: AppState = config.round_cls - self.transition_function: Optional[AbciAppTransitionFunction] = ( - config.abci_app.transition_function if config.abci_app is not None else None - ) - self.start_event: Optional[EventType] = config.start_event - self.end_event: Optional[EventType] = config.end_event - - self.type = self.specify_type() - if self.type == BackgroundAppType.INCORRECT: # pragma: nocover - raise ValueError( - f"Background app has not been initialized correctly with {given_args}. " - f"Cannot match with any of the possible background apps' types: {BackgroundAppType.correct_types()}" - ) - _logger.debug( - f"Created background app of type '{self.type}' using {given_args}." - ) - self._background_round: Optional[AbstractRound] = None - - def __eq__(self, other: Any) -> bool: # pragma: no cover - """Custom equality comparing operator.""" - if not isinstance(other, BackgroundApp): - return False - - return self.config == other.config - - def __hash__(self) -> int: - """Custom hashing operator""" - return hash(self.config) - - def specify_type(self) -> BackgroundAppType: - """Specify the type of the background app.""" - if ( - self.start_event is None - and self.end_event is None - and self.transition_function is None - ): - self.transition_function = {} - return BackgroundAppType.EVER_RUNNING - if ( - self.start_event is not None - and self.end_event is None - and self.transition_function is not None - ): - return BackgroundAppType.TERMINATING - if ( - self.start_event is not None - and self.end_event is not None - and self.transition_function is not None - ): - return BackgroundAppType.NORMAL - return BackgroundAppType.INCORRECT # pragma: nocover - - def setup( - self, initial_synchronized_data: BaseSynchronizedData, context: SkillContext - ) -> None: - """Set up the background round.""" - round_cls = cast(Type[AbstractRound], self.round_cls) - self._background_round = round_cls( - initial_synchronized_data, - context, - ) - - @property - def background_round(self) -> AbstractRound: - """Get the background round.""" - if self._background_round is None: # pragma: nocover - raise ValueError(f"Background round with class `{self.round_cls}` not set!") - return self._background_round - - def process_transaction(self, transaction: Transaction, dry: bool = False) -> bool: - """Process a transaction.""" - - payload_class = type(transaction.payload) - bg_payload_class = cast(AppState, self.round_cls).payload_class - if payload_class is bg_payload_class: - processor = ( - self.background_round.check_transaction - if dry - else self.background_round.process_transaction - ) - processor(transaction) - return True - return False - - -@dataclass -class TransitionBackup: - """Holds transition related information as a backup in case we want to transition back from a background app.""" - - round: Optional[AbstractRound] = None - round_cls: Optional[AppState] = None - transition_function: Optional[AbciAppTransitionFunction] = None - - -class AbciApp( - Generic[EventType], ABC, metaclass=_MetaAbciApp -): # pylint: disable=too-many-instance-attributes - """ - Base class for ABCI apps. - - Concrete classes of this class implement the ABCI App. - """ - - initial_round_cls: AppState - initial_states: Set[AppState] = set() - transition_function: AbciAppTransitionFunction - final_states: Set[AppState] = set() - event_to_timeout: EventToTimeout = {} - cross_period_persisted_keys: FrozenSet[str] = frozenset() - background_apps: Set[BackgroundApp] = set() - default_db_preconditions: Set[str] = BaseSynchronizedData.default_db_keys - db_pre_conditions: Dict[AppState, Set[str]] = {} - db_post_conditions: Dict[AppState, Set[str]] = {} - _is_abstract: bool = True - - def __init__( - self, - synchronized_data: BaseSynchronizedData, - logger: logging.Logger, - context: SkillContext, - ): - """Initialize the AbciApp.""" - - synchronized_data_class = self.initial_round_cls.synchronized_data_class - synchronized_data = synchronized_data_class(db=synchronized_data.db) - - self._initial_synchronized_data = synchronized_data - self.logger = logger - self.context = context - self._current_round_cls: Optional[AppState] = None - self._current_round: Optional[AbstractRound] = None - self._last_round: Optional[AbstractRound] = None - self._previous_rounds: List[AbstractRound] = [] - self._current_round_height: int = 0 - self._round_results: List[BaseSynchronizedData] = [] - self._last_timestamp: Optional[datetime.datetime] = None - self._current_timeout_entries: List[int] = [] - self._timeouts = Timeouts[EventType]() - self._transition_backup = TransitionBackup() - self._switched = False - - @classmethod - def is_abstract(cls) -> bool: - """Return if the abci app is abstract.""" - return cls._is_abstract - - @classmethod - def add_background_app( - cls, - config: BackgroundAppConfig, - ) -> Type["AbciApp"]: - """ - Sets the background related class variables. - - For a deeper understanding of the various types of background apps and how the inputs of this method influence - the generated background app's type, please refer to the `BackgroundApp` class. - The `specify_type` method provides further insight on the subject matter. - - :param config: the background app's configuration. - :return: the `AbciApp` with the new background app contained in the `background_apps` set. - """ - background_app: BackgroundApp = BackgroundApp(config) - cls.background_apps.add(background_app) - cross_period_keys = ( - config.abci_app.cross_period_persisted_keys - if config.abci_app is not None - else frozenset() - ) - cls.cross_period_persisted_keys = cls.cross_period_persisted_keys.union( - cross_period_keys - ) - return cls - - @property - def synchronized_data(self) -> BaseSynchronizedData: - """Return the current synchronized data.""" - latest_result = self.latest_result or self._initial_synchronized_data - if self._current_round_cls is None: - return latest_result - synchronized_data_class = self._current_round_cls.synchronized_data_class - result = ( - synchronized_data_class(db=latest_result.db) - if isclass(synchronized_data_class) - and issubclass(synchronized_data_class, BaseSynchronizedData) - else latest_result - ) - return result - - @classmethod - def get_all_rounds(cls) -> Set[AppState]: - """Get all the round states.""" - return set(cls.transition_function) - - @classmethod - def get_all_events(cls) -> Set[EventType]: - """Get all the events.""" - events: Set[EventType] = set() - for _, transitions in cls.transition_function.items(): - events.update(transitions.keys()) - return events - - @staticmethod - def _get_rounds_from_transition_function( - transition_function: Optional[AbciAppTransitionFunction], - ) -> Set[AppState]: - """Get rounds from a transition function.""" - if transition_function is None: - return set() - result: Set[AppState] = set() - for start, transitions in transition_function.items(): - result.add(start) - result.update(transitions.values()) - return result - - @classmethod - def get_all_round_classes( - cls, - bg_round_cls: Set[Type[AbstractRound]], - include_background_rounds: bool = False, - ) -> Set[AppState]: - """Get all round classes.""" - full_fn = deepcopy(cls.transition_function) - - if include_background_rounds: - for app in cls.background_apps: - if ( - app.type != BackgroundAppType.EVER_RUNNING - and app.round_cls in bg_round_cls - ): - transition_fn = cast( - AbciAppTransitionFunction, app.transition_function - ) - full_fn.update(transition_fn) - - return cls._get_rounds_from_transition_function(full_fn) - - @property - def bg_apps_prioritized(self) -> Tuple[List[BackgroundApp], ...]: - """Get the background apps grouped and prioritized by their types.""" - n_correct_types = len(BackgroundAppType.correct_types()) - grouped_prioritized: Tuple[List, ...] = ([],) * n_correct_types - for app in self.background_apps: - # reminder: the values correspond to the priority of the background apps - for priority in range(n_correct_types): - if app.type == BackgroundAppType(priority): - grouped_prioritized[priority].append(app) - - return grouped_prioritized - - @property - def last_timestamp(self) -> datetime.datetime: - """Get last timestamp.""" - if self._last_timestamp is None: - raise ABCIAppInternalError("last timestamp is None") - return self._last_timestamp - - def _setup_background(self) -> None: - """Set up the background rounds.""" - for app in self.background_apps: - app.setup(self._initial_synchronized_data, self.context) - - def _get_synced_value( - self, - db_key: str, - sync_classes: Set[Type[BaseSynchronizedData]], - default: Any = None, - ) -> Any: - """Get the value of a specific database key using the synchronized data.""" - for cls in sync_classes: - # try to find the value using the synchronized data as suggested in #2131 - synced_data = cls(db=self.synchronized_data.db) - try: - res = getattr(synced_data, db_key) - except AttributeError: - # if the property does not exist in the db try the next synced data class - continue - except ValueError: - # if the property raised because of using `get_strict` and the key not being present in the db - break - - # if there is a property with the same name as the key in the db, return the result, normalized - return AbciAppDB.normalize(res) - - # as a last resort, try to get the value from the db - return self.synchronized_data.db.get(db_key, default) - - def setup(self) -> None: - """Set up the behaviour.""" - self.schedule_round(self.initial_round_cls) - self._setup_background() - # iterate through all the rounds and get all the unique synced data classes - sync_classes = { - _round.synchronized_data_class for _round in self.transition_function - } - # Add `BaseSynchronizedData` in case it does not exist (TODO: investigate and remove as it might always exist) - sync_classes.add(BaseSynchronizedData) - # set the cross-period persisted keys; avoid raising when the first period ends without a key in the db - update = { - db_key: self._get_synced_value(db_key, sync_classes) - for db_key in self.cross_period_persisted_keys - } - self.synchronized_data.db.update(**update) - - def _log_start(self) -> None: - """Log the entering in the round.""" - self.logger.info( - f"Entered in the '{self.current_round.round_id}' round for period " - f"{self.synchronized_data.period_count}" - ) - - def _log_end(self, event: EventType) -> None: - """Log the exiting from the round.""" - self.logger.info( - f"'{self.current_round.round_id}' round is done with event: {event}" - ) - - def _extend_previous_rounds_with_current_round(self) -> None: - self._previous_rounds.append(self.current_round) - self._current_round_height += 1 - - def schedule_round(self, round_cls: AppState) -> None: - """ - Schedule a round class. - - this means: - - cancel timeout events belonging to the current round; - - instantiate the new round class and set it as current round; - - create new timeout events and schedule them according to the latest - timestamp. - - :param round_cls: the class of the new round. - """ - self.logger.debug("scheduling new round: %s", round_cls) - for entry_id in self._current_timeout_entries: - self._timeouts.cancel_timeout(entry_id) - - self._current_timeout_entries = [] - next_events = list(self.transition_function.get(round_cls, {}).keys()) - for event in next_events: - timeout = self.event_to_timeout.get(event, None) - # if first round, last_timestamp is None. - # This means we do not schedule timeout events, - # but we allow timeout events from the initial state - # in case of concatenation. - if timeout is not None and self._last_timestamp is not None: - # last timestamp can be in the past relative to last seen block - # time if we're scheduling from within update_time - deadline = self.last_timestamp + datetime.timedelta(0, timeout) - entry_id = self._timeouts.add_timeout(deadline, event) - self.logger.debug( - "scheduling timeout of %s seconds for event %s with deadline %s", - timeout, - event, - deadline, - ) - self._current_timeout_entries.append(entry_id) - - self._last_round = self._current_round - self._current_round_cls = round_cls - self._current_round = round_cls( - self.synchronized_data, - self.context, - ( - self._last_round.payload_class - if self._last_round is not None - and self._last_round.payload_class - != self._current_round_cls.payload_class - # when transitioning to a round with the same payload type we set None - # as otherwise it will allow no tx to be submitted - else None - ), - ) - self._log_start() - self.synchronized_data.db.increment_round_count() # ROUND_COUNT_DEFAULT is -1 - - @property - def current_round(self) -> AbstractRound: - """Get the current round.""" - if self._current_round is None: - raise ValueError("current_round not set!") - return self._current_round - - @property - def current_round_id(self) -> Optional[str]: - """Get the current round id.""" - return self._current_round.round_id if self._current_round else None - - @property - def current_round_height(self) -> int: - """Get the current round height.""" - return self._current_round_height - - @property - def last_round_id(self) -> Optional[str]: - """Get the last round id.""" - return self._last_round.round_id if self._last_round else None - - @property - def is_finished(self) -> bool: - """Check whether the AbciApp execution has finished.""" - return self._current_round is None - - @property - def latest_result(self) -> Optional[BaseSynchronizedData]: - """Get the latest result of the round.""" - return None if len(self._round_results) == 0 else self._round_results[-1] - - def cleanup_timeouts(self) -> None: - """ - Remove all timeouts. - - Note that this is method is meant to be used only when performing recovery. - Calling it in normal execution will result in unexpected behaviour. - """ - self._timeouts = Timeouts[EventType]() - self._current_timeout_entries = [] - self._last_timestamp = None - - def check_transaction(self, transaction: Transaction) -> None: - """Check a transaction.""" - - self.process_transaction(transaction, dry=True) - - def process_transaction(self, transaction: Transaction, dry: bool = False) -> None: - """ - Process a transaction. - - The background rounds run concurrently with other (normal) rounds. - First we check if the transaction is meant for a background round, - if not we forward it to the current round object. - - :param transaction: the transaction. - :param dry: whether the transaction should only be checked and not processed. - """ - - for app in self.background_apps: - processed = app.process_transaction(transaction, dry) - if processed: - return - - processor = ( - self.current_round.check_transaction - if dry - else self.current_round.process_transaction - ) - processor(transaction) - - def _resolve_bg_transition( - self, app: BackgroundApp, event: EventType - ) -> Tuple[bool, Optional[AppState]]: - """ - Resolve a background app's transition. - - First check whether the event is a special start event. - If that's the case, proceed with the corresponding background app's transition function, - regardless of what the current round is. - - :param app: the background app instance. - :param event: the event for the transition. - :return: the new app state. - """ - - if ( - app.type in (BackgroundAppType.NORMAL, BackgroundAppType.TERMINATING) - and event == app.start_event - ): - app.transition_function = cast( - AbciAppTransitionFunction, app.transition_function - ) - app.round_cls = cast(AppState, app.round_cls) - next_round_cls = app.transition_function[app.round_cls].get(event, None) - if next_round_cls is None: # pragma: nocover - return True, None - - # we backup the current round so we can return back to normal, in case the end event is received later - self._transition_backup.round = self._current_round - self._transition_backup.round_cls = self._current_round_cls - # we switch the current transition function, with the background app's transition function - self._transition_backup.transition_function = deepcopy( - self.transition_function - ) - self.transition_function = app.transition_function - self.logger.info( - f"The {event} event was produced, transitioning to " - f"`{next_round_cls.auto_round_id()}`." - ) - return True, next_round_cls - - return False, None - - def _adjust_transition_fn(self, event: EventType) -> None: - """ - Adjust the transition function if necessary. - - Check whether the event is a special end event. - If that's the case, reset the transition function back to normal. - This method is meant to be called after resolving the next round transition, given an event. - - :param event: the emitted event. - """ - if self._transition_backup.transition_function is None: - return - - for app in self.background_apps: - if app.type == BackgroundAppType.NORMAL and event == app.end_event: - self._current_round = self._transition_backup.round - self._transition_backup.round = None - self._current_round_cls = self._transition_backup.round_cls - self._transition_backup.round_cls = None - backup_fn = cast( - AbciAppTransitionFunction, - self._transition_backup.transition_function, - ) - self.transition_function = deepcopy(backup_fn) - self._transition_backup.transition_function = None - self._switched = True - self.logger.info( - f"The {app.end_event} event was produced. Switching back to the normal FSM." - ) - - def _resolve_transition(self, event: EventType) -> Optional[Type[AbstractRound]]: - """Resolve the transitioning based on the given event.""" - for app in self.background_apps: - matched, next_round_cls = self._resolve_bg_transition(app, event) - if matched: - return next_round_cls - - self._adjust_transition_fn(event) - - current_round_cls = cast(AppState, self._current_round_cls) - next_round_cls = self.transition_function[current_round_cls].get(event, None) - if next_round_cls is None: - return None - - return next_round_cls - - def process_event( - self, event: EventType, result: Optional[BaseSynchronizedData] = None - ) -> None: - """Process a round event.""" - if self._current_round_cls is None: - self.logger.warning( - f"Cannot process event '{event}' as current state is not set" - ) - return - - next_round_cls = self._resolve_transition(event) - self._extend_previous_rounds_with_current_round() - # if there is no result, we duplicate the state since the round was preemptively ended - result = self.current_round.synchronized_data if result is None else result - self._round_results.append(result) - - self._log_end(event) - if next_round_cls is not None: - self.schedule_round(next_round_cls) - return - - if self._switched: - self._switched = False - return - - self.logger.warning("AbciApp has reached a dead end.") - self._current_round_cls = None - self._current_round = None - - def update_time(self, timestamp: datetime.datetime) -> None: - """ - Observe timestamp from last block. - - :param timestamp: the latest block's timestamp. - """ - self.logger.debug("arrived block with timestamp: %s", timestamp) - self.logger.debug("current AbciApp time: %s", self._last_timestamp) - self._timeouts.pop_earliest_cancelled_timeouts() - - if self._timeouts.size == 0: - # if no pending timeouts, then it is safe to - # move forward the last known timestamp to the - # latest block's timestamp. - self.logger.debug("no pending timeout, move time forward") - self._last_timestamp = timestamp - return - - earliest_deadline, _ = self._timeouts.get_earliest_timeout() - while earliest_deadline <= timestamp: - # the earliest deadline is expired. Pop it from the - # priority queue and process the timeout event. - expired_deadline, timeout_event = self._timeouts.pop_timeout() - self.logger.warning( - "expired deadline %s with event %s at AbciApp time %s", - expired_deadline, - timeout_event, - timestamp, - ) - - # the last timestamp now becomes the expired deadline - # clearly, it is earlier than the current highest known - # timestamp that comes from the consensus engine. - # However, we need it to correctly simulate the timeouts - # of the next rounds. (for now we set it to timestamp to explore - # the impact) - self._last_timestamp = timestamp - self.logger.warning( - "current AbciApp time after expired deadline: %s", self.last_timestamp - ) - - self.process_event(timeout_event) - - self._timeouts.pop_earliest_cancelled_timeouts() - if self._timeouts.size == 0: - break - earliest_deadline, _ = self._timeouts.get_earliest_timeout() - - # at this point, there is no timeout event left to be triggered, - # so it is safe to move forward the last known timestamp to the - # new block's timestamp - self._last_timestamp = timestamp - self.logger.debug("final AbciApp time: %s", self._last_timestamp) - - def cleanup( - self, - cleanup_history_depth: int, - cleanup_history_depth_current: Optional[int] = None, - ) -> None: - """Clear data.""" - if len(self._round_results) != len(self._previous_rounds): - raise ABCIAppInternalError("Inconsistent round lengths") # pragma: nocover - # we need at least the last round result, and for symmetry we impose the same condition - # on previous rounds and state.db - cleanup_history_depth = max(cleanup_history_depth, MIN_HISTORY_DEPTH) - self._previous_rounds = self._previous_rounds[-cleanup_history_depth:] - self._round_results = self._round_results[-cleanup_history_depth:] - self.synchronized_data.db.cleanup( - cleanup_history_depth, cleanup_history_depth_current - ) - - def cleanup_current_histories(self, cleanup_history_depth_current: int) -> None: - """Reset the parameter histories for the current entry (period), keeping only the latest values for each parameter.""" - self.synchronized_data.db.cleanup_current_histories( - cleanup_history_depth_current - ) - - -class OffenseType(Enum): - """ - The types of offenses. - - The values of the enum represent the seriousness of the offence. - Offense types with values >1000 are considered serious. - See also `is_light_offence` and `is_serious_offence` functions. - """ - - NO_OFFENCE = -2 - CUSTOM = -1 - VALIDATOR_DOWNTIME = 0 - INVALID_PAYLOAD = 1 - BLACKLISTED = 2 - SUSPECTED = 3 - UNKNOWN = SERIOUS_OFFENCE_ENUM_MIN - DOUBLE_SIGNING = SERIOUS_OFFENCE_ENUM_MIN + 1 - LIGHT_CLIENT_ATTACK = SERIOUS_OFFENCE_ENUM_MIN + 2 - - -def is_light_offence(offence_type: OffenseType) -> bool: - """Check if an offence type is light.""" - return 0 <= offence_type.value < SERIOUS_OFFENCE_ENUM_MIN - - -def is_serious_offence(offence_type: OffenseType) -> bool: - """Check if an offence type is serious.""" - return offence_type.value >= SERIOUS_OFFENCE_ENUM_MIN - - -def light_offences() -> Iterator[OffenseType]: - """Get the light offences.""" - return filter(is_light_offence, OffenseType) - - -def serious_offences() -> Iterator[OffenseType]: - """Get the serious offences.""" - return filter(is_serious_offence, OffenseType) - - -class AvailabilityWindow: - """ - A cyclic array with a maximum length that holds boolean values. - - When an element is added to the array and the maximum length has been reached, - the oldest element is removed. Two attributes `num_positive` and `num_negative` - reflect the number of positive and negative elements in the AvailabilityWindow, - they are updated every time a new element is added. - """ - - def __init__(self, max_length: int) -> None: - """ - Initializes the `AvailabilityWindow` instance. - - :param max_length: the maximum length of the cyclic array. - """ - if max_length < 1: - raise ValueError( - f"An `AvailabilityWindow` with a `max_length` {max_length} < 1 is not valid." - ) - - self._max_length = max_length - self._window: Deque[bool] = deque(maxlen=max_length) - self._num_positive = 0 - self._num_negative = 0 - - def __eq__(self, other: Any) -> bool: - """Compare `AvailabilityWindow` objects.""" - if isinstance(other, AvailabilityWindow): - return self.to_dict() == other.to_dict() - return False - - def has_bad_availability_rate(self, threshold: float = 0.95) -> bool: - """Whether the agent on which the window belongs to has a bad availability rate or not.""" - return self._num_positive >= ceil(self._max_length * threshold) - - def _update_counters(self, positive: bool, removal: bool = False) -> None: - """Updates the `num_positive` and `num_negative` counters.""" - update_amount = -1 if removal else 1 - - if positive: - if self._num_positive == 0 and update_amount == -1: # pragma: no cover - return - self._num_positive += update_amount - else: - if self._num_negative == 0 and update_amount == -1: # pragma: no cover - return - self._num_negative += update_amount - - def add(self, value: bool) -> None: - """ - Adds a new boolean value to the cyclic array. - - If the maximum length has been reached, the oldest element is removed. - - :param value: The boolean value to add to the cyclic array. - """ - if len(self._window) == self._max_length and self._max_length > 0: - # we have filled the window, we need to pop the oldest element - # and update the score accordingly - oldest_value = self._window.popleft() - self._update_counters(oldest_value, removal=True) - - self._window.append(value) - self._update_counters(value) - - def to_dict(self) -> Dict[str, int]: - """Returns a dictionary representation of the `AvailabilityWindow` instance.""" - return { - "max_length": self._max_length, - # Please note that the value cannot be represented if the max length of the availability window is > 14_285 - "array": ( - int("".join(str(int(flag)) for flag in self._window), base=2) - if len(self._window) - else 0 - ), - "num_positive": self._num_positive, - "num_negative": self._num_negative, - } - - @staticmethod - def _validate_key( - data: Dict[str, int], key: str, validator: Callable[[int], bool] - ) -> None: - """Validate the given key in the data.""" - value = data.get(key, None) - if value is None: - raise ValueError(f"Missing required key: {key}.") - - if not isinstance(value, int): - raise ValueError(f"{key} must be of type int.") - - if not validator(value): - raise ValueError(f"{key} has invalid value {value}.") - - @staticmethod - def _validate(data: Dict[str, int]) -> None: - """Check if the input can be properly mapped to the class attributes.""" - if not isinstance(data, dict): - raise TypeError(f"Expected dict, got {type(data)}") - - attribute_to_validator = { - "max_length": lambda x: x > 0, - "array": lambda x: 0 <= x < 2 ** data["max_length"], - "num_positive": lambda x: x >= 0, - "num_negative": lambda x: x >= 0, - } - - errors = [] - for attribute, validator in attribute_to_validator.items(): - try: - AvailabilityWindow._validate_key(data, attribute, validator) - except ValueError as e: - errors.append(str(e)) - - if errors: - raise ValueError("Invalid input:\n" + "\n".join(errors)) - - @classmethod - def from_dict(cls, data: Dict[str, int]) -> "AvailabilityWindow": - """Initializes an `AvailabilityWindow` instance from a dictionary.""" - cls._validate(data) - - # convert the serialized array to a binary string - binary_number = bin(data["array"])[2:] - # convert each character in the binary string to a flag - flags = (bool(int(digit)) for digit in binary_number) - - instance = cls(max_length=data["max_length"]) - instance._window.extend(flags) - instance._num_positive = data["num_positive"] - instance._num_negative = data["num_negative"] - return instance - - -@dataclass -class OffenceStatus: - """A class that holds information about offence status for an agent.""" - - validator_downtime: AvailabilityWindow = field( - default_factory=lambda: AvailabilityWindow(NUMBER_OF_BLOCKS_TRACKED) - ) - invalid_payload: AvailabilityWindow = field( - default_factory=lambda: AvailabilityWindow(NUMBER_OF_ROUNDS_TRACKED) - ) - blacklisted: AvailabilityWindow = field( - default_factory=lambda: AvailabilityWindow(NUMBER_OF_ROUNDS_TRACKED) - ) - suspected: AvailabilityWindow = field( - default_factory=lambda: AvailabilityWindow(NUMBER_OF_ROUNDS_TRACKED) - ) - num_unknown_offenses: int = 0 - num_double_signed: int = 0 - num_light_client_attack: int = 0 - custom_offences_amount: int = 0 - - def slash_amount(self, light_unit_amount: int, serious_unit_amount: int) -> int: - """Get the slash amount of the current status.""" - offence_types = [] - - if self.validator_downtime.has_bad_availability_rate(): - offence_types.append(OffenseType.VALIDATOR_DOWNTIME) - if self.invalid_payload.has_bad_availability_rate(): - offence_types.append(OffenseType.INVALID_PAYLOAD) - if self.blacklisted.has_bad_availability_rate(): - offence_types.append(OffenseType.BLACKLISTED) - if self.suspected.has_bad_availability_rate(): - offence_types.append(OffenseType.SUSPECTED) - offence_types.extend([OffenseType.UNKNOWN] * self.num_unknown_offenses) - offence_types.extend([OffenseType.UNKNOWN] * self.num_double_signed) - offence_types.extend([OffenseType.UNKNOWN] * self.num_light_client_attack) - - light_multiplier = 0 - serious_multiplier = 0 - for offence_type in offence_types: - light_multiplier += bool(is_light_offence(offence_type)) - serious_multiplier += bool(is_serious_offence(offence_type)) - - return ( - light_multiplier * light_unit_amount - + serious_multiplier * serious_unit_amount - + self.custom_offences_amount - ) - - -class OffenseStatusEncoder(json.JSONEncoder): - """A custom JSON encoder for the offence status dictionary.""" - - def default(self, o: Any) -> Any: - """The default JSON encoder.""" - if is_dataclass(o): - return asdict(o) - if isinstance(o, AvailabilityWindow): - return o.to_dict() - return super().default(o) - - -class OffenseStatusDecoder(json.JSONDecoder): - """A custom JSON decoder for the offence status dictionary.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the custom JSON decoder.""" - super().__init__(object_hook=self.hook, *args, **kwargs) - - @staticmethod - def hook( - data: Dict[str, Any] - ) -> Union[AvailabilityWindow, OffenceStatus, Dict[str, OffenceStatus]]: - """Perform the custom decoding.""" - # if this is an `AvailabilityWindow` - window_attributes = sorted(AvailabilityWindow(1).to_dict().keys()) - if window_attributes == sorted(data.keys()): - return AvailabilityWindow.from_dict(data) - - # if this is an `OffenceStatus` - status_attributes = ( - OffenceStatus.__annotations__.keys() # pylint: disable=no-member - ) - if sorted(status_attributes) == sorted(data.keys()): - return OffenceStatus(**data) - - return data - - -@dataclass(frozen=True, eq=True) -class PendingOffense: - """A dataclass to represent offences that need to be addressed.""" - - accused_agent_address: str - round_count: int - offense_type: OffenseType - last_transition_timestamp: float - time_to_live: float - # only takes effect if the `OffenseType` is of type `CUSTOM`, otherwise it is ignored - custom_amount: int = 0 - - def __post_init__(self) -> None: - """Post initialization for offence type conversion in case it is given as an `int`.""" - if isinstance(self.offense_type, int): - super().__setattr__("offense_type", OffenseType(self.offense_type)) - - -class SlashingNotConfiguredError(Exception): - """Custom exception raised when slashing configuration is requested but is not available.""" - - -DEFAULT_PENDING_OFFENCE_TTL = 2 * 60 * 60 # 1 hour - - -class RoundSequence: # pylint: disable=too-many-instance-attributes - """ - This class represents a sequence of rounds - - It is a generic class that keeps track of the current round - of the consensus period. It receives 'deliver_tx' requests - from the ABCI handlers and forwards them to the current - active round instance, which implements the ABCI app logic. - It also schedules the next round (if any) whenever a round terminates. - """ - - class _BlockConstructionState(Enum): - """ - Phases of an ABCI-based block construction. - - WAITING_FOR_BEGIN_BLOCK: the app is ready to accept - "begin_block" requests from the consensus engine node. - Then, it transitions into the 'WAITING_FOR_DELIVER_TX' phase. - WAITING_FOR_DELIVER_TX: the app is building the block - by accepting "deliver_tx" requests, and waits - until the "end_block" request. - Then, it transitions into the 'WAITING_FOR_COMMIT' phase. - WAITING_FOR_COMMIT: the app finished the construction - of the block, but it is waiting for the "commit" - request from the consensus engine node. - Then, it transitions into the 'WAITING_FOR_BEGIN_BLOCK' phase. - """ - - WAITING_FOR_BEGIN_BLOCK = "waiting_for_begin_block" - WAITING_FOR_DELIVER_TX = "waiting_for_deliver_tx" - WAITING_FOR_COMMIT = "waiting_for_commit" - - def __init__(self, context: SkillContext, abci_app_cls: Type[AbciApp]): - """Initialize the round.""" - self._blockchain = Blockchain() - self._syncing_up = True - self._context = context - self._block_construction_phase = ( - RoundSequence._BlockConstructionState.WAITING_FOR_BEGIN_BLOCK - ) - - self._block_builder = BlockBuilder() - self._abci_app_cls = abci_app_cls - self._abci_app: Optional[AbciApp] = None - self._last_round_transition_timestamp: Optional[datetime.datetime] = None - self._last_round_transition_height = 0 - self._last_round_transition_root_hash = b"" - self._last_round_transition_tm_height: Optional[int] = None - self._tm_height: Optional[int] = None - self._block_stall_deadline: Optional[datetime.datetime] = None - self._terminating_round_called: bool = False - # a mapping of the validators' addresses to their agent addresses - # we create a mapping to avoid calculating the agent address from the validator address every time we need it - # since this is an operation that will be performed every time we want to create an offence - self._validator_to_agent: Dict[str, str] = {} - # a mapping of the agents' addresses to their offence status - self._offence_status: Dict[str, OffenceStatus] = {} - self._slashing_enabled = False - self.pending_offences: Set[PendingOffense] = set() - - def enable_slashing(self) -> None: - """Enable slashing.""" - self._slashing_enabled = True - - @property - def validator_to_agent(self) -> Dict[str, str]: - """Get the mapping of the validators' addresses to their agent addresses.""" - if self._validator_to_agent: - return self._validator_to_agent - raise SlashingNotConfiguredError( - "The mapping of the validators' addresses to their agent addresses has not been set." - ) - - @validator_to_agent.setter - def validator_to_agent(self, validator_to_agent: Dict[str, str]) -> None: - """Set the mapping of the validators' addresses to their agent addresses.""" - if self._validator_to_agent: - raise ValueError( - "The mapping of the validators' addresses to their agent addresses can only be set once. " - f"Attempted to set with {validator_to_agent} but it has content already: {self._validator_to_agent}." - ) - self._validator_to_agent = validator_to_agent - - @property - def offence_status(self) -> Dict[str, OffenceStatus]: - """Get the mapping of the agents' addresses to their offence status.""" - if self._offence_status: - return self._offence_status - raise SlashingNotConfiguredError( # pragma: nocover - "The mapping of the agents' addresses to their offence status has not been set." - ) - - @offence_status.setter - def offence_status(self, offence_status: Dict[str, OffenceStatus]) -> None: - """Set the mapping of the agents' addresses to their offence status.""" - self.abci_app.logger.debug(f"Setting offence status to: {offence_status}") - self._offence_status = offence_status - self.store_offence_status() - - def add_pending_offence(self, pending_offence: PendingOffense) -> None: - """ - Add a pending offence to the set of pending offences. - - Pending offences are offences that have been detected, but not yet agreed upon by the consensus. - A pending offence is removed from the set of pending offences and added to the OffenceStatus of a validator - when the majority of the agents agree on it. - - :param pending_offence: the pending offence to add - :return: None - """ - self.pending_offences.add(pending_offence) - - def sync_db_and_slashing(self, serialized_db_state: str) -> None: - """Sync the database and the slashing configuration.""" - self.abci_app.synchronized_data.db.sync(serialized_db_state) - offence_status = self.latest_synchronized_data.slashing_config - if offence_status: - # deserialize the offence status and load it to memory - self.offence_status = json.loads( - offence_status, - cls=OffenseStatusDecoder, - ) - - def serialized_offence_status(self) -> str: - """Serialize the offence status.""" - return json.dumps(self.offence_status, cls=OffenseStatusEncoder, sort_keys=True) - - def store_offence_status(self) -> None: - """Store the serialized offence status.""" - if not self._slashing_enabled: - # if slashing is not enabled, we do not update anything - return - encoded_status = self.serialized_offence_status() - self.latest_synchronized_data.slashing_config = encoded_status - self.abci_app.logger.debug(f"Updated db with: {encoded_status}") - self.abci_app.logger.debug(f"App hash now is: {self.root_hash.hex()}") - - def get_agent_address(self, validator: Validator) -> str: - """Get corresponding agent address from a `Validator` instance.""" - validator_address = validator.address.hex().upper() - - try: - return self.validator_to_agent[validator_address] - except KeyError as exc: - raise ValueError( - f"Requested agent address for an unknown validator address {validator_address}. " - f"Available validators are: {self.validator_to_agent.keys()}" - ) from exc - - def setup(self, *args: Any, **kwargs: Any) -> None: - """ - Set up the round sequence. - - :param args: the arguments to pass to the round constructor. - :param kwargs: the keyword-arguments to pass to the round constructor. - """ - kwargs["context"] = self._context - self._abci_app = self._abci_app_cls(*args, **kwargs) - self._abci_app.setup() - - def start_sync( - self, - ) -> None: # pragma: nocover - """ - Set `_syncing_up` flag to true. - - if the _syncing_up flag is set to true, the `async_act` method won't be executed. For more details refer to - https://github.com/valory-xyz/open-autonomy/issues/247#issuecomment-1012268656 - """ - self._syncing_up = True - - def end_sync( - self, - ) -> None: - """Set `_syncing_up` flag to false.""" - self._syncing_up = False - - @property - def syncing_up( - self, - ) -> bool: - """Return if the app is in sync mode.""" - return self._syncing_up - - @property - def abci_app(self) -> AbciApp: - """Get the AbciApp.""" - if self._abci_app is None: - raise ABCIAppInternalError("AbciApp not set") # pragma: nocover - return self._abci_app - - @property - def blockchain(self) -> Blockchain: - """Get the Blockchain instance.""" - return self._blockchain - - @blockchain.setter - def blockchain(self, _blockchain: Blockchain) -> None: - """Get the Blockchain instance.""" - self._blockchain = _blockchain - - @property - def height(self) -> int: - """Get the height.""" - return self._blockchain.height - - @property - def is_finished(self) -> bool: - """Check if a round sequence has finished.""" - return self.abci_app.is_finished - - def check_is_finished(self) -> None: - """Check if a round sequence has finished.""" - if self.is_finished: - raise ValueError( - "round sequence is finished, cannot accept new transactions" - ) - - @property - def current_round(self) -> AbstractRound: - """Get current round.""" - return self.abci_app.current_round - - @property - def current_round_id(self) -> Optional[str]: - """Get the current round id.""" - return self.abci_app.current_round_id - - @property - def current_round_height(self) -> int: - """Get the current round height.""" - return self.abci_app.current_round_height - - @property - def last_round_id(self) -> Optional[str]: - """Get the last round id.""" - return self.abci_app.last_round_id - - @property - def last_timestamp(self) -> datetime.datetime: - """Get the last timestamp.""" - last_timestamp = ( - self._blockchain.blocks[-1].timestamp - if self._blockchain.length != 0 - else None - ) - if last_timestamp is None: - raise ABCIAppInternalError("last timestamp is None") - return last_timestamp - - @property - def last_round_transition_timestamp( - self, - ) -> datetime.datetime: - """Returns the timestamp for last round transition.""" - if self._last_round_transition_timestamp is None: - raise ValueError( - "Trying to access `last_round_transition_timestamp` while no transition has been completed yet." - ) - - return self._last_round_transition_timestamp - - @property - def last_round_transition_height( - self, - ) -> int: - """Returns the height for last round transition.""" - if self._last_round_transition_height == 0: - raise ValueError( - "Trying to access `last_round_transition_height` while no transition has been completed yet." - ) - - return self._last_round_transition_height - - @property - def last_round_transition_root_hash( - self, - ) -> bytes: - """Returns the root hash for last round transition.""" - if self._last_round_transition_root_hash == b"": - # if called for the first chain initialization, return the hash resulting from the initial abci app's state - return self.root_hash - return self._last_round_transition_root_hash - - @property - def last_round_transition_tm_height(self) -> int: - """Returns the Tendermint height for last round transition.""" - if self._last_round_transition_tm_height is None: - raise ValueError( - "Trying to access Tendermint's last round transition height before any `end_block` calls." - ) - return self._last_round_transition_tm_height - - @property - def latest_synchronized_data(self) -> BaseSynchronizedData: - """Get the latest synchronized_data.""" - return self.abci_app.synchronized_data - - @property - def root_hash(self) -> bytes: - """ - Get the Merkle root hash of the application state. - - This is going to be the database's hash. - In this way, the app hash will be reflecting our application's state, - and will guarantee that all the agents on the chain apply the changes of the arriving blocks in the same way. - - :return: the root hash to be included as the Header.AppHash in the next block. - """ - return self.abci_app.synchronized_data.db.hash() - - @property - def tm_height(self) -> int: - """Get Tendermint's current height.""" - if self._tm_height is None: - raise ValueError( - "Trying to access Tendermint's current height before any `end_block` calls." - ) - return self._tm_height - - @tm_height.setter - def tm_height(self, _tm_height: int) -> None: - """Set Tendermint's current height.""" - self._tm_height = _tm_height - - @property - def block_stall_deadline_expired(self) -> bool: - """Get if the deadline for not having received any begin block requests from the Tendermint node has expired.""" - if self._block_stall_deadline is None: - return False - return datetime.datetime.now() > self._block_stall_deadline - - def set_block_stall_deadline(self) -> None: - """Use the local time of the agent and a predefined tolerance, to specify the expiration of the deadline.""" - self._block_stall_deadline = datetime.datetime.now() + datetime.timedelta( - seconds=BLOCKS_STALL_TOLERANCE - ) - - def init_chain(self, initial_height: int) -> None: - """Init chain.""" - # reduce `initial_height` by 1 to get block count offset as per Tendermint protocol - self._blockchain = Blockchain(initial_height - 1) - - def _track_tm_offences( - self, evidences: Evidences, last_commit_info: LastCommitInfo - ) -> None: - """Track offences provided by Tendermint, if there are any.""" - for vote_info in last_commit_info.votes: - agent_address = self.get_agent_address(vote_info.validator) - was_down = not vote_info.signed_last_block - self.offence_status[agent_address].validator_downtime.add(was_down) - - for byzantine_validator in evidences.byzantine_validators: - agent_address = self.get_agent_address(byzantine_validator.validator) - evidence_type = byzantine_validator.evidence_type - self.offence_status[agent_address].num_unknown_offenses += bool( - evidence_type == EvidenceType.UNKNOWN - ) - self.offence_status[agent_address].num_double_signed += bool( - evidence_type == EvidenceType.DUPLICATE_VOTE - ) - self.offence_status[agent_address].num_light_client_attack += bool( - evidence_type == EvidenceType.LIGHT_CLIENT_ATTACK - ) - - def _track_app_offences(self) -> None: - """Track offences provided by the app level, if there are any.""" - synced_data = self.abci_app.synchronized_data - for agent in self.offence_status.keys(): - blacklisted = agent in synced_data.blacklisted_keepers - suspected = agent in cast(tuple, synced_data.db.get("suspects", tuple())) - agent_status = self.offence_status[agent] - agent_status.blacklisted.add(blacklisted) - agent_status.suspected.add(suspected) - - def _handle_slashing_not_configured(self, exc: SlashingNotConfiguredError) -> None: - """Handle a `SlashingNotConfiguredError`.""" - # In the current slashing implementation, we do not track offences before setting the slashing - # configuration, i.e., before successfully sharing the tm configuration via ACN on registration. - # That is because we cannot slash an agent if we do not map their validator address to their agent address. - # Checking the number of participants will allow us to identify whether the registration round has finished, - # and therefore expect that the slashing configuration has been set if ACN registration is enabled. - if self.abci_app.synchronized_data.nb_participants: - _logger.error( - f"{exc} This error may occur when the ACN registration has not been successfully performed. " - "Have you set the `share_tm_config_on_startup` flag to `true` in the configuration?" - ) - self._slashing_enabled = False - _logger.warning("Slashing has been disabled!") - - def _try_track_offences( - self, evidences: Evidences, last_commit_info: LastCommitInfo - ) -> None: - """Try to track the offences. If an error occurs, log it, disable slashing, and warn about the latter.""" - try: - if self._slashing_enabled: - # only track offences if the first round has finished - # we avoid tracking offences in the first round - # because we do not have the slashing configuration synced yet - self._track_tm_offences(evidences, last_commit_info) - self._track_app_offences() - except SlashingNotConfiguredError as exc: - self._handle_slashing_not_configured(exc) - - def begin_block( - self, - header: Header, - evidences: Evidences, - last_commit_info: LastCommitInfo, - ) -> None: - """Begin block.""" - if self.is_finished: - raise ABCIAppInternalError( - "round sequence is finished, cannot accept new blocks" - ) - if ( - self._block_construction_phase - != RoundSequence._BlockConstructionState.WAITING_FOR_BEGIN_BLOCK - ): - raise ABCIAppInternalError( - f"cannot accept a 'begin_block' request. Current phase={self._block_construction_phase}" - ) - - # From now on, the ABCI app waits for 'deliver_tx' requests, until 'end_block' is received - self._block_construction_phase = ( - RoundSequence._BlockConstructionState.WAITING_FOR_DELIVER_TX - ) - self._block_builder.reset() - self._block_builder.header = header - self.abci_app.update_time(header.timestamp) - self.set_block_stall_deadline() - self.abci_app.logger.debug( - "Created a new local deadline for the next `begin_block` request from the Tendermint node: " - f"{self._block_stall_deadline}" - ) - self._try_track_offences(evidences, last_commit_info) - - def deliver_tx(self, transaction: Transaction) -> None: - """ - Deliver a transaction. - - Appends the transaction to build the block on 'end_block' later. - :param transaction: the transaction. - :raises: an Error otherwise. - """ - if ( - self._block_construction_phase - != RoundSequence._BlockConstructionState.WAITING_FOR_DELIVER_TX - ): - raise ABCIAppInternalError( - f"cannot accept a 'deliver_tx' request. Current phase={self._block_construction_phase}" - ) - - self.abci_app.check_transaction(transaction) - self.abci_app.process_transaction(transaction) - self._block_builder.add_transaction(transaction) - - def end_block(self) -> None: - """Process the 'end_block' request.""" - if ( - self._block_construction_phase - != RoundSequence._BlockConstructionState.WAITING_FOR_DELIVER_TX - ): - raise ABCIAppInternalError( - f"cannot accept a 'end_block' request. Current phase={self._block_construction_phase}" - ) - # The ABCI app waits for the commit - self._block_construction_phase = ( - RoundSequence._BlockConstructionState.WAITING_FOR_COMMIT - ) - - def commit(self) -> None: - """Process the 'commit' request.""" - if ( - self._block_construction_phase - != RoundSequence._BlockConstructionState.WAITING_FOR_COMMIT - ): - raise ABCIAppInternalError( - f"cannot accept a 'commit' request. Current phase={self._block_construction_phase}" - ) - block = self._block_builder.get_block() - try: - if self._blockchain.is_init: - # There are occasions where we wait for an init_chain() before accepting blocks. - # This can happen during hard reset, where we might've reset the local blockchain, - # But are still receiving requests from the not yet reset tendermint node. - # We only process blocks on an initialized local blockchain. - # The local blockchain gets initialized upon receiving an init_chain request from - # the tendermint node. In cases where we don't want to wait for the init_chain req, - # one can create a Blockchain instance with `is_init=True`, i.e. the default args. - self._blockchain.add_block(block) - self._update_round() - else: - self.abci_app.logger.warning( - f"Received block with height {block.header.height} before the blockchain was initialized." - ) - # The ABCI app now waits again for the next block - self._block_construction_phase = ( - RoundSequence._BlockConstructionState.WAITING_FOR_BEGIN_BLOCK - ) - except AddBlockError as exception: - raise exception - - def reset_blockchain(self, is_replay: bool = False, is_init: bool = False) -> None: - """ - Reset blockchain after tendermint reset. - - :param is_replay: whether we are resetting the blockchain while replaying blocks. - :param is_init: whether to process blocks before receiving an init_chain req from tendermint. - """ - if is_replay: - self._block_construction_phase = ( - RoundSequence._BlockConstructionState.WAITING_FOR_BEGIN_BLOCK - ) - self._blockchain = Blockchain(is_init=is_init) - - def _get_round_result( - self, - ) -> Optional[Tuple[BaseSynchronizedData, Any]]: - """ - Get the round's result. - - Give priority to: - 1. terminating bg rounds - 2. ever running bg rounds - 3. normal bg rounds - 4. normal rounds - - :return: the round's result. - """ - for prioritized_group in self.abci_app.bg_apps_prioritized: - for app in prioritized_group: - result = app.background_round.end_block() - if ( - result is None - or app.type == BackgroundAppType.TERMINATING - and self._terminating_round_called - ): - continue - if ( - app.type == BackgroundAppType.TERMINATING - and not self._terminating_round_called - ): - self._terminating_round_called = True - return result - return self.abci_app.current_round.end_block() - - def _update_round(self) -> None: - """ - Update a round. - - Check whether the round has finished. If so, get the new round and set it as the current round. - If a termination app's round has returned a result, then the other apps' rounds are ignored. - """ - result = self._get_round_result() - - if result is None: - # neither the background rounds, nor the current round returned, so no update needs to be made - return - - # update the offence status at the end of each round - # this is done to ensure that the offence status is always up-to-date & in sync - # the next step is a no-op if slashing is not enabled - self.store_offence_status() - - self._last_round_transition_timestamp = self._blockchain.last_block.timestamp - self._last_round_transition_height = self.height - self._last_round_transition_root_hash = self.root_hash - self._last_round_transition_tm_height = self.tm_height - - round_result, event = result - self.abci_app.logger.debug( - f"updating round, current_round {self.current_round.round_id}, event: {event}, round result {round_result}" - ) - self.abci_app.process_event(event, result=round_result) - - def _reset_to_default_params(self) -> None: - """Resets the instance params to their default value.""" - self._last_round_transition_timestamp = None - self._last_round_transition_height = 0 - self._last_round_transition_root_hash = b"" - self._last_round_transition_tm_height = None - self._tm_height = None - self._slashing_enabled = False - self.pending_offences = set() - - def reset_state( - self, - restart_from_round: str, - round_count: int, - serialized_db_state: Optional[str] = None, - ) -> None: - """ - This method resets the state of RoundSequence to the beginning of the period. - - Note: This is intended to be used for agent <-> tendermint communication recovery only! - - :param restart_from_round: from which round to restart the abci. - This round should be the first round in the last period. - :param round_count: the round count at the beginning of the period -1. - :param serialized_db_state: the state of the database at the beginning of the period. - If provided, the database will be reset to this state. - """ - self._reset_to_default_params() - self.abci_app.synchronized_data.db.round_count = round_count - if serialized_db_state is not None: - self.sync_db_and_slashing(serialized_db_state) - # Furthermore, that hash is then in turn used as the init hash when the tm network is reset. - self._last_round_transition_root_hash = self.root_hash - - self.abci_app.cleanup_timeouts() - round_id_to_cls = { - cls.auto_round_id(): cls for cls in self.abci_app.transition_function - } - restart_from_round_cls = round_id_to_cls.get(restart_from_round, None) - if restart_from_round_cls is None: - raise ABCIAppInternalError( - "Cannot reset state. The Tendermint recovery parameters are incorrect. " - "Did you update the `restart_from_round` with an incorrect round id? " - f"Found {restart_from_round}, but the app's transition function has the following round ids: " - f"{set(round_id_to_cls.keys())}." - ) - self.abci_app.schedule_round(restart_from_round_cls) - - -@dataclass(frozen=True) -class PendingOffencesPayload(BaseTxPayload): - """Represent a transaction payload for pending offences.""" - - accused_agent_address: str - offense_round: int - offense_type_value: int - last_transition_timestamp: float - time_to_live: float - custom_amount: int - - -class PendingOffencesRound(CollectSameUntilThresholdRound): - """Defines the pending offences background round, which runs concurrently with other rounds to sync the offences.""" - - payload_class = PendingOffencesPayload - synchronized_data_class = BaseSynchronizedData - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the `PendingOffencesRound`.""" - super().__init__(*args, **kwargs) - self._latest_round_processed = -1 - - @property - def offence_status(self) -> Dict[str, OffenceStatus]: - """Get the offence status from the round sequence.""" - return self.context.state.round_sequence.offence_status - - def end_block(self) -> None: - """ - Process the end of the block for the pending offences background round. - - It is important to note that this is a non-standard type of round, meaning it does not emit any events. - Instead, it continuously runs in the background. - The objective of this round is to consistently monitor the received pending offences - and achieve a consensus among the agents. - """ - if not self.threshold_reached: - return - - offence = PendingOffense(*self.most_voted_payload_values) - - # an offence should only be tracked once, not every time a payload is processed after the threshold is reached - if self._latest_round_processed == offence.round_count: - return - - # add synchronized offence to the offence status - # only `INVALID_PAYLOAD` offence types are supported at the moment as pending offences: - # https://github.com/valory-xyz/open-autonomy/blob/6831d6ebaf10ea8e3e04624b694c7f59a6d05bb4/packages/valory/skills/abstract_round_abci/handlers.py#L215-L222 # noqa - invalid = offence.offense_type == OffenseType.INVALID_PAYLOAD - self.offence_status[offence.accused_agent_address].invalid_payload.add(invalid) - - # if the offence is of custom type, then add the custom amount to it - if offence.offense_type == OffenseType.CUSTOM: - self.offence_status[ - offence.accused_agent_address - ].custom_offences_amount += offence.custom_amount - elif offence.custom_amount != 0: - self.context.logger.warning( - f"Custom amount for {offence=} will not take effect as it is not of `CUSTOM` type." - ) - - self._latest_round_processed = offence.round_count diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/behaviour_utils.py b/trader_backup/vendor/valory/skills/abstract_round_abci/behaviour_utils.py deleted file mode 100644 index 43f929834..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/behaviour_utils.py +++ /dev/null @@ -1,2356 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 helper classes for behaviours.""" - - -import datetime -import inspect -import json -import pprint -import re -import sys -from abc import ABC, ABCMeta, abstractmethod -from enum import Enum -from functools import partial -from typing import ( - Any, - Callable, - Dict, - Generator, - List, - Optional, - Tuple, - Type, - Union, - cast, -) - -import pytz -from aea.exceptions import enforce -from aea.mail.base import EnvelopeContext -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue -from aea.skills.behaviours import SimpleBehaviour - -from packages.open_aea.protocols.signing import SigningMessage -from packages.open_aea.protocols.signing.custom_types import ( - RawMessage, - RawTransaction, - SignedTransaction, - Terms, -) -from packages.valory.connections.http_client.connection import ( - PUBLIC_ID as HTTP_CLIENT_PUBLIC_ID, -) -from packages.valory.connections.ipfs.connection import PUBLIC_ID as IPFS_CONNECTION_ID -from packages.valory.connections.p2p_libp2p_client.connection import ( - PUBLIC_ID as P2P_LIBP2P_CLIENT_PUBLIC_ID, -) -from packages.valory.contracts.service_registry.contract import ( # noqa: F401 # pylint: disable=unused-import - ServiceRegistryContract, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.protocols.ipfs.dialogues import IpfsDialogue, IpfsDialogues -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.protocols.tendermint import TendermintMessage -from packages.valory.skills.abstract_round_abci.base import ( - AbstractRound, - BaseSynchronizedData, - BaseTxPayload, - LEDGER_API_ADDRESS, - OK_CODE, - RoundSequence, - Transaction, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue, - ContractApiDialogues, - HttpDialogue, - HttpDialogues, - LedgerApiDialogue, - LedgerApiDialogues, - SigningDialogues, - TendermintDialogues, -) -from packages.valory.skills.abstract_round_abci.io_.ipfs import ( - IPFSInteract, - IPFSInteractionError, -) -from packages.valory.skills.abstract_round_abci.io_.load import CustomLoaderType, Loader -from packages.valory.skills.abstract_round_abci.io_.store import ( - CustomStorerType, - Storer, - SupportedFiletype, - SupportedObjectType, -) -from packages.valory.skills.abstract_round_abci.models import ( - BaseParams, - Requests, - SharedState, - TendermintRecoveryParams, -) - - -# TODO: port registration code from registration_abci to here - - -NON_200_RETURN_CODE_DURING_RESET_THRESHOLD = 3 -GENESIS_TIME_FMT = "%Y-%m-%dT%H:%M:%S.%fZ" -INITIAL_APP_HASH = "" -INITIAL_HEIGHT = "0" -TM_REQ_TIMEOUT = 5 # 5 seconds -FLASHBOTS_LEDGER_ID = "ethereum_flashbots" -SOLANA_LEDGER_ID = "solana" - - -class SendException(Exception): - """Exception raised if the 'try_send' to an AsyncBehaviour failed.""" - - -class TimeoutException(Exception): - """Exception raised when a timeout during AsyncBehaviour occurs.""" - - -class BaseBehaviourInternalError(Exception): - """Internal error due to a bad implementation of the BaseBehaviour.""" - - def __init__(self, message: str, *args: Any) -> None: - """Initialize the error object.""" - super().__init__("internal error: " + message, *args) - - -class AsyncBehaviour(ABC): - """ - MixIn behaviour class that support limited asynchronous programming. - - An AsyncBehaviour can be in three states: - - READY: no suspended 'async_act' execution; - - RUNNING: 'act' called, and waiting for a message - - WAITING_TICK: 'act' called, and waiting for the next 'act' call - """ - - class AsyncState(Enum): - """Enumeration of AsyncBehaviour states.""" - - READY = "ready" - RUNNING = "running" - WAITING_MESSAGE = "waiting_message" - - def __init__(self) -> None: - """Initialize the async behaviour.""" - self.__state = self.AsyncState.READY - self.__generator_act: Optional[Generator] = None - - # temporary variables for the waiting message state - self.__stopped: bool = True - self.__notified: bool = False - self.__message: Any = None - self.__setup_called: bool = False - - @abstractmethod - def async_act(self) -> Generator: - """Do the act, supporting asynchronous execution.""" - - @abstractmethod - def async_act_wrapper(self) -> Generator: - """Do the act, supporting asynchronous execution.""" - - @property - def state(self) -> AsyncState: - """Get the 'async state'.""" - return self.__state - - @property - def is_notified(self) -> bool: - """Returns whether the behaviour has been notified about the arrival of a message.""" - return self.__notified - - @property - def received_message(self) -> Any: - """Returns the message the behaviour has received. "__message" should be None if not availble or already consumed.""" - return self.__message - - def _on_sent_message(self) -> None: - """To be called after the message received is consumed. Removes the already sent notification and message.""" - self.__notified = False - self.__message = None - - @property - def is_stopped(self) -> bool: - """Check whether the behaviour has stopped.""" - return self.__stopped - - def __get_generator_act(self) -> Generator: - """Get the _generator_act.""" - if self.__generator_act is None: - raise ValueError("generator act not set!") # pragma: nocover - return self.__generator_act - - def try_send(self, message: Any) -> None: - """ - Try to send a message to a waiting behaviour. - - It will be sent only if the behaviour is actually waiting for a message, - and it was not already notified. - - :param message: a Python object. - :raises: SendException if the behaviour was not waiting for a message, - or if it was already notified. - """ - in_waiting_message_state = self.__state == self.AsyncState.WAITING_MESSAGE - already_notified = self.__notified - enforce( - in_waiting_message_state and not already_notified, - "cannot send message", - exception_class=SendException, - ) - self.__notified = True - self.__message = message - - @classmethod - def wait_for_condition( - cls, condition: Callable[[], bool], timeout: Optional[float] = None - ) -> Generator[None, None, None]: - """Wait for a condition to happen. - - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - - :param condition: the condition to wait for - :param timeout: the maximum amount of time to wait - :yield: None - """ - if timeout is not None: - deadline = datetime.datetime.now() + datetime.timedelta(0, timeout) - else: - deadline = datetime.datetime.max - - while not condition(): - if timeout is not None and datetime.datetime.now() > deadline: - raise TimeoutException() - yield - - def sleep(self, seconds: float) -> Any: - """ - Delay execution for a given number of seconds. - - The argument may be a floating point number for subsecond precision. - This is a local method that does not depend on the global clock, so the - usage of datetime.now() is acceptable here. - - :param seconds: the seconds - :yield: None - """ - deadline = datetime.datetime.now() + datetime.timedelta(0, seconds) - - def _wait_until() -> bool: - return datetime.datetime.now() > deadline - - yield from self.wait_for_condition(_wait_until) - - def wait_for_message( - self, - condition: Callable = lambda message: True, - timeout: Optional[float] = None, - ) -> Any: - """ - Wait for message. - - Care must be taken. This method does not handle concurrent requests. - Use directly after a request is being sent. - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - - :param condition: a callable - :param timeout: max time to wait (in seconds) - :return: a message - :yield: None - """ - if timeout is not None: - deadline = datetime.datetime.now() + datetime.timedelta(0, timeout) - else: - deadline = datetime.datetime.max - - self.__state = self.AsyncState.WAITING_MESSAGE - try: - message = None - while message is None or not condition(message): - message = yield - if timeout is not None and datetime.datetime.now() > deadline: - raise TimeoutException() - message = cast(Message, message) - return message - finally: - self.__state = self.AsyncState.RUNNING - - def setup(self) -> None: # noqa: B027 # flake8 suggest make it abstract - """Setup behaviour.""" - - def act(self) -> None: - """Do the act.""" - # call setup only the first time act is called - if not self.__setup_called: - self.setup() - self.__setup_called = True - - if self.__state == self.AsyncState.READY: - self.__call_act_first_time() - return - if self.__state == self.AsyncState.WAITING_MESSAGE: - self.__handle_waiting_for_message() - return - enforce(self.__state == self.AsyncState.RUNNING, "not in 'RUNNING' state") - self.__handle_tick() - - def stop(self) -> None: - """Stop the execution of the behaviour.""" - if self.__stopped or self.__state == self.AsyncState.READY: - return - self.__get_generator_act().close() - self.__state = self.AsyncState.READY - self.__stopped = True - - def __call_act_first_time(self) -> None: - """Call the 'async_act' method for the first time.""" - self.__stopped = False - self.__state = self.AsyncState.RUNNING - try: - self.__generator_act = self.async_act_wrapper() - # if the method 'async_act' was not a generator function - # (i.e. no 'yield' or 'yield from' statement) - # just return - if not inspect.isgenerator(self.__generator_act): - self.__state = self.AsyncState.READY - return - # trigger first execution, up to next 'yield' statement - self.__get_generator_act().send(None) - except StopIteration: - # this may happen if the generator is empty - self.__state = self.AsyncState.READY - - def __handle_waiting_for_message(self) -> None: - """Handle an 'act' tick, when waiting for a message.""" - # if there is no message coming, skip. - if self.__notified: - try: - self.__get_generator_act().send(self.__message) - except StopIteration: - self.__handle_stop_iteration() - finally: - # wait for the next message - self.__notified = False - self.__message = None - - def __handle_tick(self) -> None: - """Handle an 'act' tick.""" - try: - self.__get_generator_act().send(None) - except StopIteration: - self.__handle_stop_iteration() - - def __handle_stop_iteration(self) -> None: - """ - Handle 'StopIteration' exception. - - The exception means that the 'async_act' - generator function terminated the execution, - and therefore the state needs to be reset. - """ - self.__state = self.AsyncState.READY - - -class IPFSBehaviour(SimpleBehaviour, ABC): - """Behaviour for interactions with IPFS.""" - - def __init__(self, **kwargs: Any): - """Initialize an `IPFSBehaviour`.""" - super().__init__(**kwargs) - loader_cls = kwargs.pop("loader_cls", Loader) - storer_cls = kwargs.pop("storer_cls", Storer) - self._ipfs_interact = IPFSInteract(loader_cls, storer_cls) - - def _build_ipfs_message( - self, - performative: IpfsMessage.Performative, - timeout: Optional[float] = None, - **kwargs: Any, - ) -> Tuple[IpfsMessage, IpfsDialogue]: - """Builds an IPFS message.""" - ipfs_dialogues = cast(IpfsDialogues, self.context.ipfs_dialogues) - message, dialogue = ipfs_dialogues.create( - counterparty=str(IPFS_CONNECTION_ID), - performative=performative, - timeout=timeout, - **kwargs, - ) - return message, dialogue - - def _build_ipfs_store_file_req( # pylint: disable=too-many-arguments - self, - filename: str, - obj: SupportedObjectType, - multiple: bool = False, - filetype: Optional[SupportedFiletype] = None, - custom_storer: Optional[CustomStorerType] = None, - timeout: Optional[float] = None, - **kwargs: Any, - ) -> Tuple[IpfsMessage, IpfsDialogue]: - """ - Builds a STORE_FILES ipfs message. - - :param filename: the file name to store obj in. If "multiple" is True, filename will be the name of the dir. - :param obj: the object(s) to serialize and store in IPFS as "filename". - :param multiple: whether obj should be stored as multiple files, i.e. directory. - :param custom_storer: a custom serializer for "obj". - :param timeout: timeout for the request. - :returns: the ipfs message, and its corresponding dialogue. - """ - serialized_objects = self._ipfs_interact.store( - filename, obj, multiple, filetype, custom_storer, **kwargs - ) - message, dialogue = self._build_ipfs_message( - performative=IpfsMessage.Performative.STORE_FILES, # type: ignore - files=serialized_objects, - timeout=timeout, - ) - return message, dialogue - - def _build_ipfs_get_file_req( - self, - ipfs_hash: str, - timeout: Optional[float] = None, - ) -> Tuple[IpfsMessage, IpfsDialogue]: - """ - Builds a GET_FILES IPFS request. - - :param ipfs_hash: the ipfs hash of the file/dir to download. - :param timeout: timeout for the request. - :returns: the ipfs message, and its corresponding dialogue. - """ - message, dialogue = self._build_ipfs_message( - performative=IpfsMessage.Performative.GET_FILES, # type: ignore - ipfs_hash=ipfs_hash, - timeout=timeout, - ) - return message, dialogue - - def _deserialize_ipfs_objects( # pylint: disable=too-many-arguments - self, - serialized_objects: Dict[str, str], - filetype: Optional[SupportedFiletype] = None, - custom_loader: CustomLoaderType = None, - ) -> Optional[SupportedObjectType]: - """Deserialize objects received from IPFS.""" - deserialized_object = self._ipfs_interact.load( - serialized_objects, filetype, custom_loader - ) - return deserialized_object - - -class CleanUpBehaviour(SimpleBehaviour, ABC): - """Class for clean-up related functionality of behaviours.""" - - def __init__(self, **kwargs: Any): # pylint: disable=super-init-not-called - """Initialize a base behaviour.""" - SimpleBehaviour.__init__(self, **kwargs) - - def clean_up(self) -> None: - """ - Clean up the resources due to a 'stop' event. - - It can be optionally implemented by the concrete classes. - """ - - def handle_late_messages(self, behaviour_id: str, message: Message) -> None: - """ - Handle late arriving messages. - - Runs from another behaviour, even if the behaviour implementing the method has been exited. - It can be optionally implemented by the concrete classes. - - :param behaviour_id: the id of the behaviour in which the message belongs to. - :param message: the late arriving message to handle. - """ - request_nonce = message.dialogue_reference[0] - self.context.logger.warning( - f"No callback defined for request with nonce: {request_nonce}, arriving for behaviour: {behaviour_id}" - ) - - -class RPCResponseStatus(Enum): - """A custom status of an RPC response.""" - - SUCCESS = 1 - INCORRECT_NONCE = 2 - UNDERPRICED = 3 - INSUFFICIENT_FUNDS = 4 - ALREADY_KNOWN = 5 - UNCLASSIFIED_ERROR = 6 - SIMULATION_FAILED = 7 - - -class _MetaBaseBehaviour(ABCMeta): - """A metaclass that validates BaseBehaviour's attributes.""" - - def __new__(mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any) -> Type: # type: ignore - """Initialize the class.""" - new_cls = super().__new__(mcs, name, bases, namespace, **kwargs) - - if ABC in bases: - # abstract class, return - return new_cls - if not issubclass(new_cls, BaseBehaviour): - # the check only applies to AbciApp subclasses - return new_cls - - mcs._check_consistency(cast(Type[BaseBehaviour], new_cls)) - return new_cls - - @classmethod - def _check_consistency(mcs, base_behaviour_cls: Type["BaseBehaviour"]) -> None: - """Check consistency of class attributes.""" - mcs._check_required_class_attributes(base_behaviour_cls) - - @classmethod - def _check_required_class_attributes( - mcs, base_behaviour_cls: Type["BaseBehaviour"] - ) -> None: - """Check that required class attributes are set.""" - if not hasattr(base_behaviour_cls, "matching_round"): - raise BaseBehaviourInternalError( - f"'matching_round' not set on {base_behaviour_cls}" - ) - - -class BaseBehaviour( - AsyncBehaviour, IPFSBehaviour, CleanUpBehaviour, ABC, metaclass=_MetaBaseBehaviour -): - """ - This class represents the base class for FSM behaviours - - A behaviour is a state of the FSM App execution. It usually involves - interactions between participants in the FSM App, - although this is not enforced at this level of abstraction. - - Concrete classes must set: - - matching_round: the round class matching the behaviour; - - Optionally, behaviour_id can be defined, although it is recommended to use the autogenerated id. - """ - - __pattern = re.compile(r"(? str: - """ - Get behaviour id automatically. - - This method returns the auto generated id from the class name if the - class variable behaviour_id is not set on the child class. - Otherwise, it returns the class variable behaviour_id. - """ - return ( - cls.behaviour_id - if isinstance(cls.behaviour_id, str) - else cls.__pattern.sub("_", cls.__name__).lower() - ) - - @property # type: ignore - def behaviour_id(self) -> str: - """Get behaviour id.""" - return self.auto_behaviour_id() - - @property - def params(self) -> BaseParams: - """Return the params.""" - return self.context.params - - @property - def shared_state(self) -> SharedState: - """Return the round sequence.""" - return self.context.state - - @property - def round_sequence(self) -> RoundSequence: - """Return the round sequence.""" - return self.shared_state.round_sequence - - @property - def synchronized_data(self) -> BaseSynchronizedData: - """Return the synchronized data.""" - return self.shared_state.synchronized_data - - @property - def tm_communication_unhealthy(self) -> bool: - """Return if the Tendermint communication is not healthy anymore.""" - return self.round_sequence.block_stall_deadline_expired - - def check_in_round(self, round_id: str) -> bool: - """Check that we entered a specific round.""" - return self.round_sequence.current_round_id == round_id - - def check_in_last_round(self, round_id: str) -> bool: - """Check that we entered a specific round.""" - return self.round_sequence.last_round_id == round_id - - def check_not_in_round(self, round_id: str) -> bool: - """Check that we are not in a specific round.""" - return not self.check_in_round(round_id) - - def check_not_in_last_round(self, round_id: str) -> bool: - """Check that we are not in a specific round.""" - return not self.check_in_last_round(round_id) - - def check_round_has_finished(self, round_id: str) -> bool: - """Check that the round has finished.""" - return self.check_in_last_round(round_id) - - def check_round_height_has_changed(self, round_height: int) -> bool: - """Check that the round height has changed.""" - return self.round_sequence.current_round_height != round_height - - def is_round_ended(self, round_id: str) -> Callable[[], bool]: - """Get a callable to check whether the current round has ended.""" - return partial(self.check_not_in_round, round_id) - - def wait_until_round_end( - self, timeout: Optional[float] = None - ) -> Generator[None, None, None]: - """ - Wait until the ABCI application exits from a round. - - :param timeout: the timeout for the wait - :yield: None - """ - round_id = self.matching_round.auto_round_id() - round_height = self.round_sequence.current_round_height - if self.check_not_in_round(round_id) and self.check_not_in_last_round(round_id): - raise ValueError( - f"Should be in matching round ({round_id}) or last round ({self.round_sequence.last_round_id}), " - f"actual round {self.round_sequence.current_round_id}!" - ) - yield from self.wait_for_condition( - partial(self.check_round_height_has_changed, round_height), timeout=timeout - ) - - def wait_from_last_timestamp(self, seconds: float) -> Any: - """ - Delay execution for a given number of seconds from the last timestamp. - - The argument may be a floating point number for subsecond precision. - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - - :param seconds: the seconds - :yield: None - """ - if seconds < 0: - raise ValueError("Can only wait for a positive amount of time") - deadline = self.round_sequence.abci_app.last_timestamp + datetime.timedelta( - seconds=seconds - ) - - def _wait_until() -> bool: - return datetime.datetime.now() > deadline - - yield from self.wait_for_condition(_wait_until) - - def is_done(self) -> bool: - """Check whether the behaviour is done.""" - return self._is_done - - def set_done(self) -> None: - """Set the behaviour to done.""" - self._is_done = True - - def send_a2a_transaction( - self, payload: BaseTxPayload, resetting: bool = False - ) -> Generator: - """ - Send transaction and wait for the response, and repeat until not successful. - - :param: payload: the payload to send - :param: resetting: flag indicating if we are resetting Tendermint nodes in this round. - :yield: the responses - """ - stop_condition = self.is_round_ended(self.matching_round.auto_round_id()) - round_count = self.synchronized_data.round_count - object.__setattr__(payload, "round_count", round_count) - yield from self._send_transaction( - payload, - resetting, - stop_condition=stop_condition, - ) - - def async_act_wrapper(self) -> Generator: - """Do the act, supporting asynchronous execution.""" - if not self._is_started: - self._log_start() - self._is_started = True - try: - if self.round_sequence.syncing_up: - yield from self._check_sync() - else: - yield from self.async_act() - except StopIteration: - self.clean_up() - self.set_done() - self._log_end() - return - - if self._is_done: - self._log_end() - - def _check_sync( - self, - ) -> Generator[None, None, None]: - """Check if agent has completed sync.""" - self.context.logger.info("Synchronizing with Tendermint...") - for _ in range(self.context.params.tendermint_max_retries): - self.context.logger.debug( - "Checking status @ " + self.context.params.tendermint_url + "/status", - ) - status = yield from self._get_status() - try: - json_body = json.loads(status.body.decode()) - remote_height = int( - json_body["result"]["sync_info"]["latest_block_height"] - ) - local_height = int(self.round_sequence.height) - _is_sync_complete = local_height == remote_height - if _is_sync_complete: - self.context.logger.info( - f"local height == remote == {local_height}; Synchronization complete." - ) - self.round_sequence.end_sync() - # we set the block stall deadline here because we pinged the /status endpoint - # and received a response from tm, which means that the communication is fine - self.round_sequence.set_block_stall_deadline() - return - yield from self.sleep(self.context.params.tendermint_check_sleep_delay) - except (json.JSONDecodeError, KeyError): # pragma: nocover - self.context.logger.debug( - "Tendermint not accepting transactions yet, trying again!" - ) - yield from self.sleep(self.context.params.tendermint_check_sleep_delay) - - self.context.logger.error("Could not synchronize with Tendermint!") - - def _log_start(self) -> None: - """Log the entering in the behaviour.""" - self.context.logger.info(f"Entered in the '{self.name}' behaviour") - - def _log_end(self) -> None: - """Log the exiting from the behaviour.""" - self.context.logger.info(f"'{self.name}' behaviour is done") - - @classmethod - def _get_request_nonce_from_dialogue(cls, dialogue: Dialogue) -> str: - """Get the request nonce for the request, from the protocol's dialogue.""" - return dialogue.dialogue_label.dialogue_reference[0] - - def _send_transaction( # pylint: disable=too-many-arguments,too-many-locals,too-many-statements - self, - payload: BaseTxPayload, - resetting: bool = False, - stop_condition: Callable[[], bool] = lambda: False, - request_timeout: Optional[float] = None, - request_retry_delay: Optional[float] = None, - tx_timeout: Optional[float] = None, - max_attempts: Optional[int] = None, - ) -> Generator: - """ - Send transaction and wait for the response, repeat until not successful. - - Steps: - - Request the signature of the payload to the Decision Maker - - Send the transaction to the 'price-estimation' app via the Tendermint - node, and wait/repeat until the transaction is not mined. - - Happy-path full flow of the messages. - - get_signature: - AbstractRoundAbci skill -> (SigningMessage | SIGN_MESSAGE) -> DecisionMaker - DecisionMaker -> (SigningMessage | SIGNED_MESSAGE) -> AbstractRoundAbci skill - - _submit_tx: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - _wait_until_transaction_delivered: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - :param: payload: the payload to send - :param: resetting: flag indicating if we are resetting Tendermint nodes in this round. - :param: stop_condition: the condition to be checked to interrupt the - waiting loop. - :param: request_timeout: the timeout for the requests - :param: request_retry_delay: the delay to wait after failed requests - :param: tx_timeout: the timeout to wait for tx delivery - :param: max_attempts: max retry attempts - :yield: the responses - """ - request_timeout = ( - self.params.request_timeout if request_timeout is None else request_timeout - ) - request_retry_delay = ( - self.params.request_retry_delay - if request_retry_delay is None - else request_retry_delay - ) - tx_timeout = self.params.tx_timeout if tx_timeout is None else tx_timeout - max_attempts = ( - self.params.max_attempts if max_attempts is None else max_attempts - ) - while not stop_condition(): - self.context.logger.debug( - f"Trying to send payload: {pprint.pformat(payload.json)}" - ) - signature_bytes = yield from self.get_signature(payload.encode()) - transaction = Transaction(payload, signature_bytes) - try: - response = yield from self._submit_tx( - transaction.encode(), timeout=request_timeout - ) - # There is no guarantee that beyond this line will be executed for a given behaviour execution. - # The tx could lead to a round transition which exits us from the behaviour execution. - # It's unlikely to happen anywhere before line 538 but there it is very likely to not - # yield in time before the behaviour is finished. As a result logs below might not show - # up on the happy execution path. - except TimeoutException: - self.context.logger.warning( - f"Timeout expired for submit tx. Retrying in {request_retry_delay} seconds..." - ) - payload = payload.with_new_id() - yield from self.sleep(request_retry_delay) - continue - response = cast(HttpMessage, response) - non_200_code = not self._check_http_return_code_200(response) - if non_200_code and ( - self._non_200_return_code_count - > NON_200_RETURN_CODE_DURING_RESET_THRESHOLD - or not resetting - ): - self.context.logger.error( - f"Received return code != 200 with response {response} with body {str(response.body)}. " - f"Retrying in {request_retry_delay} seconds..." - ) - elif non_200_code and resetting: - self._non_200_return_code_count += 1 - if non_200_code: - payload = payload.with_new_id() - yield from self.sleep(request_retry_delay) - continue - try: - json_body = json.loads(response.body) - except json.JSONDecodeError as e: # pragma: nocover - raise ValueError( - f"Unable to decode response: {response} with body {str(response.body)}" - ) from e - self.context.logger.debug(f"JSON response: {pprint.pformat(json_body)}") - tx_hash = json_body["result"]["hash"] - if json_body["result"]["code"] != OK_CODE: - self.context.logger.error( - f"Received tendermint code != 0. Retrying in {request_retry_delay} seconds..." - ) - yield from self.sleep(request_retry_delay) - continue # pragma: nocover - - try: - is_delivered, res = yield from self._wait_until_transaction_delivered( - tx_hash, - timeout=tx_timeout, - max_attempts=max_attempts, - request_retry_delay=request_retry_delay, - ) - except TimeoutException: - self.context.logger.warning( - f"Timeout expired for wait until transaction delivered. " - f"Retrying in {request_retry_delay} seconds..." - ) - payload = payload.with_new_id() - yield from self.sleep(request_retry_delay) - continue # pragma: nocover - - if is_delivered: - self.context.logger.debug("A2A transaction delivered!") - break - if isinstance(res, HttpMessage) and self._is_invalid_transaction(res): - self.context.logger.error( - f"Tx sent but not delivered. Invalid transaction - not trying again! Response = {res}" - ) - break - # otherwise, repeat until done, or until stop condition is true - if isinstance(res, HttpMessage) and self._tx_not_found(tx_hash, res): - self.context.logger.warning(f"Tx {tx_hash} not found! Response = {res}") - else: - self.context.logger.warning( - f"Tx sent but not delivered. Response = {res}" - ) - payload = payload.with_new_id() - self.context.logger.debug( - "Stop condition is true, no more attempts to send the transaction." - ) - - @staticmethod - def _is_invalid_transaction(res: HttpMessage) -> bool: - """Check if the transaction is invalid.""" - try: - error_codes = ["TransactionNotValidError"] - body_ = json.loads(res.body) - return any( - [error_code in body_["tx_result"]["info"] for error_code in error_codes] - ) - except Exception: # pylint: disable=broad-except # pragma: nocover - return False - - @staticmethod - def _tx_not_found(tx_hash: str, res: HttpMessage) -> bool: - """Check if the transaction could not be found.""" - try: - error = json.loads(res.body)["error"] - not_found_field_to_text = { - "code": -32603, - "message": "Internal error", - "data": f"tx ({tx_hash}) not found", - } - return all( - [ - text == error[field] - for field, text in not_found_field_to_text.items() - ] - ) - except Exception: # pylint: disable=broad-except # pragma: nocover - return False - - def _send_signing_request( - self, raw_message: bytes, is_deprecated_mode: bool = False - ) -> None: - """ - Send a signing request. - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (SigningMessage | SIGN_MESSAGE) -> DecisionMaker - DecisionMaker -> (SigningMessage | SIGNED_MESSAGE) -> AbstractRoundAbci skill - - :param raw_message: raw message bytes - :param is_deprecated_mode: is deprecated flag. - """ - signing_dialogues = cast(SigningDialogues, self.context.signing_dialogues) - signing_msg, signing_dialogue = signing_dialogues.create( - counterparty=self.context.decision_maker_address, - performative=SigningMessage.Performative.SIGN_MESSAGE, - raw_message=RawMessage( - self.context.default_ledger_id, - raw_message, - is_deprecated_mode=is_deprecated_mode, - ), - terms=Terms( - ledger_id=self.context.default_ledger_id, - sender_address="", - counterparty_address="", - amount_by_currency_id={}, - quantities_by_good_id={}, - nonce="", - ), - ) - request_nonce = self._get_request_nonce_from_dialogue(signing_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - self.context.decision_maker_message_queue.put_nowait(signing_msg) - - def _send_transaction_signing_request( - self, raw_transaction: RawTransaction, terms: Terms - ) -> None: - """ - Send a transaction signing request. - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (SigningMessage | SIGN_TRANSACTION) -> DecisionMaker - DecisionMaker -> (SigningMessage | SIGNED_TRANSACTION) -> AbstractRoundAbci skill - - :param raw_transaction: raw transaction data - :param terms: signing terms - """ - signing_dialogues = cast(SigningDialogues, self.context.signing_dialogues) - signing_msg, signing_dialogue = signing_dialogues.create( - counterparty=self.context.decision_maker_address, - performative=SigningMessage.Performative.SIGN_TRANSACTION, - raw_transaction=raw_transaction, - terms=terms, - ) - request_nonce = self._get_request_nonce_from_dialogue(signing_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - self.context.decision_maker_message_queue.put_nowait(signing_msg) - - def _send_transaction_request( - self, - signing_msg: SigningMessage, - use_flashbots: bool = False, - target_block_numbers: Optional[List[int]] = None, - chain_id: Optional[str] = None, - raise_on_failed_simulation: bool = False, - ) -> None: - """ - Send transaction request. - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (LedgerApiMessage | SEND_SIGNED_TRANSACTION) -> Ledger connection - Ledger connection -> (LedgerApiMessage | TRANSACTION_DIGEST) -> AbstractRoundAbci skill - - :param signing_msg: signing message - :param use_flashbots: whether to use flashbots for the transaction or not - :param target_block_numbers: the target block numbers in case we are using flashbots - :param chain_id: the chain name to use for the ledger call - :param raise_on_failed_simulation: whether to raise an exception if the simulation fails or not. - """ - ledger_api_dialogues = cast( - LedgerApiDialogues, self.context.ledger_api_dialogues - ) - - create_kwargs: Dict[ - str, Union[str, SignedTransaction, List[SignedTransaction]] - ] = dict( - counterparty=LEDGER_API_ADDRESS, - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, - ) - if chain_id: - kwargs = LedgerApiMessage.Kwargs({"chain_id": chain_id}) - create_kwargs.update(dict(kwargs=kwargs)) - - if use_flashbots: - _kwargs = { - "chain_id": chain_id, - "raise_on_failed_simulation": raise_on_failed_simulation, - "use_all_builders": True, # TODO: make this a proper parameter - } - if target_block_numbers is not None: - _kwargs["target_block_numbers"] = target_block_numbers # type: ignore - create_kwargs.update( - dict( - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS, - # we do not support sending multiple signed txs and receiving multiple tx hashes yet - signed_transactions=LedgerApiMessage.SignedTransactions( - ledger_id=FLASHBOTS_LEDGER_ID, - signed_transactions=[signing_msg.signed_transaction.body], - ), - kwargs=LedgerApiMessage.Kwargs(_kwargs), - ) - ) - else: - create_kwargs.update( - dict( - signed_transaction=signing_msg.signed_transaction, - ) - ) - - ledger_api_msg, ledger_api_dialogue = ledger_api_dialogues.create( - **create_kwargs - ) - ledger_api_dialogue = cast(LedgerApiDialogue, ledger_api_dialogue) - request_nonce = self._get_request_nonce_from_dialogue(ledger_api_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - self.context.outbox.put_message(message=ledger_api_msg) - self.context.logger.debug("Sending transaction to ledger...") - - def _send_transaction_receipt_request( - self, - tx_digest: str, - retry_timeout: Optional[int] = None, - retry_attempts: Optional[int] = None, - **kwargs: Any, - ) -> None: - """ - Send transaction receipt request. - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (LedgerApiMessage | GET_TRANSACTION_RECEIPT) -> Ledger connection - Ledger connection -> (LedgerApiMessage | TRANSACTION_RECEIPT) -> AbstractRoundAbci skill - - :param tx_digest: transaction digest string - :param retry_timeout: retry timeout in seconds - :param retry_attempts: number of retry attempts - """ - ledger_api_dialogues = cast( - LedgerApiDialogues, self.context.ledger_api_dialogues - ) - ledger_api_msg, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=LEDGER_API_ADDRESS, - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, - transaction_digest=LedgerApiMessage.TransactionDigest( - ledger_id=self.context.default_ledger_id, body=tx_digest - ), - retry_timeout=retry_timeout, - retry_attempts=retry_attempts, - kwargs=LedgerApiMessage.Kwargs(kwargs), - ) - ledger_api_dialogue = cast(LedgerApiDialogue, ledger_api_dialogue) - request_nonce = self._get_request_nonce_from_dialogue(ledger_api_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - self.context.outbox.put_message(message=ledger_api_msg) - self.context.logger.debug( - f"Sending transaction receipt request for tx_digest='{tx_digest}'..." - ) - - def _handle_signing_failure(self) -> None: - """Handle signing failure.""" - self.context.logger.error("The transaction could not be signed!") - - def _submit_tx( - self, tx_bytes: bytes, timeout: Optional[float] = None - ) -> Generator[None, None, HttpMessage]: - """Send a broadcast_tx_sync request. - - Happy-path full flow of the messages. - - _do_request: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - :param tx_bytes: transaction bytes - :param timeout: timeout seconds - :yield: HttpMessage object - :return: http response - """ - request_message, http_dialogue = self._build_http_request_message( - "GET", - self.context.params.tendermint_url - + f"/broadcast_tx_sync?tx=0x{tx_bytes.hex()}", - ) - result = yield from self._do_request( - request_message, http_dialogue, timeout=timeout - ) - return result - - def _get_tx_info( - self, tx_hash: str, timeout: Optional[float] = None - ) -> Generator[None, None, HttpMessage]: - """ - Get transaction info from tx hash. - - Happy-path full flow of the messages. - - _do_request: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - :param tx_hash: transaction hash - :param timeout: timeout in seconds - :yield: HttpMessage object - :return: http response - """ - request_message, http_dialogue = self._build_http_request_message( - "GET", - self.context.params.tendermint_url + f"/tx?hash=0x{tx_hash}", - ) - result = yield from self._do_request( - request_message, http_dialogue, timeout=timeout - ) - return result - - def _get_status(self) -> Generator[None, None, HttpMessage]: - """ - Get Tendermint node's status. - - Happy-path full flow of the messages. - - _do_request: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - :yield: HttpMessage object - :return: http response from tendermint - """ - request_message, http_dialogue = self._build_http_request_message( - "GET", - self.context.params.tendermint_url + "/status", - ) - result = yield from self._do_request(request_message, http_dialogue) - return result - - def _get_netinfo( - self, timeout: Optional[float] = None - ) -> Generator[None, None, HttpMessage]: - """Makes a GET request to it's tendermint node's /net_info endpoint.""" - request_message, http_dialogue = self._build_http_request_message( - method="GET", url=f"{self.context.params.tendermint_url}/net_info" - ) - result = yield from self._do_request(request_message, http_dialogue, timeout) - return result - - def num_active_peers( - self, timeout: Optional[float] = None - ) -> Generator[None, None, Optional[int]]: - """Returns the number of active peers in the network.""" - try: - http_response = yield from self._get_netinfo(timeout) - http_ok = 200 - if http_response.status_code != http_ok: - # a bad response was received, we cannot retrieve the number of active peers - self.context.logger.warning( - f"`/net_info` responded with status {http_response.status_code}." - ) - return None - - res_body = json.loads(http_response.body) - num_peers_str = res_body.get("result", {}).get("n_peers", None) - if num_peers_str is None: - return None - num_peers = int(num_peers_str) - # num_peers hold the number of peers the tm node we are - # making the TX to currently has an active connection - # we add 1 because the node we are making the request through - # is not accounted for in this number - return num_peers + 1 - except TimeoutException: - self.context.logger.warning( - f"Couldn't retrieve `/net_info` response in {timeout}s." - ) - return None - - def get_callback_request(self) -> Callable[[Message, "BaseBehaviour"], None]: - """Wrapper for callback request which depends on whether the message has not been handled on time. - - :return: the request callback. - """ - - def callback_request( - message: Message, current_behaviour: BaseBehaviour - ) -> None: - """The callback request.""" - if self.is_stopped: - self.context.logger.debug( - "Dropping message as behaviour has stopped: %s", message - ) - elif self != current_behaviour: - self.handle_late_messages(self.behaviour_id, message) - elif self.state == AsyncBehaviour.AsyncState.WAITING_MESSAGE: - self.try_send(message) - else: - self.context.logger.warning( - "Could not send message to FSMBehaviour: %s", message - ) - - return callback_request - - def get_http_response( - self, - method: str, - url: str, - content: Optional[bytes] = None, - headers: Optional[Dict[str, str]] = None, - parameters: Optional[Dict[str, str]] = None, - ) -> Generator[None, None, HttpMessage]: - """ - Send an http request message from the skill context. - - This method is skill-specific, and therefore - should not be used elsewhere. - - Happy-path full flow of the messages. - - _do_request: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - :param method: the http request method (i.e. 'GET' or 'POST'). - :param url: the url to send the message to. - :param content: the payload. - :param headers: headers to be included. - :param parameters: url query parameters. - :yield: HttpMessage object - :return: the http message and the http dialogue - """ - http_message, http_dialogue = self._build_http_request_message( - method=method, - url=url, - content=content, - headers=headers, - parameters=parameters, - ) - response = yield from self._do_request(http_message, http_dialogue) - return response - - def _do_request( - self, - request_message: HttpMessage, - http_dialogue: HttpDialogue, - timeout: Optional[float] = None, - ) -> Generator[None, None, HttpMessage]: - """ - Do a request and wait the response, asynchronously. - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - :param request_message: The request message - :param http_dialogue: the HTTP dialogue associated to the request - :param timeout: seconds to wait for the reply. - :yield: HttpMessage object - :return: the response message - """ - self.context.outbox.put_message(message=request_message) - request_nonce = self._get_request_nonce_from_dialogue(http_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - # notify caller by propagating potential timeout exception. - response = yield from self.wait_for_message(timeout=timeout) - return response - - def _build_http_request_message( - self, - method: str, - url: str, - content: Optional[bytes] = None, - headers: Optional[Dict[str, str]] = None, - parameters: Optional[Dict[str, str]] = None, - ) -> Tuple[HttpMessage, HttpDialogue]: - """ - Send an http request message from the skill context. - - This method is skill-specific, and therefore - should not be used elsewhere. - - :param method: the http request method (i.e. 'GET' or 'POST'). - :param url: the url to send the message to. - :param content: the payload. - :param headers: headers to be included. - :param parameters: url query parameters. - :return: the http message and the http dialogue - """ - if parameters: - url = url + "?" - for key, val in parameters.items(): - url += f"{key}={val}&" - url = url[:-1] - - header_string = "" - if headers: - for key, val in headers.items(): - header_string += f"{key}: {val}\r\n" - - # context - http_dialogues = cast(HttpDialogues, self.context.http_dialogues) - - # http request message - request_http_message, http_dialogue = http_dialogues.create( - counterparty=str(HTTP_CLIENT_PUBLIC_ID), - performative=HttpMessage.Performative.REQUEST, - method=method, - url=url, - headers=header_string, - version="", - body=b"" if content is None else content, - ) - request_http_message = cast(HttpMessage, request_http_message) - http_dialogue = cast(HttpDialogue, http_dialogue) - return request_http_message, http_dialogue - - def _wait_until_transaction_delivered( - self, - tx_hash: str, - timeout: Optional[float] = None, - max_attempts: Optional[int] = None, - request_retry_delay: Optional[float] = None, - ) -> Generator[None, None, Tuple[bool, Optional[HttpMessage]]]: - """ - Wait until transaction is delivered. - - Happy-path full flow of the messages. - - _get_tx_info: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - - :param tx_hash: the transaction hash to check. - :param timeout: timeout - :param: request_retry_delay: the delay to wait after failed requests - :param: max_attempts: the maximun number of attempts - :yield: None - :return: True if it is delivered successfully, False otherwise - """ - if timeout is not None: - deadline = datetime.datetime.now() + datetime.timedelta(0, timeout) - else: - deadline = datetime.datetime.max - request_retry_delay = ( - self.params.request_retry_delay - if request_retry_delay is None - else request_retry_delay - ) - max_attempts = ( - self.params.max_attempts if max_attempts is None else max_attempts - ) - - response = None - for _ in range(max_attempts): - request_timeout = ( - (deadline - datetime.datetime.now()).total_seconds() - if timeout is not None - else None - ) - if request_timeout is not None and request_timeout < 0: - raise TimeoutException() - - response = yield from self._get_tx_info(tx_hash, timeout=request_timeout) - if response.status_code != 200: - yield from self.sleep(request_retry_delay) - continue - - try: - json_body = json.loads(response.body) - except json.JSONDecodeError as e: # pragma: nocover - raise ValueError( - f"Unable to decode response: {response} with body {str(response.body)}" - ) from e - tx_result = json_body["result"]["tx_result"] - return tx_result["code"] == OK_CODE, response - - return False, response - - @classmethod - def _check_http_return_code_200(cls, response: HttpMessage) -> bool: - """Check the HTTP response has return code 200.""" - return response.status_code == 200 - - def _get_default_terms(self) -> Terms: - """ - Get default transaction terms. - - :return: terms - """ - terms = Terms( - ledger_id=self.context.default_ledger_id, - sender_address=self.context.agent_address, - counterparty_address=self.context.agent_address, - amount_by_currency_id={}, - quantities_by_good_id={}, - nonce="", - ) - return terms - - def get_signature( - self, message: bytes, is_deprecated_mode: bool = False - ) -> Generator[None, None, str]: - """ - Get signature for message. - - Happy-path full flow of the messages. - - _send_signing_request: - AbstractRoundAbci skill -> (SigningMessage | SIGN_MESSAGE) -> DecisionMaker - DecisionMaker -> (SigningMessage | SIGNED_MESSAGE) -> AbstractRoundAbci skill - - :param message: message bytes - :param is_deprecated_mode: is deprecated mode flag - :yield: SigningMessage object - :return: message signature - """ - self._send_signing_request(message, is_deprecated_mode) - signature_response = yield from self.wait_for_message() - signature_response = cast(SigningMessage, signature_response) - if signature_response.performative == SigningMessage.Performative.ERROR: - self._handle_signing_failure() - raise RuntimeError("Internal error: failure during signing.") - signature_bytes = signature_response.signed_message.body - return signature_bytes - - def send_raw_transaction( - self, - transaction: RawTransaction, - use_flashbots: bool = False, - target_block_numbers: Optional[List[int]] = None, - raise_on_failed_simulation: bool = False, - chain_id: Optional[str] = None, - ) -> Generator[ - None, - Union[None, SigningMessage, LedgerApiMessage], - Tuple[Optional[str], RPCResponseStatus], - ]: - """ - Send raw transactions to the ledger for mining. - - Happy-path full flow of the messages. - - _send_transaction_signing_request: - AbstractRoundAbci skill -> (SigningMessage | SIGN_TRANSACTION) -> DecisionMaker - DecisionMaker -> (SigningMessage | SIGNED_TRANSACTION) -> AbstractRoundAbci skill - - _send_transaction_request: - AbstractRoundAbci skill -> (LedgerApiMessage | SEND_SIGNED_TRANSACTION) -> Ledger connection - Ledger connection -> (LedgerApiMessage | TRANSACTION_DIGEST) -> AbstractRoundAbci skill - - :param transaction: transaction data - :param use_flashbots: whether to use flashbots for the transaction or not - :param target_block_numbers: the target block numbers in case we are using flashbots - :param raise_on_failed_simulation: whether to raise an exception if the transaction fails the simulation or not - :param chain_id: the chain name to use for the ledger call - :yield: SigningMessage object - :return: transaction hash - """ - if chain_id is None: - chain_id = self.params.default_chain_id - - terms = Terms( - chain_id, - self.context.agent_address, - counterparty_address="", - amount_by_currency_id={}, - quantities_by_good_id={}, - nonce="", - ) - self.context.logger.info( - f"Sending signing request to ledger '{chain_id}' for transaction: {transaction}..." - ) - self._send_transaction_signing_request(transaction, terms) - signature_response = yield from self.wait_for_message() - signature_response = cast(SigningMessage, signature_response) - tx_hash_backup = signature_response.signed_transaction.body.get("hash") - if ( - signature_response.performative - != SigningMessage.Performative.SIGNED_TRANSACTION - ): - self.context.logger.error( - f"Error when requesting transaction signature: {signature_response}" - ) - return None, RPCResponseStatus.UNCLASSIFIED_ERROR - self.context.logger.info( - f"Received signature response: {signature_response}\n Sending transaction..." - ) - self._send_transaction_request( - signature_response, - use_flashbots, - target_block_numbers, - chain_id, - raise_on_failed_simulation, - ) - transaction_digest_msg = yield from self.wait_for_message() - transaction_digest_msg = cast(LedgerApiMessage, transaction_digest_msg) - performative = transaction_digest_msg.performative - if performative not in ( - LedgerApiMessage.Performative.TRANSACTION_DIGEST, - LedgerApiMessage.Performative.TRANSACTION_DIGESTS, - ): - error = f"Error when requesting transaction digest: {transaction_digest_msg.message}" - self.context.logger.error(error) - return tx_hash_backup, self.__parse_rpc_error(error) - - tx_hash = ( - # we do not support sending multiple messages and receiving multiple tx hashes yet - transaction_digest_msg.transaction_digests.transaction_digests[0] - if performative == LedgerApiMessage.Performative.TRANSACTION_DIGESTS - else transaction_digest_msg.transaction_digest.body - ) - - self.context.logger.info( - f"Transaction sent! Received transaction digest: {tx_hash}" - ) - - if tx_hash != tx_hash_backup: - # this should never happen - self.context.logger.error( - f"Unexpected error! The signature response's hash `{tx_hash_backup}` " - f"does not match the one received from the transaction response `{tx_hash}`!" - ) - return None, RPCResponseStatus.UNCLASSIFIED_ERROR - - return tx_hash, RPCResponseStatus.SUCCESS - - def get_transaction_receipt( - self, - tx_digest: str, - retry_timeout: Optional[int] = None, - retry_attempts: Optional[int] = None, - chain_id: Optional[str] = None, - ) -> Generator[None, None, Optional[Dict]]: - """ - Get transaction receipt. - - Happy-path full flow of the messages. - - _send_transaction_receipt_request: - AbstractRoundAbci skill -> (LedgerApiMessage | GET_TRANSACTION_RECEIPT) -> Ledger connection - Ledger connection -> (LedgerApiMessage | TRANSACTION_RECEIPT) -> AbstractRoundAbci skill - - :param tx_digest: transaction digest received from raw transaction. - :param retry_timeout: retry timeout. - :param retry_attempts: number of retry attempts allowed. - :yield: LedgerApiMessage object - :return: transaction receipt data - """ - if chain_id is None: - chain_id = self.params.default_chain_id - self._send_transaction_receipt_request( - tx_digest, retry_timeout, retry_attempts, chain_id=chain_id - ) - transaction_receipt_msg = yield from self.wait_for_message() - if ( - transaction_receipt_msg.performative == LedgerApiMessage.Performative.ERROR - ): # pragma: nocover - self.context.logger.error( - f"Error when requesting transaction receipt: {transaction_receipt_msg.message}" - ) - return None - tx_receipt = transaction_receipt_msg.transaction_receipt.receipt - return tx_receipt - - def get_ledger_api_response( - self, - performative: LedgerApiMessage.Performative, - ledger_callable: str, - **kwargs: Any, - ) -> Generator[None, None, LedgerApiMessage]: - """ - Request data from ledger api - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (LedgerApiMessage | LedgerApiMessage.Performative) -> Ledger connection - Ledger connection -> (LedgerApiMessage | LedgerApiMessage.Performative) -> AbstractRoundAbci skill - - :param performative: the message performative - :param ledger_callable: the callable to call on the contract - :param kwargs: keyword argument for the contract api request - :return: the contract api response - :yields: the contract api response - """ - ledger_api_dialogues = cast( - LedgerApiDialogues, self.context.ledger_api_dialogues - ) - kwargs = { - "performative": performative, - "counterparty": LEDGER_API_ADDRESS, - "ledger_id": self.context.default_ledger_id, - "callable": ledger_callable, - "kwargs": LedgerApiMessage.Kwargs(kwargs), - "args": tuple(), - } - ledger_api_msg, ledger_api_dialogue = ledger_api_dialogues.create(**kwargs) - ledger_api_dialogue = cast( - LedgerApiDialogue, - ledger_api_dialogue, - ) - ledger_api_dialogue.terms = self._get_default_terms() - request_nonce = self._get_request_nonce_from_dialogue(ledger_api_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - self.context.outbox.put_message(message=ledger_api_msg) - response = yield from self.wait_for_message() - return response - - def get_contract_api_response( - self, - performative: ContractApiMessage.Performative, - contract_address: Optional[str], - contract_id: str, - contract_callable: str, - ledger_id: Optional[str] = None, - **kwargs: Any, - ) -> Generator[None, None, ContractApiMessage]: - """ - Request contract safe transaction hash - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (ContractApiMessage | ContractApiMessage.Performative) -> Ledger connection (contract dispatcher) - Ledger connection (contract dispatcher) -> (ContractApiMessage | ContractApiMessage.Performative) -> AbstractRoundAbci skill - - :param performative: the message performative - :param contract_address: the contract address - :param contract_id: the contract id - :param contract_callable: the callable to call on the contract - :param ledger_id: the ledger id, if not specified, the default ledger id is used - :param kwargs: keyword argument for the contract api request - :return: the contract api response - :yields: the contract api response - """ - contract_api_dialogues = cast( - ContractApiDialogues, self.context.contract_api_dialogues - ) - kwargs = { - "performative": performative, - "counterparty": LEDGER_API_ADDRESS, - "ledger_id": ledger_id or self.context.default_ledger_id, - "contract_id": contract_id, - "callable": contract_callable, - "kwargs": ContractApiMessage.Kwargs(kwargs), - } - if contract_address is not None: - kwargs["contract_address"] = contract_address - contract_api_msg, contract_api_dialogue = contract_api_dialogues.create( - **kwargs - ) - contract_api_dialogue = cast( - ContractApiDialogue, - contract_api_dialogue, - ) - contract_api_dialogue.terms = self._get_default_terms() - request_nonce = self._get_request_nonce_from_dialogue(contract_api_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - self.context.outbox.put_message(message=contract_api_msg) - response = yield from self.wait_for_message() - return response - - @staticmethod - def __parse_rpc_error(error: str) -> RPCResponseStatus: - """Parse an RPC error and return an `RPCResponseStatus`""" - if "replacement transaction underpriced" in error: - return RPCResponseStatus.UNDERPRICED - if "nonce too low" in error: - return RPCResponseStatus.INCORRECT_NONCE - if "insufficient funds" in error: - return RPCResponseStatus.INSUFFICIENT_FUNDS - if "already known" in error: - return RPCResponseStatus.ALREADY_KNOWN - if "Simulation failed for bundle" in error: - return RPCResponseStatus.SIMULATION_FAILED - return RPCResponseStatus.UNCLASSIFIED_ERROR - - def _acn_request_from_pending( - self, performative: TendermintMessage.Performative - ) -> Generator: - """Perform an ACN request to each one of the agents which have not sent a response yet.""" - not_responded_yet = { - address - for address, deliverable in self.shared_state.address_to_acn_deliverable.items() - if deliverable is None - } - - if len(not_responded_yet) == 0: - return - - self.context.logger.debug(f"Need ACN response from {not_responded_yet}.") - for address in not_responded_yet: - self.context.logger.debug(f"Sending ACN request to {address}.") - dialogues = cast(TendermintDialogues, self.context.tendermint_dialogues) - message, _ = dialogues.create( - counterparty=address, performative=performative - ) - message = cast(TendermintMessage, message) - context = EnvelopeContext(connection_id=P2P_LIBP2P_CLIENT_PUBLIC_ID) - self.context.outbox.put_message(message=message, context=context) - - # we wait for the `address_to_acn_deliverable` to be populated with the responses (done by the tm handler) - yield from self.sleep(self.params.sleep_time) - - def _perform_acn_request( - self, performative: TendermintMessage.Performative - ) -> Generator[None, None, Any]: - """Perform an ACN request. - - Waits `sleep_time` to receive a common response from the majority of the agents. - Retries `max_attempts` times only for the agents which have not responded yet. - - :param performative: the ACN request performative. - :return: the result that the majority of the agents sent. If majority cannot be reached, returns `None`. - """ - # reset the ACN deliverables at the beginning of a new request - self.shared_state.address_to_acn_deliverable = self.shared_state.acn_container() - - result = None - for i in range(self.params.max_attempts): - self.context.logger.debug( - f"ACN attempt {i + 1}/{self.params.max_attempts}." - ) - yield from self._acn_request_from_pending(performative) - - result = self.shared_state.get_acn_result() - if result is not None: - break - - return result - - def request_recovery_params(self, should_log: bool) -> Generator[None, None, bool]: - """Request the Tendermint recovery parameters from the other agents via the ACN.""" - - if should_log: - self.context.logger.info( - "Requesting the Tendermint recovery parameters from the other agents via the ACN..." - ) - - performative = TendermintMessage.Performative.GET_RECOVERY_PARAMS - acn_result = yield from self._perform_acn_request(performative) # type: ignore - - if acn_result is None: - if should_log: - self.context.logger.warning( - "No majority has been reached for the Tendermint recovery parameters request via the ACN." - ) - return False - - self.shared_state.tm_recovery_params = acn_result - if should_log: - self.context.logger.info( - f"Updated the Tendermint recovery parameters from the other agents via the ACN: {acn_result}" - ) - return True - - @property - def hard_reset_sleep(self) -> float: - """ - Amount of time to sleep before and after performing a hard reset. - - We sleep for half the reset pause duration as there are no immediate transactions on either side of the reset. - - :returns: the amount of time to sleep in seconds - """ - return self.params.reset_pause_duration / 2 - - def _start_reset(self, on_startup: bool = False) -> Generator: - """ - Start tendermint reset. - - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - - :param on_startup: Whether we are resetting on the start of the agent. - :yield: None - """ - if self._check_started is None and not self._is_healthy: - if not on_startup: - # if we are on startup we don't need to wait for the reset pause duration - # as the reset is being performed to update the tm config. - yield from self.wait_from_last_timestamp(self.hard_reset_sleep) - self._check_started = datetime.datetime.now() - self._timeout = self.params.max_healthcheck - self._is_healthy = False - yield - - def _end_reset( - self, - ) -> None: - """End tendermint reset. - - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - """ - self._check_started = None - self._timeout = -1.0 - self._is_healthy = True - - def _is_timeout_expired(self) -> bool: - """Check if the timeout expired. - - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - - :return: bool - """ - if self._check_started is None or self._is_healthy: - return False - return datetime.datetime.now() > self._check_started + datetime.timedelta( - 0, self._timeout - ) - - def _get_reset_params(self, default: bool) -> Optional[Dict[str, str]]: - """Get the parameters for a hard reset request to Tendermint.""" - if default: - return None - - last_round_transition_timestamp = ( - self.round_sequence.last_round_transition_timestamp - ) - genesis_time = last_round_transition_timestamp.astimezone(pytz.UTC).strftime( - GENESIS_TIME_FMT - ) - return { - "genesis_time": genesis_time, - "initial_height": INITIAL_HEIGHT, - "period_count": str(self.synchronized_data.period_count), - } - - def reset_tendermint_with_wait( # pylint: disable=too-many-locals, too-many-statements - self, - on_startup: bool = False, - is_recovery: bool = False, - ) -> Generator[None, None, bool]: - """ - Performs a hard reset (unsafe-reset-all) on the tendermint node. - - :param on_startup: whether we are resetting on the start of the agent. - :param is_recovery: whether the reset is being performed to recover the agent <-> tm communication. - :yields: None - :returns: whether the reset was successful. - """ - yield from self._start_reset(on_startup=on_startup) - if self._is_timeout_expired(): - # if the Tendermint node cannot update the app then the app cannot work - raise RuntimeError("Error resetting tendermint node.") - - if not self._is_healthy: - self.context.logger.info( - f"Resetting tendermint node at end of period={self.synchronized_data.period_count}." - ) - - backup_blockchain = self.round_sequence.blockchain - self.round_sequence.reset_blockchain() - reset_params = self._get_reset_params(on_startup) - request_message, http_dialogue = self._build_http_request_message( - "GET", - self.params.tendermint_com_url + "/hard_reset", - parameters=reset_params, - ) - result = yield from self._do_request(request_message, http_dialogue) - try: - response = json.loads(result.body.decode()) - if response.get("status"): - self.context.logger.debug(response.get("message")) - self.context.logger.info("Resetting tendermint node successful!") - is_replay = response.get("is_replay", False) - if is_replay: - # in case of replay, the local blockchain should be set up differently. - self.round_sequence.reset_blockchain( - is_replay=is_replay, is_init=True - ) - for handler_name in self.context.handlers.__dict__.keys(): - dialogues = getattr(self.context, f"{handler_name}_dialogues") - dialogues.cleanup() - if not is_recovery: - # in case of successful reset we store the reset params in the shared state, - # so that in the future if the communication with tendermint breaks, and we need to - # perform a hard reset to restore it, we can use these as the right ones - round_count = self.synchronized_data.db.round_count - 1 - # in case we need to reset in order to recover agent <-> tm communication - # we store this round as the one to start from - restart_from_round = self.matching_round - self.shared_state.tm_recovery_params = TendermintRecoveryParams( - reset_params=reset_params, - round_count=round_count, - reset_from_round=restart_from_round.auto_round_id(), - serialized_db_state=self.shared_state.synchronized_data.db.serialize(), - ) - self.round_sequence.abci_app.cleanup( - self.params.cleanup_history_depth, - self.params.cleanup_history_depth_current, - ) - self._end_reset() - - else: - msg = response.get("message") - self.round_sequence.blockchain = backup_blockchain - self.context.logger.error(f"Error resetting: {msg}") - yield from self.sleep(self.params.sleep_time) - return False - except json.JSONDecodeError: - self.context.logger.error( - "Error communicating with tendermint com server." - ) - self.round_sequence.blockchain = backup_blockchain - yield from self.sleep(self.params.sleep_time) - return False - - status = yield from self._get_status() - try: - json_body = json.loads(status.body.decode()) - except json.JSONDecodeError: - self.context.logger.error( - "Tendermint not accepting transactions yet, trying again!" - ) - yield from self.sleep(self.params.sleep_time) - return False - - remote_height = int(json_body["result"]["sync_info"]["latest_block_height"]) - local_height = self.round_sequence.height - if local_height != remote_height: - self.context.logger.warning( - f"local height ({local_height}) != remote height ({remote_height}); retrying..." - ) - yield from self.sleep(self.params.sleep_time) - return False - - self.context.logger.info( - f"local height == remote height == {local_height}; continuing execution..." - ) - if not on_startup: - # if we are on startup we don't need to wait for the reset pause duration - # as the reset is being performed to update the tm config. - yield from self.wait_from_last_timestamp(self.hard_reset_sleep) - self._is_healthy = False - return True - - def send_to_ipfs( # pylint: disable=too-many-arguments - self, - filename: str, - obj: SupportedObjectType, - multiple: bool = False, - filetype: Optional[SupportedFiletype] = None, - custom_storer: Optional[CustomStorerType] = None, - timeout: Optional[float] = None, - **kwargs: Any, - ) -> Generator[None, None, Optional[str]]: - """ - Store an object on IPFS. - - :param filename: the file name to store obj in. If "multiple" is True, filename will be the name of the dir. - :param obj: the object(s) to serialize and store in IPFS as "filename". - :param multiple: whether obj should be stored as multiple files, i.e. directory. - :param filetype: the file type of the object being downloaded. - :param custom_storer: a custom serializer for "obj". - :param timeout: timeout for the request. - :returns: the downloaded object, corresponding to ipfs_hash. - """ - try: - message, dialogue = self._build_ipfs_store_file_req( - filename, - obj, - multiple, - filetype, - custom_storer, - timeout, - **kwargs, - ) - ipfs_message = yield from self._do_ipfs_request(dialogue, message, timeout) - if ipfs_message.performative != IpfsMessage.Performative.IPFS_HASH: - self.context.logger.error( - f"Expected performative {IpfsMessage.Performative.IPFS_HASH} but got {ipfs_message.performative}." - ) - return None - ipfs_hash = ipfs_message.ipfs_hash - self.context.logger.info( - f"Successfully stored {filename} to IPFS with hash: {ipfs_hash}" - ) - return ipfs_hash - except IPFSInteractionError as e: # pragma: no cover - self.context.logger.error( - f"An error occurred while trying to send a file to IPFS: {str(e)}" - ) - return None - - def get_from_ipfs( # pylint: disable=too-many-arguments - self, - ipfs_hash: str, - filetype: Optional[SupportedFiletype] = None, - custom_loader: CustomLoaderType = None, - timeout: Optional[float] = None, - ) -> Generator[None, None, Optional[SupportedObjectType]]: - """ - Gets an object from IPFS. - - :param ipfs_hash: the ipfs hash of the file/dir to download. - :param filetype: the file type of the object being downloaded. - :param custom_loader: a custom deserializer for the object received from IPFS. - :param timeout: timeout for the request. - :returns: the downloaded object, corresponding to ipfs_hash. - """ - try: - message, dialogue = self._build_ipfs_get_file_req(ipfs_hash, timeout) - ipfs_message = yield from self._do_ipfs_request(dialogue, message, timeout) - if ipfs_message.performative != IpfsMessage.Performative.FILES: - self.context.logger.error( - f"Expected performative {IpfsMessage.Performative.FILES} but got {ipfs_message.performative}." - ) - return None - serialized_objects = ipfs_message.files - deserialized_objects = self._deserialize_ipfs_objects( - serialized_objects, filetype, custom_loader - ) - self.context.logger.info( - f"Retrieved {len(ipfs_message.files)} objects from ipfs." - ) - return deserialized_objects - except IPFSInteractionError as e: - self.context.logger.error( - f"An error occurred while trying to fetch a file from IPFS: {str(e)}" - ) - return None - - def _do_ipfs_request( - self, - dialogue: IpfsDialogue, - message: IpfsMessage, - timeout: Optional[float] = None, - ) -> Generator[None, None, IpfsMessage]: - """Performs an IPFS request, and asynchronosuly waits for response.""" - self.context.outbox.put_message(message=message) - request_nonce = self._get_request_nonce_from_dialogue(dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - # notify caller by propagating potential timeout exception. - response = yield from self.wait_for_message(timeout=timeout) - ipfs_message = cast(IpfsMessage, response) - return ipfs_message - - -class TmManager(BaseBehaviour): - """Util class to be used for managing the tendermint node.""" - - _active_generator: Optional[Generator] = None - _hard_reset_sleep = 20.0 # 20s - _max_reset_retry = 5 - - # TODO: TmManager is not a BaseBehaviour. It should be - # redesigned! - matching_round = Type[AbstractRound] - - def __init__(self, **kwargs: Any): - """Initialize the `TmManager`.""" - super().__init__(**kwargs) - # whether the initiation of a tm fix has been logged - self.informed: bool = False - self.acn_communication_attempted: bool = False - - def async_act(self) -> Generator: - """The behaviour act.""" - self.context.logger.error( - f"{type(self).__name__}'s async_act was called. " - f"This is not allowed as this class is not a behaviour. " - f"Exiting the agent." - ) - error_code = 1 - yield - sys.exit(error_code) - - @property - def is_acting(self) -> bool: - """This method returns whether there is an active fix being applied.""" - return self._active_generator is not None - - @property - def hard_reset_sleep(self) -> float: - """ - Amount of time to sleep before and after performing a hard reset. - - We don't need to wait for half the reset pause duration, like in normal cases where we perform a hard reset. - - :returns: the amount of time to sleep in seconds - """ - return self._hard_reset_sleep - - def _gentle_reset(self) -> Generator[None, None, None]: - """Perform a gentle reset of the Tendermint node.""" - self.context.logger.debug("Performing a gentle reset...") - request_message, http_dialogue = self._build_http_request_message( - "GET", - self.params.tendermint_com_url + "/gentle_reset", - ) - yield from self._do_request(request_message, http_dialogue) - - def _handle_unhealthy_tm(self) -> Generator: - """This method handles the case when the tendermint node is unhealthy.""" - if not self.informed: - self.context.logger.warning( - "The local deadline for the next `begin_block` request from the Tendermint node has expired! " - "Trying to reset local Tendermint node as there could be something wrong with the communication." - ) - self.informed = True - - if not self.gentle_reset_attempted: - self.gentle_reset_attempted = True - yield from self._gentle_reset() - yield from self._check_sync() - return - - is_multi_agent_service = self.synchronized_data.max_participants > 1 - if is_multi_agent_service: - # since we have reached this point, that means that the cause of blocks not being received - # cannot be fixed with a simple gentle reset, - # therefore, we request the recovery parameters via the ACN, and if we succeed, we use them to recover - # we do not need to request the recovery parameters if this is a single-agent service - acn_communication_success = yield from self.request_recovery_params( - should_log=not self.acn_communication_attempted - ) - if not acn_communication_success: - if not self.acn_communication_attempted: - self.context.logger.error( - "Failed to get the recovery parameters via the ACN. Cannot reset Tendermint." - ) - self.acn_communication_attempted = True - return - - recovery_params = self.shared_state.tm_recovery_params - self.round_sequence.reset_state( - restart_from_round=recovery_params.reset_from_round, - round_count=recovery_params.round_count, - serialized_db_state=recovery_params.serialized_db_state, - ) - - for _ in range(self._max_reset_retry): - reset_successfully = yield from self.reset_tendermint_with_wait( - on_startup=True, - is_recovery=True, - ) - if reset_successfully: - self.context.logger.info("Tendermint reset was successfully performed.") - # we sleep to give some time for tendermint to start sending us blocks - # otherwise we might end-up assuming that tendermint is still not working. - # Note that the wait_from_last_timestamp() in reset_tendermint_with_wait() - # doesn't guarantee us this, since the block stall deadline is greater than the - # hard_reset_sleep, 60s vs 20s. In other words, we haven't received a block for at - # least 60s, so wait_from_last_timestamp() will return immediately. - # By setting "on_startup" to True in the reset_tendermint_with_wait() call above, - # wait_from_last_timestamp() will not be called at all. - yield from self.sleep(self.hard_reset_sleep) - self.gentle_reset_attempted = False - return - - self.context.logger.error("Failed to reset tendermint.") - - def _get_reset_params(self, default: bool) -> Optional[Dict[str, str]]: - """ - Get the parameters for a hard reset request when trying to recover agent <-> tendermint communication. - - :param default: ignored for this use case. - :returns: the reset params. - """ - # we get the params from the latest successful reset, if they are not available, - # i.e. no successful reset has been performed, we return None. - # Returning None means default params will be used. - return self.shared_state.tm_recovery_params.reset_params - - def get_callback_request(self) -> Callable[[Message, "BaseBehaviour"], None]: - """Wrapper for callback_request(), overridden to remove checks not applicable to TmManager.""" - - def callback_request( - message: Message, _current_behaviour: BaseBehaviour - ) -> None: - """ - This method gets called when a response for a prior request is received. - - Overridden to remove the check that checks whether the behaviour that made the request is still active. - The received message gets passed to the behaviour that invoked it, in this case it's always the TmManager. - - :param message: the response. - :param _current_behaviour: not used, left in to satisfy the interface. - :return: none - """ - if self.state == AsyncBehaviour.AsyncState.WAITING_MESSAGE: - self.try_send(message) - else: - self.context.logger.warning( - "Could not send message to TmManager: %s", message - ) - - return callback_request - - def try_fix(self) -> None: - """This method tries to fix an unhealthy tendermint node.""" - if self._active_generator is None: - # There is no active generator set, we need to create one. - # A generator being active means that a reset operation is - # being performed. - self._active_generator = self._handle_unhealthy_tm() - try: - # if the behaviour is waiting for a message - # we check whether one has arrived, and if it has - # we send it to the generator. - if self.state == self.AsyncState.WAITING_MESSAGE: - if self.is_notified: - self._active_generator.send(self.received_message) - self._on_sent_message() - # note that if the behaviour is waiting for - # a message, we deliberately don't send a tick - # this was done to have consistency between - # the act here, and acts on normal AsyncBehaviours - return - # this will run the active generator until - # the first yield statement is encountered - self._active_generator.send(None) - - except StopIteration: - # the generator is finished - self.context.logger.debug("Applying tendermint fix finished.") - self._active_generator = None - # the following is required because the message - # 'tick' might be the last one the generator needs - # to complete. In that scenario, we need to call - # the callback here - if self.is_notified: - self._on_sent_message() - - -class DegenerateBehaviour(BaseBehaviour, ABC): - """An abstract matching behaviour for final and degenerate rounds.""" - - matching_round: Type[AbstractRound] - is_degenerate: bool = True - sleep_time_before_exit = 5.0 - - def async_act(self) -> Generator: - """Exit the agent with error when a degenerate round is reached.""" - self.context.logger.error( - "The execution reached a degenerate behaviour. " - "This means a degenerate round has been reached during " - "the execution of the ABCI application. Please check the " - "functioning of the ABCI app." - ) - self.context.logger.error( - f"Sleeping {self.sleep_time_before_exit} seconds before exiting." - ) - yield from self.sleep(self.sleep_time_before_exit) - error_code = 1 - sys.exit(error_code) - - -def make_degenerate_behaviour( - round_cls: Type[AbstractRound], -) -> Type[DegenerateBehaviour]: - """Make a degenerate behaviour class.""" - - class NewDegenerateBehaviour(DegenerateBehaviour): - """A newly defined degenerate behaviour class.""" - - matching_round = round_cls - - new_behaviour_cls = NewDegenerateBehaviour - new_behaviour_cls.__name__ = f"DegenerateBehaviour_{round_cls.auto_round_id()}" # pylint: disable=attribute-defined-outside-init - return new_behaviour_cls diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/behaviours.py b/trader_backup/vendor/valory/skills/abstract_round_abci/behaviours.py deleted file mode 100644 index fcf69ea0c..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/behaviours.py +++ /dev/null @@ -1,409 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the behaviours for the 'abstract_round_abci' skill.""" - -from abc import ABC, ABCMeta -from collections import defaultdict -from dataclasses import asdict -from typing import ( - AbstractSet, - Any, - Dict, - Generator, - Generic, - List, - Optional, - Set, - Tuple, - Type, - cast, -) - -from aea.skills.base import Behaviour - -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciApp, - AbstractRound, - EventType, - PendingOffencesPayload, - PendingOffencesRound, - PendingOffense, - RoundSequence, -) -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - BaseBehaviour, - TmManager, - make_degenerate_behaviour, -) -from packages.valory.skills.abstract_round_abci.models import SharedState - - -SLASHING_BACKGROUND_BEHAVIOUR_ID = "slashing_check_behaviour" -TERMINATION_BACKGROUND_BEHAVIOUR_ID = "background_behaviour" - - -BehaviourType = Type[BaseBehaviour] -Action = Optional[str] -TransitionFunction = Dict[BehaviourType, Dict[Action, BehaviourType]] - - -class _MetaRoundBehaviour(ABCMeta): - """A metaclass that validates AbstractRoundBehaviour's attributes.""" - - are_background_behaviours_set: bool = False - - def __new__(mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any) -> Type: # type: ignore - """Initialize the class.""" - new_cls = super().__new__(mcs, name, bases, namespace, **kwargs) - - if ABC in bases: - # abstract class, return - return new_cls - if not issubclass(new_cls, AbstractRoundBehaviour): - # the check only applies to AbstractRoundBehaviour subclasses - return new_cls - - mcs.are_background_behaviours_set = bool( - new_cls.background_behaviours_cls - {PendingOffencesBehaviour} - ) - mcs._check_consistency(cast(AbstractRoundBehaviour, new_cls)) - return new_cls - - @classmethod - def _check_consistency(mcs, behaviour_cls: "AbstractRoundBehaviour") -> None: - """Check consistency of class attributes.""" - mcs._check_all_required_classattributes_are_set(behaviour_cls) - mcs._check_behaviour_id_uniqueness(behaviour_cls) - mcs._check_initial_behaviour_in_set_of_behaviours(behaviour_cls) - mcs._check_matching_round_consistency(behaviour_cls) - - @classmethod - def _check_all_required_classattributes_are_set( - mcs, behaviour_cls: "AbstractRoundBehaviour" - ) -> None: - """Check that all the required class attributes are set.""" - try: - _ = behaviour_cls.abci_app_cls - _ = behaviour_cls.behaviours - _ = behaviour_cls.initial_behaviour_cls - except AttributeError as e: - raise ABCIAppInternalError(*e.args) from None - - @classmethod - def _check_behaviour_id_uniqueness( - mcs, behaviour_cls: "AbstractRoundBehaviour" - ) -> None: - """Check that behaviour ids are unique across behaviours.""" - behaviour_id_to_behaviour = defaultdict(lambda: []) - for behaviour_class in behaviour_cls.behaviours: - behaviour_id_to_behaviour[behaviour_class.auto_behaviour_id()].append( - behaviour_class - ) - if len(behaviour_id_to_behaviour[behaviour_class.auto_behaviour_id()]) > 1: - behaviour_classes_names = [ - _behaviour_cls.__name__ - for _behaviour_cls in behaviour_id_to_behaviour[ - behaviour_class.auto_behaviour_id() - ] - ] - raise ABCIAppInternalError( - f"behaviours {behaviour_classes_names} have the same behaviour id '{behaviour_class.auto_behaviour_id()}'" - ) - - @classmethod - def _check_matching_round_consistency( - mcs, behaviour_cls: "AbstractRoundBehaviour" - ) -> None: - """Check that matching rounds are: (1) unique across behaviour, and (2) covering.""" - matching_bg_round_classes = { - behaviour_cls.matching_round - for behaviour_cls in behaviour_cls.background_behaviours_cls - } - round_to_behaviour: Dict[Type[AbstractRound], List[BehaviourType]] = { - round_cls: [] - for round_cls in behaviour_cls.abci_app_cls.get_all_round_classes( - matching_bg_round_classes, - mcs.are_background_behaviours_set, - ) - } - - # check uniqueness - for b in behaviour_cls.behaviours: - behaviours = round_to_behaviour.get(b.matching_round, None) - if behaviours is None: - raise ABCIAppInternalError( - f"Behaviour {b.behaviour_id!r} specifies unknown {b.matching_round!r} as a matching round. " - "Please make sure that the round is implemented and belongs to the FSM. " - f"If {b.behaviour_id!r} is a background behaviour, please make sure that it is set correctly, " - f"by overriding the corresponding attribute of the chained skill's behaviour." - ) - behaviours.append(b) - if len(behaviours) > 1: - behaviour_cls_ids = [ - behaviour_cls_.auto_behaviour_id() for behaviour_cls_ in behaviours - ] - raise ABCIAppInternalError( - f"behaviours {behaviour_cls_ids} have the same matching round '{b.matching_round.auto_round_id()}'" - ) - - # check covering - for round_cls, behaviours in round_to_behaviour.items(): - if round_cls in behaviour_cls.abci_app_cls.final_states: - if len(behaviours) != 0: - raise ABCIAppInternalError( - f"round {round_cls.auto_round_id()} is a final round it shouldn't have any matching behaviours." - ) - elif len(behaviours) == 0: - raise ABCIAppInternalError( - f"round {round_cls.auto_round_id()} is not a matching round of any behaviour" - ) - - @classmethod - def _check_initial_behaviour_in_set_of_behaviours( - mcs, behaviour_cls: "AbstractRoundBehaviour" - ) -> None: - """Check the initial behaviour is in the set of behaviours.""" - if behaviour_cls.initial_behaviour_cls not in behaviour_cls.behaviours: - raise ABCIAppInternalError( - f"initial behaviour {behaviour_cls.initial_behaviour_cls.auto_behaviour_id()} is not in the set of behaviours" - ) - - -class PendingOffencesBehaviour(BaseBehaviour): - """A behaviour responsible for checking whether there are any pending offences.""" - - matching_round = PendingOffencesRound - - @property - def round_sequence(self) -> RoundSequence: - """Get the round sequence from the shared state.""" - return cast(SharedState, self.context.state).round_sequence - - @property - def pending_offences(self) -> Set[PendingOffense]: - """Get the pending offences from the round sequence.""" - return self.round_sequence.pending_offences - - def has_pending_offences(self) -> bool: - """Check if there are any pending offences.""" - return bool(len(self.pending_offences)) - - def async_act(self) -> Generator: - """ - Checks the pending offences. - - This behaviour simply checks if the set of pending offences is not empty. - When it’s not empty, it pops the offence from the set, and sends it to the rest of the agents via a payload - - :return: None - :yield: None - """ - yield from self.wait_for_condition(self.has_pending_offences) - offence = self.pending_offences.pop() - offence_detected_log = ( - f"An offence of type {offence.offense_type.name} has been detected " - f"for agent with address {offence.accused_agent_address} during round {offence.round_count}. " - ) - offence_expiration = offence.last_transition_timestamp + offence.time_to_live - last_timestamp = self.round_sequence.last_round_transition_timestamp - - if offence_expiration < last_timestamp.timestamp(): - ignored_log = "Offence will be ignored as it has expired." - self.context.logger.info(offence_detected_log + ignored_log) - return - - sharing_log = "Sharing offence with the other agents." - self.context.logger.info(offence_detected_log + sharing_log) - - payload = PendingOffencesPayload( - self.context.agent_address, *asdict(offence).values() - ) - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - self.set_done() - - -class AbstractRoundBehaviour( # pylint: disable=too-many-instance-attributes - Behaviour, ABC, Generic[EventType], metaclass=_MetaRoundBehaviour -): - """This behaviour implements an abstract round behaviour.""" - - abci_app_cls: Type[AbciApp[EventType]] - behaviours: AbstractSet[BehaviourType] - initial_behaviour_cls: BehaviourType - background_behaviours_cls: Set[BehaviourType] = {PendingOffencesBehaviour} # type: ignore - - def __init__(self, **kwargs: Any) -> None: - """Initialize the behaviour.""" - super().__init__(**kwargs) - self._behaviour_id_to_behaviours: Dict[ - str, BehaviourType - ] = self._get_behaviour_id_to_behaviour_mapping(self.behaviours) - self._round_to_behaviour: Dict[ - Type[AbstractRound], BehaviourType - ] = self._get_round_to_behaviour_mapping(self.behaviours) - - self.current_behaviour: Optional[BaseBehaviour] = None - self.background_behaviours: Set[BaseBehaviour] = set() - self.tm_manager: Optional[TmManager] = None - # keep track of last round height so to detect changes - self._last_round_height = 0 - - # this variable remembers the actual next transition - # when we cannot preemptively interrupt the current behaviour - # because it has not a matching round. - self._next_behaviour_cls: Optional[BehaviourType] = None - - @classmethod - def _get_behaviour_id_to_behaviour_mapping( - cls, behaviours: AbstractSet[BehaviourType] - ) -> Dict[str, BehaviourType]: - """Get behaviour id to behaviour mapping.""" - result: Dict[str, BehaviourType] = {} - for behaviour_cls in behaviours: - behaviour_id = behaviour_cls.auto_behaviour_id() - if behaviour_id in result: - raise ValueError( - f"cannot have two behaviours with the same id; got {behaviour_cls} and {result[behaviour_id]} both with id '{behaviour_id}'" - ) - result[behaviour_id] = behaviour_cls - return result - - @classmethod - def _get_round_to_behaviour_mapping( - cls, behaviours: AbstractSet[BehaviourType] - ) -> Dict[Type[AbstractRound], BehaviourType]: - """Get round-to-behaviour mapping.""" - result: Dict[Type[AbstractRound], BehaviourType] = {} - for behaviour_cls in behaviours: - round_cls = behaviour_cls.matching_round - if round_cls in result: - raise ValueError( - f"the behaviours '{behaviour_cls.auto_behaviour_id()}' and '{result[round_cls].auto_behaviour_id()}' point to the same matching round '{round_cls.auto_round_id()}'" - ) - result[round_cls] = behaviour_cls - - # iterate over rounds and map final (i.e. degenerate) rounds - # to the degenerate behaviour class - for final_round_cls in cls.abci_app_cls.final_states: - new_degenerate_behaviour = make_degenerate_behaviour(final_round_cls) - new_degenerate_behaviour.matching_round = final_round_cls - result[final_round_cls] = new_degenerate_behaviour - - return result - - def instantiate_behaviour_cls(self, behaviour_cls: BehaviourType) -> BaseBehaviour: - """Instantiate the behaviours class.""" - return behaviour_cls( - name=behaviour_cls.auto_behaviour_id(), skill_context=self.context - ) - - def _setup_background(self) -> None: - """Set up the background behaviours.""" - params = cast(BaseBehaviour, self.current_behaviour).params - for background_cls in self.background_behaviours_cls: - background_cls = cast(Type[BaseBehaviour], background_cls) - - if ( - not params.use_termination - and background_cls.auto_behaviour_id() - == TERMINATION_BACKGROUND_BEHAVIOUR_ID - ) or ( - not params.use_slashing - and background_cls.auto_behaviour_id() - == SLASHING_BACKGROUND_BEHAVIOUR_ID - or background_cls == PendingOffencesBehaviour - ): - # comparing with the behaviour id is not entirely safe, as there is a potential for conflicts - # if a user creates a behaviour with the same name - continue - - self.background_behaviours.add( - self.instantiate_behaviour_cls(background_cls) - ) - - def setup(self) -> None: - """Set up the behaviours.""" - self.current_behaviour = self.instantiate_behaviour_cls( - self.initial_behaviour_cls - ) - self.tm_manager = self.instantiate_behaviour_cls(TmManager) # type: ignore - self._setup_background() - - def teardown(self) -> None: - """Tear down the behaviour""" - - def _background_act(self) -> None: - """Call the act wrapper for the background behaviours.""" - for behaviour in self.background_behaviours: - behaviour.act_wrapper() - - def act(self) -> None: - """Implement the behaviour.""" - tm_manager = cast(TmManager, self.tm_manager) - if tm_manager.tm_communication_unhealthy or tm_manager.is_acting: - # tendermint is not healthy, or we are already applying a fix. - # try_fix() internally uses generators, that's why it's relevant - # to know whether a fix is already being applied. - # It might happen that tendermint is healthy, but the fix is not yet finished. - tm_manager.try_fix() - return - - tm_manager.informed = False - tm_manager.acn_communication_attempted = False - self._process_current_round() - if self.current_behaviour is None: - return - - self.current_behaviour.act_wrapper() - if self.current_behaviour.is_done(): - self.current_behaviour.clean_up() - self.current_behaviour = None - - self._background_act() - - def _process_current_round(self) -> None: - """Process current ABCIApp round.""" - current_round_height = self.context.state.round_sequence.current_round_height - if ( - self.current_behaviour is not None - and self._last_round_height == current_round_height - ): - # round has not changed - do nothing - return - self._last_round_height = current_round_height - current_round_cls = type(self.context.state.round_sequence.current_round) - - # each round has a behaviour associated to it - next_behaviour_cls = self._round_to_behaviour[current_round_cls] - - # stop the current behaviour and replace it with the new behaviour - if self.current_behaviour is not None: - current_behaviour = cast(BaseBehaviour, self.current_behaviour) - current_behaviour.clean_up() - current_behaviour.stop() - self.context.logger.debug( - "overriding transition: current behaviour: '%s', next behaviour: '%s'", - self.current_behaviour.behaviour_id if self.current_behaviour else None, - next_behaviour_cls.auto_behaviour_id(), - ) - - self.current_behaviour = self.instantiate_behaviour_cls(next_behaviour_cls) diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/common.py b/trader_backup/vendor/valory/skills/abstract_round_abci/common.py deleted file mode 100644 index c6ee52e46..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/common.py +++ /dev/null @@ -1,231 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the behaviours, round and payloads for the 'abstract_round_abci' skill.""" - -import hashlib -import random -from abc import ABC -from math import floor -from typing import Any, Dict, Generator, List, Optional, Type, Union, cast - -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.utils import VerifyDrand - - -RandomnessObservation = Optional[Dict[str, Union[str, int]]] - - -drand_check = VerifyDrand() - - -def random_selection(elements: List[Any], randomness: float) -> str: - """ - Select a random element from a list. - - :param: elements: a list of elements to choose among - :param: randomness: a random number in the [0,1) interval - :return: a randomly chosen element - """ - if not elements: - raise ValueError("No elements to randomly select among") - if randomness < 0 or randomness >= 1: - raise ValueError("Randomness should lie in the [0,1) interval") - random_position = floor(randomness * len(elements)) - return elements[random_position] - - -class RandomnessBehaviour(BaseBehaviour, ABC): - """Behaviour to collect randomness values from DRAND service for keeper agent selection.""" - - payload_class: Type[BaseTxPayload] - - def failsafe_randomness( - self, - ) -> Generator[None, None, RandomnessObservation]: - """ - This methods provides a failsafe for randomness retrieval. - - :return: derived randomness - :yields: derived randomness - """ - ledger_api_response = yield from self.get_ledger_api_response( - performative=LedgerApiMessage.Performative.GET_STATE, # type: ignore - ledger_callable="get_block", - block_identifier="latest", - ) - - if ( - ledger_api_response.performative == LedgerApiMessage.Performative.ERROR - or "hash" not in ledger_api_response.state.body - ): - return None - - randomness = hashlib.sha256( - cast(str, ledger_api_response.state.body.get("hash")).encode() - + str(self.params.service_id).encode() - ).hexdigest() - return {"randomness": randomness, "round": 0} - - def get_randomness_from_api( - self, - ) -> Generator[None, None, RandomnessObservation]: - """Retrieve randomness from given api specs.""" - api_specs = self.context.randomness_api.get_spec() - response = yield from self.get_http_response( - method=api_specs["method"], - url=api_specs["url"], - ) - observation = self.context.randomness_api.process_response(response) - if observation is not None: - self.context.logger.info("Verifying DRAND values...") - check, error = drand_check.verify(observation, self.params.drand_public_key) - if check: - self.context.logger.info("DRAND check successful.") - else: - self.context.logger.error(f"DRAND check failed, {error}.") - return None - return observation - - def async_act(self) -> Generator: - """ - Retrieve randomness from API. - - Steps: - - Do a http request to the API. - - Retry until receiving valid values for randomness or retries exceed. - - If retrieved values are valid continue else generate randomness from chain. - """ - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - if self.context.randomness_api.is_retries_exceeded(): - self.context.logger.warning("Cannot retrieve randomness from api.") - self.context.logger.info("Generating randomness from chain...") - observation = yield from self.failsafe_randomness() - if observation is None: - self.context.logger.error( - "Could not generate randomness from chain!" - ) - return - else: - self.context.logger.info("Retrieving DRAND values from api...") - observation = yield from self.get_randomness_from_api() - self.context.logger.info(f"Retrieved DRAND values: {observation}.") - - if observation: - payload = self.payload_class( # type: ignore - self.context.agent_address, - round_id=observation["round"], - randomness=observation["randomness"], - ) - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - else: - self.context.logger.error( - f"Could not get randomness from {self.context.randomness_api.api_id}" - ) - yield from self.sleep( - self.context.randomness_api.retries_info.suggested_sleep_time - ) - self.context.randomness_api.increment_retries() - - def clean_up(self) -> None: - """ - Clean up the resources due to a 'stop' event. - - It can be optionally implemented by the concrete classes. - """ - self.context.randomness_api.reset_retries() - - -class SelectKeeperBehaviour(BaseBehaviour, ABC): - """Select the keeper agent.""" - - payload_class: Type[BaseTxPayload] - - def _select_keeper(self) -> str: - """ - Select a new keeper randomly. - - 1. Sort the list of participants who are not blacklisted as keepers. - 2. Randomly shuffle it. - 3. Pick the first keeper in order. - 4. If he has already been selected, pick the next one. - - :return: the selected keeper's address. - """ - # Get all the participants who have not been blacklisted as keepers - non_blacklisted = ( - self.synchronized_data.participants - - self.synchronized_data.blacklisted_keepers - ) - if not non_blacklisted: - raise RuntimeError( - "Cannot continue if all the keepers have been blacklisted!" - ) - - # Sorted list of participants who are not blacklisted as keepers - relevant_set = sorted(list(non_blacklisted)) - - # Random seeding and shuffling of the set - random.seed(self.synchronized_data.keeper_randomness) - random.shuffle(relevant_set) - - # If the keeper is not set yet, pick the first address - keeper_address = relevant_set[0] - - # If the keeper has been already set, select the next. - if ( - self.synchronized_data.is_keeper_set - and len(self.synchronized_data.participants) > 1 - ): - old_keeper_index = relevant_set.index( - self.synchronized_data.most_voted_keeper_address - ) - keeper_address = relevant_set[(old_keeper_index + 1) % len(relevant_set)] - - self.context.logger.info(f"Selected a new keeper: {keeper_address}.") - - return keeper_address - - def async_act(self) -> Generator: - """ - Do the action. - - Steps: - - Select a keeper randomly. - - Send the transaction with the keeper and wait for it to be mined. - - Wait until ABCI application transitions to the next round. - - Go to the next behaviour state (set done event). - """ - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - payload = self.payload_class( # type: ignore - self.context.agent_address, self._select_keeper() - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/dialogues.py b/trader_backup/vendor/valory/skills/abstract_round_abci/dialogues.py deleted file mode 100644 index 7f0b53a38..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/dialogues.py +++ /dev/null @@ -1,368 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the classes required for dialogue management.""" - -from typing import Any, Optional, Type - -from aea.exceptions import enforce -from aea.helpers.transaction.base import Terms -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel as BaseDialogueLabel -from aea.skills.base import Model - -from packages.open_aea.protocols.signing.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.open_aea.protocols.signing.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.protocols.abci.dialogues import AbciDialogue as BaseAbciDialogue -from packages.valory.protocols.abci.dialogues import AbciDialogues as BaseAbciDialogues -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.contract_api.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.protocols.contract_api.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.protocols.http.dialogues import HttpDialogue as BaseHttpDialogue -from packages.valory.protocols.http.dialogues import HttpDialogues as BaseHttpDialogues -from packages.valory.protocols.ipfs.dialogues import IpfsDialogue as BaseIpfsDialogue -from packages.valory.protocols.ipfs.dialogues import IpfsDialogues as BaseIpfsDialogues -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.protocols.ledger_api.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.protocols.ledger_api.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.protocols.tendermint.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.protocols.tendermint.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue - - -class AbciDialogues(Model, BaseAbciDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.CLIENT - - BaseAbciDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - ) - - -HttpDialogue = BaseHttpDialogue - - -class HttpDialogues(Model, BaseHttpDialogues): - """This class keeps track of all http dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return BaseHttpDialogue.Role.CLIENT - - BaseHttpDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - ) - - -SigningDialogue = BaseSigningDialogue - - -class SigningDialogues(Model, BaseSigningDialogues): - """This class keeps track of all signing dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return BaseSigningDialogue.Role.SKILL - - BaseSigningDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - ) - - -class LedgerApiDialogue( # pylint: disable=too-few-public-methods - BaseLedgerApiDialogue -): - """The dialogue class maintains state of a dialogue and manages it.""" - - __slots__ = ("_terms",) - - def __init__( - self, - dialogue_label: BaseDialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[LedgerApiMessage] = LedgerApiMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - BaseLedgerApiDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - self._terms = None # type: Optional[Terms] - - @property - def terms(self) -> Terms: - """Get the terms.""" - if self._terms is None: - raise ValueError("Terms not set!") - return self._terms - - @terms.setter - def terms(self, terms: Terms) -> None: - """Set the terms.""" - enforce(self._terms is None, "Terms already set!") - self._terms = terms - - -class LedgerApiDialogues(Model, BaseLedgerApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return BaseLedgerApiDialogue.Role.AGENT - - BaseLedgerApiDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - dialogue_class=LedgerApiDialogue, - ) - - -class ContractApiDialogue( # pylint: disable=too-few-public-methods - BaseContractApiDialogue -): - """The dialogue class maintains state of a dialogue and manages it.""" - - __slots__ = ("_terms",) - - def __init__( - self, - dialogue_label: BaseDialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[ContractApiMessage] = ContractApiMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - BaseContractApiDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - self._terms = None # type: Optional[Terms] - - @property - def terms(self) -> Terms: - """Get the terms.""" - if self._terms is None: - raise ValueError("Terms not set!") - return self._terms - - @terms.setter - def terms(self, terms: Terms) -> None: - """Set the terms.""" - enforce(self._terms is None, "Terms already set!") - self._terms = terms - - -class ContractApiDialogues(Model, BaseContractApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize dialogues.""" - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return ContractApiDialogue.Role.AGENT - - BaseContractApiDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - dialogue_class=ContractApiDialogue, - ) - - -TendermintDialogue = BaseTendermintDialogue - - -class TendermintDialogues(Model, BaseTendermintDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return TendermintDialogue.Role.AGENT - - BaseTendermintDialogues.__init__( - self, - self_address=self.context.agent_address, - role_from_first_message=role_from_first_message, - ) - - -IpfsDialogue = BaseIpfsDialogue - - -class IpfsDialogues(Model, BaseIpfsDialogues): - """A class to keep track of IPFS dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return IpfsDialogue.Role.SKILL - - BaseIpfsDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - ) diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/handlers.py b/trader_backup/vendor/valory/skills/abstract_round_abci/handlers.py deleted file mode 100644 index 88cf072e6..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/handlers.py +++ /dev/null @@ -1,790 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the handler for the 'abstract_round_abci' skill.""" - -import ipaddress -import json -from abc import ABC -from calendar import timegm -from dataclasses import asdict -from enum import Enum -from typing import Any, Callable, Dict, FrozenSet, List, Optional, cast - -from aea.configurations.data_types import PublicId -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, Dialogues -from aea.skills.base import Handler - -from packages.open_aea.protocols.signing import SigningMessage -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import Events, ValidatorUpdates -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.protocols.tendermint.dialogues import ( - TendermintDialogue, - TendermintDialogues, -) -from packages.valory.protocols.tendermint.message import TendermintMessage -from packages.valory.skills.abstract_abci.handlers import ABCIHandler -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AddBlockError, - DEFAULT_PENDING_OFFENCE_TTL, - ERROR_CODE, - LateArrivingTransaction, - OK_CODE, - OffenseType, - PendingOffense, - SignatureNotValidError, - Transaction, - TransactionNotValidError, - TransactionTypeNotRecognizedError, -) -from packages.valory.skills.abstract_round_abci.behaviours import AbstractRoundBehaviour -from packages.valory.skills.abstract_round_abci.dialogues import AbciDialogue -from packages.valory.skills.abstract_round_abci.models import ( - Requests, - SharedState, - TendermintRecoveryParams, -) - - -def exception_to_info_msg(exception: Exception) -> str: - """Transform an exception to an info string message.""" - return f"{exception.__class__.__name__}: {str(exception)}" - - -class ABCIRoundHandler(ABCIHandler): - """ABCI handler.""" - - SUPPORTED_PROTOCOL = AbciMessage.protocol_id - - def info(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """ - Handle the 'info' request. - - As per Tendermint spec (https://github.com/tendermint/spec/blob/038f3e025a19fed9dc96e718b9834ab1b545f136/spec/abci/abci.md#info): - - - Return information about the application state. - - Used to sync Tendermint with the application during a handshake that happens on startup. - - The returned app_version will be included in the Header of every block. - - Tendermint expects last_block_app_hash and last_block_height to be updated during Commit, ensuring that Commit is never called twice for the same block height. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - # some arbitrary information - info_data = "" - # the application software semantic version - version = "" - # the application protocol version - app_version = 0 - # latest block for which the app has called Commit - last_block_height = self.context.state.round_sequence.height - # latest result of Commit - last_block_app_hash = self.context.state.round_sequence.root_hash - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_INFO, - target_message=message, - info_data=info_data, - version=version, - app_version=app_version, - last_block_height=last_block_height, - last_block_app_hash=last_block_app_hash, - ) - return cast(AbciMessage, reply) - - def init_chain(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """ - Handle a message of REQUEST_INIT_CHAIN performative. - - As per Tendermint spec (https://github.com/tendermint/spec/blob/038f3e025a19fed9dc96e718b9834ab1b545f136/spec/abci/abci.md#initchain): - - - Called once upon genesis. - - If ResponseInitChain.Validators is empty, the initial validator set will be the RequestInitChain.Validators. - - If ResponseInitChain.Validators is not empty, it will be the initial validator set (regardless of what is in RequestInitChain.Validators). - - This allows the app to decide if it wants to accept the initial validator set proposed by tendermint (ie. in the genesis file), or if it wants to use a different one (perhaps computed based on some application specific information in the genesis file). - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - # Initial validator set (optional). - validators: List = [] - # Get the root hash of the last round transition as the initial application hash. - # If no round transitions have occurred yet, `last_root_hash` returns the hash of the initial abci app's state. - # `init_chain` will be called between resets when restarting again. - app_hash = self.context.state.round_sequence.last_round_transition_root_hash - cast(SharedState, self.context.state).round_sequence.init_chain( - message.initial_height - ) - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_INIT_CHAIN, - target_message=message, - validators=ValidatorUpdates(validators), - app_hash=app_hash, - ) - return cast(AbciMessage, reply) - - def begin_block(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """Handle the 'begin_block' request.""" - cast(SharedState, self.context.state).round_sequence.begin_block( - message.header, message.byzantine_validators, message.last_commit_info - ) - return super().begin_block(message, dialogue) - - def check_tx(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """Handle the 'check_tx' request.""" - transaction_bytes = message.tx - # check we can decode the transaction - try: - transaction = Transaction.decode(transaction_bytes) - transaction.verify(self.context.default_ledger_id) - cast(SharedState, self.context.state).round_sequence.check_is_finished() - except ( - SignatureNotValidError, - TransactionNotValidError, - TransactionTypeNotRecognizedError, - ) as exception: - self._log_exception(exception) - return self._check_tx_failed( - message, dialogue, exception_to_info_msg(exception) - ) - except LateArrivingTransaction as exception: # pragma: nocover - self.context.logger.debug(exception_to_info_msg(exception)) - return self._check_tx_failed( - message, dialogue, exception_to_info_msg(exception) - ) - - # return check_tx success - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, - target_message=message, - code=OK_CODE, - data=b"", - log="", - info="check_tx succeeded", - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, reply) - - def settle_pending_offence( - self, accused_agent_address: Optional[str], invalid: bool - ) -> None: - """Add an invalid pending offence or a no-offence for the given accused agent address, if possible.""" - if accused_agent_address is None: - # only add the offence if we know and can verify the sender, - # otherwise someone could pretend to be someone else, which may lead to wrong punishments - return - - round_sequence = cast(SharedState, self.context.state).round_sequence - - try: - last_round_transition_timestamp = timegm( - round_sequence.last_round_transition_timestamp.utctimetuple() - ) - except ValueError: # pragma: no cover - # do not add an offence if no round transition has been completed yet - return - - offence_type = ( - OffenseType.INVALID_PAYLOAD if invalid else OffenseType.NO_OFFENCE - ) - pending_offense = PendingOffense( - accused_agent_address, - round_sequence.current_round_height, - offence_type, - last_round_transition_timestamp, - DEFAULT_PENDING_OFFENCE_TTL, - ) - round_sequence.add_pending_offence(pending_offense) - - def deliver_tx(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """Handle the 'deliver_tx' request.""" - transaction_bytes = message.tx - round_sequence = cast(SharedState, self.context.state).round_sequence - payload_sender: Optional[str] = None - try: - transaction = Transaction.decode(transaction_bytes) - transaction.verify(self.context.default_ledger_id) - payload_sender = transaction.payload.sender - round_sequence.check_is_finished() - round_sequence.deliver_tx(transaction) - except ( - SignatureNotValidError, - TransactionNotValidError, - TransactionTypeNotRecognizedError, - ) as exception: - self._log_exception(exception) - # the transaction is invalid, it's potentially an offence, so we add it to the list of pending offences - self.settle_pending_offence(payload_sender, invalid=True) - return self._deliver_tx_failed( - message, dialogue, exception_to_info_msg(exception) - ) - except LateArrivingTransaction as exception: # pragma: nocover - self.context.logger.debug(exception_to_info_msg(exception)) - return self._deliver_tx_failed( - message, dialogue, exception_to_info_msg(exception) - ) - - # the invalid payloads' availability window needs to be populated with the negative values as well - self.settle_pending_offence(payload_sender, invalid=False) - - # return deliver_tx success - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, - target_message=message, - code=OK_CODE, - data=b"", - log="", - info="deliver_tx succeeded", - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, reply) - - def end_block(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """Handle the 'end_block' request.""" - self.context.state.round_sequence.tm_height = message.height - cast(SharedState, self.context.state).round_sequence.end_block() - return super().end_block(message, dialogue) - - def commit(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """ - Handle the 'commit' request. - - As per Tendermint spec (https://github.com/tendermint/spec/blob/038f3e025a19fed9dc96e718b9834ab1b545f136/spec/abci/abci.md#commit): - - Empty request meant to signal to the app it can write state transitions to state. - - - Persist the application state. - - Return a Merkle root hash of the application state. - - It's critical that all application instances return the same hash. If not, they will not be able to agree on the next block, because the hash is included in the next block! - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - try: - cast(SharedState, self.context.state).round_sequence.commit() - except AddBlockError as exception: - self._log_exception(exception) - raise exception - # The Merkle root hash of the application state. - data = self.context.state.round_sequence.root_hash - # Blocks below this height may be removed. Defaults to 0 (retain all). - retain_height = 0 - # return commit success - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_COMMIT, - target_message=message, - data=data, - retain_height=retain_height, - ) - return cast(AbciMessage, reply) - - @classmethod - def _check_tx_failed( - cls, message: AbciMessage, dialogue: AbciDialogue, info: str = "" - ) -> AbciMessage: - """Handle a failed check_tx request.""" - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, - target_message=message, - code=ERROR_CODE, - data=b"", - log="", - info=info, - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, reply) - - @classmethod - def _deliver_tx_failed( - cls, message: AbciMessage, dialogue: AbciDialogue, info: str = "" - ) -> AbciMessage: - """Handle a failed deliver_tx request.""" - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, - target_message=message, - code=ERROR_CODE, - data=b"", - log="", - info=info, - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, reply) - - def _log_exception(self, exception: Exception) -> None: - """Log an exception.""" - self.context.logger.error(exception_to_info_msg(exception)) - - -class AbstractResponseHandler(Handler, ABC): - """ - Abstract response Handler. - - This abstract handler works in tandem with the 'Requests' model. - Whenever a message of 'response' type arrives, the handler - tries to dispatch it to a pending request previously registered - in 'Requests' by some other code in the same skill. - - The concrete classes must set the 'allowed_response_performatives' - class attribute to the (frozen)set of performative the developer - wants the handler to handle. - """ - - allowed_response_performatives: FrozenSet[Message.Performative] - - def setup(self) -> None: - """Set up the handler.""" - - def teardown(self) -> None: - """Tear down the handler.""" - - def handle(self, message: Message) -> None: - """ - Handle the response message. - - Steps: - 1. Try to recover the 'dialogues' instance, for the protocol - of this handler, from the skill context. The attribute name used to - read the attribute is computed by '_get_dialogues_attribute_name()' - method. If no dialogues instance is found, log a message and return. - 2. Try to recover the dialogue; if no dialogue is present, log a message - and return. - 3. Check whether the performative is in the set of allowed performative; - if not, log a message and return. - 4. Try to recover the callback of the request associated to the response - from the 'Requests' model; if no callback is present, log a message - and return. - 5. If the above check have passed, then call the callback with the - received message. - - :param message: the message to handle. - """ - protocol_dialogues = self._recover_protocol_dialogues() - if protocol_dialogues is None: - self._handle_missing_dialogues() - return - protocol_dialogues = cast(Dialogues, protocol_dialogues) - - protocol_dialogue = cast(Optional[Dialogue], protocol_dialogues.update(message)) - if protocol_dialogue is None: - self._handle_unidentified_dialogue(message) - return - - if message.performative not in self.allowed_response_performatives: - self._handle_unallowed_performative(message) - return - - request_nonce = protocol_dialogue.dialogue_label.dialogue_reference[0] - ctx_requests = cast(Requests, self.context.requests) - - try: - callback = cast( - Callable, - ctx_requests.request_id_to_callback.pop(request_nonce), - ) - except KeyError as e: - raise ABCIAppInternalError( - f"No callback defined for request with nonce: {request_nonce}" - ) from e - - self._log_message_handling(message) - current_behaviour = cast( - AbstractRoundBehaviour, self.context.behaviours.main - ).current_behaviour - callback(message, current_behaviour) - - def _get_dialogues_attribute_name(self) -> str: - """ - Get dialogues attribute name. - - By convention, the Dialogues model of the skill follows - the template '{protocol_name}_dialogues'. - - Override this method accordingly if the name of hte Dialogues - model is different. - - :return: the dialogues attribute name. - """ - return cast(PublicId, self.SUPPORTED_PROTOCOL).name + "_dialogues" - - def _recover_protocol_dialogues(self) -> Optional[Dialogues]: - """ - Recover protocol dialogues from supported protocol id. - - :return: the dialogues, or None if the dialogues object was not found. - """ - attribute = self._get_dialogues_attribute_name() - return getattr(self.context, attribute, None) - - def _handle_missing_dialogues(self) -> None: - """Handle missing dialogues in context.""" - expected_attribute_name = self._get_dialogues_attribute_name() - self.context.logger.warning( - "Cannot find Dialogues object in skill context with attribute name: %s", - expected_attribute_name, - ) - - def _handle_unidentified_dialogue(self, message: Message) -> None: - """ - Handle an unidentified dialogue. - - :param message: the unidentified message to be handled - """ - self.context.logger.warning( - "Received invalid message: unidentified dialogue. message=%s", message - ) - - def _handle_unallowed_performative(self, message: Message) -> None: - """ - Handle a message with an unallowed response performative. - - Log an error message saying that the handler did not expect requests - but only responses. - - :param message: the message - """ - self.context.logger.warning( - "Received invalid message: unallowed performative. message=%s.", message - ) - - def _log_message_handling(self, message: Message) -> None: - """Log the handling of the message.""" - self.context.logger.debug( - "Calling registered callback with message=%s", message - ) - - -class HttpHandler(AbstractResponseHandler): - """The HTTP response handler.""" - - SUPPORTED_PROTOCOL: Optional[PublicId] = HttpMessage.protocol_id - allowed_response_performatives = frozenset({HttpMessage.Performative.RESPONSE}) - - -class SigningHandler(AbstractResponseHandler): - """Implement the transaction handler.""" - - SUPPORTED_PROTOCOL: Optional[PublicId] = SigningMessage.protocol_id - allowed_response_performatives = frozenset( - { - SigningMessage.Performative.SIGNED_MESSAGE, - SigningMessage.Performative.SIGNED_TRANSACTION, - SigningMessage.Performative.ERROR, - } - ) - - -class LedgerApiHandler(AbstractResponseHandler): - """Implement the ledger handler.""" - - SUPPORTED_PROTOCOL: Optional[PublicId] = LedgerApiMessage.protocol_id - allowed_response_performatives = frozenset( - { - LedgerApiMessage.Performative.BALANCE, - LedgerApiMessage.Performative.RAW_TRANSACTION, - LedgerApiMessage.Performative.TRANSACTION_DIGEST, - LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - LedgerApiMessage.Performative.ERROR, - LedgerApiMessage.Performative.STATE, - } - ) - - -class ContractApiHandler(AbstractResponseHandler): - """Implement the contract api handler.""" - - SUPPORTED_PROTOCOL: Optional[PublicId] = ContractApiMessage.protocol_id - allowed_response_performatives = frozenset( - { - ContractApiMessage.Performative.RAW_TRANSACTION, - ContractApiMessage.Performative.RAW_MESSAGE, - ContractApiMessage.Performative.ERROR, - ContractApiMessage.Performative.STATE, - } - ) - - -class TendermintHandler(Handler): - """ - The Tendermint config-sharing request / response handler. - - This handler is used to share the information necessary - to set up the Tendermint network. The agents use it during - the RegistrationStartupBehaviour, and communicate with - each other over the Agent Communication Network using a - p2p_libp2p or p2p_libp2p_client connection. - - This handler does NOT use the ABCI connection. - """ - - SUPPORTED_PROTOCOL: Optional[PublicId] = TendermintMessage.protocol_id - - class LogMessages(Enum): - """Log messages used in the TendermintHandler""" - - unidentified_dialogue = "Unidentified Tendermint dialogue" - no_addresses_retrieved_yet = "No registered addresses retrieved yet" - not_in_registered_addresses = "Sender not registered for on-chain service" - sending_request_response = "Sending Tendermint request response" - failed_to_parse_address = "Failed to parse Tendermint network address" - failed_to_parse_params = ( - "Failed to parse Tendermint recovery parameters from message" - ) - collected_config_info = "Collected Tendermint config info" - collected_params = "Collected Tendermint recovery parameters" - received_error_without_target_message = ( - "Received error message but could not retrieve target message" - ) - received_error_response = "Received error response" - sending_error_response = "Sending error response" - performative_not_recognized = "Performative not recognized" - - def __str__(self) -> str: # pragma: no cover - """For ease of use in formatted string literals""" - return self.value - - def setup(self) -> None: - """Set up the handler.""" - - def teardown(self) -> None: - """Tear down the handler.""" - - @property - def initial_tm_configs(self) -> Dict[str, Dict[str, Any]]: - """A mapping of the other agents' addresses to their initial Tendermint configuration.""" - return self.context.state.initial_tm_configs - - @initial_tm_configs.setter - def initial_tm_configs(self, configs: Dict[str, Dict[str, Any]]) -> None: - """A mapping of the other agents' addresses to their initial Tendermint configuration.""" - self.context.state.initial_tm_configs = configs - - @property - def dialogues(self) -> Optional[TendermintDialogues]: - """Tendermint config-sharing request / response protocol dialogues""" - - attribute = cast(PublicId, self.SUPPORTED_PROTOCOL).name + "_dialogues" - return getattr(self.context, attribute, None) - - def handle(self, message: Message) -> None: - """Handle incoming Tendermint config-sharing messages""" - - dialogues = cast(TendermintDialogues, self.dialogues) - dialogue = cast(TendermintDialogue, dialogues.update(message)) - - if dialogue is None: - log_message = self.LogMessages.unidentified_dialogue.value - self.context.logger.error(f"{log_message}: {message}") - return - - message = cast(TendermintMessage, message) - handler_name = f"_{message.performative.value}" - handler = getattr(self, handler_name, None) - if handler is None: - log_message = self.LogMessages.performative_not_recognized.value - self.context.logger.error(f"{log_message}: {message}") - return - - handler(message, dialogue) - - def _reply_with_tendermint_error( - self, - message: TendermintMessage, - dialogue: TendermintDialogue, - error_message: str, - ) -> None: - """Reply with Tendermint config-sharing error""" - response = dialogue.reply( - performative=TendermintMessage.Performative.ERROR, - target_message=message, - error_code=TendermintMessage.ErrorCode.INVALID_REQUEST, - error_msg=error_message, - error_data={}, - ) - self.context.outbox.put_message(response) - log_message = self.LogMessages.sending_error_response.value - log_message += f". Received: {message}, replied: {response}" - self.context.logger.error(log_message) - - def _not_registered_error( - self, message: TendermintMessage, dialogue: TendermintDialogue - ) -> None: - """Check if sender is among on-chain registered addresses""" - # do not respond to errors to avoid loops - log_message = self.LogMessages.not_in_registered_addresses.value - self.context.logger.error(f"{log_message}: {message}") - self._reply_with_tendermint_error(message, dialogue, log_message) - - def _check_registered( - self, message: TendermintMessage, dialogue: TendermintDialogue - ) -> bool: - """Check if the sender is registered on-chain and if not, reply with an error""" - others_addresses = self.context.state.acn_container() - if message.sender in others_addresses: - return True - - self._not_registered_error(message, dialogue) - return False - - def _get_genesis_info( - self, message: TendermintMessage, dialogue: TendermintDialogue - ) -> None: - """Handler Tendermint config-sharing request message""" - - if not self._check_registered(message, dialogue): - return - info = self.initial_tm_configs.get(self.context.agent_address, None) - if info is None: - log_message = self.LogMessages.no_addresses_retrieved_yet.value - self.context.logger.info(f"{log_message}: {message}") - self._reply_with_tendermint_error(message, dialogue, log_message) - return - - response = dialogue.reply( - performative=TendermintMessage.Performative.GENESIS_INFO, - target_message=message, - info=json.dumps(info), - ) - self.context.outbox.put_message(message=response) - log_message = self.LogMessages.sending_request_response.value - self.context.logger.info(f"{log_message}: {response}") - - def _get_recovery_params( - self, message: TendermintMessage, dialogue: TendermintDialogue - ) -> None: - """Handle a request message for the recovery parameters.""" - if not self._check_registered(message, dialogue): - return - - shared_state = cast(SharedState, self.context.state) - recovery_params = shared_state.tm_recovery_params - response = dialogue.reply( - performative=TendermintMessage.Performative.RECOVERY_PARAMS, - target_message=message, - params=json.dumps(asdict(recovery_params)), - ) - self.context.outbox.put_message(message=response) - log_message = self.LogMessages.sending_request_response.value - self.context.logger.info(f"{log_message}: {response}") - - def _genesis_info( - self, message: TendermintMessage, dialogue: TendermintDialogue - ) -> None: - """Process Tendermint config-sharing response messages""" - - if not self._check_registered(message, dialogue): - return - - try: # validate message contains a valid address - validator_config = json.loads(message.info) - self.context.logger.info(f"Validator config received: {validator_config}") - hostname = cast(str, validator_config["hostname"]) - if hostname != "localhost" and not hostname.startswith("node"): - ipaddress.ip_network(hostname) - except (KeyError, ValueError) as e: - log_message = self.LogMessages.failed_to_parse_address.value - self.context.logger.error(f"{log_message}: {e} {message}") - self._reply_with_tendermint_error(message, dialogue, log_message) - return - - initial_tm_configs = self.initial_tm_configs - initial_tm_configs[message.sender] = validator_config - self.initial_tm_configs = initial_tm_configs - log_message = self.LogMessages.collected_config_info.value - self.context.logger.info(f"{log_message}: {message}") - dialogues = cast(TendermintDialogues, self.dialogues) - dialogues.dialogue_stats.add_dialogue_endstate( - TendermintDialogue.EndState.COMMUNICATED, dialogue.is_self_initiated - ) - - def _recovery_params( - self, message: TendermintMessage, dialogue: TendermintDialogue - ) -> None: - """Process params-sharing response messages.""" - - if not self._check_registered(message, dialogue): - return - - try: - recovery_params = json.loads(message.params) - shared_state = cast(SharedState, self.context.state) - shared_state.address_to_acn_deliverable[ - message.sender - ] = TendermintRecoveryParams(**recovery_params) - except (json.JSONDecodeError, TypeError) as exc: - log_message = self.LogMessages.failed_to_parse_params.value - self.context.logger.error(f"{log_message}: {exc} {message}") - self._reply_with_tendermint_error(message, dialogue, log_message) - return - - log_message = self.LogMessages.collected_params.value - self.context.logger.info(f"{log_message}: {message}") - dialogues = cast(TendermintDialogues, self.dialogues) - dialogues.dialogue_stats.add_dialogue_endstate( - TendermintDialogue.EndState.COMMUNICATED, dialogue.is_self_initiated - ) - - def _error(self, message: TendermintMessage, dialogue: TendermintDialogue) -> None: - """Handle error message as response""" - - target_message = dialogue.get_message_by_id(message.target) - if not target_message: - log_message = self.LogMessages.received_error_without_target_message.value - self.context.logger.error(log_message) - return - - log_message = self.LogMessages.received_error_response.value - log_message += f". Received: {message}, in reply to: {target_message}" - self.context.logger.error(log_message) - dialogues = cast(TendermintDialogues, self.dialogues) - dialogues.dialogue_stats.add_dialogue_endstate( - TendermintDialogue.EndState.NOT_COMMUNICATED, dialogue.is_self_initiated - ) - - -class IpfsHandler(AbstractResponseHandler): - """A class for handling IPFS messages.""" - - SUPPORTED_PROTOCOL: Optional[PublicId] = IpfsMessage.protocol_id - allowed_response_performatives = frozenset( - { - IpfsMessage.Performative.IPFS_HASH, - IpfsMessage.Performative.FILES, - IpfsMessage.Performative.ERROR, - } - ) diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/io_/__init__.py b/trader_backup/vendor/valory/skills/abstract_round_abci/io_/__init__.py deleted file mode 100644 index 346ca66a6..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/io_/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 package contains all the input-output operations logic of the behaviours.""" # pragma: nocover diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/io_/ipfs.py b/trader_backup/vendor/valory/skills/abstract_round_abci/io_/ipfs.py deleted file mode 100644 index cfd914c60..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/io_/ipfs.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 all the interaction operations of the behaviours with IPFS.""" - - -import os -from typing import Any, Dict, Optional, Type - -from packages.valory.skills.abstract_round_abci.io_.load import ( - CustomLoaderType, - Loader, - SupportedFiletype, - SupportedObjectType, -) -from packages.valory.skills.abstract_round_abci.io_.store import ( - CustomStorerType, - Storer, -) - - -class IPFSInteractionError(Exception): - """A custom exception for IPFS interaction errors.""" - - -class IPFSInteract: - """Class for interacting with IPFS.""" - - def __init__(self, loader_cls: Type = Loader, storer_cls: Type = Storer): - """Initialize an `IPFSInteract` object.""" - # Set loader/storer class. - self._loader_cls = loader_cls - self._storer_cls = storer_cls - - def store( - self, - filepath: str, - obj: SupportedObjectType, - multiple: bool, - filetype: Optional[SupportedFiletype] = None, - custom_storer: Optional[CustomStorerType] = None, - **kwargs: Any, - ) -> Dict[str, str]: - """Temporarily store a file locally, in order to send it to IPFS and retrieve a hash, and then delete it.""" - filepath = os.path.normpath(filepath) - if multiple: - # Add trailing slash in order to treat path as a folder. - filepath = os.path.join(filepath, "") - storer = self._storer_cls(filetype, custom_storer, filepath) - - try: - name_to_obj = storer.store(obj, multiple, **kwargs) - return name_to_obj - except Exception as e: # pylint: disable=broad-except - raise IPFSInteractionError(str(e)) from e - - def load( # pylint: disable=too-many-arguments - self, - serialized_objects: Dict[str, str], - filetype: Optional[SupportedFiletype] = None, - custom_loader: CustomLoaderType = None, - ) -> SupportedObjectType: - """Deserialize objects received via IPFS.""" - loader = self._loader_cls(filetype, custom_loader) - try: - deserialized_objects = loader.load(serialized_objects) - return deserialized_objects - except Exception as e: # pylint: disable=broad-except - raise IPFSInteractionError(str(e)) from e diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/io_/load.py b/trader_backup/vendor/valory/skills/abstract_round_abci/io_/load.py deleted file mode 100644 index c9ceafb09..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/io_/load.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 all the loading operations of the behaviours.""" - -import json -from abc import ABC, abstractmethod -from typing import Any, Callable, Dict, Optional - -from packages.valory.skills.abstract_round_abci.io_.store import ( - CustomObjectType, - NativelySupportedSingleObjectType, - SupportedFiletype, - SupportedObjectType, - SupportedSingleObjectType, -) - - -CustomLoaderType = Optional[Callable[[str], CustomObjectType]] -SupportedLoaderType = Callable[[str], SupportedSingleObjectType] - - -class AbstractLoader(ABC): - """An abstract `Loader` class.""" - - @abstractmethod - def load_single_object( - self, serialized_object: str - ) -> NativelySupportedSingleObjectType: - """Load a single object.""" - - def load(self, serialized_objects: Dict[str, str]) -> SupportedObjectType: - """ - Load one or more serialized objects. - - :param serialized_objects: A mapping of filenames to serialized object they contained. - :return: the loaded file(s). - """ - if len(serialized_objects) == 0: - # no objects are present, raise an error - raise ValueError('"serialized_objects" does not contain any objects') - - objects = {} - for filename, body in serialized_objects.items(): - objects[filename] = self.load_single_object(body) - - if len(objects) > 1: - # multiple object are present - # we return them as mapping of - # names and their value - return objects - - # one object is present, we simply return it as an object, i.e. without its name - _name, deserialized_body = objects.popitem() - return deserialized_body - - -class JSONLoader(AbstractLoader): - """A JSON file loader.""" - - def load_single_object( - self, serialized_object: str - ) -> NativelySupportedSingleObjectType: - """Read a json file. - - :param serialized_object: the file serialized into a JSON string. - :return: the deserialized json file's content. - """ - try: - deserialized_file = json.loads(serialized_object) - return deserialized_file - except json.JSONDecodeError as e: # pragma: no cover - raise IOError( - f"File '{serialized_object}' has an invalid JSON encoding!" - ) from e - except ValueError as e: # pragma: no cover - raise IOError( - f"There is an encoding error in the '{serialized_object}' file!" - ) from e - - -class Loader(AbstractLoader): - """Class which loads objects.""" - - def __init__(self, filetype: Optional[Any], custom_loader: CustomLoaderType): - """Initialize a `Loader`.""" - self._filetype = filetype - self._custom_loader = custom_loader - self.__filetype_to_loader: Dict[SupportedFiletype, SupportedLoaderType] = { - SupportedFiletype.JSON: JSONLoader().load_single_object, - } - - def load_single_object(self, serialized_object: str) -> SupportedSingleObjectType: - """Load a single file.""" - loader = self._get_single_loader_from_filetype() - return loader(serialized_object) - - def _get_single_loader_from_filetype(self) -> SupportedLoaderType: - """Get an object loader from a given filetype or keep a custom loader.""" - if self._filetype is not None: - return self.__filetype_to_loader[self._filetype] - - if self._custom_loader is not None: # pragma: no cover - return self._custom_loader - - raise ValueError( # pragma: no cover - "Please provide either a supported filetype or a custom loader function." - ) diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/io_/paths.py b/trader_backup/vendor/valory/skills/abstract_round_abci/io_/paths.py deleted file mode 100644 index 40b89233b..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/io_/paths.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 all the path related operations of the behaviours.""" - - -import os - - -def create_pathdirs(path: str) -> None: - """Create the non-existing directories of a given path. - - :param path: the given path. - """ - dirname = os.path.dirname(path) - - if dirname: - os.makedirs(dirname, exist_ok=True) diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/io_/store.py b/trader_backup/vendor/valory/skills/abstract_round_abci/io_/store.py deleted file mode 100644 index 588dc3629..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/io_/store.py +++ /dev/null @@ -1,153 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 all the storing operations of the behaviours.""" - - -import json -import os.path -from abc import ABC, abstractmethod -from enum import Enum, auto -from typing import Any, Callable, Dict, Optional, TypeVar, Union, cast - -from packages.valory.skills.abstract_round_abci.io_.paths import create_pathdirs - - -StoredJSONType = Union[dict, list] -NativelySupportedSingleObjectType = StoredJSONType -NativelySupportedMultipleObjectsType = Dict[str, NativelySupportedSingleObjectType] -NativelySupportedObjectType = Union[ - NativelySupportedSingleObjectType, NativelySupportedMultipleObjectsType -] -NativelySupportedStorerType = Callable[[str, NativelySupportedObjectType, Any], None] -CustomObjectType = TypeVar("CustomObjectType") -CustomStorerType = Callable[[str, CustomObjectType, Any], None] -SupportedSingleObjectType = Union[NativelySupportedObjectType, CustomObjectType] -SupportedMultipleObjectsType = Dict[str, SupportedSingleObjectType] -SupportedObjectType = Union[SupportedSingleObjectType, SupportedMultipleObjectsType] -SupportedStorerType = Union[NativelySupportedStorerType, CustomStorerType] -NativelySupportedJSONStorerType = Callable[ - [str, Union[StoredJSONType, Dict[str, StoredJSONType]], Any], None -] - - -class SupportedFiletype(Enum): - """Enum for the supported filetypes of the IPFS interacting methods.""" - - JSON = auto() - - -class AbstractStorer(ABC): - """An abstract `Storer` class.""" - - def __init__(self, path: str): - """Initialize an abstract storer.""" - self._path = path - # Create the dirs of the path if it does not exist. - create_pathdirs(path) - - @abstractmethod - def serialize_object( - self, filename: str, obj: SupportedSingleObjectType, **kwargs: Any - ) -> Dict[str, str]: - """Store a single file.""" - - def store( - self, obj: SupportedObjectType, multiple: bool, **kwargs: Any - ) -> Dict[str, str]: - """Serialize one or multiple objects.""" - serialized_files: Dict[str, str] = {} - if multiple: - if not isinstance(obj, dict): # pragma: no cover - raise ValueError( - f"Cannot store multiple files of type {type(obj)}!" - f"Should be a dictionary of filenames mapped to their objects." - ) - for filename, single_obj in obj.items(): - filename = os.path.join(self._path, filename) - serialized_file = self.serialize_object(filename, single_obj, **kwargs) - serialized_files.update(**serialized_file) - else: - serialized_file = self.serialize_object(self._path, obj, **kwargs) - serialized_files.update(**serialized_file) - return serialized_files - - -class JSONStorer(AbstractStorer): - """A JSON file storer.""" - - def serialize_object( - self, filename: str, obj: NativelySupportedSingleObjectType, **kwargs: Any - ) -> Dict[str, str]: - """ - Serialize an object to JSON. - - :param filename: under which name the provided object should be serialized. Note that it will appear in IPFS with this name. - :param obj: the object to store. - :returns: a dict mapping the name to the serialized object. - """ - if not any(isinstance(obj, type_) for type_ in (dict, list)): - raise ValueError( # pragma: no cover - f"`JSONStorer` cannot be used with a {type(obj)}! Only with a {StoredJSONType}" - ) - try: - serialized_object = json.dumps(obj, ensure_ascii=False, indent=4) - name_to_obj = {filename: serialized_object} - return name_to_obj - except (TypeError, OSError) as e: # pragma: no cover - raise IOError(str(e)) from e - - -class Storer(AbstractStorer): - """Class which serializes objects.""" - - def __init__( - self, - filetype: Optional[Any], - custom_storer: Optional[CustomStorerType], - path: str, - ): - """Initialize a `Storer`.""" - super().__init__(path) - self._filetype = filetype - self._custom_storer = custom_storer - self._filetype_to_storer: Dict[Enum, SupportedStorerType] = { - SupportedFiletype.JSON: cast( - NativelySupportedJSONStorerType, JSONStorer(path).serialize_object - ), - } - - def serialize_object( - self, filename: str, obj: NativelySupportedObjectType, **kwargs: Any - ) -> Dict[str, str]: - """Store a single object.""" - storer = self._get_single_storer_from_filetype() - return storer(filename, obj, **kwargs) # type: ignore - - def _get_single_storer_from_filetype(self) -> SupportedStorerType: - """Get an object storer from a given filetype or keep a custom storer.""" - if self._filetype is not None: - return self._filetype_to_storer[self._filetype] - - if self._custom_storer is not None: # pragma: no cover - return self._custom_storer - - raise ValueError( # pragma: no cover - "Please provide either a supported filetype or a custom storing function." - ) diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/models.py b/trader_backup/vendor/valory/skills/abstract_round_abci/models.py deleted file mode 100644 index 27304eb37..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/models.py +++ /dev/null @@ -1,893 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the core models for all the ABCI apps.""" - -import inspect -import json -from abc import ABC, ABCMeta -from collections import Counter -from dataclasses import dataclass -from enum import Enum -from pathlib import Path -from time import time -from typing import ( - Any, - Callable, - Dict, - List, - Optional, - OrderedDict, - Tuple, - Type, - cast, - get_type_hints, -) - -from aea.configurations.data_types import PublicId -from aea.exceptions import enforce -from aea.skills.base import Model, SkillContext - -from packages.valory.protocols.http.message import HttpMessage -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppDB, - BaseSynchronizedData, - OffenceStatus, - ROUND_COUNT_DEFAULT, - RoundSequence, - VALUE_NOT_PROVIDED, - get_name, -) -from packages.valory.skills.abstract_round_abci.utils import ( - check, - check_type, - consensus_threshold, - get_data_from_nested_dict, - get_value_with_type, -) - - -MIN_RESET_PAUSE_DURATION = 10 -NUMBER_OF_RETRIES: int = 5 -DEFAULT_BACKOFF_FACTOR: float = 2.0 -DEFAULT_TYPE_NAME: str = "str" -DEFAULT_CHAIN = "ethereum" - - -class FrozenMixin: # pylint: disable=too-few-public-methods - """Mixin for classes to enforce read-only attributes.""" - - _frozen: bool = False - - def __delattr__(self, *args: Any) -> None: - """Override __delattr__ to make object immutable.""" - if self._frozen: - raise AttributeError( - "This object is frozen! To unfreeze switch `self._frozen` via `__dict__`." - ) - super().__delattr__(*args) - - def __setattr__(self, *args: Any) -> None: - """Override __setattr__ to make object immutable.""" - if self._frozen: - raise AttributeError( - "This object is frozen! To unfreeze switch `self._frozen` via `__dict__`." - ) - super().__setattr__(*args) - - -class TypeCheckMixin: # pylint: disable=too-few-public-methods - """Mixin for data classes & models to enforce attribute types on construction.""" - - def __post_init__(self) -> None: - """Check that the type of the provided attributes is correct.""" - for attr, type_ in get_type_hints(self).items(): - value = getattr(self, attr) - check_type(attr, value, type_) - - @classmethod - def _ensure(cls, key: str, kwargs: Dict, type_: Any) -> Any: - """Get and ensure the configuration field is not None (if no default is provided) and of correct type.""" - enforce("skill_context" in kwargs, "Only use on models!") - skill_id = kwargs["skill_context"].skill_id - enforce( - key in kwargs, - f"'{key}' of type '{type_}' required, but it is not set in `models.params.args` of `skill.yaml` of `{skill_id}`", - ) - value = kwargs.pop(key) - try: - check_type(key, value, type_) - except TypeError: # pragma: nocover - enforce( - False, - f"'{key}' must be a {type_}, but type {type(value)} was found in `models.params.args` of `skill.yaml` of `{skill_id}`", - ) - return value - - -@dataclass(frozen=True) -class GenesisBlock(TypeCheckMixin): - """A dataclass to store the genesis block.""" - - max_bytes: str - max_gas: str - time_iota_ms: str - - def to_json(self) -> Dict[str, str]: - """Get a GenesisBlock instance as a json dictionary.""" - return { - "max_bytes": self.max_bytes, - "max_gas": self.max_gas, - "time_iota_ms": self.time_iota_ms, - } - - -@dataclass(frozen=True) -class GenesisEvidence(TypeCheckMixin): - """A dataclass to store the genesis evidence.""" - - max_age_num_blocks: str - max_age_duration: str - max_bytes: str - - def to_json(self) -> Dict[str, str]: - """Get a GenesisEvidence instance as a json dictionary.""" - return { - "max_age_num_blocks": self.max_age_num_blocks, - "max_age_duration": self.max_age_duration, - "max_bytes": self.max_bytes, - } - - -@dataclass(frozen=True) -class GenesisValidator(TypeCheckMixin): - """A dataclass to store the genesis validator.""" - - pub_key_types: Tuple[str, ...] - - def to_json(self) -> Dict[str, List[str]]: - """Get a GenesisValidator instance as a json dictionary.""" - return {"pub_key_types": list(self.pub_key_types)} - - -@dataclass(frozen=True) -class GenesisConsensusParams(TypeCheckMixin): - """A dataclass to store the genesis consensus parameters.""" - - block: GenesisBlock - evidence: GenesisEvidence - validator: GenesisValidator - version: dict - - @classmethod - def from_json_dict(cls, json_dict: dict) -> "GenesisConsensusParams": - """Get a GenesisConsensusParams instance from a json dictionary.""" - block = GenesisBlock(**json_dict["block"]) - evidence = GenesisEvidence(**json_dict["evidence"]) - validator = GenesisValidator(tuple(json_dict["validator"]["pub_key_types"])) - return cls(block, evidence, validator, json_dict["version"]) - - def to_json(self) -> Dict[str, Any]: - """Get a GenesisConsensusParams instance as a json dictionary.""" - return { - "block": self.block.to_json(), - "evidence": self.evidence.to_json(), - "validator": self.validator.to_json(), - "version": self.version, - } - - -@dataclass(frozen=True) -class GenesisConfig(TypeCheckMixin): - """A dataclass to store the genesis configuration.""" - - genesis_time: str - chain_id: str - consensus_params: GenesisConsensusParams - voting_power: str - - @classmethod - def from_json_dict(cls, json_dict: dict) -> "GenesisConfig": - """Get a GenesisConfig instance from a json dictionary.""" - consensus_params = GenesisConsensusParams.from_json_dict( - json_dict["consensus_params"] - ) - return cls( - json_dict["genesis_time"], - json_dict["chain_id"], - consensus_params, - json_dict["voting_power"], - ) - - def to_json(self) -> Dict[str, Any]: - """Get a GenesisConfig instance as a json dictionary.""" - return { - "genesis_time": self.genesis_time, - "chain_id": self.chain_id, - "consensus_params": self.consensus_params.to_json(), - "voting_power": self.voting_power, - } - - -class BaseParams( - Model, FrozenMixin, TypeCheckMixin -): # pylint: disable=too-many-instance-attributes - """Parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """ - Initialize the parameters object. - - The genesis configuration should be a dictionary with the following format: - genesis_time: str - chain_id: str - consensus_params: - block: - max_bytes: str - max_gas: str - time_iota_ms: str - evidence: - max_age_num_blocks: str - max_age_duration: str - max_bytes: str - validator: - pub_key_types: List[str] - version: dict - voting_power: str - - :param args: positional arguments - :param kwargs: keyword arguments - """ - self.genesis_config: GenesisConfig = GenesisConfig.from_json_dict( - self._ensure("genesis_config", kwargs, dict) - ) - self.service_id: str = self._ensure("service_id", kwargs, str) - self.tendermint_url: str = self._ensure("tendermint_url", kwargs, str) - self.max_healthcheck: int = self._ensure("max_healthcheck", kwargs, int) - self.round_timeout_seconds: float = self._ensure( - "round_timeout_seconds", kwargs, float - ) - self.sleep_time: int = self._ensure("sleep_time", kwargs, int) - self.retry_timeout: int = self._ensure("retry_timeout", kwargs, int) - self.retry_attempts: int = self._ensure("retry_attempts", kwargs, int) - self.keeper_timeout: float = self._ensure("keeper_timeout", kwargs, float) - self.reset_pause_duration: int = self._ensure_gte( - "reset_pause_duration", kwargs, int, min_value=MIN_RESET_PAUSE_DURATION - ) - self.drand_public_key: str = self._ensure("drand_public_key", kwargs, str) - self.tendermint_com_url: str = self._ensure("tendermint_com_url", kwargs, str) - self.tendermint_max_retries: int = self._ensure( - "tendermint_max_retries", kwargs, int - ) - self.tendermint_check_sleep_delay: int = self._ensure( - "tendermint_check_sleep_delay", kwargs, int - ) - self.reset_tendermint_after: int = self._ensure( - "reset_tendermint_after", kwargs, int - ) - self.cleanup_history_depth: int = self._ensure( - "cleanup_history_depth", kwargs, int - ) - self.cleanup_history_depth_current: Optional[int] = self._ensure( - "cleanup_history_depth_current", kwargs, Optional[int] - ) - self.request_timeout: float = self._ensure("request_timeout", kwargs, float) - self.request_retry_delay: float = self._ensure( - "request_retry_delay", kwargs, float - ) - self.tx_timeout: float = self._ensure("tx_timeout", kwargs, float) - self.max_attempts: int = self._ensure("max_attempts", kwargs, int) - self.service_registry_address: Optional[str] = self._ensure( - "service_registry_address", kwargs, Optional[str] - ) - self.on_chain_service_id: Optional[int] = self._ensure( - "on_chain_service_id", kwargs, Optional[int] - ) - self.share_tm_config_on_startup: bool = self._ensure( - "share_tm_config_on_startup", kwargs, bool - ) - self.tendermint_p2p_url: str = self._ensure("tendermint_p2p_url", kwargs, str) - self.use_termination: bool = self._ensure("use_termination", kwargs, bool) - self.use_slashing: bool = self._ensure("use_slashing", kwargs, bool) - self.slash_cooldown_hours: int = self._ensure( - "slash_cooldown_hours", kwargs, int - ) - self.slash_threshold_amount: int = self._ensure( - "slash_threshold_amount", kwargs, int - ) - self.light_slash_unit_amount: int = self._ensure( - "light_slash_unit_amount", kwargs, int - ) - self.serious_slash_unit_amount: int = self._ensure( - "serious_slash_unit_amount", kwargs, int - ) - self.setup_params: Dict[str, Any] = self._ensure("setup", kwargs, dict) - # TODO add to all configs - self.default_chain_id: str = kwargs.get("default_chain_id", DEFAULT_CHAIN) - - # we sanitize for null values as these are just kept for schema definitions - skill_id = kwargs["skill_context"].skill_id - super().__init__(*args, **kwargs) - - if not self.context.is_abstract_component: - # setup data are mandatory for non-abstract skills, - # and they should always contain at least `all_participants` and `safe_contract_address` - self._ensure_setup( - { - get_name(BaseSynchronizedData.safe_contract_address): str, - get_name(BaseSynchronizedData.all_participants): List[str], - get_name(BaseSynchronizedData.consensus_threshold): cast( - Type, Optional[int] - ), - }, - skill_id, - ) - self._frozen = True - - def _ensure_setup( - self, necessary_params: Dict[str, Type], skill_id: PublicId - ) -> Any: - """Ensure that the `setup` params contain all the `necessary_keys` and have the correct types.""" - enforce(bool(self.setup_params), "`setup` params contain no values!") - - for key, type_ in necessary_params.items(): - # check that the key is present, note that None is acceptable for optional keys - value = self.setup_params.get(key, VALUE_NOT_PROVIDED) - if value is VALUE_NOT_PROVIDED: - fail_msg = f"Value for `{key}` missing from the `setup` params." - enforce(False, fail_msg) - - # check that the value is of the correct type - try: - check_type(key, value, type_) - except TypeError: # pragma: nocover - enforce( - False, - f"'{key}' must be a {type_}, but type {type(value)} was found in `models.params.args.setup` " - f"of `skill.yaml` of `{skill_id}`", - ) - - def _ensure_gte( - self, key: str, kwargs: Dict[str, Any], type_: Type, min_value: Any - ) -> Any: - """Ensure that the value for the key is greater than or equal to the provided min_value.""" - err = check(min_value, type_) - enforce( - err is None, - f"min_value must be of type {type_.__name__}, but got {type(min_value).__name__}.", - ) - value = self._ensure(key, kwargs, type_) - enforce( - value >= min_value, f"`{key}` must be greater than or equal to {min_value}." - ) - return value - - -class _MetaSharedState(ABCMeta): - """A metaclass that validates SharedState's attributes.""" - - def __new__(mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any) -> Type: # type: ignore - """Initialize the class.""" - new_cls = super().__new__(mcs, name, bases, namespace, **kwargs) - - if ABC in bases: - # abstract class, return - return new_cls - if not issubclass(new_cls, SharedState): - # the check only applies to SharedState subclasses - return new_cls - - mcs._check_consistency(cast(Type[SharedState], new_cls)) - return new_cls - - @classmethod - def _check_consistency(mcs, shared_state_cls: Type["SharedState"]) -> None: - """Check consistency of class attributes.""" - mcs._check_required_class_attributes(shared_state_cls) - - @classmethod - def _check_required_class_attributes( - mcs, shared_state_cls: Type["SharedState"] - ) -> None: - """Check that required class attributes are set.""" - if not hasattr(shared_state_cls, "abci_app_cls"): - raise AttributeError(f"'abci_app_cls' not set on {shared_state_cls}") - abci_app_cls = shared_state_cls.abci_app_cls - if not inspect.isclass(abci_app_cls): - raise AttributeError(f"The object `{abci_app_cls}` is not a class") - if not issubclass(abci_app_cls, AbciApp): - cls_name = AbciApp.__name__ - cls_module = AbciApp.__module__ - raise AttributeError( - f"The class {abci_app_cls} is not an instance of {cls_module}.{cls_name}" - ) - - -class SharedState(Model, ABC, metaclass=_MetaSharedState): # type: ignore - """Keep the current shared state of the skill.""" - - abci_app_cls: Type[AbciApp] - - def __init__( - self, - *args: Any, - skill_context: SkillContext, - **kwargs: Any, - ) -> None: - """Initialize the state.""" - self.abci_app_cls._is_abstract = skill_context.is_abstract_component - self._round_sequence: Optional[RoundSequence] = None - # a mapping of the agents' addresses to their initial Tendermint configuration, to be retrieved via ACN - self.initial_tm_configs: Dict[str, Optional[Dict[str, Any]]] = {} - # a mapping of the other agents' addresses to ACN deliverables - self.address_to_acn_deliverable: Dict[str, Any] = {} - self.tm_recovery_params: TendermintRecoveryParams = TendermintRecoveryParams( - self.abci_app_cls.initial_round_cls.auto_round_id() - ) - kwargs["skill_context"] = skill_context - super().__init__(*args, **kwargs) - - def setup_slashing(self, validator_to_agent: Dict[str, str]) -> None: - """Initialize the structures required for slashing.""" - configured_agents = set(self.initial_tm_configs.keys()) - agents_mapped = set(validator_to_agent.values()) - diff = agents_mapped.symmetric_difference(configured_agents) - if diff: - raise ValueError( - f"Trying to use the mapping `{validator_to_agent}`, which contains validators for non-configured " - "agents and/or does not contain validators for some configured agents. " - f"The agents which have been configured via ACN are `{configured_agents}` and the diff was for {diff}." - ) - self.round_sequence.validator_to_agent = validator_to_agent - self.round_sequence.offence_status = { - agent: OffenceStatus() for agent in agents_mapped - } - - def get_validator_address(self, agent_address: str) -> str: - """Get the validator address of an agent.""" - if agent_address not in self.synchronized_data.all_participants: - raise ValueError( - f"The validator address of non-participating agent `{agent_address}` was requested." - ) - - try: - agent_config = self.initial_tm_configs[agent_address] - except KeyError as e: - raise ValueError( - "SharedState's setup was not performed successfully." - ) from e - - if agent_config is None: - raise ValueError( - f"ACN registration has not been successfully performed for agent `{agent_address}`. " - "Have you set the `share_tm_config_on_startup` flag to `true` in the configuration?" - ) - - validator_address = agent_config.get("address", None) - if validator_address is None: - raise ValueError( - f"The tendermint configuration for agent `{agent_address}` is invalid: `{agent_config}`." - ) - - return validator_address - - def acn_container(self) -> Dict[str, Any]: - """Create a container for ACN results, i.e., a mapping from others' addresses to `None`.""" - ourself = {self.context.agent_address} - others_addresses = self.synchronized_data.all_participants - ourself - - return dict.fromkeys(others_addresses) - - def setup(self) -> None: - """Set up the model.""" - self._round_sequence = RoundSequence(self.context, self.abci_app_cls) - setup_params = cast(BaseParams, self.context.params).setup_params - self.round_sequence.setup( - BaseSynchronizedData( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists(setup_params), - cross_period_persisted_keys=self.abci_app_cls.cross_period_persisted_keys, - logger=self.context.logger, - ) - ), - self.context.logger, - ) - if not self.context.is_abstract_component: - self.initial_tm_configs = dict.fromkeys( - self.synchronized_data.all_participants - ) - - @property - def round_sequence(self) -> RoundSequence: - """Get the round_sequence.""" - if self._round_sequence is None: - raise ValueError("round sequence not available") - return self._round_sequence - - @property - def synchronized_data(self) -> BaseSynchronizedData: - """Get the latest synchronized_data if available.""" - return self.round_sequence.latest_synchronized_data - - def get_acn_result(self) -> Any: - """Get the majority of the ACN deliverables.""" - if len(self.address_to_acn_deliverable) == 0: - return None - - # the current agent does not participate, so we need `nb_participants - 1` - threshold = consensus_threshold(self.synchronized_data.nb_participants - 1) - counter = Counter(self.address_to_acn_deliverable.values()) - most_common_value, n_appearances = counter.most_common(1)[0] - - if n_appearances < threshold: - return None - - self.context.logger.debug( - f"ACN result is '{most_common_value}' from '{self.address_to_acn_deliverable}'." - ) - return most_common_value - - -class Requests(Model, FrozenMixin): - """Keep the current pending requests.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the state.""" - # mapping from dialogue reference nonce to a callback - self.request_id_to_callback: Dict[str, Callable] = {} - super().__init__(*args, **kwargs) - self._frozen = True - - -class UnexpectedResponseError(Exception): - """Exception class for unexpected responses from Apis.""" - - -@dataclass -class ResponseInfo(TypeCheckMixin): - """A dataclass to hold all the information related to the response.""" - - response_key: Optional[str] - response_index: Optional[int] - response_type: str - error_key: Optional[str] - error_index: Optional[int] - error_type: str - error_data: Any = None - - @classmethod - def from_json_dict(cls, kwargs: Dict) -> "ResponseInfo": - """Initialize a response info object from kwargs.""" - response_key: Optional[str] = kwargs.pop("response_key", None) - response_index: Optional[int] = kwargs.pop("response_index", None) - response_type: str = kwargs.pop("response_type", DEFAULT_TYPE_NAME) - error_key: Optional[str] = kwargs.pop("error_key", None) - error_index: Optional[int] = kwargs.pop("error_index", None) - error_type: str = kwargs.pop("error_type", DEFAULT_TYPE_NAME) - return cls( - response_key, - response_index, - response_type, - error_key, - error_index, - error_type, - ) - - -@dataclass -class RetriesInfo(TypeCheckMixin): - """A dataclass to hold all the information related to the retries.""" - - retries: int - backoff_factor: float - retries_attempted: int = 0 - - @classmethod - def from_json_dict(cls, kwargs: Dict) -> "RetriesInfo": - """Initialize a retries info object from kwargs.""" - retries: int = kwargs.pop("retries", NUMBER_OF_RETRIES) - backoff_factor: float = kwargs.pop("backoff_factor", DEFAULT_BACKOFF_FACTOR) - return cls(retries, backoff_factor) - - @property - def suggested_sleep_time(self) -> float: - """The suggested amount of time to sleep.""" - return self.backoff_factor**self.retries_attempted - - -@dataclass(frozen=True) -class TendermintRecoveryParams(TypeCheckMixin): - """ - A dataclass to hold all parameters related to agent <-> tendermint recovery procedures. - - This must be frozen so that we make sure it does not get edited. - """ - - reset_from_round: str - round_count: int = ROUND_COUNT_DEFAULT - reset_params: Optional[Dict[str, str]] = None - serialized_db_state: Optional[str] = None - - def __hash__(self) -> int: - """Hash the object.""" - return hash( - self.reset_from_round - + str(self.round_count) - + str(self.serialized_db_state) - + json.dumps(self.reset_params, sort_keys=True) - ) - - -class ApiSpecs(Model, FrozenMixin, TypeCheckMixin): - """A model that wraps APIs to get cryptocurrency prices.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize ApiSpecsModel.""" - self.url: str = self._ensure("url", kwargs, str) - self.api_id: str = self._ensure("api_id", kwargs, str) - self.method: str = self._ensure("method", kwargs, str) - self.headers: Dict[str, str] = dict( - self._ensure("headers", kwargs, OrderedDict[str, str]) - ) - self.parameters: Dict[str, str] = dict( - self._ensure("parameters", kwargs, OrderedDict[str, str]) - ) - self.response_info = ResponseInfo.from_json_dict(kwargs) - self.retries_info = RetriesInfo.from_json_dict(kwargs) - super().__init__(*args, **kwargs) - self._frozen = True - - def get_spec( - self, - ) -> Dict: - """Returns dictionary containing api specifications.""" - - return { - "url": self.url, - "method": self.method, - "headers": self.headers, - "parameters": self.parameters, - } - - def _log_response(self, decoded_response: str) -> None: - """Log the decoded response message using error level.""" - pretty_json_str = json.dumps(decoded_response, indent=4) - self.context.logger.error(f"Response: {pretty_json_str}") - - @staticmethod - def _parse_response( - response_data: Any, - response_keys: Optional[str], - response_index: Optional[int], - response_type: str, - ) -> Any: - """Parse a response from an API.""" - if response_keys is not None: - response_data = get_data_from_nested_dict(response_data, response_keys) - - if response_index is not None: - response_data = response_data[response_index] - - return get_value_with_type(response_data, response_type) - - def _get_error_from_response(self, response_data: Any) -> Any: - """Try to get an error from the response.""" - try: - return self._parse_response( - response_data, - self.response_info.error_key, - self.response_info.error_index, - self.response_info.error_type, - ) - except (KeyError, IndexError, TypeError): - self.context.logger.error( - f"Could not parse error using the given key(s) ({self.response_info.error_key}) " - f"and index ({self.response_info.error_index})!" - ) - return None - - def _parse_response_data(self, response_data: Any) -> Any: - """Get the response data.""" - try: - return self._parse_response( - response_data, - self.response_info.response_key, - self.response_info.response_index, - self.response_info.response_type, - ) - except (KeyError, IndexError, TypeError) as e: - raise UnexpectedResponseError from e - - def process_response(self, response: HttpMessage) -> Any: - """Process response from api.""" - decoded_response = response.body.decode() - self.response_info.error_data = None - - try: - response_data = json.loads(decoded_response) - except json.JSONDecodeError: - self.context.logger.error("Could not parse the response body!") - self._log_response(decoded_response) - return None - - try: - return self._parse_response_data(response_data) - except UnexpectedResponseError: - self.context.logger.error( - f"Could not access response using the given key(s) ({self.response_info.response_key}) " - f"and index ({self.response_info.response_index})!" - ) - self._log_response(decoded_response) - self.response_info.error_data = self._get_error_from_response(response_data) - return None - - def increment_retries(self) -> None: - """Increment the retries counter.""" - self.retries_info.retries_attempted += 1 - - def reset_retries(self) -> None: - """Reset the retries counter.""" - self.retries_info.retries_attempted = 0 - - def is_retries_exceeded(self) -> bool: - """Check if the retries amount has been exceeded.""" - return self.retries_info.retries_attempted > self.retries_info.retries - - -class BenchmarkBlockTypes(Enum): - """Benchmark block types.""" - - LOCAL = "local" - CONSENSUS = "consensus" - TOTAL = "total" - - -class BenchmarkBlock: - """ - Benchmark - - This class represents logic to measure the code block using a - context manager. - """ - - start: float - total_time: float - block_type: str - - def __init__(self, block_type: str) -> None: - """Benchmark for single round.""" - self.block_type = block_type - self.start = 0 - self.total_time = 0 - - def __enter__( - self, - ) -> None: - """Enter context.""" - self.start = time() - - def __exit__(self, *args: List, **kwargs: Dict) -> None: - """Exit context""" - self.total_time = time() - self.start - - -class BenchmarkBehaviour: - """ - BenchmarkBehaviour - - This class represents logic to benchmark a single behaviour. - """ - - local_data: Dict[str, BenchmarkBlock] - - def __init__( - self, - ) -> None: - """Initialize Benchmark behaviour object.""" - self.local_data = {} - - def _measure(self, block_type: str) -> BenchmarkBlock: - """ - Returns a BenchmarkBlock object. - - :param block_type: type of block (e.g. local, consensus, request) - :return: BenchmarkBlock - """ - - if block_type not in self.local_data: - self.local_data[block_type] = BenchmarkBlock(block_type) - - return self.local_data[block_type] - - def local( - self, - ) -> BenchmarkBlock: - """Measure local block.""" - return self._measure(BenchmarkBlockTypes.LOCAL.value) - - def consensus( - self, - ) -> BenchmarkBlock: - """Measure consensus block.""" - return self._measure(BenchmarkBlockTypes.CONSENSUS.value) - - -class BenchmarkTool(Model, TypeCheckMixin, FrozenMixin): - """ - BenchmarkTool - - Tool to benchmark ABCI apps. - """ - - benchmark_data: Dict[str, BenchmarkBehaviour] - log_dir: Path - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Benchmark tool for rounds behaviours.""" - self.benchmark_data = {} - log_dir_ = self._ensure("log_dir", kwargs, str) - self.log_dir = Path(log_dir_) - super().__init__(*args, **kwargs) - self._frozen = True - - def measure(self, behaviour: str) -> BenchmarkBehaviour: - """Measure time to complete round.""" - if behaviour not in self.benchmark_data: - self.benchmark_data[behaviour] = BenchmarkBehaviour() - return self.benchmark_data[behaviour] - - @property - def data( - self, - ) -> List: - """Returns formatted data.""" - - behavioural_data = [] - for behaviour, tool in self.benchmark_data.items(): - data = {k: v.total_time for k, v in tool.local_data.items()} - data[BenchmarkBlockTypes.TOTAL.value] = sum(data.values()) - behavioural_data.append({"behaviour": behaviour, "data": data}) - - return behavioural_data - - def save(self, period: int = 0, reset: bool = True) -> None: - """Save logs to a file.""" - - try: - self.log_dir.mkdir(exist_ok=True) - agent_dir = self.log_dir / self.context.agent_address - agent_dir.mkdir(exist_ok=True) - filepath = agent_dir / f"{period}.json" - - with open(str(filepath), "w+", encoding="utf-8") as outfile: - json.dump(self.data, outfile) - self.context.logger.debug(f"Saving benchmarking data for period: {period}") - - except PermissionError as e: # pragma: nocover - self.context.logger.error(f"Error saving benchmark data:\n{e}") - - if reset: - self.reset() - - def reset( - self, - ) -> None: - """Reset benchmark data""" - self.benchmark_data.clear() diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/skill.yaml b/trader_backup/vendor/valory/skills/abstract_round_abci/skill.yaml deleted file mode 100644 index 7264c012a..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/skill.yaml +++ /dev/null @@ -1,164 +0,0 @@ -name: abstract_round_abci -author: valory -version: 0.1.0 -type: skill -description: abstract round-based ABCI application -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeievb7bhfm46p5adx3x4gvsynjpq35fcrrapzn5m2whcdt4ufxfvfq - __init__.py: bafybeihxbinbrvhj2edqthpzc2mywfzxzkf7l4v5uj6ubwnffrwgzelmre - abci_app_chain.py: bafybeibhzrixbp5x26wqhb6ogtr3af5lc4tax7lcsvk4v5rvg4psrq5yzi - base.py: bafybeihm7lf4nfqcwfvs4antge2l7eyc7vrafaw6p5canlxwy4qy4akwme - behaviour_utils.py: bafybeidhnu2ucjhlluwthpl4d6374nzmvjopy7byc2uyirajb3kswfggle - behaviours.py: bafybeifzbzy2ppabm6dpgvbsuvpgduyg7g7rei6u4ouy3nnak5top5be5u - common.py: bafybeib4coyhaxvpup7m25lsab2lpebv2wrkjp2cwihuitxmaibo6u6z2m - dialogues.py: bafybeid5sgrfa7ghnnjpssltgtey5gzt5kc2jlaitffaukvhhdbhrzcjti - handlers.py: bafybeidgby4h72qgcp3civ3c55oz3k7s4gdbkcotwhqjsbft6ylbaenjxy - io_/__init__.py: bafybeihv6ytxeo5jkbdlqjum4pfo4aaluvw4m7c55k5xncvvs7ubrlokhy - io_/ipfs.py: bafybeiffdxdt36rcwu5tyfav2umvw3hvlfjwbys3626p2g2gdlfi7djzly - io_/load.py: bafybeigkywwlsheqvd4gpyfwaxqzkkb2ih2poyicqk7e7n2mrsghxzyns4 - io_/paths.py: bafybeicfno2l4vwtmjcm3rzpp6tqi3xlkof47pypf5teecad22d44u2ple - io_/store.py: bafybeig24lslvhf7amim55ig5zzre4z45pcx3r2ozlagg3mtbr6rry2wpu - models.py: bafybeiaffpzuduwwo367cqm4uzl46mq34pdspq57o5itdb5ivyi4s743by - test_tools/__init__.py: bafybeibayeahoo73eztt2chpwi45taj2uv3dxbpyn47ksqfjoepjyaoca4 - test_tools/abci_app.py: bafybeigmrjzxfoc63xgecyngdecz4msvze4aw2iejcjewatjefjbvdlmce - test_tools/base.py: bafybeibef4lclyecne5qj4zaxnaxaqzwpxjaitqqmddgsiezduhb7pfxly - test_tools/common.py: bafybeibxlx7es632kdoeivfrjahns3kknkxfmw4rj2dcxjwqm5j6vx25sq - test_tools/integration.py: bafybeifqq3bx46hz2deph3usvrt7u45tpsapvocofd2zu3yh7rfl5nlmzq - test_tools/rounds.py: bafybeie576yxtiramzt5czpt4hnv76gfetzio2t3k5kprhdhvbpfddbaem - tests/__init__.py: bafybeie54sgqid64dyarbcttz3nnmyympyrtdyxy4lcc7c7yjxhefodbgq - tests/conftest.py: bafybeiauvmnuetxooprdsy3vlys3pha6x2rfg7acr3xrdfffr7onlmnave - tests/data/__init__.py: bafybeifmqjnrqgbau4tshhdtrosru7xyjky72ljlrf3ynrk76fxjcsgfpi - tests/data/dummy_abci/__init__.py: bafybeiaoqyjlgez5gkvutl22ihebcjk3zskve5gdt5wbap5zkmhehoddca - tests/data/dummy_abci/behaviours.py: bafybeibei4ngebbktuq6a2uvwhrulgkvn6uhaj5k3a75zihkxwnfarqh4m - tests/data/dummy_abci/dialogues.py: bafybeiaswubmqa7trhajbjn34okmpftk2sehsqrjg7znzrrd7j32xzx4vq - tests/data/dummy_abci/handlers.py: bafybeifik3ftljs63u7nm4gadxpqbcvqj53p7qftzzzfto3ioad57k3x3u - tests/data/dummy_abci/models.py: bafybeiear3i45wbaylrkbnm2fbtqorxx56glul36piuah7m7jb56f5rpoq - tests/data/dummy_abci/payloads.py: bafybeiczldqiumb7prcusb7l5vb575vschwyseyigpupvteldfyz7h6fyi - tests/data/dummy_abci/rounds.py: bafybeihhheznpcntg4z5cdd7dysnivo2g4x5biv7blriyiyoouqp6xf5aq - tests/test_abci_app_chain.py: bafybeihqvjkcwkwxowhb3umtk52us4pd5f6nbppw4ycx76oljw4j3j7xpa - tests/test_base.py: bafybeihtx2ktf6uck2l6yw72lvnvm5y224vlgawxette75cluc6juedeqe - tests/test_base_rounds.py: bafybeiadkpwuhz6y5k5ffvoqvyi6nqetf5ov5bmodejge7yvscm6yqzpse - tests/test_behaviours.py: bafybeibxxev34avddvezqumr56k7txmqkubl2c5u6y7ydjqn6kp3wabbvq - tests/test_behaviours_utils.py: bafybeidkxzhu26r2shkblz2l3syzc62uet4cxrdbschnf7vuwuuior6xkm - tests/test_common.py: bafybeiekicwjh3vu5kqppictya2bmqm3p5dcauj7cvsiunvhhultpzmyla - tests/test_dialogues.py: bafybeigpfrslqaz2yullyehia5bsl7cmy2qqxtz627ig7rbrypw5xfzeum - tests/test_handlers.py: bafybeih64lmsukci3oc5mwi636gntyx243xnbzwx64dwjxittch77qyqsu - tests/test_io/__init__.py: bafybeid3sssvbbyju4snrdssxyafleuo57sqyuepl25btxcbuj3p5oonsm - tests/test_io/test_ipfs.py: bafybeidm6f6naq6y7ntoivrqon2bkwdvd2dqru467fxqvgonv5oq5huhra - tests/test_io/test_load.py: bafybeidgnxt5rt67ackbcgi5vnlliedxakcnzgihogplolck7kp57pc6iy - tests/test_io/test_store.py: bafybeid2zbdjtgbplenacudk6re7si7dloqs2u7faqt7vhapjipjuw35ku - tests/test_models.py: bafybeicrbu6xtprfgwjs3msa3idilwqe3ymz5zx6xm326huhspzrdngrwi - tests/test_tools/__init__.py: bafybeiew6gu4pgp2sjevq4dbnmv2ail5dph7vj4yi7h3eae4gzx7vj7cbq - tests/test_tools/base.py: bafybeihi7ax53326dhin3riwwwk3bouqvsoeq26han4nspodzj6hrk3gia - tests/test_tools/test_base.py: bafybeie2hox7v6sy677grl6awq57ouliohpwhmlvrypz5rqcz5gxsxn24y - tests/test_tools/test_common.py: bafybeieauphpcqm5on7d2u2lc5lrf3esbhojp6sxlf7phrlmpqy5cfoitq - tests/test_tools/test_integration.py: bafybeidxkvb2kizi7djrpuw446dqxo2v5s7j2dbdrdpfmnd2ggezaxbnkm - tests/test_tools/test_rounds.py: bafybeibaoj4miysneipgukz7xufs47vpv5rds3ptgmu3yxlcl7gjss6ccm - tests/test_utils.py: bafybeift6igxoan2bnuexps7rrdl25jmlniqujw3odnir3cgjy4oukjjfq - utils.py: bafybeidbha3c3tcxo4lhucyx2x6yra4z2p2fp6sucqqzhxanbvgrraykbi -fingerprint_ignore_patterns: [] -connections: -- valory/abci:0.1.0:bafybeia6etkacvqend7xj6viejkqgo7ozu3yn4yg3qezfthf2xhrjjwse4 -- valory/http_client:0.23.0:bafybeihi772xgzpqeipp3fhmvpct4y6e6tpjp4sogwqrnf3wqspgeilg4u -- valory/ipfs:0.1.0:bafybeigcijdbwgdekow5c2ikeltetoteabfp52ewy3xfkd7ygaqbl7j3ke -- valory/ledger:0.19.0:bafybeig7woeog4srdby75hpjkmx4rhpkzncbf4h2pm5r6varsp26pf2uhu -- valory/p2p_libp2p_client:0.1.0:bafybeid3xg5k2ol5adflqloy75ibgljmol6xsvzvezebsg7oudxeeolz7e -contracts: -- valory/service_registry:0.1.0:bafybeiaop64kwdoetxtedoehabmsalojmms7ihuoqcdwxtwb2hk5i6bzye -protocols: -- open_aea/signing:1.0.0:bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi -- valory/abci:0.1.0:bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -- valory/ipfs:0.1.0:bafybeiftxi2qhreewgsc5wevogi7yc5g6hbcbo4uiuaibauhv3nhfcdtvm -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -- valory/tendermint:0.1.0:bafybeig4mi3vmlv5zpbjbfuzcgida6j5f2nhrpedxicmrrfjweqc5r7cra -skills: -- valory/abstract_abci:0.1.0:bafybeieeaseuy5rbbw465knz27vccvpkfge43q7isl7fkdlfapwd7bpi24 -behaviours: - main: - args: {} - class_name: AbstractRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - api_specs: - args: {} - class_name: ApiSpecs - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: - eth_typing: {} - hypothesis: - version: ==6.21.6 - ipfshttpclient: - version: ==0.8.0a2 - open-aea-cli-ipfs: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - protobuf: - version: <4.25.0,>=4.21.6 - py-ecc: - version: ==6.0.0 - pytest: - version: ==7.2.1 - pytz: - version: ==2022.2.1 - requests: - version: <2.31.2,>=2.28.1 - typing_extensions: - version: '>=3.10.0.2' -is_abstract: true -customs: [] diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/__init__.py b/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/__init__.py deleted file mode 100644 index 33f9dae86..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for abstract_round_abci derived skills.""" # pragma: nocover diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/abci_app.py b/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/abci_app.py deleted file mode 100644 index 10e126096..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/abci_app.py +++ /dev/null @@ -1,203 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""ABCI App test tools.""" - - -from abc import ABC -from enum import Enum -from typing import Dict, Tuple, Type, Union -from unittest.mock import MagicMock - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbstractRound, - BaseSynchronizedData, - BaseTxPayload, - DegenerateRound, -) - - -class _ConcreteRound(AbstractRound, ABC): - """ConcreteRound""" - - synchronized_data_class = BaseSynchronizedData - payload_attribute = "" - - def end_block(self) -> Union[None, Tuple[MagicMock, MagicMock]]: - """End block.""" - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - - -class ConcreteRoundA(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - def end_block(self) -> Tuple[MagicMock, MagicMock]: - """End block.""" - return MagicMock(), MagicMock() - - -class ConcreteRoundB(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteRoundC(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteBackgroundRound(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteBackgroundSlashingRound(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteTerminationRoundA(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteTerminationRoundB(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteTerminationRoundC(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteSlashingRoundA(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteSlashingRoundB(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteEvents(Enum): - """Defines dummy events to be used for testing purposes.""" - - TERMINATE = "terminate" - PENDING_OFFENCE = "pending_offence" - SLASH_START = "slash_start" - SLASH_END = "slash_end" - A = "a" - B = "b" - C = "c" - D = "c" - TIMEOUT = "timeout" - - def __str__(self) -> str: - """Get the string representation of the event.""" - return self.value - - -class TerminationAppTest(AbciApp[ConcreteEvents]): - """A dummy Termination abci for testing purposes.""" - - initial_round_cls: Type[AbstractRound] = ConcreteBackgroundRound - transition_function: Dict[ - Type[AbstractRound], Dict[ConcreteEvents, Type[AbstractRound]] - ] = { - ConcreteBackgroundRound: { - ConcreteEvents.TERMINATE: ConcreteTerminationRoundA, - }, - ConcreteTerminationRoundA: { - ConcreteEvents.A: ConcreteTerminationRoundA, - ConcreteEvents.B: ConcreteTerminationRoundB, - ConcreteEvents.C: ConcreteTerminationRoundC, - }, - ConcreteTerminationRoundB: { - ConcreteEvents.B: ConcreteTerminationRoundB, - ConcreteEvents.TIMEOUT: ConcreteTerminationRoundA, - }, - ConcreteTerminationRoundC: { - ConcreteEvents.C: ConcreteTerminationRoundA, - ConcreteEvents.TIMEOUT: ConcreteTerminationRoundC, - }, - } - - -class SlashingAppTest(AbciApp[ConcreteEvents]): - """A dummy Slashing abci for testing purposes.""" - - initial_round_cls: Type[AbstractRound] = ConcreteBackgroundSlashingRound - transition_function: Dict[ - Type[AbstractRound], Dict[ConcreteEvents, Type[AbstractRound]] - ] = { - ConcreteBackgroundSlashingRound: { - ConcreteEvents.SLASH_START: ConcreteSlashingRoundA, - }, - ConcreteSlashingRoundA: {ConcreteEvents.D: ConcreteSlashingRoundB}, - ConcreteSlashingRoundB: { - ConcreteEvents.SLASH_END: DegenerateRound, - }, - } - - -class AbciAppTest(AbciApp[ConcreteEvents]): - """A dummy AbciApp for testing purposes.""" - - TIMEOUT: float = 1.0 - - initial_round_cls: Type[AbstractRound] = ConcreteRoundA - transition_function: Dict[ - Type[AbstractRound], Dict[ConcreteEvents, Type[AbstractRound]] - ] = { - ConcreteRoundA: { - ConcreteEvents.A: ConcreteRoundA, - ConcreteEvents.B: ConcreteRoundB, - ConcreteEvents.C: ConcreteRoundC, - }, - ConcreteRoundB: { - ConcreteEvents.B: ConcreteRoundB, - ConcreteEvents.TIMEOUT: ConcreteRoundA, - }, - ConcreteRoundC: { - ConcreteEvents.C: ConcreteRoundA, - ConcreteEvents.TIMEOUT: ConcreteRoundC, - }, - } - event_to_timeout: Dict[ConcreteEvents, float] = { - ConcreteEvents.TIMEOUT: TIMEOUT, - } diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/base.py b/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/base.py deleted file mode 100644 index 30640e941..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/base.py +++ /dev/null @@ -1,444 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/abstract_round_abci skill's behaviours.""" -import json -from abc import ABC -from copy import copy -from enum import Enum -from pathlib import Path -from tempfile import TemporaryDirectory -from typing import Any, Dict, Type, cast -from unittest import mock -from unittest.mock import MagicMock - -from aea.helpers.transaction.base import SignedMessage -from aea.test_tools.test_skill import BaseSkillTestCase - -from packages.open_aea.protocols.signing import SigningMessage -from packages.valory.connections.http_client.connection import ( - PUBLIC_ID as HTTP_CLIENT_PUBLIC_ID, -) -from packages.valory.connections.ledger.connection import ( - PUBLIC_ID as LEDGER_CONNECTION_PUBLIC_ID, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import ( - AbstractRound, - BaseSynchronizedData, - BaseTxPayload, - OK_CODE, - _MetaPayload, -) -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler, - HttpHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, -) - - -# pylint: disable=protected-access,too-few-public-methods,consider-using-with - - -class FSMBehaviourBaseCase(BaseSkillTestCase, ABC): - """Base case for testing FSMBehaviour classes.""" - - path_to_skill: Path - behaviour: AbstractRoundBehaviour - ledger_handler: LedgerApiHandler - http_handler: HttpHandler - contract_handler: ContractApiHandler - signing_handler: SigningHandler - tendermint_handler: TendermintHandler - old_tx_type_to_payload_cls: Dict[str, Type[BaseTxPayload]] - benchmark_dir: TemporaryDirectory - default_ledger: str = "ethereum" - - @classmethod - def setup_class(cls, **kwargs: Any) -> None: - """Setup the test class.""" - if not hasattr(cls, "path_to_skill"): - raise ValueError(f"No `path_to_skill` set on {cls}") # pragma: nocover - # works once https://github.com/valory-xyz/open-aea/issues/492 is fixed - # we need to store the current value of the meta-class attribute - # _MetaPayload.transaction_type_to_payload_cls, and restore it - # in the teardown function. We do a shallow copy so we avoid - # to modify the old mapping during the execution of the tests. - cls.old_tx_type_to_payload_cls = copy(_MetaPayload.registry) - _MetaPayload.registry = {} - super().setup_class(**kwargs) # pylint: disable=no-value-for-parameter - assert ( - cls._skill.skill_context._agent_context is not None - ), "Agent context not set" # nosec - cls._skill.skill_context._agent_context.identity._default_address_key = ( - cls.default_ledger - ) - cls._skill.skill_context._agent_context._default_ledger_id = cls.default_ledger - behaviour = cls._skill.skill_context.behaviours.main - assert isinstance( - behaviour, AbstractRoundBehaviour - ), f"{behaviour} is not of type {AbstractRoundBehaviour}" - cls.behaviour = behaviour - for attr, handler, handler_type in [ - ("http_handler", cls._skill.skill_context.handlers.http, HttpHandler), - ( - "signing_handler", - cls._skill.skill_context.handlers.signing, - SigningHandler, - ), - ( - "contract_handler", - cls._skill.skill_context.handlers.contract_api, - ContractApiHandler, - ), - ( - "ledger_handler", - cls._skill.skill_context.handlers.ledger_api, - LedgerApiHandler, - ), - ( - "tendermint_handler", - cls._skill.skill_context.handlers.tendermint, - TendermintHandler, - ), - ]: - assert isinstance( - handler, handler_type - ), f"{handler} is not of type {handler_type}" - setattr(cls, attr, handler) - - if kwargs.get("param_overrides") is not None: - for param_name, param_value in kwargs["param_overrides"].items(): - cls.behaviour.context.params.__dict__[param_name] = param_value - - def setup(self, **kwargs: Any) -> None: - """ - Set up the test method. - - Called each time before a test method is called. - - :param kwargs: the keyword arguments passed to _prepare_skill - """ - super().setup(**kwargs) - self.behaviour.setup() - self._skill.skill_context.state.setup() - self._skill.skill_context.state.round_sequence.end_sync() - - self.benchmark_dir = TemporaryDirectory() - self._skill.skill_context.benchmark_tool.__dict__["log_dir"] = Path( - self.benchmark_dir.name - ) - assert ( # nosec - cast(BaseBehaviour, self.behaviour.current_behaviour).behaviour_id - == self.behaviour.initial_behaviour_cls.auto_behaviour_id() - ) - - def fast_forward_to_behaviour( - self, - behaviour: AbstractRoundBehaviour, - behaviour_id: str, - synchronized_data: BaseSynchronizedData, - ) -> None: - """Fast forward the FSM to a behaviour.""" - next_behaviour = {s.auto_behaviour_id(): s for s in behaviour.behaviours}[ - behaviour_id - ] - next_behaviour = cast(Type[BaseBehaviour], next_behaviour) - behaviour.current_behaviour = next_behaviour( - name=next_behaviour.auto_behaviour_id(), skill_context=behaviour.context - ) - self.skill.skill_context.state.round_sequence.abci_app._round_results.append( - synchronized_data - ) - self.skill.skill_context.state.round_sequence.abci_app._extend_previous_rounds_with_current_round() - self.skill.skill_context.behaviours.main._last_round_height = ( - self.skill.skill_context.state.round_sequence.abci_app.current_round_height - ) - self.skill.skill_context.state.round_sequence.abci_app._current_round_cls = ( - next_behaviour.matching_round - ) - # consensus parameters will not be available if the current skill is abstract - consensus_params = getattr( - self.skill.skill_context.params, "consensus_params", None - ) - self.skill.skill_context.state.round_sequence.abci_app._current_round = ( - next_behaviour.matching_round(synchronized_data, consensus_params) - ) - - def mock_ledger_api_request( - self, request_kwargs: Dict, response_kwargs: Dict - ) -> None: - """ - Mock http request. - - :param request_kwargs: keyword arguments for request check. - :param response_kwargs: keyword arguments for mock response. - """ - - self.assert_quantity_in_outbox(1) - actual_ledger_api_message = self.get_message_from_outbox() - assert actual_ledger_api_message is not None, "No message in outbox." # nosec - has_attributes, error_str = self.message_has_attributes( - actual_message=actual_ledger_api_message, - message_type=LedgerApiMessage, - to=str(LEDGER_CONNECTION_PUBLIC_ID), - sender=str(self.skill.skill_context.skill_id), - **request_kwargs, - ) - - assert has_attributes, error_str # nosec - incoming_message = self.build_incoming_message( - message_type=LedgerApiMessage, - dialogue_reference=( - actual_ledger_api_message.dialogue_reference[0], - "stub", - ), - target=actual_ledger_api_message.message_id, - message_id=-1, - to=str(self.skill.skill_context.skill_id), - sender=str(LEDGER_CONNECTION_PUBLIC_ID), - ledger_id=str(LEDGER_CONNECTION_PUBLIC_ID), - **response_kwargs, - ) - self.ledger_handler.handle(incoming_message) - self.behaviour.act_wrapper() - - def mock_contract_api_request( - self, contract_id: str, request_kwargs: Dict, response_kwargs: Dict - ) -> None: - """ - Mock http request. - - :param contract_id: contract id. - :param request_kwargs: keyword arguments for request check. - :param response_kwargs: keyword arguments for mock response. - """ - - self.assert_quantity_in_outbox(1) - actual_contract_ledger_message = self.get_message_from_outbox() - assert ( # nosec - actual_contract_ledger_message is not None - ), "No message in outbox." - has_attributes, error_str = self.message_has_attributes( - actual_message=actual_contract_ledger_message, - message_type=ContractApiMessage, - to=str(LEDGER_CONNECTION_PUBLIC_ID), - sender=str(self.skill.skill_context.skill_id), - ledger_id="ethereum", - contract_id=contract_id, - message_id=1, - **request_kwargs, - ) - assert has_attributes, error_str # nosec - self.behaviour.act_wrapper() - - incoming_message = self.build_incoming_message( - message_type=ContractApiMessage, - dialogue_reference=( - actual_contract_ledger_message.dialogue_reference[0], - "stub", - ), - target=actual_contract_ledger_message.message_id, - message_id=-1, - to=str(self.skill.skill_context.skill_id), - sender=str(LEDGER_CONNECTION_PUBLIC_ID), - ledger_id="ethereum", - contract_id="mock_contract_id", - **response_kwargs, - ) - self.contract_handler.handle(incoming_message) - self.behaviour.act_wrapper() - - def mock_http_request(self, request_kwargs: Dict, response_kwargs: Dict) -> None: - """ - Mock http request. - - :param request_kwargs: keyword arguments for request check. - :param response_kwargs: keyword arguments for mock response. - """ - - self.assert_quantity_in_outbox(1) - actual_http_message = self.get_message_from_outbox() - assert actual_http_message is not None, "No message in outbox." # nosec - has_attributes, error_str = self.message_has_attributes( - actual_message=actual_http_message, - message_type=HttpMessage, - performative=HttpMessage.Performative.REQUEST, - to=str(HTTP_CLIENT_PUBLIC_ID), - sender=str(self.skill.skill_context.skill_id), - **request_kwargs, - ) - assert has_attributes, error_str # nosec - self.behaviour.act_wrapper() - self.assert_quantity_in_outbox(0) - incoming_message = self.build_incoming_message( - message_type=HttpMessage, - dialogue_reference=(actual_http_message.dialogue_reference[0], "stub"), - performative=HttpMessage.Performative.RESPONSE, - target=actual_http_message.message_id, - message_id=-1, - to=str(self.skill.skill_context.skill_id), - sender=str(HTTP_CLIENT_PUBLIC_ID), - **response_kwargs, - ) - self.http_handler.handle(incoming_message) - self.behaviour.act_wrapper() - - def mock_signing_request(self, request_kwargs: Dict, response_kwargs: Dict) -> None: - """Mock signing request.""" - self.assert_quantity_in_decision_making_queue(1) - actual_signing_message = self.get_message_from_decision_maker_inbox() - assert actual_signing_message is not None, "No message in outbox." # nosec - has_attributes, error_str = self.message_has_attributes( - actual_message=actual_signing_message, - message_type=SigningMessage, - to=self.skill.skill_context.decision_maker_address, - sender=str(self.skill.skill_context.skill_id), - **request_kwargs, - ) - assert has_attributes, error_str # nosec - incoming_message = self.build_incoming_message( - message_type=SigningMessage, - dialogue_reference=(actual_signing_message.dialogue_reference[0], "stub"), - target=actual_signing_message.message_id, - message_id=-1, - to=str(self.skill.skill_context.skill_id), - sender=self.skill.skill_context.decision_maker_address, - **response_kwargs, - ) - self.signing_handler.handle(incoming_message) - self.behaviour.act_wrapper() - - def mock_a2a_transaction( - self, - ) -> None: - """Performs mock a2a transaction.""" - - self.mock_signing_request( - request_kwargs=dict( - performative=SigningMessage.Performative.SIGN_MESSAGE, - ), - response_kwargs=dict( - performative=SigningMessage.Performative.SIGNED_MESSAGE, - signed_message=SignedMessage( - ledger_id="ethereum", body="stub_signature" - ), - ), - ) - - self.mock_http_request( - request_kwargs=dict( - method="GET", - headers="", - version="", - body=b"", - ), - response_kwargs=dict( - version="", - status_code=200, - status_text="", - headers="", - body=json.dumps({"result": {"hash": "", "code": OK_CODE}}).encode( - "utf-8" - ), - ), - ) - self.mock_http_request( - request_kwargs=dict( - method="GET", - headers="", - version="", - body=b"", - ), - response_kwargs=dict( - version="", - status_code=200, - status_text="", - headers="", - body=json.dumps({"result": {"tx_result": {"code": OK_CODE}}}).encode( - "utf-8" - ), - ), - ) - - def end_round(self, done_event: Enum) -> None: - """Ends round early to cover `wait_for_end` generator.""" - current_behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - if current_behaviour is None: - return - current_behaviour = cast(BaseBehaviour, current_behaviour) - abci_app = current_behaviour.context.state.round_sequence.abci_app - old_round = abci_app._current_round - abci_app._last_round = old_round - abci_app._current_round = abci_app.transition_function[ - current_behaviour.matching_round - ][done_event](abci_app.synchronized_data, context=MagicMock()) - abci_app._previous_rounds.append(old_round) - abci_app._current_round_height += 1 - self.behaviour._process_current_round() - - def _test_done_flag_set(self) -> None: - """Test that, when round ends, the 'done' flag is set.""" - current_behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert not current_behaviour.is_done() # nosec - with mock.patch.object( - self.behaviour.context.state, "_round_sequence" - ) as mock_round_sequence: - mock_round_sequence.last_round_id = cast( - AbstractRound, current_behaviour.matching_round - ).auto_round_id() - current_behaviour.act_wrapper() - assert current_behaviour.is_done() # nosec - - @classmethod - def teardown_class(cls) -> None: - """Teardown the test class.""" - if getattr(cls, "old_tx_type_to_payload_cls", False): - _MetaPayload.registry = cls.old_tx_type_to_payload_cls - - def teardown(self, **kwargs: Any) -> None: - """Teardown.""" - super().teardown(**kwargs) - self.benchmark_dir.cleanup() - - -class DummyContext: - """Dummy Context class for testing shared state initialization.""" - - class params: - """Dummy param variable.""" - - round_timeout_seconds: float = 1.0 - - _skill: MagicMock = MagicMock() - logger: MagicMock = MagicMock() - skill_id = "dummy_skill_id" - - @property - def is_abstract_component(self) -> bool: - """Mock for is_abstract.""" - return True diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/common.py b/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/common.py deleted file mode 100644 index 8fdab2638..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/common.py +++ /dev/null @@ -1,432 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Test common classes.""" -import binascii -import json -import time -from pathlib import Path -from typing import Any, Set, Type, cast -from unittest import mock - -import pytest -from aea.exceptions import AEAActException -from aea.skills.base import SkillContext - -from packages.valory.protocols.contract_api.custom_types import State -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - BaseSynchronizedData, -) -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) - - -PACKAGE_DIR = Path(__file__).parent.parent -DRAND_VALUE = { - "round": 1416669, - "randomness": "f6be4bf1fa229f22340c1a5b258f809ac4af558200775a67dacb05f0cb258a11", - "signature": ( - "b44d00516f46da3a503f9559a634869b6dc2e5d839e46ec61a090e3032172954929a5" - "d9bd7197d7739fe55db770543c71182562bd0ad20922eb4fe6b8a1062ed21df3b68de" - "44694eb4f20b35262fa9d63aa80ad3f6172dd4d33a663f21179604" - ), - "previous_signature": ( - "903c60a4b937a804001032499a855025573040cb86017c38e2b1c3725286756ce8f33" - "61188789c17336beaf3f9dbf84b0ad3c86add187987a9a0685bc5a303e37b008fba8c" - "44f02a416480dd117a3ff8b8075b1b7362c58af195573623187463" - ), -} - - -class CommonBaseCase(FSMBehaviourBaseCase): - """Base case for testing PriceEstimation FSMBehaviour.""" - - path_to_skill = PACKAGE_DIR = Path(__file__).parent.parent - - -class BaseRandomnessBehaviourTest(CommonBaseCase): - """Test RandomnessBehaviour.""" - - randomness_behaviour_class: Type[BaseBehaviour] - next_behaviour_class: Type[BaseBehaviour] - done_event: Any - - def test_randomness_behaviour( - self, - ) -> None: - """Test RandomnessBehaviour.""" - - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.act_wrapper() - self.mock_http_request( - request_kwargs=dict( - method="GET", - headers="", - version="", - body=b"", - url="https://drand.cloudflare.com/public/latest", - ), - response_kwargs=dict( - version="", - status_code=200, - status_text="", - headers="", - body=json.dumps(DRAND_VALUE).encode("utf-8"), - ), - ) - - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(self.done_event) - - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == self.next_behaviour_class.auto_behaviour_id() - - def test_invalid_drand_value( - self, - ) -> None: - """Test invalid drand values.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.act_wrapper() - - drand_value = DRAND_VALUE.copy() - drand_value["randomness"] = binascii.hexlify(b"randomness_hex").decode() - self.mock_http_request( - request_kwargs=dict( - method="GET", - headers="", - version="", - body=b"", - url="https://drand.cloudflare.com/public/latest", - ), - response_kwargs=dict( - version="", - status_code=200, - status_text="", - headers="", - body=json.dumps(drand_value).encode(), - ), - ) - - def test_invalid_response( - self, - ) -> None: - """Test invalid json response.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.act_wrapper() - - self.mock_http_request( - request_kwargs=dict( - method="GET", - headers="", - version="", - body=b"", - url="https://drand.cloudflare.com/public/latest", - ), - response_kwargs=dict( - version="", status_code=200, status_text="", headers="", body=b"" - ), - ) - self.behaviour.act_wrapper() - time.sleep(1) - self.behaviour.act_wrapper() - - def test_max_retries_reached_fallback( - self, - ) -> None: - """Test with max retries reached.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.context.randomness_api.__dict__["_frozen"] = False - with mock.patch.object( - self.behaviour.context.randomness_api, - "is_retries_exceeded", - return_value=True, - ): - self.behaviour.act_wrapper() - self.mock_ledger_api_request( - request_kwargs=dict( - performative=LedgerApiMessage.Performative.GET_STATE - ), - response_kwargs=dict( - performative=LedgerApiMessage.Performative.STATE, - state=State(ledger_id="ethereum", body={"hash": "0xa"}), - ), - ) - - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(self.done_event) - - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert ( - behaviour.behaviour_id == self.next_behaviour_class.auto_behaviour_id() - ) - self.behaviour.context.randomness_api.__dict__["_frozen"] = True - - def test_max_retries_reached_fallback_fail( - self, - ) -> None: - """Test with max retries reached.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.context.randomness_api.__dict__["_frozen"] = False - with mock.patch.object( - self.behaviour.context.randomness_api, - "is_retries_exceeded", - return_value=True, - ): - self.behaviour.act_wrapper() - self.mock_ledger_api_request( - request_kwargs=dict( - performative=LedgerApiMessage.Performative.GET_STATE - ), - response_kwargs=dict( - performative=LedgerApiMessage.Performative.ERROR, - state=State(ledger_id="ethereum", body={}), - ), - ) - - self.behaviour.act_wrapper() - self.behaviour.context.randomness_api.__dict__["_frozen"] = True - - def test_max_retries_reached_fallback_fail_case_2( - self, - ) -> None: - """Test with max retries reached.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.context.randomness_api.__dict__["_frozen"] = False - with mock.patch.object( - self.behaviour.context.randomness_api, - "is_retries_exceeded", - return_value=True, - ): - self.behaviour.act_wrapper() - self.mock_ledger_api_request( - request_kwargs=dict( - performative=LedgerApiMessage.Performative.GET_STATE - ), - response_kwargs=dict( - performative=LedgerApiMessage.Performative.STATE, - state=State(ledger_id="ethereum", body={}), - ), - ) - - self.behaviour.act_wrapper() - self.behaviour.context.randomness_api.__dict__["_frozen"] = True - - def test_clean_up( - self, - ) -> None: - """Test when `observed` value is none.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.context.randomness_api.retries_info.retries_attempted = ( # pylint: disable=protected-access - 1 - ) - assert self.behaviour.current_behaviour is not None - self.behaviour.current_behaviour.clean_up() - assert ( - self.behaviour.context.randomness_api.retries_info.retries_attempted # pylint: disable=protected-access - == 0 - ) - - -class BaseSelectKeeperBehaviourTest(CommonBaseCase): - """Test SelectKeeperBehaviour.""" - - select_keeper_behaviour_class: Type[BaseBehaviour] - next_behaviour_class: Type[BaseBehaviour] - done_event: Any - _synchronized_data: Type[BaseSynchronizedData] = BaseSynchronizedData - - @mock.patch.object(SkillContext, "agent_address", new_callable=mock.PropertyMock) - @pytest.mark.parametrize( - "blacklisted_keepers", - ( - set(), - {"a_1"}, - {"test_agent_address" + "t" * 24}, - {"a_1" + "t" * 39, "a_2" + "t" * 39, "test_agent_address" + "t" * 24}, - ), - ) - def test_select_keeper( - self, agent_address_mock: mock.Mock, blacklisted_keepers: Set[str] - ) -> None: - """Test select keeper agent.""" - agent_address_mock.return_value = "test_agent_address" + "t" * 24 - participants = ( - self.skill.skill_context.agent_address, - "a_1" + "t" * 39, - "a_2" + "t" * 39, - ) - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.select_keeper_behaviour_class.auto_behaviour_id(), - synchronized_data=self._synchronized_data( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - participants=participants, - most_voted_randomness="56cbde9e9bbcbdcaf92f183c678eaa5288581f06b1c9c7f884ce911776727688", - blacklisted_keepers="".join(blacklisted_keepers), - ) - ), - ) - ), - ) - assert self.behaviour.current_behaviour is not None - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.select_keeper_behaviour_class.auto_behaviour_id() - ) - - if ( - self.behaviour.current_behaviour.synchronized_data.participants - - self.behaviour.current_behaviour.synchronized_data.blacklisted_keepers - ): - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(self.done_event) - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.next_behaviour_class.auto_behaviour_id() - ) - else: - with pytest.raises( - AEAActException, - match="Cannot continue if all the keepers have been blacklisted!", - ): - self.behaviour.act_wrapper() - - def test_select_keeper_preexisting_keeper( - self, - ) -> None: - """Test select keeper agent.""" - participants = (self.skill.skill_context.agent_address, "a_1", "a_2") - preexisting_keeper = next(iter(participants)) - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.select_keeper_behaviour_class.auto_behaviour_id(), - synchronized_data=self._synchronized_data( - AbciAppDB( - setup_data=dict( - participants=[participants], - most_voted_randomness=[ - "56cbde9e9bbcbdcaf92f183c678eaa5288581f06b1c9c7f884ce911776727688" - ], - most_voted_keeper_address=[preexisting_keeper], - ), - ) - ), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.select_keeper_behaviour_class.auto_behaviour_id() - ) - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(self.done_event) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == self.next_behaviour_class.auto_behaviour_id() diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/integration.py b/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/integration.py deleted file mode 100644 index 913413985..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/integration.py +++ /dev/null @@ -1,301 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Integration tests for various transaction settlement skill's failure modes.""" - - -import asyncio -import os -import tempfile -import time -from abc import ABC -from pathlib import Path -from threading import Thread -from typing import Any, Callable, Dict, List, Optional, Tuple, cast - -from aea.crypto.wallet import Wallet -from aea.decision_maker.base import DecisionMaker -from aea.decision_maker.default import DecisionMakerHandler -from aea.identity.base import Identity -from aea.mail.base import Envelope -from aea.multiplexer import Multiplexer -from aea.protocols.base import Address, Message -from aea.skills.base import Handler -from web3 import HTTPProvider, Web3 -from web3.providers import BaseProvider - -from packages.valory.skills.abstract_round_abci.base import BaseSynchronizedData -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.handlers import SigningHandler -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) - - -# pylint: disable=protected-access,too-many-ancestors,unbalanced-tuple-unpacking,too-many-locals,consider-using-with,unspecified-encoding,too-many-arguments,unidiomatic-typecheck - -HandlersType = List[Optional[Handler]] -ExpectedContentType = List[ - Optional[ - Dict[ - str, - Any, - ] - ] -] -ExpectedTypesType = List[ - Optional[ - Dict[ - str, - Any, - ] - ] -] - - -class IntegrationBaseCase(FSMBehaviourBaseCase, ABC): - """Base test class for integration tests.""" - - running_loop: asyncio.AbstractEventLoop - thread_loop: Thread - multiplexer: Multiplexer - decision_maker: DecisionMaker - agents: Dict[str, Address] = { - "0xBcd4042DE499D14e55001CcbB24a551F3b954096": "0xf214f2b2cd398c806f84e317254e0f0b801d0643303237d97a22a48e01628897", - "0x71bE63f3384f5fb98995898A86B02Fb2426c5788": "0x701b615bbdfb9de65240bc28bd21bbc0d996645a3dd57e7b12bc2bdf6f192c82", - "0xFABB0ac9d68B0B445fB7357272Ff202C5651694a": "0xa267530f49f8280200edf313ee7af6b827f2a8bce2897751d06a843f644967b1", - "0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec": "0x47c99abed3324a2707c28affff1267e45918ec8c3f20b8aa892e8b065d2942dd", - } - current_agent: Address - ROOT_DIR: Path - make_ledger_api_connection_callable: Callable - - @classmethod - def _setup_class(cls, **kwargs: Any) -> None: - """Setup class.""" - - @classmethod - def setup_class(cls, **kwargs: Any) -> None: - """Setup.""" - super().setup_class() - - # set up a multiplexer with the required connections - cls.running_loop = asyncio.new_event_loop() - cls.thread_loop = Thread(target=cls.running_loop.run_forever) - cls.thread_loop.start() - cls.multiplexer = Multiplexer( - [cls.make_ledger_api_connection_callable()], loop=cls.running_loop - ) - cls.multiplexer.connect() - - # hardhat configuration - # setup decision maker - with tempfile.TemporaryDirectory() as temp_dir: - fp = os.path.join(temp_dir, "key.txt") - f = open(fp, "w") - f.write(cls.agents[next(iter(cls.agents))]) - f.close() - wallet = Wallet(private_key_paths={"ethereum": str(fp)}) - identity = Identity( - "test_agent_name", - addresses=wallet.addresses, - public_keys=wallet.public_keys, - default_address_key="ethereum", - ) - cls._skill._skill_context._agent_context._identity = identity - cls.current_agent = identity.address - - cls.decision_maker = DecisionMaker( - decision_maker_handler=DecisionMakerHandler(identity, wallet, {}) - ) - cls._skill._skill_context._agent_context._decision_maker_message_queue = ( - cls.decision_maker.message_in_queue - ) - cls._skill.skill_context._agent_context._decision_maker_address = ( - "decision_maker" - ) - - @classmethod - def teardown_class(cls) -> None: - """Tear down the multiplexer.""" - cls.multiplexer.disconnect() - cls.running_loop.call_soon_threadsafe(cls.running_loop.stop) - cls.thread_loop.join() - super().teardown_class() - - def get_message_from_decision_maker_inbox(self) -> Optional[Message]: - """Get message from decision maker inbox.""" - if self._skill.skill_context.decision_maker_message_queue.empty(): - return None - return self._skill.skill_context.decision_maker_message_queue.protected_get( - self.decision_maker._queue_access_code, block=True - ) - - def process_message_cycle( - self, - handler: Optional[Handler] = None, - expected_content: Optional[Dict] = None, - expected_types: Optional[Dict] = None, - mining_interval_secs: float = 0, - ) -> Optional[Message]: - """ - Processes one request-response type message cycle. - - Steps: - 1. Calls act on behaviour to generate outgoing message - 2. Checks for message in outbox - 3. Sends message to multiplexer and waits for response. - 4. Passes message to handler - 5. Calls act on behaviour to process incoming message - - :param handler: the handler to handle a potential incoming message - :param expected_content: the content to be expected - :param expected_types: the types to be expected - :param mining_interval_secs: the mining interval used in the tests - :return: the incoming message - """ - if expected_types and tuple(expected_types)[0] == "transaction_receipt": - time.sleep(mining_interval_secs) # pragma: no cover - self.behaviour.act_wrapper() - incoming_message = None - - if type(handler) == SigningHandler: - self.assert_quantity_in_decision_making_queue(1) - message = self.get_message_from_decision_maker_inbox() - assert message is not None, "No message in outbox." # nosec - self.decision_maker.handle(message) - if handler is not None: - incoming_message = self.decision_maker.message_out_queue.get(block=True) - assert isinstance(incoming_message, Message) # nosec - else: - self.assert_quantity_in_outbox(1) - message = self.get_message_from_outbox() - assert message is not None, "No message in outbox." # nosec - self.multiplexer.put( - Envelope( - to=message.to, - sender=message.sender, - message=message, - context=None, - ) - ) - if handler is not None: - envelope = self.multiplexer.get(block=True) - assert envelope is not None, "No envelope" # nosec - incoming_message = envelope.message - assert isinstance(incoming_message, Message) # nosec - - if handler is not None: - assert incoming_message is not None # nosec - if expected_content is not None: - assert all( # nosec - [ - incoming_message._body.get(key, None) == value - for key, value in expected_content.items() - ] - ), f"Actual content: {incoming_message._body}, expected: {expected_content}" - - if expected_types is not None: - assert all( # nosec - [ - type(incoming_message._body.get(key, None)) == value_type - for key, value_type in expected_types.items() - ] - ), "Content type mismatch" - handler.handle(incoming_message) - return incoming_message - return None - - def process_n_messages( - self, - ncycles: int, - synchronized_data: Optional[BaseSynchronizedData] = None, - behaviour_id: Optional[str] = None, - handlers: Optional[HandlersType] = None, - expected_content: Optional[ExpectedContentType] = None, - expected_types: Optional[ExpectedTypesType] = None, - fail_send_a2a: bool = False, - mining_interval_secs: float = 0, - ) -> Tuple[Optional[Message], ...]: - """ - Process n message cycles. - - :param behaviour_id: the behaviour to fast forward to - :param ncycles: the number of message cycles to process - :param synchronized_data: a synchronized_data - :param handlers: a list of handlers - :param expected_content: the expected_content - :param expected_types: the expected type - :param fail_send_a2a: flag that indicates whether we want to simulate a failure in the `send_a2a_transaction` - :param mining_interval_secs: the mining interval used in the tests. - - :return: tuple of incoming messages - """ - handlers = [None] * ncycles if handlers is None else handlers - expected_content = ( - [None] * ncycles if expected_content is None else expected_content - ) - expected_types = [None] * ncycles if expected_types is None else expected_types - assert ( # nosec - len(expected_content) == len(expected_types) - and len(expected_content) == len(handlers) - and len(expected_content) == ncycles - ), "Number of cycles, handlers, contents and types does not match" - - if behaviour_id is not None and synchronized_data is not None: - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=behaviour_id, - synchronized_data=synchronized_data, - ) - assert ( # nosec - cast(BaseBehaviour, self.behaviour.current_behaviour).behaviour_id - == behaviour_id - ) - - incoming_messages = [] - for i in range(ncycles): - incoming_message = self.process_message_cycle( - handlers[i], - expected_content[i], - expected_types[i], - mining_interval_secs, - ) - incoming_messages.append(incoming_message) - - self.behaviour.act_wrapper() - if not fail_send_a2a: - self.mock_a2a_transaction() - return tuple(incoming_messages) - - -class HardHatHelperIntegration(IntegrationBaseCase, ABC): # pragma: no cover - """Base test class for integration tests with HardHat provider.""" - - hardhat_provider: BaseProvider - - @classmethod - def setup_class(cls, **kwargs: Any) -> None: - """Setup.""" - super().setup_class() - - # create an API for HardHat - cls.hardhat_provider = Web3( - provider=HTTPProvider("http://localhost:8545") - ).provider diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/rounds.py b/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/rounds.py deleted file mode 100644 index 77f50c83d..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/test_tools/rounds.py +++ /dev/null @@ -1,599 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Test tools for testing rounds.""" - -import re -from copy import deepcopy -from dataclasses import dataclass -from enum import Enum -from typing import ( - Any, - Callable, - FrozenSet, - Generator, - List, - Mapping, - Optional, - Tuple, - Type, -) -from unittest import mock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciAppDB, - AbstractRound, - BaseSynchronizedData, - BaseTxPayload, - CollectDifferentUntilAllRound, - CollectDifferentUntilThresholdRound, - CollectNonEmptyUntilThresholdRound, - CollectSameUntilAllRound, - CollectSameUntilThresholdRound, - CollectionRound, - OnlyKeeperSendsRound, - TransactionNotValidError, - VotingRound, -) - - -MAX_PARTICIPANTS: int = 4 - - -def get_participants() -> FrozenSet[str]: - """Participants""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -class DummyEvent(Enum): - """Dummy Event""" - - DONE = "done" - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - RESET_TIMEOUT = "reset_timeout" - NEGATIVE = "negative" - NONE = "none" - FAIL = "fail" - - -@dataclass(frozen=True) -class DummyTxPayload(BaseTxPayload): - """Dummy Transaction Payload.""" - - value: Optional[str] = None - vote: Optional[bool] = None - - -class DummySynchronizedData(BaseSynchronizedData): - """Dummy synchronized data for tests.""" - - -def get_dummy_tx_payloads( - participants: FrozenSet[str], - value: Any = None, - vote: Optional[bool] = False, - is_value_none: bool = False, - is_vote_none: bool = False, -) -> List[DummyTxPayload]: - """Returns a list of DummyTxPayload objects.""" - return [ - DummyTxPayload( - sender=agent, - value=(value or agent) if not is_value_none else value, - vote=vote if not is_vote_none else None, - ) - for agent in sorted(participants) - ] - - -class DummyRound(AbstractRound): - """Dummy round.""" - - payload_class = DummyTxPayload - payload_attribute = "value" - synchronized_data_class = BaseSynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """end_block method.""" - - -class DummyCollectionRound(CollectionRound, DummyRound): - """Dummy Class for CollectionRound""" - - -class DummyCollectDifferentUntilAllRound(CollectDifferentUntilAllRound, DummyRound): - """Dummy Class for CollectDifferentUntilAllRound""" - - -class DummyCollectSameUntilAllRound(CollectSameUntilAllRound, DummyRound): - """Dummy Class for CollectSameUntilThresholdRound""" - - -class DummyCollectDifferentUntilThresholdRound( - CollectDifferentUntilThresholdRound, DummyRound -): - """Dummy Class for CollectDifferentUntilThresholdRound""" - - -class DummyCollectSameUntilThresholdRound(CollectSameUntilThresholdRound, DummyRound): - """Dummy Class for CollectSameUntilThresholdRound""" - - -class DummyOnlyKeeperSendsRound(OnlyKeeperSendsRound, DummyRound): - """Dummy Class for OnlyKeeperSendsRound""" - - fail_event = "FAIL_EVENT" - - -class DummyVotingRound(VotingRound, DummyRound): - """Dummy Class for VotingRound""" - - -class DummyCollectNonEmptyUntilThresholdRound( - CollectNonEmptyUntilThresholdRound, DummyRound -): - """Dummy Class for `CollectNonEmptyUntilThresholdRound`""" - - -class BaseRoundTestClass: # pylint: disable=too-few-public-methods - """Base test class.""" - - synchronized_data: BaseSynchronizedData - participants: FrozenSet[str] - - _synchronized_data_class: Type[BaseSynchronizedData] - _event_class: Any - - def setup( - self, - ) -> None: - """Setup test class.""" - - self.participants = get_participants() - self.synchronized_data = self._synchronized_data_class( - db=AbciAppDB( - setup_data=dict( - participants=[tuple(self.participants)], - all_participants=[tuple(self.participants)], - consensus_threshold=[3], - safe_contract_address=["test_address"], - ), - ) - ) - - def _test_no_majority_event(self, round_obj: AbstractRound) -> None: - """Test the NO_MAJORITY event.""" - with mock.patch.object(round_obj, "is_majority_possible", return_value=False): - result = round_obj.end_block() - assert result is not None - _, event = result - assert event == self._event_class.NO_MAJORITY - - @staticmethod - def _complete_run( - test_runner: Generator, iter_count: int = MAX_PARTICIPANTS - ) -> None: - """ - This method represents logic to execute test logic defined in _test_round method. - - _test_round should follow these steps - - 1. process first payload - 2. yield test_round - 3. test collection, end_block and thresholds - 4. process rest of the payloads - 5. yield test_round - 6. yield synchronized_data, event ( returned from end_block ) - 7. test synchronized_data and event - - :param test_runner: test runner - :param iter_count: iter_count - """ - - for _ in range(iter_count): - next(test_runner) - - -class BaseCollectDifferentUntilAllRoundTest( # pylint: disable=too-few-public-methods - BaseRoundTestClass -): - """Tests for rounds derived from CollectDifferentUntilAllRound.""" - - def _test_round( - self, - test_round: CollectDifferentUntilAllRound, - round_payloads: List[BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - ) -> Generator: - """Test round.""" - - first_payload = round_payloads.pop(0) - test_round.process_payload(first_payload) - - yield test_round - assert test_round.collection[first_payload.sender] == first_payload - assert not test_round.collection_threshold_reached - assert test_round.end_block() is None - - for payload in round_payloads: - test_round.process_payload(payload) - yield test_round - assert test_round.collection_threshold_reached - - actual_next_synchronized_data = synchronized_data_update_fn( - deepcopy(self.synchronized_data), test_round - ) - - res = test_round.end_block() - yield res - if exit_event is None: - assert res is exit_event - else: - assert res is not None - synchronized_data, event = res - for behaviour_attr_getter in synchronized_data_attr_checks: - assert behaviour_attr_getter( - synchronized_data - ) == behaviour_attr_getter(actual_next_synchronized_data) - assert event == exit_event - yield - - -class BaseCollectSameUntilAllRoundTest( - BaseRoundTestClass -): # pylint: disable=too-few-public-methods - """Tests for rounds derived from CollectSameUntilAllRound.""" - - def _test_round( # pylint: disable=too-many-arguments,too-many-locals - self, - test_round: CollectSameUntilAllRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - most_voted_payload: Any, - exit_event: Any, - finished: bool, - ) -> Generator: - """Test rounds derived from CollectionRound.""" - - (_, first_payload), *payloads = round_payloads.items() - - test_round.process_payload(first_payload) - yield test_round - assert test_round.collection[first_payload.sender] == first_payload - assert not test_round.collection_threshold_reached - assert test_round.end_block() is None - - with pytest.raises( - ABCIAppInternalError, - match="internal error: 1 votes are not enough for `CollectSameUntilAllRound`. " - f"Expected: `n_votes = max_participants = {MAX_PARTICIPANTS}`", - ): - _ = test_round.common_payload - - for _, payload in payloads: - test_round.process_payload(payload) - yield test_round - if finished: - assert test_round.collection_threshold_reached - assert test_round.common_payload == most_voted_payload - - actual_next_synchronized_data = synchronized_data_update_fn( - deepcopy(self.synchronized_data), test_round - ) - res = test_round.end_block() - yield res - assert res is not None - - synchronized_data, event = res - - for behaviour_attr_getter in synchronized_data_attr_checks: - assert behaviour_attr_getter(synchronized_data) == behaviour_attr_getter( - actual_next_synchronized_data - ), f"Mismatch in synchronized_data. Actual:\n{behaviour_attr_getter(synchronized_data)}\nExpected:\n{behaviour_attr_getter(actual_next_synchronized_data)}" - assert event == exit_event - yield - - -class BaseCollectSameUntilThresholdRoundTest( # pylint: disable=too-few-public-methods - BaseRoundTestClass -): - """Tests for rounds derived from CollectSameUntilThresholdRound.""" - - def _test_round( # pylint: disable=too-many-arguments,too-many-locals - self, - test_round: CollectSameUntilThresholdRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - most_voted_payload: Any, - exit_event: Any, - ) -> Generator: - """Test rounds derived from CollectionRound.""" - - (_, first_payload), *payloads = round_payloads.items() - - test_round.process_payload(first_payload) - yield test_round - assert test_round.collection[first_payload.sender] == first_payload - assert not test_round.threshold_reached - assert test_round.end_block() is None - - self._test_no_majority_event(test_round) - with pytest.raises(ABCIAppInternalError, match="not enough votes"): - _ = test_round.most_voted_payload - - for _, payload in payloads: - test_round.process_payload(payload) - yield test_round - assert test_round.threshold_reached - assert test_round.most_voted_payload == most_voted_payload - - actual_next_synchronized_data = synchronized_data_update_fn( - deepcopy(self.synchronized_data), test_round - ) - res = test_round.end_block() - yield res - assert res is not None - - synchronized_data, event = res - - for behaviour_attr_getter in synchronized_data_attr_checks: - assert behaviour_attr_getter(synchronized_data) == behaviour_attr_getter( - actual_next_synchronized_data - ), f"Mismatch in synchronized_data. Actual:\n{behaviour_attr_getter(synchronized_data)}\nExpected:\n{behaviour_attr_getter(actual_next_synchronized_data)}" - assert event == exit_event - yield - - -class BaseOnlyKeeperSendsRoundTest( # pylint: disable=too-few-public-methods - BaseRoundTestClass -): - """Tests for rounds derived from OnlyKeeperSendsRound.""" - - def _test_round( - self, - test_round: OnlyKeeperSendsRound, - keeper_payloads: BaseTxPayload, - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - ) -> Generator: - """Test for rounds derived from OnlyKeeperSendsRound.""" - - assert test_round.end_block() is None - assert test_round.keeper_payload is None - - test_round.process_payload(keeper_payloads) - yield test_round - assert test_round.keeper_payload is not None - - yield test_round - actual_next_synchronized_data = synchronized_data_update_fn( - deepcopy(self.synchronized_data), test_round - ) - res = test_round.end_block() - yield res - assert res is not None - - synchronized_data, event = res - - for behaviour_attr_getter in synchronized_data_attr_checks: - assert behaviour_attr_getter(synchronized_data) == behaviour_attr_getter( - actual_next_synchronized_data - ), f"Mismatch in synchronized_data. Actual:\n{behaviour_attr_getter(synchronized_data)}\nExpected:\n{behaviour_attr_getter(actual_next_synchronized_data)}" - assert event == exit_event - yield - - -class BaseVotingRoundTest(BaseRoundTestClass): # pylint: disable=too-few-public-methods - """Tests for rounds derived from VotingRound.""" - - def _test_round( # pylint: disable=too-many-arguments,too-many-locals - self, - test_round: VotingRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - threshold_check: Callable, - ) -> Generator: - """Test for rounds derived from VotingRound.""" - - (_, first_payload), *payloads = round_payloads.items() - - test_round.process_payload(first_payload) - yield test_round - assert not threshold_check(test_round) # negative_vote_threshold_reached - assert test_round.end_block() is None - self._test_no_majority_event(test_round) - - for _, payload in payloads: - test_round.process_payload(payload) - yield test_round - assert threshold_check(test_round) - - actual_next_synchronized_data = synchronized_data_update_fn( - deepcopy(self.synchronized_data), test_round - ) - res = test_round.end_block() - yield res - assert res is not None - - synchronized_data, event = res - - for behaviour_attr_getter in synchronized_data_attr_checks: - assert behaviour_attr_getter(synchronized_data) == behaviour_attr_getter( - actual_next_synchronized_data - ), f"Mismatch in synchronized_data. Actual:\n{behaviour_attr_getter(synchronized_data)}\nExpected:\n{behaviour_attr_getter(actual_next_synchronized_data)}" - assert event == exit_event - yield - - def _test_voting_round_positive( - self, - test_round: VotingRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - ) -> Generator: - """Test for rounds derived from VotingRound.""" - - return self._test_round( - test_round, - round_payloads, - synchronized_data_update_fn, - synchronized_data_attr_checks, - exit_event, - threshold_check=lambda x: x.positive_vote_threshold_reached, - ) - - def _test_voting_round_negative( - self, - test_round: VotingRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - ) -> Generator: - """Test for rounds derived from VotingRound.""" - - return self._test_round( - test_round, - round_payloads, - synchronized_data_update_fn, - synchronized_data_attr_checks, - exit_event, - threshold_check=lambda x: x.negative_vote_threshold_reached, - ) - - def _test_voting_round_none( - self, - test_round: VotingRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - ) -> Generator: - """Test for rounds derived from VotingRound.""" - - return self._test_round( - test_round, - round_payloads, - synchronized_data_update_fn, - synchronized_data_attr_checks, - exit_event, - threshold_check=lambda x: x.none_vote_threshold_reached, - ) - - -class BaseCollectDifferentUntilThresholdRoundTest( # pylint: disable=too-few-public-methods - BaseRoundTestClass -): - """Tests for rounds derived from CollectDifferentUntilThresholdRound.""" - - def _test_round( - self, - test_round: CollectDifferentUntilThresholdRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - ) -> Generator: - """Test for rounds derived from CollectDifferentUntilThresholdRound.""" - - (_, first_payload), *payloads = round_payloads.items() - - test_round.process_payload(first_payload) - yield test_round - assert not test_round.collection_threshold_reached - assert test_round.end_block() is None - - for _, payload in payloads: - test_round.process_payload(payload) - yield test_round - assert test_round.collection_threshold_reached - - actual_next_synchronized_data = synchronized_data_update_fn( - deepcopy(self.synchronized_data), test_round - ) - - res = test_round.end_block() - yield res - assert res is not None - - synchronized_data, event = res - - for behaviour_attr_getter in synchronized_data_attr_checks: - assert behaviour_attr_getter(synchronized_data) == behaviour_attr_getter( - actual_next_synchronized_data - ), f"Mismatch in synchronized_data. Actual:\n{behaviour_attr_getter(synchronized_data)}\nExpected:\n{behaviour_attr_getter(actual_next_synchronized_data)}" - assert event == exit_event - yield - - -class BaseCollectNonEmptyUntilThresholdRound( # pylint: disable=too-few-public-methods - BaseCollectDifferentUntilThresholdRoundTest -): - """Tests for rounds derived from `CollectNonEmptyUntilThresholdRound`.""" - - -class _BaseRoundTestClass(BaseRoundTestClass): # pylint: disable=too-few-public-methods - """Base test class.""" - - synchronized_data: BaseSynchronizedData - participants: FrozenSet[str] - tx_payloads: List[DummyTxPayload] - - _synchronized_data_class = DummySynchronizedData - - def setup( - self, - ) -> None: - """Setup test class.""" - - super().setup() - self.tx_payloads = get_dummy_tx_payloads(self.participants) - - @staticmethod - def _test_payload_with_wrong_round_count( - test_round: AbstractRound, - value: Optional[str] = None, - vote: Optional[bool] = None, - ) -> None: - """Test errors raised by payloads with wrong round count.""" - payload_with_wrong_round_count = DummyTxPayload("sender", value, vote) - object.__setattr__(payload_with_wrong_round_count, "round_count", 0) - with pytest.raises( - TransactionNotValidError, - match=re.escape("Expected round count -1 and got 0."), - ): - test_round.check_payload(payload=payload_with_wrong_round_count) - - with pytest.raises( - ABCIAppInternalError, - match=re.escape("Expected round count -1 and got 0."), - ): - test_round.process_payload(payload=payload_with_wrong_round_count) diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/__init__.py deleted file mode 100644 index 7561108a8..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/abstract_round_abci skill.""" - -from hypothesis import settings # pragma: nocover - - -CI = "CI" # pragma: nocover - -settings.register_profile(CI, deadline=5000) # pragma: nocover diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/conftest.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/conftest.py deleted file mode 100644 index 5dde4f1b0..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/conftest.py +++ /dev/null @@ -1,116 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Conftest module for io tests.""" - -import os -import shutil -from contextlib import suppress -from pathlib import Path -from typing import Dict, Generator - -import pytest -from hypothesis import settings - -from packages.valory.skills.abstract_round_abci.io_.store import StoredJSONType -from packages.valory.skills.abstract_round_abci.models import MIN_RESET_PAUSE_DURATION - - -# pylint: skip-file - - -CI = "CI" -PACKAGE_DIR = Path(__file__).parent.parent -settings.register_profile(CI, deadline=5000) -profile_name = ("default", "CI")[bool(os.getenv("CI"))] - - -@pytest.fixture -def dummy_obj() -> StoredJSONType: - """A dummy custom object to test the storing with.""" - return {"test_col": ["test_val_1", "test_val_2"]} - - -@pytest.fixture -def dummy_multiple_obj(dummy_obj: StoredJSONType) -> Dict[str, StoredJSONType]: - """Many dummy custom objects to test the storing with.""" - return {f"test_obj_{i}": dummy_obj for i in range(10)} - - -@pytest.fixture(scope="session", autouse=True) -def hypothesis_cleanup() -> Generator: - """Fixture to remove hypothesis directory after tests.""" - yield - hypothesis_dir = PACKAGE_DIR / ".hypothesis" - if hypothesis_dir.exists(): - with suppress(OSError, PermissionError): # pragma: nocover - shutil.rmtree(hypothesis_dir) - - -# We do not care about these keys but need to set them in the behaviours' tests, -# because `packages.valory.skills.abstract_round_abci.models._ensure` is used. -irrelevant_genesis_config = { - "consensus_params": { - "block": {"max_bytes": "str", "max_gas": "str", "time_iota_ms": "str"}, - "evidence": { - "max_age_num_blocks": "str", - "max_age_duration": "str", - "max_bytes": "str", - }, - "validator": {"pub_key_types": ["str"]}, - "version": {}, - }, - "genesis_time": "str", - "chain_id": "str", - "voting_power": "str", -} -irrelevant_config = { - "tendermint_url": "str", - "max_healthcheck": 0, - "round_timeout_seconds": 0.0, - "sleep_time": 0, - "retry_timeout": 0, - "retry_attempts": 0, - "keeper_timeout": 0.0, - "reset_pause_duration": MIN_RESET_PAUSE_DURATION, - "drand_public_key": "str", - "tendermint_com_url": "str", - "tendermint_max_retries": 0, - "reset_tendermint_after": 0, - "cleanup_history_depth": 0, - "voting_power": 0, - "tendermint_check_sleep_delay": 0, - "cleanup_history_depth_current": None, - "request_timeout": 0.0, - "request_retry_delay": 0.0, - "tx_timeout": 0.0, - "max_attempts": 0, - "service_registry_address": None, - "on_chain_service_id": None, - "share_tm_config_on_startup": False, - "tendermint_p2p_url": "str", - "setup": {}, - "genesis_config": irrelevant_genesis_config, - "use_termination": False, - "use_slashing": False, - "slash_cooldown_hours": 3, - "slash_threshold_amount": 10_000_000_000_000_000, - "light_slash_unit_amount": 5_000_000_000_000_000, - "serious_slash_unit_amount": 8_000_000_000_000_000, -} diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/__init__.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/__init__.py deleted file mode 100644 index 7266f7868..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for abstract_round_abci/test_tools""" diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/__init__.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/__init__.py deleted file mode 100644 index c378e8c43..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/__init__.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 the implementation of the default skill.""" - -from pathlib import Path - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("dummy/dummy_abci:0.1.0") -PATH_TO_SKILL = Path(__file__).parent diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/behaviours.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/behaviours.py deleted file mode 100644 index ee99805c6..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/behaviours.py +++ /dev/null @@ -1,158 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 package contains round behaviours of DummyAbciApp.""" - -from abc import ABC -from collections import deque -from typing import Deque, Generator, Set, Type, cast - -from packages.valory.skills.abstract_round_abci.base import AbstractRound -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.abstract_round_abci.common import ( - RandomnessBehaviour, - SelectKeeperBehaviour, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.models import ( - Params, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.payloads import ( - DummyFinalPayload, - DummyKeeperSelectionPayload, - DummyRandomnessPayload, - DummyStartingPayload, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.rounds import ( - DummyAbciApp, - DummyFinalRound, - DummyKeeperSelectionRound, - DummyRandomnessRound, - DummyStartingRound, - SynchronizedData, -) - - -class DummyBaseBehaviour(BaseBehaviour, ABC): - """Base behaviour for the common apps' skill.""" - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return cast(SynchronizedData, super().synchronized_data) - - @property - def params(self) -> Params: - """Return the params.""" - return cast(Params, super().params) - - -class DummyStartingBehaviour(DummyBaseBehaviour): - """DummyStartingBehaviour""" - - behaviour_id: str = "dummy_starting" - matching_round: Type[AbstractRound] = DummyStartingRound - - def async_act(self) -> Generator: - """Do the act, supporting asynchronous execution.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - content = "dummy" - sender = self.context.agent_address - payload = DummyStartingPayload(sender=sender, content=content) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class DummyRandomnessBehaviour(RandomnessBehaviour): - """DummyRandomnessBehaviour""" - - behaviour_id: str = "dummy_randomness" - matching_round: Type[AbstractRound] = DummyRandomnessRound - payload_class = DummyRandomnessPayload - - -class DummyKeeperSelectionBehaviour(SelectKeeperBehaviour): - """DummyKeeperSelectionBehaviour""" - - behaviour_id: str = "dummy_keeper_selection" - matching_round: Type[AbstractRound] = DummyKeeperSelectionRound - payload_class = DummyKeeperSelectionPayload - - @staticmethod - def serialized_keepers(keepers: Deque[str], keeper_retries: int = 1) -> str: - """Get the keepers serialized.""" - if not keepers: - return "" - return keeper_retries.to_bytes(32, "big").hex() + "".join(keepers) - - def async_act(self) -> Generator: - """Do the act, supporting asynchronous execution.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - keepers = deque((self._select_keeper(),)) - payload = self.payload_class( - self.context.agent_address, self.serialized_keepers(keepers) - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class DummyFinalBehaviour(DummyBaseBehaviour): - """DummyFinalBehaviour""" - - behaviour_id: str = "dummy_final" - matching_round: Type[AbstractRound] = DummyFinalRound - - def async_act(self) -> Generator: - """Do the act, supporting asynchronous execution.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - content = True - sender = self.context.agent_address - payload = DummyFinalPayload(sender=sender, content=content) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class DummyRoundBehaviour(AbstractRoundBehaviour): - """DummyRoundBehaviour""" - - initial_behaviour_cls = DummyStartingBehaviour - abci_app_cls = DummyAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - DummyFinalBehaviour, # type: ignore - DummyKeeperSelectionBehaviour, # type: ignore - DummyRandomnessBehaviour, # type: ignore - DummyStartingBehaviour, # type: ignore - } diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/dialogues.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/dialogues.py deleted file mode 100644 index 24aa94dd7..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/dialogues.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 the dialogues of the DummyAbciApp.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/handlers.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/handlers.py deleted file mode 100644 index fc0edb2df..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/handlers.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 the handlers for the skill of DummyAbciApp.""" - -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIRoundHandler = BaseABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/models.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/models.py deleted file mode 100644 index 5fba375a7..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/models.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 the shared state for the abci skill of DummyAbciApp.""" - -from packages.valory.skills.abstract_round_abci.models import ApiSpecs, BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.rounds import ( - DummyAbciApp, -) - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = DummyAbciApp - - -Params = BaseParams -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool -RandomnessApi = ApiSpecs diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/payloads.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/payloads.py deleted file mode 100644 index bc4308ba6..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/payloads.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 the transaction payloads of the DummyAbciApp.""" - -from dataclasses import dataclass - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class DummyStartingPayload(BaseTxPayload): - """Represent a transaction payload for the DummyStartingRound.""" - - content: str - - -@dataclass(frozen=True) -class DummyRandomnessPayload(BaseTxPayload): - """Represent a transaction payload for the DummyRandomnessRound.""" - - round_id: int - randomness: str - - -@dataclass(frozen=True) -class DummyKeeperSelectionPayload(BaseTxPayload): - """Represent a transaction payload for the DummyKeeperSelectionRound.""" - - keepers: str - - -@dataclass(frozen=True) -class DummyFinalPayload(BaseTxPayload): - """Represent a transaction payload for the DummyFinalRound.""" - - content: bool diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/rounds.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/rounds.py deleted file mode 100644 index b3ee3bc17..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/rounds.py +++ /dev/null @@ -1,152 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 package contains the rounds of DummyAbciApp.""" - -from abc import ABC -from enum import Enum -from typing import FrozenSet, Optional, Set, Tuple, cast - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AbstractRound, - AppState, - BaseSynchronizedData, - CollectSameUntilAllRound, - CollectSameUntilThresholdRound, - EventToTimeout, - OnlyKeeperSendsRound, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.payloads import ( - DummyFinalPayload, - DummyKeeperSelectionPayload, - DummyRandomnessPayload, - DummyStartingPayload, -) - - -class Event(Enum): - """DummyAbciApp Events""" - - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - DONE = "done" - - -class SynchronizedData(BaseSynchronizedData): - """ - Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - -class DummyMixinRound(AbstractRound, ABC): - """DummyMixinRound""" - - done_event = Event.DONE - no_majority_event = Event.NO_MAJORITY - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return cast(SynchronizedData, self._synchronized_data) - - -class DummyStartingRound(CollectSameUntilAllRound, DummyMixinRound): - """DummyStartingRound""" - - round_id: str = "dummy_starting" - payload_class = DummyStartingPayload - payload_attribute: str = "dummy_starting" - synchronized_data_class = SynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - - if self.collection_threshold_reached: - synchronized_data = self.synchronized_data.update( - participants=tuple(sorted(self.collection)), - synchronized_data_class=SynchronizedData, - ) - return synchronized_data, Event.DONE - return None - - -class DummyRandomnessRound(CollectSameUntilThresholdRound, DummyMixinRound): - """DummyRandomnessRound""" - - round_id: str = "dummy_randomness" - payload_class = DummyRandomnessPayload - payload_attribute: str = "dummy_randomness" - collection_key = "participant_to_randomness" - selection_key = "most_voted_randomness" - synchronized_data_class = SynchronizedData - - -class DummyKeeperSelectionRound(CollectSameUntilThresholdRound, DummyMixinRound): - """DummyKeeperSelectionRound""" - - round_id: str = "dummy_keeper_selection" - payload_class = DummyKeeperSelectionPayload - payload_attribute: str = "dummy_keeper_selection" - collection_key = "participant_to_keeper" - selection_key = "most_voted_keeper" - synchronized_data_class = SynchronizedData - - -class DummyFinalRound(OnlyKeeperSendsRound, DummyMixinRound): - """DummyFinalRound""" - - round_id: str = "dummy_final" - payload_class = DummyFinalPayload - payload_attribute: str = "dummy_final" - synchronized_data_class = SynchronizedData - - -class DummyAbciApp(AbciApp[Event]): - """DummyAbciApp""" - - initial_round_cls: AppState = DummyStartingRound - transition_function: AbciAppTransitionFunction = { - DummyStartingRound: { - Event.DONE: DummyRandomnessRound, - Event.ROUND_TIMEOUT: DummyStartingRound, - Event.NO_MAJORITY: DummyStartingRound, - }, - DummyRandomnessRound: { - Event.DONE: DummyKeeperSelectionRound, - Event.ROUND_TIMEOUT: DummyRandomnessRound, - Event.NO_MAJORITY: DummyRandomnessRound, - }, - DummyKeeperSelectionRound: { - Event.DONE: DummyFinalRound, - Event.ROUND_TIMEOUT: DummyKeeperSelectionRound, - Event.NO_MAJORITY: DummyKeeperSelectionRound, - }, - DummyFinalRound: { - Event.DONE: DummyStartingRound, - Event.ROUND_TIMEOUT: DummyFinalRound, - Event.NO_MAJORITY: DummyFinalRound, - }, - } - final_states: Set[AppState] = set() - event_to_timeout: EventToTimeout = {} - cross_period_persisted_keys: FrozenSet[str] = frozenset() diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/skill.yaml b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/skill.yaml deleted file mode 100644 index 4ac35e9e0..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/skill.yaml +++ /dev/null @@ -1,148 +0,0 @@ -name: dummy_abci -author: dummy -version: 0.1.0 -type: skill -description: The scaffold skill is a scaffold for your own skill implementation. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeielxta5wbywv6cb2p65phk73zeodroif7imk33qc7sxgxrcelr62y - behaviours.py: bafybeicwwlex4z5ro6hrw5cdwxyp5742klcqsjwcn423wgg3jk6xclzwvi - dialogues.py: bafybeiaswubmqa7trhajbjn34okmpftk2sehsqrjg7znzrrd7j32xzx4vq - handlers.py: bafybeifik3ftljs63u7nm4gadxpqbcvqj53p7qftzzzfto3ioad57k3x3u - models.py: bafybeif4lp5i6an4z4kkquh3x3ttsvfctvsu5excmxahjywbbbo7g3js5y - payloads.py: bafybeidllmzsctg3m5jhawbt3kzk6ieodtvgwklrquqehtqtzzwhkxxg4a - rounds.py: bafybeiab5q6pzh544uuc672hksh4rv6a74dunt4ztdnqo4gw3hnzd452ti - tests/__init__.py: bafybeiaxqzwmh36bhquqztcyrkxjjkz5cctseqetglrwdezgnkjrtg2654 - tests/test_behaviours.py: bafybeich3uo67gdbxrxsivlrxfgpfuixupl6qtotxxp2qqpyqnck4i67eu - tests/test_dialogues.py: bafybeice2v4xnsjhhlnpbejnvpory5spmrewwcfsefzqzq3uhfyya5hypm - tests/test_handlers.py: bafybeidrfumnc743qh5s2ahf5rxu3rzrroygxwpbqa7jtqxg5kirjzedjm - tests/test_models.py: bafybeifuxjmpv3eet2zn7vc5btprakueqlk2ybc2fxgzbtiho5wdslkeb4 - tests/test_payloads.py: bafybeicvbisfw5prv6jw3is3vw6gehsplt3teyeo6dbeh37xazh4izeyhq - tests/test_rounds.py: bafybeihjepr2hubbgmb7jkeldbam3zmsgwn6nffif7zp4etqlv2bt5rsxy -fingerprint_ignore_patterns: [] -connections: [] -contracts: [] -protocols: [] -skills: -- valory/abstract_round_abci:0.1.0:bafybeifjnk2v3cw233ke5qhakurvdsex64c5runjctclrh7y64tyh7uqrq -behaviours: - main: - args: {} - class_name: DummyRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIRoundHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_duration: '172800000000000' - max_age_num_blocks: '100000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - genesis_time: '2022-05-20T16:00:21.735122717Z' - voting_power: '10' - keeper_timeout: 30.0 - max_healthcheck: 120 - reset_pause_duration: 10 - on_chain_service_id: null - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 30.0 - service_id: dummy - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - sleep_time: 1 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_url: http://localhost:26657 - request_timeout: 10.0 - request_retry_delay: 1.0 - tx_timeout: 10.0 - max_attempts: 10 - share_tm_config_on_startup: false - tendermint_p2p_url: localhost:26656 - use_termination: false - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10_000_000_000_000_000 - light_slash_unit_amount: 5_000_000_000_000_000 - serious_slash_unit_amount: 8_000_000_000_000_000 - class_name: Params - randomness_api: - args: - api_id: cloudflare - headers: {} - method: GET - parameters: {} - response_key: null - response_type: dict - retries: 5 - url: https://drand.cloudflare.com/public/latest - class_name: RandomnessApi - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: {} -is_abstract: false diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_abci_app_chain.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_abci_app_chain.py deleted file mode 100644 index 4a95580cf..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_abci_app_chain.py +++ /dev/null @@ -1,508 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the abci_app_chain.py module of the skill.""" - -# pylint: skip-file - -import logging -from typing import Dict, Set, Tuple, Type -from unittest.mock import MagicMock - -import pytest -from _pytest.logging import LogCaptureFixture -from aea.exceptions import AEAEnforceError - -from packages.valory.skills.abstract_round_abci.abci_app_chain import ( - AbciAppTransitionMapping, - chain, -) -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppDB, - AbstractRound, - AppState, - BaseSynchronizedData, - BaseTxPayload, - DegenerateRound, -) - - -def make_round_class(name: str, bases: Tuple = (AbstractRound,)) -> Type[AbstractRound]: - """Make a round class.""" - new_round_cls = type( - name, - bases, - { - "synchronized_data_class": MagicMock(), - "payload_class": MagicMock(), - "payload_attribute": MagicMock(), - }, - ) - setattr(new_round_cls, "round_id", name) # noqa: B010 - assert issubclass(new_round_cls, AbstractRound) # nosec - return new_round_cls - - -class TestAbciAppChaining: - """Test chaning of AbciApps.""" - - def setup(self) -> None: - """Setup test.""" - self.round_1a = make_round_class("round_1a") - self.round_1b = make_round_class("round_1b") - self.round_1b_dupe = make_round_class("round_1b") # duplicated round id - self.round_1c = make_round_class("round_1c", (DegenerateRound,)) - - self.round_2a = make_round_class("round_2a") - self.round_2b = make_round_class("round_2b") - self.round_2c = make_round_class("round_2c", (DegenerateRound,)) - self.round_2d = make_round_class("round_2d") - - self.round_3a = make_round_class("round_3a") - self.round_3b = make_round_class("round_3b") - self.round_3c = make_round_class("round_3c", (DegenerateRound,)) - - self.key_1 = "1" - self.key_2 = "2" - self.key_3 = "3" - - self.event_1a = "event_1a" - self.event_1b = "event_1b" - self.event_1c = "event_1c" - self.event_timeout1 = "timeout_1" - - self.event_2a = "event_2a" - self.event_2b = "event_2b" - self.event_2c = "event_2c" - self.event_timeout2 = "timeout_2" - - self.event_3a = "event_3a" - self.event_3b = "event_3b" - self.event_3c = "event_3c" - self.event_timeout3 = "timeout_3" - - self.timeout1 = 10.0 - self.timeout2 = 15.0 - self.timeout3 = 20.0 - - self.cross_period_persisted_keys_1 = frozenset({"1", "2"}) - self.cross_period_persisted_keys_2 = frozenset({"2", "3"}) - - class AbciApp1(AbciApp): - initial_round_cls = self.round_1a - transition_function = { - self.round_1a: { - self.event_timeout1: self.round_1a, - self.event_1b: self.round_1b, - }, - self.round_1b: { - self.event_1a: self.round_1a, - self.event_1c: self.round_1c, - }, - self.round_1c: {}, - } - final_states = {self.round_1c} - event_to_timeout = {self.event_timeout1: self.timeout1} - db_pre_conditions: Dict[AppState, Set[str]] = {self.round_1a: set()} - db_post_conditions: Dict[AppState, Set[str]] = {self.round_1c: {self.key_1}} - cross_period_persisted_keys = self.cross_period_persisted_keys_1 - - self.app1_class = AbciApp1 - - class AbciApp2(AbciApp): - initial_round_cls = self.round_2a - transition_function = { - self.round_2a: { - self.event_timeout2: self.round_2a, - self.event_2b: self.round_2b, - }, - self.round_2b: { - self.event_2a: self.round_2a, - self.event_2c: self.round_2c, - }, - self.round_2c: {}, - } - final_states = {self.round_2c} - event_to_timeout = {self.event_timeout2: self.timeout2} - db_pre_conditions: Dict[AppState, Set[str]] = {self.round_2a: {self.key_1}} - db_post_conditions: Dict[AppState, Set[str]] = {self.round_2c: {self.key_2}} - cross_period_persisted_keys = self.cross_period_persisted_keys_2 - - self.app2_class = AbciApp2 - - class AbciApp3(AbciApp): - initial_round_cls = self.round_3a - transition_function = { - self.round_3a: { - self.event_timeout3: self.round_3a, - self.event_3b: self.round_3b, - }, - self.round_3b: { - self.event_3a: self.round_3a, - self.event_3c: self.round_3c, - self.event_1a: self.round_3a, # duplicated event - }, - self.round_3c: {}, - } - final_states = {self.round_3c} - event_to_timeout = {self.event_timeout3: self.timeout3} - db_pre_conditions: Dict[AppState, Set[str]] = { - self.round_3a: {self.key_1, self.key_2} - } - db_post_conditions: Dict[AppState, Set[str]] = {self.round_3c: {self.key_3}} - - self.app3_class = AbciApp3 - - class AbciApp3Dupe(AbciApp): - initial_round_cls = self.round_3a - transition_function = { - self.round_3a: { - self.event_timeout3: self.round_3a, - self.event_3b: self.round_3b, - }, - self.round_1b_dupe: { # duplucated round id - self.event_3a: self.round_3a, - self.event_3c: self.round_3c, - self.event_1a: self.round_3a, # duplicated event - }, - self.round_3c: {}, - } - final_states = {self.round_3c} - event_to_timeout = {self.event_timeout3: self.timeout3} - db_post_conditions: Dict[AppState, Set[str]] = {self.round_3c: set()} - - self.app3_class_dupe = AbciApp3Dupe - - class AbciApp2Faulty1(AbciApp): - initial_round_cls = self.round_2a - transition_function = { - self.round_2a: { - self.event_timeout2: self.round_2a, - self.event_2b: self.round_2b, - }, - self.round_2b: { - self.event_2a: self.round_2a, - self.event_2c: self.round_2c, - }, - self.round_2c: {}, - } - final_states = {self.round_2c} - event_to_timeout = {self.event_timeout1: self.timeout2} - db_pre_conditions: Dict[AppState, Set[str]] = {self.round_2a: {self.key_1}} - db_post_conditions: Dict[AppState, Set[str]] = {self.round_2c: {self.key_2}} - - self.app2_class_faulty1 = AbciApp2Faulty1 - - def test_chain_two(self) -> None: - """Test the AbciApp chain function.""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_1a, - } - - ComposedAbciApp = chain( - (self.app1_class, self.app2_class), abci_app_transition_mapping - ) - - assert ComposedAbciApp.initial_round_cls == self.round_1a - assert ComposedAbciApp.transition_function == { - self.round_1a: { - self.event_timeout1: self.round_1a, - self.event_1b: self.round_1b, - }, - self.round_1b: { - self.event_1a: self.round_1a, - self.event_1c: self.round_2a, - }, - self.round_2a: { - self.event_timeout2: self.round_2a, - self.event_2b: self.round_2b, - }, - self.round_2b: { - self.event_2a: self.round_2a, - self.event_2c: self.round_1a, - }, - } - assert ComposedAbciApp.final_states == set() - assert ComposedAbciApp.event_to_timeout == { - self.event_timeout1: self.timeout1, - self.event_timeout2: self.timeout2, - } - assert ( - ComposedAbciApp.cross_period_persisted_keys - == self.cross_period_persisted_keys_1.union( - self.cross_period_persisted_keys_2 - ) - ) - - def test_chain_three(self) -> None: - """Test the AbciApp chain function.""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_3a, - } - - ComposedAbciApp = chain( - (self.app1_class, self.app2_class, self.app3_class), - abci_app_transition_mapping, - ) - - assert ComposedAbciApp.initial_round_cls == self.round_1a - assert ComposedAbciApp.transition_function == { - self.round_1a: { - self.event_timeout1: self.round_1a, - self.event_1b: self.round_1b, - }, - self.round_1b: { - self.event_1a: self.round_1a, - self.event_1c: self.round_2a, - }, - self.round_2a: { - self.event_timeout2: self.round_2a, - self.event_2b: self.round_2b, - }, - self.round_2b: { - self.event_2a: self.round_2a, - self.event_2c: self.round_3a, - }, - self.round_3a: { - self.event_timeout3: self.round_3a, - self.event_3b: self.round_3b, - }, - self.round_3b: { - self.event_3a: self.round_3a, - self.event_3c: self.round_3c, - self.event_1a: self.round_3a, - }, - self.round_3c: {}, - } - assert ComposedAbciApp.final_states == {self.round_3c} - assert ComposedAbciApp.event_to_timeout == { - self.event_timeout1: self.timeout1, - self.event_timeout2: self.timeout2, - self.event_timeout3: self.timeout3, - } - - def test_chain_two_negative_timeouts(self) -> None: - """Test the AbciApp chain function.""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_1a, - } - - with pytest.raises( - ValueError, match="but it is already defined in a prior app with timeout" - ): - _ = chain( - (self.app1_class, self.app2_class_faulty1), abci_app_transition_mapping - ) - - def test_chain_two_negative_mapping_initial_states(self) -> None: - """Test the AbciApp chain function.""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2b, - self.round_2c: self.round_1a, - } - - with pytest.raises(ValueError, match="Found non-initial state"): - _ = chain((self.app1_class, self.app2_class), abci_app_transition_mapping) - - def test_chain_two_negative_mapping_final_states(self) -> None: - """Test the AbciApp chain function.""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2b: self.round_1a, - } - - with pytest.raises(ValueError, match="Found non-final state"): - _ = chain((self.app1_class, self.app2_class), abci_app_transition_mapping) - - def test_chain_two_dupe(self) -> None: - """Test the AbciApp chain function.""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_1a, - } - with pytest.raises( - AEAEnforceError, - match=r"round ids in common between abci apps are not allowed.*", - ): - chain((self.app1_class, self.app3_class_dupe), abci_app_transition_mapping) - - def test_chain_with_abstract_abci_app_fails(self) -> None: - """Test chaining with an abstract AbciApp fails.""" - self.app2_class._is_abstract = False - self.app3_class._is_abstract = False - with pytest.raises( - AEAEnforceError, - match=r"found non-abstract AbciApp during chaining: \['AbciApp2', 'AbciApp3'\]", - ): - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_3a, - } - chain( - (self.app1_class, self.app2_class, self.app3_class), - abci_app_transition_mapping, - ) - - def test_synchronized_data_type(self, caplog: LogCaptureFixture) -> None: - """Test synchronized data type""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_1a, - } - - sentinel_app1 = object() - sentinel_app2 = object() - - def make_sync_data(sentinel: object) -> Type: - class SynchronizedData(BaseSynchronizedData): - @property - def dummy_attr(self) -> object: - return sentinel - - return SynchronizedData - - def make_concrete(round_cls: Type[AbstractRound]) -> Type[AbstractRound]: - class ConcreteRound(round_cls): # type: ignore - def check_payload(self, payload: BaseTxPayload) -> None: - pass - - def process_payload(self, payload: BaseTxPayload) -> None: - pass - - def end_block(self) -> None: - pass - - payload_class = None - - return ConcreteRound - - sync_data_cls_app1 = make_sync_data(sentinel_app1) - sync_data_cls_app2 = make_sync_data(sentinel_app2) - - # don't need to mock all of this since setup creates these classes - for abci_app_cls, sync_data_cls in ( - (self.app1_class, sync_data_cls_app1), - (self.app2_class, sync_data_cls_app2), - ): - synchronized_data = sync_data_cls(db=AbciAppDB(setup_data={})) - abci_app = abci_app_cls(synchronized_data, logging.getLogger(), MagicMock()) - for r in abci_app_cls.get_all_rounds(): - r.synchronized_data_class = sync_data_cls - - abci_app_cls = chain( - (self.app1_class, self.app2_class), abci_app_transition_mapping - ) - synchronized_data = sync_data_cls_app2(db=AbciAppDB(setup_data={})) - abci_app = abci_app_cls(synchronized_data, logging.getLogger(), MagicMock()) - - assert abci_app.initial_round_cls == self.round_1a - assert isinstance(abci_app.synchronized_data, sync_data_cls_app1) - assert abci_app.synchronized_data.dummy_attr == sentinel_app1 - - app2_classes = self.app2_class.get_all_rounds() - for round_ in sorted(abci_app.get_all_rounds(), key=str): - abci_app._round_results.append(abci_app.synchronized_data) - abci_app.schedule_round(make_concrete(round_)) - expected_cls = (sync_data_cls_app1, sync_data_cls_app2)[ - round_ in app2_classes - ] - assert isinstance(abci_app.synchronized_data, expected_cls) - expected_sentinel = (sentinel_app1, sentinel_app2)[round_ in app2_classes] - assert abci_app.synchronized_data.dummy_attr == expected_sentinel - - def test_precondition_for_next_app_missing_raises( - self, caplog: LogCaptureFixture - ) -> None: - """Test that when precondition for next AbciApp is missing an error is raised""" - - class AbciApp1(AbciApp): - initial_round_cls = self.round_1a - transition_function = { - self.round_1a: { - self.event_timeout1: self.round_1a, - self.event_1b: self.round_1b, - }, - self.round_1b: { - self.event_1a: self.round_1a, - self.event_1c: self.round_1c, - }, - self.round_1c: {}, - } - final_states = {self.round_1c} - event_to_timeout = {self.event_timeout1: self.timeout1} - db_pre_conditions: Dict[AppState, Set[str]] = {self.round_1a: set()} - db_post_conditions: Dict[AppState, Set[str]] = {self.round_1c: set()} - cross_period_persisted_keys = self.cross_period_persisted_keys_1 - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_1a, - } - - expected = "Pre conditions '.*' of app '.*' not a post condition of app '.*' or any preceding app in path .*." - with pytest.raises(ValueError, match=expected): - chain( - ( - AbciApp1, - self.app2_class, - ), - abci_app_transition_mapping, - ) - - def test_precondition_app_missing_raises(self, caplog: LogCaptureFixture) -> None: - """Test that missing precondition specification for next AbciApp is missing an error is raised""" - - class AbciApp2(AbciApp): - initial_round_cls = self.round_2a - transition_function = { - self.round_2a: { - self.event_timeout2: self.round_2a, - self.event_2b: self.round_2b, - }, - self.round_2b: { - self.event_2a: self.round_2a, - self.event_2c: self.round_2c, - }, - self.round_2c: {}, - } - final_states = {self.round_2c} - event_to_timeout = {self.event_timeout2: self.timeout2} - db_pre_conditions: Dict[AppState, Set[str]] = {} - db_post_conditions: Dict[AppState, Set[str]] = {self.round_2c: {self.key_2}} - cross_period_persisted_keys = self.cross_period_persisted_keys_2 - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_1a, - } - - expected = "No pre-conditions have been set for .*! You need to explicitly specify them as empty if there are no pre-conditions for this FSM." - with pytest.raises(ValueError, match=expected): - chain((self.app1_class, AbciApp2), abci_app_transition_mapping) diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_base.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_base.py deleted file mode 100644 index c5ff0f49e..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_base.py +++ /dev/null @@ -1,3420 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the base.py module of the skill.""" - -import dataclasses -import datetime -import json -import logging -import re -import shutil -from abc import ABC -from calendar import timegm -from collections import deque -from contextlib import suppress -from copy import copy, deepcopy -from dataclasses import dataclass -from enum import Enum -from pathlib import Path -from time import sleep -from typing import ( - Any, - Callable, - Deque, - Dict, - FrozenSet, - Generator, - List, - Optional, - Set, - Tuple, - Type, - cast, -) -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from _pytest.logging import LogCaptureFixture -from aea.exceptions import AEAEnforceError -from aea_ledger_ethereum import EthereumCrypto -from hypothesis import HealthCheck, given, settings -from hypothesis.strategies import ( - DrawFn, - binary, - booleans, - builds, - composite, - data, - datetimes, - dictionaries, - floats, - integers, - just, - lists, - none, - one_of, - sampled_from, - text, -) - -import packages.valory.skills.abstract_round_abci.base as abci_base -from packages.valory.connections.abci.connection import MAX_READ_IN_BYTES -from packages.valory.protocols.abci.custom_types import ( - Evidence, - EvidenceType, - Evidences, - LastCommitInfo, - Timestamp, - Validator, - VoteInfo, -) -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppException, - ABCIAppInternalError, - AbciApp, - AbciAppDB, - AbciAppTransitionFunction, - AbstractRound, - AbstractRoundInternalError, - AddBlockError, - AppState, - AvailabilityWindow, - BaseSynchronizedData, - BaseTxPayload, - Block, - BlockBuilder, - Blockchain, - CollectionRound, - EventType, - LateArrivingTransaction, - OffenceStatus, - OffenseStatusDecoder, - OffenseStatusEncoder, - OffenseType, - RoundSequence, - SignatureNotValidError, - SlashingNotConfiguredError, - Timeouts, - Transaction, - TransactionTypeNotRecognizedError, - _MetaAbciApp, - _MetaAbstractRound, - _MetaPayload, - get_name, - light_offences, - serious_offences, -) -from packages.valory.skills.abstract_round_abci.test_tools.abci_app import ( - AbciAppTest, - ConcreteBackgroundRound, - ConcreteBackgroundSlashingRound, - ConcreteEvents, - ConcreteRoundA, - ConcreteRoundB, - ConcreteRoundC, - ConcreteSlashingRoundA, - ConcreteTerminationRoundA, - ConcreteTerminationRoundB, - ConcreteTerminationRoundC, - SlashingAppTest, - TerminationAppTest, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseRoundTestClass, - get_participants, -) -from packages.valory.skills.abstract_round_abci.tests.conftest import profile_name - - -# pylint: skip-file - - -settings.load_profile(profile_name) - - -PACKAGE_DIR = Path(__file__).parent.parent - - -DUMMY_CONCRETE_BACKGROUND_PAYLOAD = ConcreteBackgroundRound.payload_class( - sender="sender" -) - - -@pytest.fixture(scope="session", autouse=True) -def hypothesis_cleanup() -> Generator: - """Fixture to remove hypothesis directory after tests.""" - yield - hypothesis_dir = PACKAGE_DIR / ".hypothesis" - if hypothesis_dir.exists(): - with suppress(OSError, PermissionError): - shutil.rmtree(hypothesis_dir) - - -class BasePayload(BaseTxPayload, ABC): - """Base payload class for testing.""" - - -@dataclass(frozen=True) -class PayloadA(BasePayload): - """Payload class for payload type 'A'.""" - - -@dataclass(frozen=True) -class PayloadB(BasePayload): - """Payload class for payload type 'B'.""" - - -@dataclass(frozen=True) -class PayloadC(BasePayload): - """Payload class for payload type 'C'.""" - - -@dataclass(frozen=True) -class PayloadD(BasePayload): - """Payload class for payload type 'D'.""" - - -@dataclass(frozen=True) -class DummyPayload(BasePayload): - """Dummy payload class.""" - - dummy_attribute: int - - -@dataclass(frozen=True) -class TooBigPayload(BaseTxPayload): - """Base payload class for testing.""" - - dummy_field: str = "0" * 10**7 - - -class ObjectImitator: - """For custom __eq__ implementation testing""" - - def __init__(self, other: Any): - """Copying references to class attr, and instance attr""" - - for attr, value in vars(other.__class__).items(): - if not attr.startswith("__") and not attr.endswith("__"): - setattr(self.__class__, attr, value) - - self.__dict__ = other.__dict__ - - -def test_base_tx_payload() -> None: - """Test BaseTxPayload.""" - - payload = PayloadA(sender="sender") - object.__setattr__(payload, "round_count", 9) - new_payload = payload.with_new_id() - - assert not payload == new_payload - payload_data, new_payload_data = payload.json, new_payload.json - assert not payload_data.pop("id_") == new_payload_data.pop("id_") - assert payload_data == new_payload_data - with pytest.raises(dataclasses.FrozenInstanceError): - payload.round_count = 1 # type: ignore - object.__setattr__(payload, "round_count", 1) - assert payload.round_count == 1 - assert type(hash(payload)) == int - - -def test_meta_round_abstract_round_when_instance_not_subclass_of_abstract_round() -> ( - None -): - """Test instantiation of meta class when instance not a subclass of abstract round.""" - - class MyAbstractRound(metaclass=_MetaAbstractRound): - pass - - -def test_abstract_round_instantiation_without_attributes_raises_error() -> None: - """Test that definition of concrete subclass of AbstractRound without attributes raises error.""" - with pytest.raises(AbstractRoundInternalError): - - class MyRoundBehaviour(AbstractRound): - pass - - with pytest.raises(AbstractRoundInternalError): - - class MyRoundBehaviourB(AbstractRound): - synchronized_data_class = MagicMock() - - -class TestTransactions: - """Test Transactions class.""" - - def setup(self) -> None: - """Set up the test.""" - self.old_value = copy(_MetaPayload.registry) - - def test_encode_decode(self) -> None: - """Test encoding and decoding of payloads.""" - sender = "sender" - - expected_payload = PayloadA(sender=sender) - actual_payload = PayloadA.decode(expected_payload.encode()) - assert expected_payload == actual_payload - - expected_payload_ = PayloadB(sender=sender) - actual_payload_ = PayloadB.decode(expected_payload_.encode()) - assert expected_payload_ == actual_payload_ - - expected_payload__ = PayloadC(sender=sender) - actual_payload__ = PayloadC.decode(expected_payload__.encode()) - assert expected_payload__ == actual_payload__ - - expected_payload___ = PayloadD(sender=sender) - actual_payload___ = PayloadD.decode(expected_payload___.encode()) - assert expected_payload___ == actual_payload___ - - def test_encode_decode_transaction(self) -> None: - """Test encode/decode of a transaction.""" - sender = "sender" - signature = "signature" - payload = PayloadA(sender) - expected = Transaction(payload, signature) - actual = expected.decode(expected.encode()) - assert expected == actual - - def test_encode_too_big_payload(self) -> None: - """Test encode of a too big payload.""" - sender = "sender" - payload = TooBigPayload(sender) - with pytest.raises( - ValueError, - match=f"{type(payload)} must be smaller than {MAX_READ_IN_BYTES} bytes", - ): - payload.encode() - - def test_encode_too_big_transaction(self) -> None: - """Test encode of a too big transaction.""" - sender = "sender" - signature = "signature" - payload = TooBigPayload(sender) - tx = Transaction(payload, signature) - with pytest.raises( - ValueError, - match=f"Transaction must be smaller than {MAX_READ_IN_BYTES} bytes", - ): - tx.encode() - - def test_sign_verify_transaction(self) -> None: - """Test sign/verify transaction.""" - crypto = EthereumCrypto() - sender = crypto.address - payload = PayloadA(sender) - payload_bytes = payload.encode() - signature = crypto.sign_message(payload_bytes) - transaction = Transaction(payload, signature) - transaction.verify(crypto.identifier) - - def test_payload_not_equal_lookalike(self) -> None: - """Test payload __eq__ reflection via NotImplemented""" - payload = PayloadA(sender="sender") - lookalike = ObjectImitator(payload) - assert not payload == lookalike - - def test_transaction_not_equal_lookalike(self) -> None: - """Test transaction __eq__ reflection via NotImplemented""" - payload = PayloadA(sender="sender") - transaction = Transaction(payload, signature="signature") - lookalike = ObjectImitator(transaction) - assert not transaction == lookalike - - def teardown(self) -> None: - """Tear down the test.""" - _MetaPayload.registry = self.old_value - - -@mock.patch( - "aea.crypto.ledger_apis.LedgerApis.recover_message", return_value={"wrong_sender"} -) -def test_verify_transaction_negative_case(*_mocks: Any) -> None: - """Test verify() of transaction, negative case.""" - transaction = Transaction(MagicMock(sender="right_sender", json={}), "") - with pytest.raises( - SignatureNotValidError, match="Signature not valid on transaction: .*" - ): - transaction.verify("") - - -@dataclass(frozen=True) -class SomeClass(BaseTxPayload): - """Test class.""" - - content: Dict - - -@given( - dictionaries( - keys=text(), - values=one_of(floats(allow_nan=False, allow_infinity=False), booleans()), - ) -) -def test_payload_serializer_is_deterministic(obj: Any) -> None: - """Test that 'DictProtobufStructSerializer' is deterministic.""" - obj_ = SomeClass(sender="", content=obj) - obj_bytes = obj_.encode() - assert obj_ == BaseTxPayload.decode(obj_bytes) - - -def test_initialize_block() -> None: - """Test instantiation of a Block instance.""" - block = Block(MagicMock(), []) - assert block.transactions == tuple() - - -class TestBlockchain: - """Test a blockchain object.""" - - def setup(self) -> None: - """Set up the test.""" - self.blockchain = Blockchain() - - def test_height(self) -> None: - """Test the 'height' property getter.""" - assert self.blockchain.height == 0 - - def test_len(self) -> None: - """Test the 'length' property getter.""" - assert self.blockchain.length == 0 - - def test_add_block_positive(self) -> None: - """Test 'add_block', success.""" - block = Block(MagicMock(height=1), []) - self.blockchain.add_block(block) - assert self.blockchain.length == 1 - assert self.blockchain.height == 1 - - def test_add_block_negative_wrong_height(self) -> None: - """Test 'add_block', wrong height.""" - wrong_height = 42 - block = Block(MagicMock(height=wrong_height), []) - with pytest.raises( - AddBlockError, - match=f"expected height {self.blockchain.height + 1}, got {wrong_height}", - ): - self.blockchain.add_block(block) - - def test_add_block_before_initial_height(self) -> None: - """Test 'add_block', too old height.""" - height_offset = 42 - blockchain = Blockchain(height_offset=height_offset) - block = Block(MagicMock(height=height_offset - 1), []) - blockchain.add_block(block) - - def test_blocks(self) -> None: - """Test 'blocks' property getter.""" - assert self.blockchain.blocks == tuple() - - -class TestBlockBuilder: - """Test block builder.""" - - def setup(self) -> None: - """Set up the method.""" - self.block_builder = BlockBuilder() - - def test_get_header_positive(self) -> None: - """Test header property getter, positive.""" - expected_header = MagicMock() - self.block_builder._current_header = expected_header - actual_header = self.block_builder.header - assert expected_header == actual_header - - def test_get_header_negative(self) -> None: - """Test header property getter, negative.""" - with pytest.raises(ValueError, match="header not set"): - self.block_builder.header - - def test_set_header_positive(self) -> None: - """Test header property setter, positive.""" - expected_header = MagicMock() - self.block_builder.header = expected_header - actual_header = self.block_builder.header - assert expected_header == actual_header - - def test_set_header_negative(self) -> None: - """Test header property getter, negative.""" - self.block_builder.header = MagicMock() - with pytest.raises(ValueError, match="header already set"): - self.block_builder.header = MagicMock() - - def test_transitions_getter(self) -> None: - """Test 'transitions' property getter.""" - assert self.block_builder.transactions == tuple() - - def test_add_transitions(self) -> None: - """Test 'add_transition'.""" - transaction = MagicMock() - self.block_builder.add_transaction(transaction) - assert self.block_builder.transactions == (transaction,) - - def test_get_block_negative_header_not_set_yet(self) -> None: - """Test 'get_block', negative case (header not set yet).""" - with pytest.raises(ValueError, match="header not set"): - self.block_builder.get_block() - - def test_get_block_positive(self) -> None: - """Test 'get_block', positive case.""" - self.block_builder.header = MagicMock() - self.block_builder.get_block() - - -class TestAbciAppDB: - """Test 'AbciAppDB' class.""" - - def setup(self) -> None: - """Set up the tests.""" - self.participants = ("a", "b") - self.db = AbciAppDB( - setup_data=dict(participants=[self.participants]), - ) - - @pytest.mark.parametrize( - "data, setup_data", - ( - ({"participants": ["a", "b"]}, {"participants": ["a", "b"]}), - ({"participants": []}, {}), - ({"participants": None}, None), - ("participants", None), - (1, None), - (object(), None), - (["participants"], None), - ({"participants": [], "other": [1, 2]}, {"other": [1, 2]}), - ), - ) - @pytest.mark.parametrize( - "cross_period_persisted_keys, expected_cross_period_persisted_keys", - ((None, set()), (set(), set()), ({"test"}, {"test"})), - ) - def test_init( - self, - data: Dict, - setup_data: Optional[Dict], - cross_period_persisted_keys: Optional[Set[str]], - expected_cross_period_persisted_keys: Set[str], - ) -> None: - """Test constructor.""" - # keys are a set, but we cast them to a frozenset, so we can still update them and also make `mypy` - # think that the type is correct, to simulate a user incorrectly passing a different type and check if the - # attribute can be altered - cast_keys = cast(Optional[FrozenSet[str]], cross_period_persisted_keys) - # update with the default keys - expected_cross_period_persisted_keys.update(AbciAppDB.default_cross_period_keys) - - if setup_data is None: - # the parametrization of `setup_data` set to `None` is in order to check if the exception is raised - # when we incorrectly set the data in the configuration file with a type that is not allowed - with pytest.raises( - ValueError, - match=re.escape( - f"AbciAppDB data must be `Dict[str, List[Any]]`, found `{type(data)}` instead" - ), - ): - AbciAppDB( - data, - ) - return - - # use copies because otherwise the arguments will be modified and the next test runs will be polluted - data_copy = deepcopy(data) - cross_period_persisted_keys_copy = cast_keys.copy() if cast_keys else cast_keys - db = AbciAppDB(data_copy, cross_period_persisted_keys_copy) - assert db._data == {0: setup_data} - assert db.setup_data == setup_data - assert db.cross_period_persisted_keys == expected_cross_period_persisted_keys - - def data_assertion() -> None: - """Assert that the data are fine.""" - assert db._data == {0: setup_data} and db.setup_data == setup_data, ( - "The database's `setup_data` have been altered indirectly, " - "by updating an item passed via the `__init__`!" - ) - - new_value_attempt = "new_value_attempt" - data_copy.update({"dummy_key": [new_value_attempt]}) - data_assertion() - - data_copy["participants"].append(new_value_attempt) - data_assertion() - - if cross_period_persisted_keys_copy: - # cast back to set - cast(Set[str], cross_period_persisted_keys_copy).add(new_value_attempt) - assert ( - db.cross_period_persisted_keys == expected_cross_period_persisted_keys - ), ( - "The database's `cross_period_persisted_keys` have been altered indirectly, " - "by updating an item passed via the `__init__`!" - ) - - class EnumTest(Enum): - """A test Enum class""" - - test = 10 - - @pytest.mark.parametrize( - "data_in, expected_output", - ( - (0, 0), - ([], []), - ({"test": 2}, {"test": 2}), - (EnumTest.test, 10), - (b"test", b"test".hex()), - ({3, 4}, "[3, 4]"), - (object(), None), - ), - ) - def test_normalize(self, data_in: Any, expected_output: Any) -> None: - """Test `normalize`.""" - if expected_output is None: - with pytest.raises(ValueError): - self.db.normalize(data_in) - return - assert self.db.normalize(data_in) == expected_output - - @pytest.mark.parametrize("data", {0: [{"test": 2}]}) - def test_reset_index(self, data: Dict) -> None: - """Test `reset_index`.""" - assert self.db.reset_index == 0 - self.db.sync(self.db.serialize()) - assert self.db.reset_index == 0 - - def test_round_count_setter(self) -> None: - """Tests the round count setter.""" - expected_value = 1 - - # assume the round count is 0 in the begging - self.db._round_count = 0 - - # update to one via the setter - self.db.round_count = expected_value - - assert self.db.round_count == expected_value - - def test_try_alter_init_data(self) -> None: - """Test trying to alter the init data.""" - data_key = "test" - data_value = [data_key] - expected_data = {data_key: data_value} - passed_data = {data_key: data_value.copy()} - db = AbciAppDB(passed_data) - assert db.setup_data == expected_data - - mutability_error_message = ( - "The database's `setup_data` have been altered indirectly, " - "by updating an item retrieved via the `setup_data` property!" - ) - - db.setup_data.update({data_key: ["altered"]}) - assert db.setup_data == expected_data, mutability_error_message - - db.setup_data[data_key].append("altered") - assert db.setup_data == expected_data, mutability_error_message - - def test_cross_period_persisted_keys(self) -> None: - """Test `cross_period_persisted_keys` property""" - setup_data: Dict[str, List] = {} - cross_period_persisted_keys = frozenset({"test"}) - db = AbciAppDB(setup_data, cross_period_persisted_keys.copy()) - - assert isinstance(db.cross_period_persisted_keys, frozenset), ( - "The database's `cross_period_persisted_keys` can be altered indirectly. " - "The `cross_period_persisted_keys` was expected to be a `frozenset`!" - ) - - def test_get(self) -> None: - """Test getters.""" - assert self.db.get("participants", default="default") == self.participants - assert self.db.get("inexistent", default="default") == "default" - assert self.db.get_latest_from_reset_index(0) == { - "participants": self.participants - } - assert self.db.get_latest() == {"participants": self.participants} - - mutable_key = "mutable" - mutable_value = ["test"] - self.db.update(**{mutable_key: mutable_value.copy()}) - mutable_getters = set() - for getter, kwargs in ( - ("get", {"key": mutable_key}), - ("get_strict", {"key": mutable_key}), - ("get_latest_from_reset_index", {"reset_index": 0}), - ("get_latest", {}), - ): - retrieved = getattr(self.db, getter)(**kwargs) - if getter.startswith("get_latest"): - retrieved = retrieved[mutable_key] - retrieved.append("new_value_attempt") - - if self.db.get(mutable_key) != mutable_value: - mutable_getters.add(getter) - - assert not mutable_getters, ( - "The database has been altered indirectly, " - f"by updating the item(s) retrieved via the `{mutable_getters}` method(s)!" - ) - - def test_increment_round_count(self) -> None: - """Test increment_round_count.""" - assert self.db.round_count == -1 - self.db.increment_round_count() - assert self.db.round_count == 0 - - @mock.patch.object( - abci_base, - "is_json_serializable", - return_value=False, - ) - def test_validate(self, _: mock._patch) -> None: - """Test `validate` method.""" - data = "does not matter" - - with pytest.raises( - ABCIAppInternalError, - match=re.escape( - "internal error: `AbciAppDB` data must be json-serializable. Please convert non-serializable data in " - f"`{data}`. You may use `AbciAppDB.validate(your_data)` to validate your data for the `AbciAppDB`." - ), - ): - AbciAppDB.validate(data) - - @pytest.mark.parametrize( - "setup_data, update_data, expected_data", - ( - (dict(), {"dummy_key": "dummy_value"}, {0: {"dummy_key": ["dummy_value"]}}), - ( - dict(), - {"dummy_key": ["dummy_value1", "dummy_value2"]}, - {0: {"dummy_key": [["dummy_value1", "dummy_value2"]]}}, - ), - ( - {"test": ["test"]}, - {"dummy_key": "dummy_value"}, - {0: {"dummy_key": ["dummy_value"], "test": ["test"]}}, - ), - ( - {"test": ["test"]}, - {"test": "dummy_value"}, - {0: {"test": ["test", "dummy_value"]}}, - ), - ( - {"test": [["test"]]}, - {"test": ["dummy_value1", "dummy_value2"]}, - {0: {"test": [["test"], ["dummy_value1", "dummy_value2"]]}}, - ), - ( - {"test": ["test"]}, - {"test": ["dummy_value1", "dummy_value2"]}, - {0: {"test": ["test", ["dummy_value1", "dummy_value2"]]}}, - ), - ), - ) - def test_update( - self, setup_data: Dict, update_data: Dict, expected_data: Dict[int, Dict] - ) -> None: - """Test update db.""" - db = AbciAppDB(setup_data) - db.update(**update_data) - assert db._data == expected_data - - mutable_key = "mutable" - mutable_value = ["test"] - update_data = {mutable_key: mutable_value.copy()} - db.update(**update_data) - - update_data[mutable_key].append("new_value_attempt") - assert ( - db.get(mutable_key) == mutable_value - ), "The database has been altered indirectly, by updating the item passed via the `update` method!" - - @pytest.mark.parametrize( - "replacement_value, expected_replacement", - ( - (132, 132), - ("test", "test"), - (set("132"), ("1", "2", "3")), - ({"132"}, ("132",)), - (frozenset("231"), ("1", "2", "3")), - (frozenset({"231"}), ("231",)), - (("1", "3", "2"), ("1", "3", "2")), - (["1", "5", "3"], ["1", "5", "3"]), - ), - ) - @pytest.mark.parametrize( - "setup_data, cross_period_persisted_keys", - ( - (dict(), frozenset()), - ({"test": [["test"]]}, frozenset()), - ({"test": [["test"]]}, frozenset({"test"})), - ({"test": ["test"]}, frozenset({"test"})), - ), - ) - def test_create( - self, - replacement_value: Any, - expected_replacement: Any, - setup_data: Dict, - cross_period_persisted_keys: FrozenSet[str], - ) -> None: - """Test `create` db.""" - db = AbciAppDB(setup_data) - db._cross_period_persisted_keys = cross_period_persisted_keys - db.create() - assert db._data == { - 0: setup_data, - 1: setup_data if cross_period_persisted_keys else {}, - }, "`create` did not produce the expected result!" - - mutable_key = "mutable" - mutable_value = ["test"] - existing_key = "test" - create_data = { - mutable_key: mutable_value.copy(), - existing_key: replacement_value, - } - db.create(**create_data) - - assert db._data == { - 0: setup_data, - 1: setup_data if cross_period_persisted_keys else {}, - 2: db.data_to_lists( - { - mutable_key: mutable_value.copy(), - existing_key: expected_replacement, - } - ), - }, "`create` did not produce the expected result!" - - create_data[mutable_key].append("new_value_attempt") - assert ( - db.get(mutable_key) == mutable_value - ), "The database has been altered indirectly, by updating the item passed via the `create` method!" - - def test_create_key_not_in_db(self) -> None: - """Test the `create` method when a given or a cross-period key does not exist in the db.""" - existing_key = "existing_key" - non_existing_key = "non_existing_key" - - db = AbciAppDB({existing_key: ["test_value"]}) - db._cross_period_persisted_keys = frozenset({non_existing_key}) - with pytest.raises( - ABCIAppInternalError, - match=f"Cross period persisted key `{non_existing_key}` " - "was not found in the db but was required for the next period.", - ): - db.create() - - db._cross_period_persisted_keys = frozenset({existing_key}) - db.create(**{non_existing_key: "test_value"}) - - @pytest.mark.parametrize( - "existing_data, cleanup_history_depth, cleanup_history_depth_current, expected", - ( - ( - {1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}}, - 0, - None, - {1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}}, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": [0]}, - }, - 0, - None, - {2: {"test": [0]}}, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": [0, 1, 2]}, - }, - 0, - 0, - {2: {"test": [0, 1, 2]}}, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": [0, 1, 2]}, - }, - 0, - 1, - {2: {"test": [2]}}, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": list(range(5))}, - 3: {"test": list(range(5, 10))}, - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15, 20))}, - }, - 3, - 0, - { - 3: {"test": list(range(5, 10))}, - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15, 20))}, - }, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": list(range(5))}, - 3: {"test": list(range(5, 10))}, - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15, 20))}, - }, - 5, - 3, - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": list(range(5))}, - 3: {"test": list(range(5, 10))}, - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15 + 2, 20))}, - }, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": list(range(5))}, - 3: {"test": list(range(5, 10))}, - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15, 20))}, - }, - 2, - 3, - { - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15 + 2, 20))}, - }, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": list(range(5))}, - 3: {"test": list(range(5, 10))}, - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15, 20))}, - }, - 0, - 1, - { - 5: {"test": [19]}, - }, - ), - ), - ) - def test_cleanup( - self, - existing_data: Dict[int, Dict[str, List[Any]]], - cleanup_history_depth: int, - cleanup_history_depth_current: Optional[int], - expected: Dict[int, Dict[str, List[Any]]], - ) -> None: - """Test cleanup db.""" - db = AbciAppDB({}) - db._cross_period_persisted_keys = frozenset() - for _, _data in existing_data.items(): - db._create_from_keys(**_data) - - db.cleanup(cleanup_history_depth, cleanup_history_depth_current) - assert db._data == expected - - def test_serialize(self) -> None: - """Test `serialize` method.""" - assert ( - self.db.serialize() - == '{"db_data": {"0": {"participants": [["a", "b"]]}}, "slashing_config": ""}' - ) - - @pytest.mark.parametrize( - "_data", - ({"db_data": {0: {"test": [0]}}, "slashing_config": "serialized_config"},), - ) - def test_sync(self, _data: Dict[str, Dict[int, Dict[str, List[Any]]]]) -> None: - """Test `sync` method.""" - try: - serialized_data = json.dumps(_data) - except TypeError as exc: - raise AssertionError( - "Incorrectly parametrized test. Data must be json serializable." - ) from exc - - self.db.sync(serialized_data) - assert self.db._data == _data["db_data"] - assert self.db.slashing_config == _data["slashing_config"] - - @pytest.mark.parametrize( - "serialized_data, match", - ( - (b"", "Could not decode data using "), - ( - json.dumps({"both_mandatory_keys_missing": {}}), - "internal error: Mandatory keys `db_data`, `slashing_config` are missing from the deserialized data: " - "{'both_mandatory_keys_missing': {}}\nThe following serialized data were given: " - '{"both_mandatory_keys_missing": {}}', - ), - ( - json.dumps({"db_data": {}}), - "internal error: Mandatory keys `db_data`, `slashing_config` are missing from the deserialized data: " - "{'db_data': {}}\nThe following serialized data were given: {\"db_data\": {}}", - ), - ( - json.dumps({"slashing_config": {}}), - "internal error: Mandatory keys `db_data`, `slashing_config` are missing from the deserialized data: " - "{'slashing_config': {}}\nThe following serialized data were given: {\"slashing_config\": {}}", - ), - ( - json.dumps( - {"db_data": {"invalid_index": {}}, "slashing_config": "anything"} - ), - "An invalid index was found while trying to sync the db using data: ", - ), - ( - json.dumps({"db_data": "invalid", "slashing_config": "anything"}), - "Could not decode db data with an invalid format: ", - ), - ), - ) - def test_sync_incorrect_data(self, serialized_data: Any, match: str) -> None: - """Test `sync` method with incorrect data.""" - with pytest.raises( - ABCIAppInternalError, - match=match, - ): - self.db.sync(serialized_data) - - def test_hash(self) -> None: - """Test `hash` method.""" - expected_hash = ( - b"\xd0^\xb0\x85\xf1\xf5\xd2\xe8\xe8\x85\xda\x1a\x99k" - b"\x1c\xde\xfa1\x8a\x87\xcc\xd7q?\xdf\xbbofz\xfb\x7fI" - ) - assert self.db.hash() == expected_hash - - -class TestBaseSynchronizedData: - """Test 'BaseSynchronizedData' class.""" - - def setup(self) -> None: - """Set up the tests.""" - self.participants = ("a", "b") - self.base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB(setup_data=dict(participants=[self.participants])) - ) - - @given(text()) - def test_slashing_config(self, slashing_config: str) -> None: - """Test the `slashing_config` property.""" - self.base_synchronized_data.slashing_config = slashing_config - assert ( - self.base_synchronized_data.slashing_config - == self.base_synchronized_data.db.slashing_config - == slashing_config - ) - - def test_participants_getter_positive(self) -> None: - """Test 'participants' property getter.""" - assert frozenset(self.participants) == self.base_synchronized_data.participants - - def test_nb_participants_getter(self) -> None: - """Test 'participants' property getter.""" - assert len(self.participants) == self.base_synchronized_data.nb_participants - - def test_participants_getter_negative(self) -> None: - """Test 'participants' property getter, negative case.""" - base_synchronized_data = BaseSynchronizedData(db=AbciAppDB(setup_data={})) - # with pytest.raises(ValueError, match="Value of key=participants is None"): - with pytest.raises( - ValueError, - match=re.escape( - "'participants' field is not set for this period [0] and no default value was provided." - ), - ): - base_synchronized_data.participants - - def test_update(self) -> None: - """Test the 'update' method.""" - participants = ("a",) - expected = BaseSynchronizedData( - db=AbciAppDB(setup_data=dict(participants=[participants])) - ) - actual = self.base_synchronized_data.update(participants=participants) - assert expected.participants == actual.participants - assert actual.db._data == {0: {"participants": [("a", "b"), ("a",)]}} - - def test_create(self) -> None: - """Test the 'create' method.""" - self.base_synchronized_data.db._cross_period_persisted_keys = frozenset( - {"participants"} - ) - assert self.base_synchronized_data.db._data == { - 0: {"participants": [("a", "b")]} - } - actual = self.base_synchronized_data.create() - assert actual.db._data == { - 0: {"participants": [("a", "b")]}, - 1: {"participants": [("a", "b")]}, - } - - def test_repr(self) -> None: - """Test the '__repr__' magic method.""" - actual_repr = repr(self.base_synchronized_data) - expected_repr_regex = r"BaseSynchronizedData\(db=AbciAppDB\({(.*)}\)\)" - assert re.match(expected_repr_regex, actual_repr) is not None - - def test_participants_list_is_empty( - self, - ) -> None: - """Tets when participants list is set to zero.""" - base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB(setup_data=dict(participants=[tuple()])) - ) - with pytest.raises(ValueError, match="List participants cannot be empty."): - _ = base_synchronized_data.participants - - def test_all_participants_list_is_empty( - self, - ) -> None: - """Tets when participants list is set to zero.""" - base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB(setup_data=dict(all_participants=[tuple()])) - ) - with pytest.raises(ValueError, match="List participants cannot be empty."): - _ = base_synchronized_data.all_participants - - @pytest.mark.parametrize( - "n_participants, given_threshold, expected_threshold", - ( - (1, None, 1), - (5, None, 4), - (10, None, 7), - (345, None, 231), - (246236, None, 164158), - (1, 1, 1), - (5, 5, 5), - (10, 7, 7), - (10, 8, 8), - (10, 9, 9), - (10, 10, 10), - (345, 300, 300), - (246236, 194158, 194158), - ), - ) - def test_consensus_threshold( - self, n_participants: int, given_threshold: int, expected_threshold: int - ) -> None: - """Test the `consensus_threshold` property.""" - base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB( - setup_data=dict( - all_participants=[tuple(range(n_participants))], - consensus_threshold=[given_threshold], - ) - ) - ) - - assert base_synchronized_data.consensus_threshold == expected_threshold - - @pytest.mark.parametrize( - "n_participants, given_threshold", - ( - (1, 2), - (5, 2), - (10, 4), - (10, 11), - (10, 18), - (345, 200), - (246236, 164157), - (246236, 246237), - ), - ) - def test_consensus_threshold_incorrect( - self, - n_participants: int, - given_threshold: int, - ) -> None: - """Test the `consensus_threshold` property when an incorrect threshold value has been inserted to the db.""" - base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB( - setup_data=dict( - all_participants=[tuple(range(n_participants))], - consensus_threshold=[given_threshold], - ) - ) - ) - - with pytest.raises(ValueError, match="Consensus threshold "): - _ = base_synchronized_data.consensus_threshold - - def test_properties(self) -> None: - """Test several properties""" - participants = ["b", "a"] - randomness_str = ( - "3439d92d58e47d342131d446a3abe264396dd264717897af30525c98408c834f" - ) - randomness_value = 0.20400769574270503 - most_voted_keeper_address = "most_voted_keeper_address" - blacklisted_keepers = "blacklisted_keepers" - participant_to_selection = participant_to_randomness = participant_to_votes = { - "sender": DummyPayload(sender="sender", dummy_attribute=0) - } - safe_contract_address = "0x0" - - base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - participants=participants, - all_participants=participants, - most_voted_randomness=randomness_str, - most_voted_keeper_address=most_voted_keeper_address, - blacklisted_keepers=blacklisted_keepers, - participant_to_selection=CollectionRound.serialize_collection( - participant_to_selection - ), - participant_to_randomness=CollectionRound.serialize_collection( - participant_to_randomness - ), - participant_to_votes=CollectionRound.serialize_collection( - participant_to_votes - ), - safe_contract_address=safe_contract_address, - ) - ) - ) - ) - assert self.base_synchronized_data.period_count == 0 - assert base_synchronized_data.all_participants == frozenset(participants) - assert base_synchronized_data.sorted_participants == ["a", "b"] - assert base_synchronized_data.max_participants == len(participants) - assert abs(base_synchronized_data.keeper_randomness - randomness_value) < 1e-10 - assert base_synchronized_data.most_voted_randomness == randomness_str - assert ( - base_synchronized_data.most_voted_keeper_address - == most_voted_keeper_address - ) - assert base_synchronized_data.is_keeper_set - assert base_synchronized_data.blacklisted_keepers == {blacklisted_keepers} - assert ( - base_synchronized_data.participant_to_selection == participant_to_selection - ) - assert ( - base_synchronized_data.participant_to_randomness - == participant_to_randomness - ) - assert base_synchronized_data.participant_to_votes == participant_to_votes - assert base_synchronized_data.safe_contract_address == safe_contract_address - - -class DummyConcreteRound(AbstractRound): - """A dummy concrete round's implementation.""" - - payload_class: Optional[Type[BaseTxPayload]] = None - synchronized_data_class = MagicMock() - payload_attribute = MagicMock() - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, EventType]]: - """A dummy `end_block` implementation.""" - - def check_payload(self, payload: BaseTxPayload) -> None: - """A dummy `check_payload` implementation.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """A dummy `process_payload` implementation.""" - - -class TestAbstractRound: - """Test the 'AbstractRound' class.""" - - def setup(self) -> None: - """Set up the tests.""" - self.known_payload_type = ConcreteRoundA.payload_class - self.participants = ("a", "b") - self.base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB( - setup_data=dict( - all_participants=[self.participants], - participants=[self.participants], - consensus_threshold=[2], - ) - ) - ) - self.round = ConcreteRoundA(self.base_synchronized_data, MagicMock()) - - def test_auto_round_id(self) -> None: - """Test that the 'auto_round_id()' method works as expected.""" - - assert DummyConcreteRound.auto_round_id() == "dummy_concrete_round" - - def test_must_not_set_round_id(self) -> None: - """Test that the 'round_id' must be set in concrete classes.""" - - # no exception as round id is auto-assigned - my_concrete_round = DummyConcreteRound(MagicMock(), MagicMock()) - assert my_concrete_round.round_id == "dummy_concrete_round" - - def test_must_set_payload_class_type(self) -> None: - """Test that the 'payload_class' must be set in concrete classes.""" - - with pytest.raises( - AbstractRoundInternalError, match="'payload_class' not set on .*" - ): - - class MyConcreteRound(AbstractRound): - synchronized_data_class = MagicMock() - payload_attribute = MagicMock() - # here payload_class is missing - - def test_check_payload_type_with_previous_round_transaction(self) -> None: - """Test check 'check_payload_type'.""" - - class MyConcreteRound(DummyConcreteRound): - """A concrete round with the payload class defined.""" - - payload_class = BaseTxPayload - - with pytest.raises(LateArrivingTransaction): - MyConcreteRound(MagicMock(), MagicMock(), BaseTxPayload).check_payload_type( - MagicMock(payload=BaseTxPayload("dummy")) - ) - - def test_check_payload_type(self) -> None: - """Test check 'check_payload_type'.""" - - with pytest.raises( - TransactionTypeNotRecognizedError, - match="current round does not allow transactions", - ): - DummyConcreteRound(MagicMock(), MagicMock()).check_payload_type(MagicMock()) - - def test_synchronized_data_getter(self) -> None: - """Test 'synchronized_data' property getter.""" - state = self.round.synchronized_data - assert state.participants == frozenset(self.participants) - - def test_check_transaction_unknown_payload(self) -> None: - """Test 'check_transaction' method, with unknown payload type.""" - tx_type = "unknown_payload" - tx_mock = MagicMock() - tx_mock.payload_class = tx_type - with pytest.raises( - TransactionTypeNotRecognizedError, - match="request '.*' not recognized", - ): - self.round.check_transaction(tx_mock) - - def test_check_transaction_known_payload(self) -> None: - """Test 'check_transaction' method, with known payload type.""" - tx_mock = MagicMock() - tx_mock.payload = self.known_payload_type(sender="dummy") - self.round.check_transaction(tx_mock) - - def test_process_transaction_negative_unknown_payload(self) -> None: - """Test 'process_transaction' method, with unknown payload type.""" - tx_mock = MagicMock() - tx_mock.payload = object - with pytest.raises( - TransactionTypeNotRecognizedError, - match="request '.*' not recognized", - ): - self.round.process_transaction(tx_mock) - - def test_process_transaction_negative_check_transaction_fails(self) -> None: - """Test 'process_transaction' method, with 'check_transaction' failing.""" - tx_mock = MagicMock() - tx_mock.payload = object - error_message = "transaction not valid" - with mock.patch.object( - self.round, "check_payload_type", side_effect=ValueError(error_message) - ): - with pytest.raises(ValueError, match=error_message): - self.round.process_transaction(tx_mock) - - def test_process_transaction_positive(self) -> None: - """Test 'process_transaction' method, positive case.""" - tx_mock = MagicMock() - tx_mock.payload = BaseTxPayload(sender="dummy") - self.round.process_transaction(tx_mock) - - def test_check_majority_possible_raises_error_when_nb_participants_is_0( - self, - ) -> None: - """Check that 'check_majority_possible' raises error when nb_participants=0.""" - with pytest.raises( - ABCIAppInternalError, - match="nb_participants not consistent with votes_by_participants", - ): - DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).check_majority_possible({}, 0) - - def test_check_majority_possible_passes_when_vote_set_is_empty(self) -> None: - """Check that 'check_majority_possible' passes when the set of votes is empty.""" - DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).check_majority_possible({}, 1) - - def test_check_majority_possible_passes_when_vote_set_nonempty_and_check_passes( - self, - ) -> None: - """ - Check that 'check_majority_possible' passes when set of votes is non-empty. - - The check passes because: - - the threshold is 2 - - the other voter can vote for the same item of the first voter - """ - DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).check_majority_possible({"alice": DummyPayload("alice", True)}, 2) - - def test_check_majority_possible_passes_when_payload_attributes_majority_match( - self, - ) -> None: - """ - Test 'check_majority_possible' when set of votes is non-empty and the majority of the attribute values match. - - The check passes because: - - the threshold is 3 (participants are 4) - - 3 voters have the same attribute value in their payload - """ - DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).check_majority_possible( - { - "voter_1": DummyPayload("voter_1", 0), - "voter_2": DummyPayload("voter_2", 0), - "voter_3": DummyPayload("voter_3", 0), - }, - 4, - ) - - def test_check_majority_possible_passes_when_vote_set_nonempty_and_check_doesnt_pass( - self, - ) -> None: - """ - Check that 'check_majority_possible' doesn't pass when set of votes is non-empty. - - the check does not pass because: - - the threshold is 2 - - both voters have already voted for different items - """ - with pytest.raises( - ABCIAppException, - match="cannot reach quorum=2, number of remaining votes=0, number of most voted item's votes=1", - ): - DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).check_majority_possible( - { - "alice": DummyPayload("alice", False), - "bob": DummyPayload("bob", True), - }, - 2, - ) - - def test_is_majority_possible_positive_case(self) -> None: - """Test 'is_majority_possible', positive case.""" - assert DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).is_majority_possible({"alice": DummyPayload("alice", False)}, 2) - - def test_is_majority_possible_negative_case(self) -> None: - """Test 'is_majority_possible', negative case.""" - assert not DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).is_majority_possible( - { - "alice": DummyPayload("alice", False), - "bob": DummyPayload("bob", True), - }, - 2, - ) - - def test_check_majority_possible_raises_error_when_new_voter_already_voted( - self, - ) -> None: - """Test 'check_majority_possible_with_new_vote' raises when new voter already voted.""" - with pytest.raises(ABCIAppInternalError, match="voter has already voted"): - DummyConcreteRound( - self.base_synchronized_data, - MagicMock(), - ).check_majority_possible_with_new_voter( - {"alice": DummyPayload("alice", False)}, - "alice", - DummyPayload("alice", True), - 2, - ) - - def test_check_majority_possible_raises_error_when_nb_participants_inconsistent( - self, - ) -> None: - """Test 'check_majority_possible_with_new_vote' raises when 'nb_participants' inconsistent with other args.""" - with pytest.raises( - ABCIAppInternalError, - match="nb_participants not consistent with votes_by_participants", - ): - DummyConcreteRound( - self.base_synchronized_data, - MagicMock(), - ).check_majority_possible_with_new_voter( - {"alice": DummyPayload("alice", True)}, - "bob", - DummyPayload("bob", True), - 1, - ) - - def test_check_majority_possible_when_check_passes( - self, - ) -> None: - """ - Test 'check_majority_possible_with_new_vote' when the check passes. - - The test passes because: - - the number of participants is 2, and so the threshold is 2 - - the new voter votes for the same item already voted by voter 1. - """ - DummyConcreteRound( - self.base_synchronized_data, - MagicMock(), - ).check_majority_possible_with_new_voter( - {"alice": DummyPayload("alice", True)}, "bob", DummyPayload("bob", True), 2 - ) - - -class TestTimeouts: - """Test the 'Timeouts' class.""" - - def setup(self) -> None: - """Set up the test.""" - self.timeouts: Timeouts = Timeouts() - - def test_size(self) -> None: - """Test the 'size' property.""" - assert self.timeouts.size == 0 - self.timeouts._heap.append(MagicMock()) - assert self.timeouts.size == 1 - - def test_add_timeout(self) -> None: - """Test the 'add_timeout' method.""" - # the first time, entry_count = 0 - entry_count = self.timeouts.add_timeout(datetime.datetime.now(), MagicMock()) - assert entry_count == 0 - - # the second time, entry_count is incremented - entry_count = self.timeouts.add_timeout(datetime.datetime.now(), MagicMock()) - assert entry_count == 1 - - def test_cancel_timeout(self) -> None: - """Test the 'cancel_timeout' method.""" - entry_count = self.timeouts.add_timeout(datetime.datetime.now(), MagicMock()) - assert self.timeouts.size == 1 - - self.timeouts.cancel_timeout(entry_count) - - # cancelling timeouts does not remove them from the heap - assert self.timeouts.size == 1 - - def test_pop_earliest_cancelled_timeouts(self) -> None: - """Test the 'pop_earliest_cancelled_timeouts' method.""" - entry_count_1 = self.timeouts.add_timeout(datetime.datetime.now(), MagicMock()) - entry_count_2 = self.timeouts.add_timeout(datetime.datetime.now(), MagicMock()) - self.timeouts.cancel_timeout(entry_count_1) - self.timeouts.cancel_timeout(entry_count_2) - self.timeouts.pop_earliest_cancelled_timeouts() - assert self.timeouts.size == 0 - - def test_get_earliest_timeout_a(self) -> None: - """Test the 'get_earliest_timeout' method.""" - deadline_1 = datetime.datetime.now() - event_1 = MagicMock() - - sleep(0.5) - - deadline_2 = datetime.datetime.now() - event_2 = MagicMock() - assert deadline_1 < deadline_2 - - self.timeouts.add_timeout(deadline_2, event_2) - self.timeouts.add_timeout(deadline_1, event_1) - - assert self.timeouts.size == 2 - # test that we get the event with the earliest deadline - timeout, event = self.timeouts.get_earliest_timeout() - assert timeout == deadline_1 - assert event == event_1 - - # test that get_earliest_timeout does not remove elements - assert self.timeouts.size == 2 - - popped_timeout, popped_event = self.timeouts.pop_timeout() - assert popped_timeout == timeout - assert popped_event == event - - def test_get_earliest_timeout_b(self) -> None: - """Test the 'get_earliest_timeout' method.""" - - deadline_1 = datetime.datetime.now() - event_1 = MagicMock() - - sleep(0.5) - - deadline_2 = datetime.datetime.now() - event_2 = MagicMock() - assert deadline_1 < deadline_2 - - self.timeouts.add_timeout(deadline_1, event_1) - self.timeouts.add_timeout(deadline_2, event_2) - - assert self.timeouts.size == 2 - # test that we get the event with the earliest deadline - timeout, event = self.timeouts.get_earliest_timeout() - assert timeout == deadline_1 - assert event == event_1 - - # test that get_earliest_timeout does not remove elements - assert self.timeouts.size == 2 - - def test_pop_timeout(self) -> None: - """Test the 'pop_timeout' method.""" - deadline_1 = datetime.datetime.now() - event_1 = MagicMock() - - sleep(0.5) - - deadline_2 = datetime.datetime.now() - event_2 = MagicMock() - assert deadline_1 < deadline_2 - - self.timeouts.add_timeout(deadline_2, event_2) - self.timeouts.add_timeout(deadline_1, event_1) - - assert self.timeouts.size == 2 - # test that we get the event with the earliest deadline - timeout, event = self.timeouts.pop_timeout() - assert timeout == deadline_1 - assert event == event_1 - - # test that pop_timeout removes elements - assert self.timeouts.size == 1 - - -STUB_TERMINATION_CONFIG = abci_base.BackgroundAppConfig( - round_cls=ConcreteBackgroundRound, - start_event=ConcreteEvents.TERMINATE, - abci_app=TerminationAppTest, -) - -STUB_SLASH_CONFIG = abci_base.BackgroundAppConfig( - round_cls=ConcreteBackgroundSlashingRound, - start_event=ConcreteEvents.SLASH_START, - end_event=ConcreteEvents.SLASH_END, - abci_app=SlashingAppTest, -) - - -class TestAbciApp: - """Test the 'AbciApp' class.""" - - def setup(self) -> None: - """Set up the test.""" - self.abci_app = AbciAppTest(MagicMock(), MagicMock(), MagicMock()) - self.abci_app.add_background_app(STUB_TERMINATION_CONFIG) - - def teardown(self) -> None: - """Teardown the test.""" - self.abci_app.background_apps.clear() - - @pytest.mark.parametrize("flag", (True, False)) - def test_is_abstract(self, flag: bool) -> None: - """Test `is_abstract` property.""" - - class CopyOfAbciApp(AbciAppTest): - """Copy to avoid side effects due to state change""" - - CopyOfAbciApp._is_abstract = flag - assert CopyOfAbciApp.is_abstract() is flag - - def test_initial_round_cls_not_set(self) -> None: - """Test when 'initial_round_cls' is not set.""" - - with pytest.raises( - ABCIAppInternalError, match="'initial_round_cls' field not set" - ): - - class MyAbciApp(AbciApp): - # here 'initial_round_cls' should be defined. - # ... - transition_function: AbciAppTransitionFunction = {} - - def test_transition_function_not_set(self) -> None: - """Test when 'transition_function' is not set.""" - with pytest.raises( - ABCIAppInternalError, match="'transition_function' field not set" - ): - - class MyAbciApp(AbciApp): - initial_round_cls = ConcreteRoundA - # here 'transition_function' should be defined. - # ... - - def test_last_timestamp_negative(self) -> None: - """Test the 'last_timestamp' property, negative case.""" - with pytest.raises(ABCIAppInternalError, match="last timestamp is None"): - self.abci_app.last_timestamp - - def test_last_timestamp_positive(self) -> None: - """Test the 'last_timestamp' property, positive case.""" - expected = MagicMock() - self.abci_app._last_timestamp = expected - assert expected == self.abci_app.last_timestamp - - @pytest.mark.parametrize( - "db_key, sync_classes, default, property_found", - ( - ("", set(), "default", False), - ("non_existing_key", {BaseSynchronizedData}, True, False), - ("participants", {BaseSynchronizedData}, {}, False), - ("is_keeper_set", {BaseSynchronizedData}, True, True), - ), - ) - def test_get_synced_value( - self, - db_key: str, - sync_classes: Set[Type[BaseSynchronizedData]], - default: Any, - property_found: bool, - ) -> None: - """Test the `_get_synced_value` method.""" - res = self.abci_app._get_synced_value(db_key, sync_classes, default) - if property_found: - assert res == getattr(self.abci_app.synchronized_data, db_key) - return - assert res == self.abci_app.synchronized_data.db.get(db_key, default) - - def test_process_event(self) -> None: - """Test the 'process_event' method, positive case, with timeout events.""" - self.abci_app.add_background_app(STUB_SLASH_CONFIG) - self.abci_app.setup() - self.abci_app._last_timestamp = MagicMock() - assert self.abci_app._transition_backup.transition_function is None - assert isinstance(self.abci_app.current_round, ConcreteRoundA) - self.abci_app.process_event(ConcreteEvents.B) - assert isinstance(self.abci_app.current_round, ConcreteRoundB) - self.abci_app.process_event(ConcreteEvents.TIMEOUT) - assert isinstance(self.abci_app.current_round, ConcreteRoundA) - self.abci_app.process_event(ConcreteEvents.TERMINATE) - assert isinstance(self.abci_app.current_round, ConcreteTerminationRoundA) - expected_backup = deepcopy(self.abci_app.transition_function) - assert ( - self.abci_app._transition_backup.transition_function - == AbciAppTest.transition_function - ) - self.abci_app.process_event(ConcreteEvents.SLASH_START) - assert isinstance(self.abci_app.current_round, ConcreteSlashingRoundA) - assert ( - self.abci_app._transition_backup.transition_function - == expected_backup - == TerminationAppTest.transition_function - ) - assert self.abci_app.transition_function == SlashingAppTest.transition_function - self.abci_app.process_event(ConcreteEvents.SLASH_END) - # should return back to the round that was running before the slashing started - assert isinstance(self.abci_app.current_round, ConcreteTerminationRoundA) - assert self.abci_app.transition_function == expected_backup - assert self.abci_app._transition_backup.transition_function is None - assert self.abci_app._transition_backup.round is None - - def test_process_event_negative_case(self) -> None: - """Test the 'process_event' method, negative case.""" - with mock.patch.object(self.abci_app.logger, "warning") as mock_warning: - self.abci_app.process_event(ConcreteEvents.A) - mock_warning.assert_called_with( - "Cannot process event 'a' as current state is not set" - ) - - def test_update_time(self) -> None: - """Test the 'update_time' method.""" - # schedule round_a - current_time = datetime.datetime.now() - self.abci_app.setup() - self.abci_app._last_timestamp = current_time - - # move to round_b that schedules timeout events - self.abci_app.process_event(ConcreteEvents.B) - assert self.abci_app.current_round_id == "concrete_round_b" - - # simulate most recent timestamp beyond earliest deadline - # after pop, len(timeouts) == 0, because round_a does not schedule new timeout events - current_time = current_time + datetime.timedelta(0, AbciAppTest.TIMEOUT) - self.abci_app.update_time(current_time) - - # now we are back to round_a - assert self.abci_app.current_round_id == "concrete_round_a" - - # move to round_c that schedules timeout events to itself - self.abci_app.process_event(ConcreteEvents.C) - assert self.abci_app.current_round_id == "concrete_round_c" - - # simulate most recent timestamp beyond earliest deadline - # after pop, len(timeouts) == 0, because round_c schedules timeout events - current_time = current_time + datetime.timedelta(0, AbciAppTest.TIMEOUT) - self.abci_app.update_time(current_time) - - assert self.abci_app.current_round_id == "concrete_round_c" - - # further update changes nothing - height = self.abci_app.current_round_height - self.abci_app.update_time(current_time) - assert height == self.abci_app.current_round_height - - def test_get_all_events(self) -> None: - """Test the all events getter.""" - assert { - ConcreteEvents.A, - ConcreteEvents.B, - ConcreteEvents.C, - ConcreteEvents.TIMEOUT, - } == self.abci_app.get_all_events() - - @pytest.mark.parametrize("include_background_rounds", (True, False)) - def test_get_all_rounds_classes( - self, - include_background_rounds: bool, - ) -> None: - """Test the get all rounds getter.""" - expected_rounds = {ConcreteRoundA, ConcreteRoundB, ConcreteRoundC} - - if include_background_rounds: - expected_rounds.update( - { - ConcreteBackgroundRound, - ConcreteTerminationRoundA, - ConcreteTerminationRoundB, - ConcreteTerminationRoundC, - } - ) - - actual_rounds = self.abci_app.get_all_round_classes( - {ConcreteBackgroundRound}, include_background_rounds - ) - - assert actual_rounds == expected_rounds - - def test_get_all_rounds_classes_bg_ever_running( - self, - ) -> None: - """Test the get all rounds when the background round is of an ever running type.""" - # we clear the pre-existing bg apps and add an ever running - self.abci_app.background_apps.clear() - self.abci_app.add_background_app( - abci_base.BackgroundAppConfig(ConcreteBackgroundRound) - ) - include_background_rounds = True - expected_rounds = { - ConcreteRoundA, - ConcreteRoundB, - ConcreteRoundC, - } - assert expected_rounds == self.abci_app.get_all_round_classes( - {ConcreteBackgroundRound}, include_background_rounds - ) - - def test_add_background_app(self) -> None: - """Tests the add method for the background apps.""" - # remove the terminating bg round added in `setup()` and the pending offences bg app added in the metaclass - self.abci_app.background_apps.clear() - - class EmptyAbciApp(AbciAppTest): - """An AbciApp without background apps' attributes set.""" - - cross_period_persisted_keys = frozenset({"1", "2"}) - - class BackgroundAbciApp(AbciAppTest): - """A mock background AbciApp.""" - - cross_period_persisted_keys = frozenset({"2", "3"}) - - assert len(EmptyAbciApp.background_apps) == 0 - assert EmptyAbciApp.cross_period_persisted_keys == {"1", "2"} - # add the background app - bg_app_config = abci_base.BackgroundAppConfig( - round_cls=ConcreteBackgroundRound, - start_event=ConcreteEvents.TERMINATE, - abci_app=BackgroundAbciApp, - ) - EmptyAbciApp.add_background_app(bg_app_config) - assert len(EmptyAbciApp.background_apps) == 1 - assert EmptyAbciApp.cross_period_persisted_keys == {"1", "2", "3"} - - def test_cleanup(self) -> None: - """Test the cleanup method.""" - self.abci_app.setup() - - # Dummy parameters, synchronized data and round - cleanup_history_depth = 1 - start_history_depth = 5 - max_participants = 4 - dummy_synchronized_data = BaseSynchronizedData( - db=AbciAppDB(setup_data=dict(participants=[max_participants])) - ) - dummy_round = ConcreteRoundA(dummy_synchronized_data, MagicMock()) - - # Add dummy data - self.abci_app._previous_rounds = [dummy_round] * start_history_depth - self.abci_app._round_results = [dummy_synchronized_data] * start_history_depth - self.abci_app.synchronized_data.db._data = { - i: {"dummy_key": ["dummy_value"]} for i in range(start_history_depth) - } - - round_height = self.abci_app.current_round_height - # Verify that cleanup reduces the data amount - assert len(self.abci_app._previous_rounds) == start_history_depth - assert len(self.abci_app._round_results) == start_history_depth - assert len(self.abci_app.synchronized_data.db._data) == start_history_depth - assert list(self.abci_app.synchronized_data.db._data.keys()) == list( - range(start_history_depth) - ) - previous_reset_index = self.abci_app.synchronized_data.db.reset_index - - self.abci_app.cleanup(cleanup_history_depth) - - assert len(self.abci_app._previous_rounds) == cleanup_history_depth - assert len(self.abci_app._round_results) == cleanup_history_depth - assert len(self.abci_app.synchronized_data.db._data) == cleanup_history_depth - assert list(self.abci_app.synchronized_data.db._data.keys()) == list( - range(start_history_depth - cleanup_history_depth, start_history_depth) - ) - # reset_index must not change after a cleanup - assert self.abci_app.synchronized_data.db.reset_index == previous_reset_index - - # Verify round height stays unaffected - assert self.abci_app.current_round_height == round_height - - # Add more values to the history - reset_index = self.abci_app.synchronized_data.db.reset_index - cleanup_history_depth_current = 3 - for _ in range(10): - self.abci_app.synchronized_data.db.update(dummy_key="dummy_value") - - # Check that the history cleanup keeps the desired history length - self.abci_app.cleanup_current_histories(cleanup_history_depth_current) - history_len = len( - self.abci_app.synchronized_data.db._data[reset_index]["dummy_key"] - ) - assert history_len == cleanup_history_depth_current - - @mock.patch.object(ConcreteBackgroundRound, "check_transaction") - @pytest.mark.parametrize( - "transaction", - [mock.MagicMock(payload=DUMMY_CONCRETE_BACKGROUND_PAYLOAD)], - ) - def test_check_transaction_for_termination_round( - self, - check_transaction_mock: mock.Mock, - transaction: Transaction, - ) -> None: - """Tests process_transaction when it's a transaction meant for the termination app.""" - self.abci_app.setup() - self.abci_app.check_transaction(transaction) - check_transaction_mock.assert_called_with(transaction) - - @mock.patch.object(ConcreteBackgroundRound, "process_transaction") - @pytest.mark.parametrize( - "transaction", - [mock.MagicMock(payload=DUMMY_CONCRETE_BACKGROUND_PAYLOAD)], - ) - def test_process_transaction_for_termination_round( - self, - process_transaction_mock: mock.Mock, - transaction: Transaction, - ) -> None: - """Tests process_transaction when it's a transaction meant for the termination app.""" - self.abci_app.setup() - self.abci_app.process_transaction(transaction) - process_transaction_mock.assert_called_with(transaction) - - -class TestOffenceTypeFns: - """Test `OffenceType`-related functions.""" - - @staticmethod - def test_light_offences() -> None: - """Test `light_offences` function.""" - assert list(light_offences()) == [ - OffenseType.VALIDATOR_DOWNTIME, - OffenseType.INVALID_PAYLOAD, - OffenseType.BLACKLISTED, - OffenseType.SUSPECTED, - ] - - @staticmethod - def test_serious_offences() -> None: - """Test `serious_offences` function.""" - assert list(serious_offences()) == [ - OffenseType.UNKNOWN, - OffenseType.DOUBLE_SIGNING, - OffenseType.LIGHT_CLIENT_ATTACK, - ] - - -@composite -def availability_window_data(draw: DrawFn) -> Dict[str, int]: - """A strategy for building valid availability window data.""" - max_length = draw(integers(min_value=1, max_value=12_000)) - array = draw(integers(min_value=0, max_value=(2**max_length) - 1)) - num_positive = draw(integers(min_value=0, max_value=1_000_000)) - num_negative = draw(integers(min_value=0, max_value=1_000_000)) - - return { - "max_length": max_length, - "array": array, - "num_positive": num_positive, - "num_negative": num_negative, - } - - -class TestAvailabilityWindow: - """Test `AvailabilityWindow`.""" - - @staticmethod - @given(integers(min_value=1, max_value=100)) - def test_not_equal(max_length: int) -> None: - """Test the `add` method.""" - availability_window_1 = AvailabilityWindow(max_length) - availability_window_2 = AvailabilityWindow(max_length) - assert availability_window_1 == availability_window_2 - availability_window_2.add(False) - assert availability_window_1 != availability_window_2 - # test with a different type - assert availability_window_1 != MagicMock() - - @staticmethod - @given(integers(min_value=0, max_value=100), data()) - def test_add(max_length: int, hypothesis_data: Any) -> None: - """Test the `add` method.""" - if max_length < 1: - with pytest.raises( - ValueError, - match=f"An `AvailabilityWindow` with a `max_length` {max_length} < 1 is not valid.", - ): - AvailabilityWindow(max_length) - return - - availability_window = AvailabilityWindow(max_length) - - expected_positives = expected_negatives = 0 - for i in range(max_length): - value = hypothesis_data.draw(booleans()) - availability_window.add(value) - items_in = i + 1 - assert len(availability_window._window) == items_in - assert availability_window._window[-1] is value - expected_positives += 1 if value else 0 - assert availability_window._num_positive == expected_positives - expected_negatives = items_in - expected_positives - assert availability_window._num_negative == expected_negatives - - # max length is reached and window starts cycling - assert len(availability_window._window) == max_length - for _ in range(10): - value = hypothesis_data.draw(booleans()) - expected_popped_value = ( - None if max_length == 0 else availability_window._window[0] - ) - availability_window.add(value) - assert len(availability_window._window) == max_length - if expected_popped_value is not None: - expected_positives -= bool(expected_popped_value) - expected_negatives -= bool(not expected_popped_value) - expected_positives += bool(value) - expected_negatives += bool(not value) - assert availability_window._num_positive == expected_positives - assert availability_window._num_negative == expected_negatives - - @staticmethod - @given( - max_length=integers(min_value=1, max_value=30_000), - num_positive=integers(min_value=0), - num_negative=integers(min_value=0), - ) - @pytest.mark.parametrize( - "window, expected_serialization", - ( - (deque(()), 0), - (deque((False, False, False)), 0), - (deque((True, False, True)), 5), - (deque((True for _ in range(3))), 7), - ( - deque((True for _ in range(1000))), - int( - "10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958" - "58127594672917553146825187145285692314043598457757469857480393456777482423098542107460506237114187" - "79541821530464749835819412673987675591655439460770629145711964776865421676604298316526243868372056" - "68069375" - ), - ), - ), - ) - def test_to_dict( - max_length: int, - num_positive: int, - num_negative: int, - window: Deque, - expected_serialization: int, - ) -> None: - """Test `to_dict` method.""" - availability_window = AvailabilityWindow(max_length) - availability_window._num_positive = num_positive - availability_window._num_negative = num_negative - availability_window._window = window - assert availability_window.to_dict() == { - "max_length": max_length, - "array": expected_serialization, - "num_positive": num_positive, - "num_negative": num_negative, - } - - @staticmethod - @pytest.mark.parametrize( - "data_, key, validator, expected_error", - ( - ({"a": 1, "b": 2, "c": 3}, "a", lambda x: x > 0, None), - ( - {"a": 1, "b": 2, "c": 3}, - "d", - lambda x: x > 0, - r"Missing required key: d\.", - ), - ( - {"a": "1", "b": 2, "c": 3}, - "a", - lambda x: x > 0, - r"a must be of type int\.", - ), - ( - {"a": -1, "b": 2, "c": 3}, - "a", - lambda x: x > 0, - r"a has invalid value -1\.", - ), - ), - ) - def test_validate_key( - data_: dict, key: str, validator: Callable, expected_error: Optional[str] - ) -> None: - """Test the `_validate_key` method.""" - if expected_error: - with pytest.raises(ValueError, match=expected_error): - AvailabilityWindow._validate_key(data_, key, validator) - else: - AvailabilityWindow._validate_key(data_, key, validator) - - @staticmethod - @pytest.mark.parametrize( - "data_, error_regex", - ( - ("not a dict", r"Expected dict, got"), - ( - {"max_length": -1, "array": 42, "num_positive": 10, "num_negative": 0}, - r"max_length", - ), - ( - {"max_length": 2, "array": 4, "num_positive": 10, "num_negative": 0}, - r"array", - ), - ( - {"max_length": 8, "array": 42, "num_positive": -1, "num_negative": 0}, - r"num_positive", - ), - ( - {"max_length": 8, "array": 42, "num_positive": 10, "num_negative": -1}, - r"num_negative", - ), - ), - ) - def test_validate_negative(data_: dict, error_regex: str) -> None: - """Negative tests for the `_validate` method.""" - with pytest.raises((TypeError, ValueError), match=error_regex): - AvailabilityWindow._validate(data_) - - @staticmethod - @given(availability_window_data()) - def test_validate_positive(data_: Dict[str, int]) -> None: - """Positive tests for the `_validate` method.""" - AvailabilityWindow._validate(data_) - - @staticmethod - @given(availability_window_data()) - def test_from_dict(data_: Dict[str, int]) -> None: - """Test `from_dict` method.""" - availability_window = AvailabilityWindow.from_dict(data_) - - # convert the serialized array to a binary string - binary_number = bin(data_["array"])[2:] - # convert each character in the binary string to a flag - flags = [bool(int(digit)) for digit in binary_number] - expected_window = deque(flags, maxlen=data_["max_length"]) - - assert availability_window._max_length == data_["max_length"] - assert availability_window._window == expected_window - assert availability_window._num_positive == data_["num_positive"] - assert availability_window._num_negative == data_["num_negative"] - - @staticmethod - @given(availability_window_data()) - def test_to_dict_and_back(data_: Dict[str, int]) -> None: - """Test that the `from_dict` produces an object that generates the input data again when calling `to_dict`.""" - availability_window = AvailabilityWindow.from_dict(data_) - assert availability_window.to_dict() == data_ - - -class TestOffenceStatus: - """Test the `OffenceStatus` dataclass.""" - - @staticmethod - @pytest.mark.parametrize("custom_amount", (0, 5)) - @pytest.mark.parametrize("light_unit_amount, serious_unit_amount", ((1, 2),)) - @pytest.mark.parametrize( - "validator_downtime, invalid_payload, blacklisted, suspected, " - "num_unknown_offenses, num_double_signed, num_light_client_attack, expected", - ( - (False, False, False, False, 0, 0, 0, 0), - (True, False, False, False, 0, 0, 0, 1), - (False, True, False, False, 0, 0, 0, 1), - (False, False, True, False, 0, 0, 0, 1), - (False, False, False, True, 0, 0, 0, 1), - (False, False, False, False, 1, 0, 0, 2), - (False, False, False, False, 0, 1, 0, 2), - (False, False, False, False, 0, 0, 1, 2), - (False, False, False, False, 0, 2, 1, 6), - (False, True, False, True, 5, 2, 1, 18), - (True, True, True, True, 5, 2, 1, 20), - ), - ) - def test_slash_amount( - custom_amount: int, - light_unit_amount: int, - serious_unit_amount: int, - validator_downtime: bool, - invalid_payload: bool, - blacklisted: bool, - suspected: bool, - num_unknown_offenses: int, - num_double_signed: int, - num_light_client_attack: int, - expected: int, - ) -> None: - """Test the `slash_amount` method.""" - status = OffenceStatus() - - if validator_downtime: - for _ in range(abci_base.NUMBER_OF_BLOCKS_TRACKED): - status.validator_downtime.add(True) - - for _ in range(abci_base.NUMBER_OF_ROUNDS_TRACKED): - if invalid_payload: - status.invalid_payload.add(True) - if blacklisted: - status.blacklisted.add(True) - if suspected: - status.suspected.add(True) - - status.num_unknown_offenses = num_unknown_offenses - status.num_double_signed = num_double_signed - status.num_light_client_attack = num_light_client_attack - status.custom_offences_amount = custom_amount - - actual = status.slash_amount(light_unit_amount, serious_unit_amount) - assert actual == expected + status.custom_offences_amount - - -@composite -def offence_tracking(draw: DrawFn) -> Tuple[Evidences, LastCommitInfo]: - """A strategy for building offences reported by Tendermint.""" - n_validators = draw(integers(min_value=1, max_value=10)) - - validators = [ - draw( - builds( - Validator, - address=just(bytes(i)), - power=integers(min_value=0), - ) - ) - for i in range(n_validators) - ] - - evidences = builds( - Evidences, - byzantine_validators=lists( - builds( - Evidence, - evidence_type=sampled_from(EvidenceType), - validator=sampled_from(validators), - height=integers(min_value=0), - time=builds( - Timestamp, - seconds=integers(min_value=0), - nanos=integers(min_value=0, max_value=999_999_999), - ), - total_voting_power=integers(min_value=0), - ), - min_size=n_validators, - max_size=n_validators, - unique_by=lambda v: v.validator.address, - ), - ) - - last_commit_info = builds( - LastCommitInfo, - round_=integers(min_value=0), - votes=lists( - builds( - VoteInfo, - validator=sampled_from(validators), - signed_last_block=booleans(), - ), - min_size=n_validators, - max_size=n_validators, - unique_by=lambda v: v.validator.address, - ), - ) - - ev_example, commit_example = draw(evidences), draw(last_commit_info) - - # this assertion proves that all the validators are unique - unique_commit_addresses = set( - v.validator.address.decode() for v in commit_example.votes - ) - assert len(unique_commit_addresses) == n_validators - - # this assertion proves that the same validators are used for evidences and votes - assert unique_commit_addresses == set( - e.validator.address.decode() for e in ev_example.byzantine_validators - ) - - return ev_example, commit_example - - -@composite -def offence_status(draw: DrawFn) -> OffenceStatus: - """Build an offence status instance.""" - validator_downtime = just( - AvailabilityWindow.from_dict(draw(availability_window_data())) - ) - invalid_payload = just( - AvailabilityWindow.from_dict(draw(availability_window_data())) - ) - blacklisted = just(AvailabilityWindow.from_dict(draw(availability_window_data()))) - suspected = just(AvailabilityWindow.from_dict(draw(availability_window_data()))) - - status = builds( - OffenceStatus, - validator_downtime=validator_downtime, - invalid_payload=invalid_payload, - blacklisted=blacklisted, - suspected=suspected, - num_unknown_offenses=integers(min_value=0), - num_double_signed=integers(min_value=0), - num_light_client_attack=integers(min_value=0), - ) - - return draw(status) - - -class TestOffenseStatusEncoderDecoder: - """Test the `OffenseStatusEncoder` and the `OffenseStatusDecoder`.""" - - @staticmethod - @given(dictionaries(keys=text(), values=offence_status(), min_size=1)) - def test_encode_decode_offense_status(offense_status: str) -> None: - """Test encoding an offense status mapping and then decoding it by using the custom encoder/decoder.""" - encoded = json.dumps(offense_status, cls=OffenseStatusEncoder) - decoded = json.loads(encoded, cls=OffenseStatusDecoder) - - assert decoded == offense_status - - def test_encode_unknown(self) -> None: - """Test the encoder with an unknown input.""" - - class Unknown: - """A dummy class that the encoder is not aware of.""" - - unknown = "?" - - with pytest.raises( - TypeError, match="Object of type Unknown is not JSON serializable" - ): - json.dumps(Unknown(), cls=OffenseStatusEncoder) - - -class TestRoundSequence: - """Test the RoundSequence class.""" - - def setup(self) -> None: - """Set up the test.""" - self.round_sequence = RoundSequence( - context=MagicMock(), abci_app_cls=AbciAppTest - ) - self.round_sequence.setup(MagicMock(), logging.getLogger()) - self.round_sequence.tm_height = 1 - - @pytest.mark.parametrize( - "property_name, set_twice_exc, config_exc", - ( - ( - "validator_to_agent", - "The mapping of the validators' addresses to their agent addresses can only be set once. " - "Attempted to set with {new_content_attempt} but it has content already: {value}.", - "The mapping of the validators' addresses to their agent addresses has not been set.", - ), - ), - ) - @given(data()) - def test_slashing_properties( - self, property_name: str, set_twice_exc: str, config_exc: str, _data: Any - ) -> None: - """Test `validator_to_agent` getter and setter.""" - if property_name == "validator_to_agent": - data_generator = dictionaries(text(), text()) - else: - data_generator = dictionaries(text(), just(OffenceStatus())) - - value = _data.draw(data_generator) - round_sequence = RoundSequence(context=MagicMock(), abci_app_cls=AbciAppTest) - - if value: - setattr(round_sequence, property_name, value) - assert getattr(round_sequence, property_name) == value - new_content_attempt = _data.draw(data_generator) - with pytest.raises( - ValueError, - match=re.escape( - set_twice_exc.format( - new_content_attempt=new_content_attempt, value=value - ) - ), - ): - setattr(round_sequence, property_name, new_content_attempt) - return - - with pytest.raises(SlashingNotConfiguredError, match=config_exc): - getattr(round_sequence, property_name) - - @mock.patch("json.loads", return_value="json_serializable") - @pytest.mark.parametrize("slashing_config", (None, "", "test")) - def test_sync_db_and_slashing( - self, mock_loads: mock.MagicMock, slashing_config: str - ) -> None: - """Test the `sync_db_and_slashing` method.""" - self.round_sequence.latest_synchronized_data.slashing_config = slashing_config - serialized_db_state = "dummy_db_state" - self.round_sequence.sync_db_and_slashing(serialized_db_state) - - # Check that `sync()` was called with the correct arguments - mock_sync = cast( - mock.Mock, self.round_sequence.abci_app.synchronized_data.db.sync - ) - mock_sync.assert_called_once_with(serialized_db_state) - - if slashing_config: - mock_loads.assert_called_once_with( - slashing_config, cls=OffenseStatusDecoder - ) - else: - mock_loads.assert_not_called() - - @mock.patch("json.dumps") - @pytest.mark.parametrize("slashing_enabled", (True, False)) - def test_store_offence_status( - self, mock_dumps: mock.MagicMock, slashing_enabled: bool - ) -> None: - """Test the `store_offence_status` method.""" - # Set up mock objects and return values - self.round_sequence._offence_status = {"not_encoded": OffenceStatus()} - mock_encoded_status = "encoded_status" - mock_dumps.return_value = mock_encoded_status - - self.round_sequence._slashing_enabled = slashing_enabled - - # Call the method to be tested - self.round_sequence.store_offence_status() - - if slashing_enabled: - # Check that `json.dumps()` was called with the correct arguments, only if slashing is enabled - mock_dumps.assert_called_once_with( - self.round_sequence.offence_status, - cls=OffenseStatusEncoder, - sort_keys=True, - ) - assert ( - self.round_sequence.abci_app.synchronized_data.db.slashing_config - == mock_encoded_status - ) - return - - # otherwise check that it was not called - mock_dumps.assert_not_called() - - @given( - validator=builds(Validator, address=binary(), power=integers()), - agent_address=text(), - ) - def test_get_agent_address(self, validator: Validator, agent_address: str) -> None: - """Test `get_agent_address` method.""" - round_sequence = RoundSequence(context=MagicMock(), abci_app_cls=AbciAppTest) - round_sequence.validator_to_agent = { - validator.address.hex().upper(): agent_address - } - assert round_sequence.get_agent_address(validator) == agent_address - - unknown = deepcopy(validator) - unknown.address += b"unknown" - with pytest.raises( - ValueError, - match=re.escape( - f"Requested agent address for an unknown validator address {unknown.address.hex().upper()}. " - f"Available validators are: {round_sequence.validator_to_agent.keys()}" - ), - ): - round_sequence.get_agent_address(unknown) - - @pytest.mark.parametrize("offset", tuple(range(5))) - @pytest.mark.parametrize("n_blocks", (0, 1, 10)) - def test_height(self, n_blocks: int, offset: int) -> None: - """Test 'height' property.""" - self.round_sequence._blockchain._blocks = [MagicMock() for _ in range(n_blocks)] - self.round_sequence._blockchain._height_offset = offset - assert self.round_sequence._blockchain.length == n_blocks - assert self.round_sequence.height == n_blocks + offset - - def test_is_finished(self) -> None: - """Test 'is_finished' property.""" - assert not self.round_sequence.is_finished - self.round_sequence.abci_app._current_round = None - assert self.round_sequence.is_finished - - def test_last_round(self) -> None: - """Test 'last_round' property.""" - assert self.round_sequence.last_round_id is None - - def test_last_timestamp_none(self) -> None: - """ - Test 'last_timestamp' property. - - The property is None because there are no blocks. - """ - with pytest.raises(ABCIAppInternalError, match="last timestamp is None"): - self.round_sequence.last_timestamp - - def test_last_timestamp(self) -> None: - """Test 'last_timestamp' property, positive case.""" - seconds = 1 - nanoseconds = 1000 - expected_timestamp = datetime.datetime.fromtimestamp( - seconds + nanoseconds / 10**9 - ) - self.round_sequence._blockchain.add_block( - Block(MagicMock(height=1, timestamp=expected_timestamp), []) - ) - assert self.round_sequence.last_timestamp == expected_timestamp - - def test_abci_app_negative(self) -> None: - """Test 'abci_app' property, negative case.""" - self.round_sequence._abci_app = None - with pytest.raises(ABCIAppInternalError, match="AbciApp not set"): - self.round_sequence.abci_app - - def test_check_is_finished_negative(self) -> None: - """Test 'check_is_finished', negative case.""" - self.round_sequence.abci_app._current_round = None - with pytest.raises( - ValueError, - match="round sequence is finished, cannot accept new transactions", - ): - self.round_sequence.check_is_finished() - - def test_current_round_positive(self) -> None: - """Test 'current_round' property getter, positive case.""" - assert isinstance(self.round_sequence.current_round, ConcreteRoundA) - - def test_current_round_negative_current_round_not_set(self) -> None: - """Test 'current_round' property getter, negative case (current round not set).""" - self.round_sequence.abci_app._current_round = None - with pytest.raises(ValueError, match="current_round not set!"): - self.round_sequence.current_round - - def test_current_round_id(self) -> None: - """Test 'current_round_id' property getter""" - assert self.round_sequence.current_round_id == ConcreteRoundA.auto_round_id() - - def test_latest_result(self) -> None: - """Test 'latest_result' property getter.""" - assert self.round_sequence.latest_synchronized_data - - @pytest.mark.parametrize("committed", (True, False)) - def test_last_round_transition_timestamp(self, committed: bool) -> None: - """Test 'last_round_transition_timestamp' method.""" - if committed: - self.round_sequence.begin_block( - MagicMock(height=1), MagicMock(), MagicMock() - ) - self.round_sequence.end_block() - self.round_sequence.commit() - assert ( - self.round_sequence.last_round_transition_timestamp - == self.round_sequence._blockchain.last_block.timestamp - ) - else: - assert self.round_sequence._blockchain.height == 0 - with pytest.raises( - ValueError, - match="Trying to access `last_round_transition_timestamp` while no transition has been completed yet.", - ): - _ = self.round_sequence.last_round_transition_timestamp - - @pytest.mark.parametrize("committed", (True, False)) - def test_last_round_transition_height(self, committed: bool) -> None: - """Test 'last_round_transition_height' method.""" - if committed: - self.round_sequence.begin_block( - MagicMock(height=1), MagicMock(), MagicMock() - ) - self.round_sequence.end_block() - self.round_sequence.commit() - assert ( - self.round_sequence.last_round_transition_height - == self.round_sequence._blockchain.height - == 1 - ) - else: - assert self.round_sequence._blockchain.height == 0 - with pytest.raises( - ValueError, - match="Trying to access `last_round_transition_height` while no transition has been completed yet.", - ): - _ = self.round_sequence.last_round_transition_height - - def test_block_before_blockchain_is_init(self, caplog: LogCaptureFixture) -> None: - """Test block received before blockchain initialized.""" - - self.round_sequence.begin_block(MagicMock(height=1), MagicMock(), MagicMock()) - self.round_sequence.end_block() - blockchain = self.round_sequence.blockchain - blockchain._is_init = False - self.round_sequence.blockchain = blockchain - with caplog.at_level(logging.INFO): - self.round_sequence.commit() - expected = "Received block with height 1 before the blockchain was initialized." - assert expected in caplog.text - - @pytest.mark.parametrize("last_round_transition_root_hash", (b"", b"test")) - def test_last_round_transition_root_hash( - self, - last_round_transition_root_hash: bytes, - ) -> None: - """Test 'last_round_transition_root_hash' method.""" - self.round_sequence._last_round_transition_root_hash = ( - last_round_transition_root_hash - ) - - if last_round_transition_root_hash == b"": - with mock.patch.object( - RoundSequence, - "root_hash", - new_callable=mock.PropertyMock, - return_value="test", - ): - assert self.round_sequence.last_round_transition_root_hash == "test" - else: - assert ( - self.round_sequence.last_round_transition_root_hash - == last_round_transition_root_hash - ) - - @pytest.mark.parametrize("tm_height", (None, 1, 5)) - def test_last_round_transition_tm_height(self, tm_height: Optional[int]) -> None: - """Test 'last_round_transition_tm_height' method.""" - if tm_height is None: - with pytest.raises( - ValueError, - match="Trying to access Tendermint's last round transition height before any `end_block` calls.", - ): - _ = self.round_sequence.last_round_transition_tm_height - else: - self.round_sequence.tm_height = tm_height - self.round_sequence.begin_block( - MagicMock(height=1), MagicMock(), MagicMock() - ) - self.round_sequence.end_block() - self.round_sequence.commit() - assert self.round_sequence.last_round_transition_tm_height == tm_height - - @given(one_of(none(), integers())) - def test_tm_height(self, tm_height: int) -> None: - """Test `tm_height` getter and setter.""" - - self.round_sequence.tm_height = tm_height - - if tm_height is None: - with pytest.raises( - ValueError, - match="Trying to access Tendermint's current height before any `end_block` calls.", - ): - _ = self.round_sequence.tm_height - else: - assert ( - self.round_sequence.tm_height - == self.round_sequence._tm_height - == tm_height - ) - - @given(one_of(none(), datetimes())) - def test_block_stall_deadline_expired( - self, block_stall_deadline: datetime.datetime - ) -> None: - """Test 'block_stall_deadline_expired' method.""" - - self.round_sequence._block_stall_deadline = block_stall_deadline - actual = self.round_sequence.block_stall_deadline_expired - - if block_stall_deadline is None: - assert actual is False - else: - expected = datetime.datetime.now() > block_stall_deadline - assert actual is expected - - @pytest.mark.parametrize("begin_height", tuple(range(0, 50, 10))) - @pytest.mark.parametrize("initial_height", tuple(range(0, 11, 5))) - def test_init_chain(self, begin_height: int, initial_height: int) -> None: - """Test 'init_chain' method.""" - for i in range(begin_height): - self.round_sequence._blockchain.add_block( - MagicMock(header=MagicMock(height=i + 1)) - ) - assert self.round_sequence._blockchain.height == begin_height - self.round_sequence.init_chain(initial_height) - assert self.round_sequence._blockchain.height == initial_height - 1 - - @given(offence_tracking()) - @settings(suppress_health_check=[HealthCheck.too_slow]) - def test_track_tm_offences( - self, offences: Tuple[Evidences, LastCommitInfo] - ) -> None: - """Test `_track_tm_offences` method.""" - evidences, last_commit_info = offences - dummy_addr_template = "agent_{i}" - round_sequence = RoundSequence(context=MagicMock(), abci_app_cls=AbciAppTest) - synchronized_data_mock = MagicMock() - round_sequence.setup(synchronized_data_mock, MagicMock()) - round_sequence.enable_slashing() - - expected_offence_status = { - dummy_addr_template.format(i=i): OffenceStatus() - for i in range(len(last_commit_info.votes)) - } - for i, vote_info in enumerate(last_commit_info.votes): - agent_address = dummy_addr_template.format(i=i) - # initialize dummy round sequence's offence status and validator to agent address mapping - round_sequence._offence_status[agent_address] = OffenceStatus() - validator_address = vote_info.validator.address.hex() - round_sequence._validator_to_agent[validator_address] = agent_address - # set expected result - expected_was_down = not vote_info.signed_last_block - expected_offence_status[agent_address].validator_downtime.add( - expected_was_down - ) - - for byzantine_validator in evidences.byzantine_validators: - agent_address = round_sequence._validator_to_agent[ - byzantine_validator.validator.address.hex() - ] - evidence_type = byzantine_validator.evidence_type - expected_offence_status[agent_address].num_unknown_offenses += bool( - evidence_type == EvidenceType.UNKNOWN - ) - expected_offence_status[agent_address].num_double_signed += bool( - evidence_type == EvidenceType.DUPLICATE_VOTE - ) - expected_offence_status[agent_address].num_light_client_attack += bool( - evidence_type == EvidenceType.LIGHT_CLIENT_ATTACK - ) - - round_sequence._track_tm_offences(evidences, last_commit_info) - assert round_sequence._offence_status == expected_offence_status - - @mock.patch.object(abci_base, "ADDRESS_LENGTH", len("agent_i")) - def test_track_app_offences(self) -> None: - """Test `_track_app_offences` method.""" - dummy_addr_template = "agent_{i}" - stub_offending_keepers = [dummy_addr_template.format(i=i) for i in range(2)] - self.round_sequence.enable_slashing() - self.round_sequence._offence_status = { - dummy_addr_template.format(i=i): OffenceStatus() for i in range(4) - } - expected_offence_status = deepcopy(self.round_sequence._offence_status) - - for i in (dummy_addr_template.format(i=i) for i in range(4)): - offended = i in stub_offending_keepers - expected_offence_status[i].blacklisted.add(offended) - expected_offence_status[i].suspected.add(offended) - - with mock.patch.object( - self.round_sequence.latest_synchronized_data.db, - "get", - return_value="".join(stub_offending_keepers), - ): - self.round_sequence._track_app_offences() - assert self.round_sequence._offence_status == expected_offence_status - - @given(builds(SlashingNotConfiguredError, text())) - def test_handle_slashing_not_configured( - self, exc: SlashingNotConfiguredError - ) -> None: - """Test `_handle_slashing_not_configured` method.""" - logging.disable(logging.CRITICAL) - - round_sequence = RoundSequence(context=MagicMock(), abci_app_cls=AbciAppTest) - round_sequence.setup(MagicMock(), MagicMock()) - - assert not round_sequence._slashing_enabled - assert round_sequence.latest_synchronized_data.nb_participants == 0 - round_sequence._handle_slashing_not_configured(exc) - assert not round_sequence._slashing_enabled - - with mock.patch.object( - round_sequence.latest_synchronized_data.db, - "get", - return_value=[i for i in range(4)], - ): - assert round_sequence.latest_synchronized_data.nb_participants == 4 - round_sequence._handle_slashing_not_configured(exc) - assert not round_sequence._slashing_enabled - - logging.disable(logging.NOTSET) - - @pytest.mark.parametrize("_track_offences_raises", (True, False)) - def test_try_track_offences(self, _track_offences_raises: bool) -> None: - """Test `_try_track_offences` method.""" - evidences, last_commit_info = MagicMock(), MagicMock() - self.round_sequence.enable_slashing() - with mock.patch.object( - self.round_sequence, - "_track_app_offences", - ), mock.patch.object( - self.round_sequence, - "_track_tm_offences", - side_effect=SlashingNotConfiguredError if _track_offences_raises else None, - ) as _track_offences_mock, mock.patch.object( - self.round_sequence, "_handle_slashing_not_configured" - ) as _handle_slashing_not_configured_mock: - self.round_sequence._try_track_offences(evidences, last_commit_info) - if _track_offences_raises: - _handle_slashing_not_configured_mock.assert_called_once() - else: - _track_offences_mock.assert_called_once_with( - evidences, last_commit_info - ) - - def test_begin_block_negative_is_finished(self) -> None: - """Test 'begin_block' method, negative case (round sequence is finished).""" - self.round_sequence.abci_app._current_round = None - with pytest.raises( - ABCIAppInternalError, - match="internal error: round sequence is finished, cannot accept new blocks", - ): - self.round_sequence.begin_block(MagicMock(), MagicMock(), MagicMock()) - - def test_begin_block_negative_wrong_phase(self) -> None: - """Test 'begin_block' method, negative case (wrong phase).""" - self.round_sequence._block_construction_phase = MagicMock() - with pytest.raises( - ABCIAppInternalError, - match="internal error: cannot accept a 'begin_block' request.", - ): - self.round_sequence.begin_block(MagicMock(), MagicMock(), MagicMock()) - - def test_begin_block_positive(self) -> None: - """Test 'begin_block' method, positive case.""" - self.round_sequence.begin_block(MagicMock(), MagicMock(), MagicMock()) - - def test_deliver_tx_negative_wrong_phase(self) -> None: - """Test 'begin_block' method, negative (wrong phase).""" - with pytest.raises( - ABCIAppInternalError, - match="internal error: cannot accept a 'deliver_tx' request", - ): - self.round_sequence.deliver_tx(MagicMock()) - - def test_deliver_tx_positive_not_valid(self) -> None: - """Test 'begin_block' method, positive (not valid).""" - self.round_sequence.begin_block(MagicMock(), MagicMock(), MagicMock()) - with mock.patch.object( - self.round_sequence.current_round, "check_transaction", return_value=True - ): - with mock.patch.object( - self.round_sequence.current_round, "process_transaction" - ): - self.round_sequence.deliver_tx(MagicMock()) - - def test_end_block_negative_wrong_phase(self) -> None: - """Test 'end_block' method, negative case (wrong phase).""" - with pytest.raises( - ABCIAppInternalError, - match="internal error: cannot accept a 'end_block' request.", - ): - self.round_sequence.end_block() - - def test_end_block_positive(self) -> None: - """Test 'end_block' method, positive case.""" - self.round_sequence.begin_block(MagicMock(), MagicMock(), MagicMock()) - self.round_sequence.end_block() - - def test_commit_negative_wrong_phase(self) -> None: - """Test 'end_block' method, negative case (wrong phase).""" - with pytest.raises( - ABCIAppInternalError, - match="internal error: cannot accept a 'commit' request.", - ): - self.round_sequence.commit() - - def test_commit_negative_exception(self) -> None: - """Test 'end_block' method, negative case (raise exception).""" - self.round_sequence.begin_block(MagicMock(height=1), MagicMock(), MagicMock()) - self.round_sequence.end_block() - with mock.patch.object( - self.round_sequence._blockchain, "add_block", side_effect=AddBlockError - ): - with pytest.raises(AddBlockError): - self.round_sequence.commit() - - def test_commit_positive_no_change_round(self) -> None: - """Test 'end_block' method, positive (no change round).""" - self.round_sequence.begin_block(MagicMock(height=1), MagicMock(), MagicMock()) - self.round_sequence.end_block() - with mock.patch.object( - self.round_sequence.current_round, - "end_block", - return_value=None, - ): - assert isinstance(self.round_sequence.current_round, ConcreteRoundA) - - def test_commit_positive_with_change_round(self) -> None: - """Test 'end_block' method, positive (with change round).""" - self.round_sequence.begin_block(MagicMock(height=1), MagicMock(), MagicMock()) - self.round_sequence.end_block() - round_result, next_round = MagicMock(), MagicMock() - with mock.patch.object( - self.round_sequence.current_round, - "end_block", - return_value=(round_result, next_round), - ): - self.round_sequence.commit() - assert not isinstance( - self.round_sequence.abci_app._current_round, ConcreteRoundA - ) - assert self.round_sequence.latest_synchronized_data == round_result - - @pytest.mark.parametrize("is_replay", (True, False)) - def test_reset_blockchain(self, is_replay: bool) -> None: - """Test `reset_blockchain` method.""" - self.round_sequence.reset_blockchain(is_replay) - if is_replay: - assert ( - self.round_sequence._block_construction_phase - == RoundSequence._BlockConstructionState.WAITING_FOR_BEGIN_BLOCK - ) - assert self.round_sequence._blockchain.height == 0 - - def last_round_values_updated(self, any_: bool = True) -> bool: - """Check if the values for the last round-related attributes have been updated.""" - seq = self.round_sequence - - current_last_pairs = ( - ( - seq._blockchain.last_block.timestamp, - seq._last_round_transition_timestamp, - ), - (seq._blockchain.height, seq._last_round_transition_height), - (seq.root_hash, seq._last_round_transition_root_hash), - (seq.tm_height, seq._last_round_transition_tm_height), - ) - - if any_: - return any(current == last for current, last in current_last_pairs) - - return all(current == last for current, last in current_last_pairs) - - @mock.patch.object(AbciApp, "process_event") - @mock.patch.object(RoundSequence, "serialized_offence_status") - @pytest.mark.parametrize("end_block_res", (None, (MagicMock(), MagicMock()))) - @pytest.mark.parametrize( - "slashing_enabled, offence_status_", - ( - ( - False, - False, - ), - ( - False, - True, - ), - ( - False, - False, - ), - ( - True, - True, - ), - ), - ) - def test_update_round( - self, - serialized_offence_status_mock: mock.Mock, - process_event_mock: mock.Mock, - end_block_res: Optional[Tuple[BaseSynchronizedData, Any]], - slashing_enabled: bool, - offence_status_: dict, - ) -> None: - """Test '_update_round' method.""" - self.round_sequence.begin_block(MagicMock(height=1), MagicMock(), MagicMock()) - block = self.round_sequence._block_builder.get_block() - self.round_sequence._blockchain.add_block(block) - self.round_sequence._slashing_enabled = slashing_enabled - self.round_sequence._offence_status = offence_status_ - - with mock.patch.object( - self.round_sequence.current_round, "end_block", return_value=end_block_res - ): - self.round_sequence._update_round() - - if end_block_res is None: - assert not self.last_round_values_updated() - process_event_mock.assert_not_called() - return - - assert self.last_round_values_updated(any_=False) - process_event_mock.assert_called_with( - end_block_res[-1], result=end_block_res[0] - ) - - if slashing_enabled: - serialized_offence_status_mock.assert_called_once() - else: - serialized_offence_status_mock.assert_not_called() - - @mock.patch.object(AbciApp, "process_event") - @pytest.mark.parametrize( - "termination_round_result, current_round_result", - [ - (None, None), - (None, (MagicMock(), MagicMock())), - ((MagicMock(), MagicMock()), None), - ((MagicMock(), MagicMock()), (MagicMock(), MagicMock())), - ], - ) - def test_update_round_when_termination_returns( - self, - process_event_mock: mock.Mock, - termination_round_result: Optional[Tuple[BaseSynchronizedData, Any]], - current_round_result: Optional[Tuple[BaseSynchronizedData, Any]], - ) -> None: - """Test '_update_round' method.""" - self.round_sequence.begin_block(MagicMock(height=1), MagicMock(), MagicMock()) - block = self.round_sequence._block_builder.get_block() - self.round_sequence._blockchain.add_block(block) - self.round_sequence.abci_app.add_background_app(STUB_TERMINATION_CONFIG) - self.round_sequence.abci_app.setup() - - with mock.patch.object( - self.round_sequence.current_round, - "end_block", - return_value=current_round_result, - ), mock.patch.object( - ConcreteBackgroundRound, - "end_block", - return_value=termination_round_result, - ): - self.round_sequence._update_round() - - if termination_round_result is None and current_round_result is None: - assert ( - self.round_sequence._last_round_transition_timestamp - != self.round_sequence._blockchain.last_block.timestamp - ) - assert ( - self.round_sequence._last_round_transition_height - != self.round_sequence._blockchain.height - ) - assert ( - self.round_sequence._last_round_transition_root_hash - != self.round_sequence.root_hash - ) - assert ( - self.round_sequence._last_round_transition_tm_height - != self.round_sequence.tm_height - ) - process_event_mock.assert_not_called() - elif termination_round_result is None and current_round_result is not None: - assert ( - self.round_sequence._last_round_transition_timestamp - == self.round_sequence._blockchain.last_block.timestamp - ) - assert ( - self.round_sequence._last_round_transition_height - == self.round_sequence._blockchain.height - ) - assert ( - self.round_sequence._last_round_transition_root_hash - == self.round_sequence.root_hash - ) - assert ( - self.round_sequence._last_round_transition_tm_height - == self.round_sequence.tm_height - ) - process_event_mock.assert_called_with( - current_round_result[-1], - result=current_round_result[0], - ) - elif termination_round_result is not None: - assert ( - self.round_sequence._last_round_transition_timestamp - == self.round_sequence._blockchain.last_block.timestamp - ) - assert ( - self.round_sequence._last_round_transition_height - == self.round_sequence._blockchain.height - ) - assert ( - self.round_sequence._last_round_transition_root_hash - == self.round_sequence.root_hash - ) - assert ( - self.round_sequence._last_round_transition_tm_height - == self.round_sequence.tm_height - ) - process_event_mock.assert_called_with( - termination_round_result[-1], - result=termination_round_result[0], - ) - - self.round_sequence.abci_app.background_apps.clear() - - @pytest.mark.parametrize("restart_from_round", (ConcreteRoundA, MagicMock())) - @pytest.mark.parametrize("serialized_db_state", (None, "serialized state")) - @given(integers()) - def test_reset_state( - self, - restart_from_round: AbstractRound, - serialized_db_state: str, - round_count: int, - ) -> None: - """Tests reset_state""" - with mock.patch.object( - self.round_sequence, - "_reset_to_default_params", - ) as mock_reset, mock.patch.object( - self.round_sequence, "sync_db_and_slashing" - ) as mock_sync_db_and_slashing: - transition_fn = self.round_sequence.abci_app.transition_function - round_id = restart_from_round.auto_round_id() - if restart_from_round in transition_fn: - self.round_sequence.reset_state( - round_id, round_count, serialized_db_state - ) - mock_reset.assert_called() - - if serialized_db_state is None: - mock_sync_db_and_slashing.assert_not_called() - - else: - mock_sync_db_and_slashing.assert_called_once_with( - serialized_db_state - ) - assert ( - self.round_sequence._last_round_transition_root_hash - == self.round_sequence.root_hash - ) - - else: - round_ids = {cls.auto_round_id() for cls in transition_fn} - with pytest.raises( - ABCIAppInternalError, - match=re.escape( - "internal error: Cannot reset state. The Tendermint recovery parameters are incorrect. " - "Did you update the `restart_from_round` with an incorrect round id? " - f"Found {round_id}, but the app's transition function has the following round ids: " - f"{round_ids}.", - ), - ): - self.round_sequence.reset_state( - restart_from_round.auto_round_id(), - round_count, - serialized_db_state, - ) - - def test_reset_to_default_params(self) -> None: - """Tests _reset_to_default_params.""" - # we set some values to the parameters, to make sure that they are not "empty" - self.round_sequence._last_round_transition_timestamp = MagicMock() - self.round_sequence._last_round_transition_height = MagicMock() - self.round_sequence._last_round_transition_root_hash = MagicMock() - self.round_sequence._last_round_transition_tm_height = MagicMock() - self.round_sequence._tm_height = MagicMock() - self._pending_offences = MagicMock() - self._slashing_enabled = MagicMock() - - # we reset them - self.round_sequence._reset_to_default_params() - - # we check whether they have been reset - assert self.round_sequence._last_round_transition_timestamp is None - assert self.round_sequence._last_round_transition_height == 0 - assert self.round_sequence._last_round_transition_root_hash == b"" - assert self.round_sequence._last_round_transition_tm_height is None - assert self.round_sequence._tm_height is None - assert self.round_sequence.pending_offences == set() - assert not self.round_sequence._slashing_enabled - - def test_add_pending_offence(self) -> None: - """Tests add_pending_offence.""" - assert self.round_sequence.pending_offences == set() - mock_offence = MagicMock() - self.round_sequence.add_pending_offence(mock_offence) - assert self.round_sequence.pending_offences == {mock_offence} - - -def test_meta_abci_app_when_instance_not_subclass_of_abstract_round() -> None: - """ - Test instantiation of meta-class when instance not a subclass of AbciApp. - - Since the class is not a subclass of AbciApp, the checks performed by - the meta-class should not apply. - """ - - class MyAbciApp(metaclass=_MetaAbciApp): - pass - - -def test_meta_abci_app_when_final_round_not_subclass_of_degenerate_round() -> None: - """Test instantiation of meta-class when a final round is not a subclass of DegenerateRound.""" - - class FinalRound(AbstractRound, ABC): - """A round class for testing.""" - - payload_class = MagicMock() - synchronized_data_class = MagicMock() - payload_attribute = MagicMock() - round_id = "final_round" - - with pytest.raises( - AEAEnforceError, - match="non-final state.*must have at least one non-timeout transition", - ): - - class MyAbciApp(AbciApp, metaclass=_MetaAbciApp): - initial_round_cls: Type[AbstractRound] = ConcreteRoundA - transition_function: Dict[ - Type[AbstractRound], Dict[str, Type[AbstractRound]] - ] = { - ConcreteRoundA: {"event": FinalRound, "timeout": ConcreteRoundA}, - FinalRound: {}, - } - event_to_timeout = {"timeout": 1.0} - final_states: Set[AppState] = set() - - -def test_synchronized_data_type_on_abci_app_init(caplog: LogCaptureFixture) -> None: - """Test synchronized data access""" - - # NOTE: the synchronized data of a particular AbciApp is only - # updated at the end of a round. However, we want to make sure - # that the instance during the first round of any AbciApp is - # in fact and instance of the locally defined SynchronizedData - - sentinel = object() - - class SynchronizedData(BaseSynchronizedData): - """SynchronizedData""" - - @property - def dummy_attr(self) -> object: - return sentinel - - # this is how it's setup in SharedState.setup, using BaseSynchronizedData - synchronized_data = BaseSynchronizedData(db=AbciAppDB(setup_data={})) - - with mock.patch.object(AbciAppTest, "initial_round_cls") as m: - m.synchronized_data_class = SynchronizedData - abci_app = AbciAppTest(synchronized_data, logging.getLogger(), MagicMock()) - abci_app.setup() - assert isinstance(abci_app.synchronized_data, SynchronizedData) - assert abci_app.synchronized_data.dummy_attr == sentinel - - -def test_get_name() -> None: - """Test the get_name method.""" - - class SomeObject: - @property - def some_property(self) -> Any: - """Some getter.""" - return object() - - assert get_name(SomeObject.some_property) == "some_property" - with pytest.raises(ValueError, match="1 is not a property"): - get_name(1) - - -@pytest.mark.parametrize( - "sender, accused_agent_address, offense_round, offense_type_value, last_transition_timestamp, time_to_live, custom_amount", - ( - ( - "sender", - "test_address", - 90, - 3, - 10, - 2, - 10, - ), - ), -) -def test_pending_offences_payload( - sender: str, - accused_agent_address: str, - offense_round: int, - offense_type_value: int, - last_transition_timestamp: int, - time_to_live: int, - custom_amount: int, -) -> None: - """Test `PendingOffencesPayload`""" - - payload = abci_base.PendingOffencesPayload( - sender, - accused_agent_address, - offense_round, - offense_type_value, - last_transition_timestamp, - time_to_live, - custom_amount, - ) - - assert payload.id_ - assert payload.round_count == abci_base.ROUND_COUNT_DEFAULT - assert payload.sender == sender - assert payload.accused_agent_address == accused_agent_address - assert payload.offense_round == offense_round - assert payload.offense_type_value == offense_type_value - assert payload.last_transition_timestamp == last_transition_timestamp - assert payload.time_to_live == time_to_live - assert payload.custom_amount == custom_amount - assert payload.data == { - "accused_agent_address": accused_agent_address, - "offense_round": offense_round, - "offense_type_value": offense_type_value, - "last_transition_timestamp": last_transition_timestamp, - "time_to_live": time_to_live, - "custom_amount": custom_amount, - } - - -class TestPendingOffencesRound(BaseRoundTestClass): - """Tests for `PendingOffencesRound`.""" - - _synchronized_data_class = BaseSynchronizedData - - @given( - accused_agent_address=sampled_from(list(get_participants())), - offense_round=integers(min_value=0), - offense_type_value=sampled_from( - [value.value for value in OffenseType.__members__.values()] - ), - last_transition_timestamp=floats( - min_value=timegm(datetime.datetime(1971, 1, 1).utctimetuple()), - max_value=timegm(datetime.datetime(8000, 1, 1).utctimetuple()) - 2000, - ), - time_to_live=floats(min_value=1, max_value=2000), - custom_amount=integers(min_value=0), - ) - def test_run( - self, - accused_agent_address: str, - offense_round: int, - offense_type_value: int, - last_transition_timestamp: float, - time_to_live: float, - custom_amount: int, - ) -> None: - """Run tests.""" - - test_round = abci_base.PendingOffencesRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - # initialize the offence status - status_initialization = dict.fromkeys(self.participants, OffenceStatus()) - test_round.context.state.round_sequence.offence_status = status_initialization - - # create the actual and expected value - actual = test_round.context.state.round_sequence.offence_status - expected_invalid = offense_type_value == OffenseType.INVALID_PAYLOAD.value - expected_custom_amount = offense_type_value == OffenseType.CUSTOM.value - expected = deepcopy(status_initialization) - - first_payload, *payloads = [ - abci_base.PendingOffencesPayload( - sender, - accused_agent_address, - offense_round, - offense_type_value, - last_transition_timestamp, - time_to_live, - custom_amount, - ) - for sender in self.participants - ] - - test_round.process_payload(first_payload) - assert test_round.collection == {first_payload.sender: first_payload} - test_round.end_block() - assert actual == expected - - for payload in payloads: - test_round.process_payload(payload) - test_round.end_block() - - expected[accused_agent_address].invalid_payload.add(expected_invalid) - if expected_custom_amount: - expected[accused_agent_address].custom_offences_amount += custom_amount - - assert actual == expected diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_base_rounds.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_base_rounds.py deleted file mode 100644 index 06da2581f..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_base_rounds.py +++ /dev/null @@ -1,668 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the base round classes.""" - -# pylint: skip-file - -import re -from enum import Enum -from typing import FrozenSet, List, Optional, Tuple, Union, cast -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - BaseSynchronizedData, - BaseTxPayload, - TransactionNotValidError, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseOnlyKeeperSendsRoundTest, - DummyCollectDifferentUntilAllRound, - DummyCollectDifferentUntilThresholdRound, - DummyCollectNonEmptyUntilThresholdRound, - DummyCollectSameUntilAllRound, - DummyCollectSameUntilThresholdRound, - DummyCollectionRound, - DummyEvent, - DummyOnlyKeeperSendsRound, - DummyTxPayload, - DummyVotingRound, - MAX_PARTICIPANTS, - _BaseRoundTestClass, - get_dummy_tx_payloads, -) - - -class TestCollectionRound(_BaseRoundTestClass): - """Test class for CollectionRound.""" - - def setup( - self, - ) -> None: - """Setup test.""" - super().setup() - - self.test_round = DummyCollectionRound( - synchronized_data=self.synchronized_data, context=MagicMock() - ) - - def test_serialized_collection(self) -> None: - """Test `serialized_collection` property.""" - assert self.test_round.serialized_collection == {} - - for payload in self.tx_payloads: - self.test_round.process_payload(payload) - - mcs_key = "packages.valory.skills.abstract_round_abci.test_tools.rounds.DummyTxPayload" - expected = { - f"agent_{i}": { - "_metaclass_registry_key": mcs_key, - "id_": self.tx_payloads[i].id_, - "round_count": self.tx_payloads[i].round_count, - "sender": self.tx_payloads[i].sender, - "value": self.tx_payloads[i].value, - "vote": self.tx_payloads[i].vote, - } - for i in range(4) - } - - assert self.test_round.serialized_collection == expected - - def test_run( - self, - ) -> None: - """Run tests.""" - - round_id = DummyCollectionRound.auto_round_id() - - # collection round may set a flag to allow payments from inactive agents (rejoin) - assert self.test_round._allow_rejoin_payloads is False # default - assert ( - self.test_round.accepting_payloads_from - == self.synchronized_data.participants - ) - self.test_round._allow_rejoin_payloads = True - assert ( - self.test_round.accepting_payloads_from - == self.synchronized_data.all_participants - ) - - first_payload, *_ = self.tx_payloads - self.test_round.process_payload(first_payload) - assert self.test_round.collection[first_payload.sender] == first_payload - - with pytest.raises( - ABCIAppInternalError, - match=f"internal error: sender agent_0 has already sent value for round: {round_id}", - ): - self.test_round.process_payload(first_payload) - - with pytest.raises( - ABCIAppInternalError, - match=re.escape( - "internal error: sender not in list of participants: ['agent_0', 'agent_1', 'agent_2', 'agent_3']" - ), - ): - self.test_round.process_payload(DummyTxPayload("sender", "value")) - - with pytest.raises( - TransactionNotValidError, - match=f"sender agent_0 has already sent value for round: {round_id}", - ): - self.test_round.check_payload(first_payload) - - with pytest.raises( - TransactionNotValidError, - match=re.escape( - "sender not in list of participants: ['agent_0', 'agent_1', 'agent_2', 'agent_3']" - ), - ): - self.test_round.check_payload(DummyTxPayload("sender", "value")) - - self._test_payload_with_wrong_round_count(self.test_round) - - -class TestCollectDifferentUntilAllRound(_BaseRoundTestClass): - """Test class for CollectDifferentUntilAllRound.""" - - def test_run( - self, - ) -> None: - """Run Tests.""" - - test_round = DummyCollectDifferentUntilAllRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - round_id = DummyCollectDifferentUntilAllRound.auto_round_id() - - first_payload, *payloads = self.tx_payloads - test_round.process_payload(first_payload) - assert not test_round.collection_threshold_reached - - with pytest.raises( - ABCIAppInternalError, - match=f"internal error: sender agent_0 has already sent value for round: {round_id}", - ): - test_round.process_payload(first_payload) - - with pytest.raises( - TransactionNotValidError, - match=f"sender agent_0 has already sent value for round: {round_id}", - ): - test_round.check_payload(first_payload) - - with pytest.raises( - ABCIAppInternalError, - match="internal error: `CollectDifferentUntilAllRound` encountered a value '.*' that already exists.", - ): - object.__setattr__(first_payload, "sender", "other") - test_round.process_payload(first_payload) - - with pytest.raises( - TransactionNotValidError, - match="`CollectDifferentUntilAllRound` encountered a value '.*' that already exists.", - ): - test_round.check_payload(first_payload) - - for payload in payloads: - assert not test_round.collection_threshold_reached - test_round.process_payload(payload) - - assert test_round.collection_threshold_reached - self._test_payload_with_wrong_round_count(test_round) - - -class TestCollectSameUntilAllRound(_BaseRoundTestClass): - """Test class for CollectSameUntilAllRound.""" - - def test_run( - self, - ) -> None: - """Run Tests.""" - - test_round = DummyCollectSameUntilAllRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - round_id = DummyCollectSameUntilAllRound.auto_round_id() - - first_payload, *payloads = [ - DummyTxPayload( - sender=agent, - value="test", - ) - for agent in sorted(self.participants) - ] - test_round.process_payload(first_payload) - assert not test_round.collection_threshold_reached - - with pytest.raises( - ABCIAppInternalError, - match="1 votes are not enough for `CollectSameUntilAllRound`", - ): - assert test_round.common_payload - - with pytest.raises( - ABCIAppInternalError, - match=f"internal error: sender agent_0 has already sent value for round: {round_id}", - ): - test_round.process_payload(first_payload) - - with pytest.raises( - TransactionNotValidError, - match=f"sender agent_0 has already sent value for round: {round_id}", - ): - test_round.check_payload(first_payload) - - with pytest.raises( - ABCIAppInternalError, - match="internal error: `CollectSameUntilAllRound` encountered a value '.*' " - "which is not the same as the already existing one: '.*'", - ): - bad_payload = DummyTxPayload( - sender="other", - value="other", - ) - test_round.process_payload(bad_payload) - - with pytest.raises( - TransactionNotValidError, - match="`CollectSameUntilAllRound` encountered a value '.*' " - "which is not the same as the already existing one: '.*'", - ): - test_round.check_payload(bad_payload) - - for payload in payloads: - assert not test_round.collection_threshold_reached - test_round.process_payload(payload) - - assert test_round.collection_threshold_reached - assert test_round.common_payload - self._test_payload_with_wrong_round_count(test_round, "test") - - -class TestCollectSameUntilThresholdRound(_BaseRoundTestClass): - """Test CollectSameUntilThresholdRound.""" - - @pytest.mark.parametrize( - "selection_key", - ("dummy_selection_key", tuple(f"dummy_selection_key_{i}" for i in range(2))), - ) - def test_run( - self, - selection_key: Union[str, Tuple[str, ...]], - ) -> None: - """Run tests.""" - - test_round = DummyCollectSameUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - test_round.collection_key = "dummy_collection_key" - test_round.selection_key = selection_key - assert test_round.end_block() is None - - first_payload, *payloads = get_dummy_tx_payloads( - self.participants, value="vote" - ) - test_round.process_payload(first_payload) - - assert not test_round.threshold_reached - with pytest.raises(ABCIAppInternalError, match="not enough votes"): - _ = test_round.most_voted_payload - - for payload in payloads: - test_round.process_payload(payload) - - assert test_round.threshold_reached - assert test_round.most_voted_payload == "vote" - - self._test_payload_with_wrong_round_count(test_round) - - test_round.done_event = DummyEvent.DONE - return_value = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert return_value[-1] == test_round.done_event - - test_round.none_event = DummyEvent.NONE - test_round.collection.clear() - payloads = get_dummy_tx_payloads( - self.participants, value=None, is_value_none=True, is_vote_none=True - ) - for payload in payloads: - test_round.process_payload(payload) - assert test_round.most_voted_payload is None - return_value = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert return_value[-1] == test_round.none_event - - test_round.no_majority_event = DummyEvent.NO_MAJORITY - test_round.collection.clear() - for participant in self.participants: - payload = DummyTxPayload(participant, value=participant) - test_round.process_payload(payload) - return_value = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert return_value[-1] == test_round.no_majority_event - - def test_run_with_none( - self, - ) -> None: - """Run tests.""" - - test_round = DummyCollectSameUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - first_payload, *payloads = get_dummy_tx_payloads( - self.participants, - value=None, - is_value_none=True, - ) - test_round.process_payload(first_payload) - - assert not test_round.threshold_reached - with pytest.raises(ABCIAppInternalError, match="not enough votes"): - _ = test_round.most_voted_payload - - for payload in payloads: - test_round.process_payload(payload) - - assert test_round.threshold_reached - assert test_round.most_voted_payload is None - - -class TestOnlyKeeperSendsRound(_BaseRoundTestClass, BaseOnlyKeeperSendsRoundTest): - """Test OnlyKeeperSendsRound.""" - - @pytest.mark.parametrize( - "payload_key", ("dummy_key", tuple(f"dummy_key_{i}" for i in range(2))) - ) - def test_run( - self, - payload_key: Union[str, Tuple[str, ...]], - ) -> None: - """Run tests.""" - - test_round = DummyOnlyKeeperSendsRound( - synchronized_data=self.synchronized_data.update( - most_voted_keeper_address="agent_0" - ), - context=MagicMock(), - ) - - assert test_round.keeper_payload is None - first_payload, *_ = self.tx_payloads - test_round.process_payload(first_payload) - assert test_round.keeper_payload is not None - - with pytest.raises( - ABCIAppInternalError, - match="internal error: keeper already set the payload.", - ): - test_round.process_payload(first_payload) - - with pytest.raises( - ABCIAppInternalError, - match=re.escape( - "internal error: sender not in list of participants: ['agent_0', 'agent_1', 'agent_2', 'agent_3']" - ), - ): - test_round.process_payload(DummyTxPayload(sender="sender", value="sender")) - - with pytest.raises( - ABCIAppInternalError, match="internal error: agent_1 not elected as keeper." - ): - test_round.process_payload(DummyTxPayload(sender="agent_1", value="sender")) - - with pytest.raises( - TransactionNotValidError, match="keeper payload value already set." - ): - test_round.check_payload(first_payload) - - with pytest.raises( - TransactionNotValidError, - match=re.escape( - "sender not in list of participants: ['agent_0', 'agent_1', 'agent_2', 'agent_3']" - ), - ): - test_round.check_payload(DummyTxPayload(sender="sender", value="sender")) - - with pytest.raises( - TransactionNotValidError, match="agent_1 not elected as keeper." - ): - test_round.check_payload(DummyTxPayload(sender="agent_1", value="sender")) - - self._test_payload_with_wrong_round_count(test_round) - - test_round.done_event = DummyEvent.DONE - test_round.payload_key = payload_key - assert test_round.end_block() - - def test_keeper_payload_is_none( - self, - ) -> None: - """Test keeper payload valur set to none.""" - - keeper = "agent_0" - self._complete_run( - self._test_round( - test_round=DummyOnlyKeeperSendsRound( - synchronized_data=self.synchronized_data.update( - most_voted_keeper_address=keeper, - ), - context=MagicMock(), - ), - keeper_payloads=DummyTxPayload(keeper, None), - synchronized_data_update_fn=lambda _synchronized_data, _test_round: _synchronized_data, - synchronized_data_attr_checks=[], - exit_event="FAIL_EVENT", - ) - ) - - -class TestVotingRound(_BaseRoundTestClass): - """Test VotingRound.""" - - def setup_test_voting_round(self) -> DummyVotingRound: - """Setup test voting round""" - return DummyVotingRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - def test_vote_count(self) -> None: - """Testing agent vote count""" - test_round = self.setup_test_voting_round() - a, b, c, d = self.participants - for agents, vote in [((a, d), True), ((c,), False), ((b,), None)]: - for payload in get_dummy_tx_payloads(frozenset(agents), vote=vote): - test_round.process_payload(payload) - assert dict(test_round.vote_count) == {True: 2, False: 1, None: 1} - - self._test_payload_with_wrong_round_count(test_round) - - @pytest.mark.parametrize("vote", [True, False, None]) - def test_threshold(self, vote: Optional[bool]) -> None: - """Runs threshold test.""" - - test_round = self.setup_test_voting_round() - test_round.collection_key = "dummy_collection_key" - test_round.done_event = DummyEvent.DONE - test_round.negative_event = DummyEvent.NEGATIVE - test_round.none_event = DummyEvent.NONE - - expected_threshold = { - True: lambda: test_round.positive_vote_threshold_reached, - False: lambda: test_round.negative_vote_threshold_reached, - None: lambda: test_round.none_vote_threshold_reached, - }[vote] - - expected_event = { - True: test_round.done_event, - False: test_round.negative_event, - None: test_round.none_event, - }[vote] - - first_payload, *payloads = get_dummy_tx_payloads(self.participants, vote=vote) - test_round.process_payload(first_payload) - assert test_round.end_block() is None - assert not expected_threshold() - for payload in payloads: - test_round.process_payload(payload) - assert expected_threshold() - return_value = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert return_value[-1] == expected_event - - def test_end_round_no_majority(self) -> None: - """Test end round""" - - test_round = self.setup_test_voting_round() - test_round.no_majority_event = DummyEvent.NO_MAJORITY - for i, participant in enumerate(self.participants): - payload = DummyTxPayload(participant, value=participant, vote=bool(i % 2)) - test_round.process_payload(payload) - return_value = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert return_value[-1] == test_round.no_majority_event - - def test_invalid_vote_payload_count(self) -> None: - """Testing agent vote count with invalid payload.""" - test_round = self.setup_test_voting_round() - a, b, c, d = self.participants - - class InvalidPayload(BaseTxPayload): - """InvalidPayload""" - - def get_dummy_tx_payloads_( - participants: FrozenSet[str], - ) -> List[BaseTxPayload]: - """Returns a list of DummyTxPayload objects.""" - return [InvalidPayload(sender=agent) for agent in sorted(participants)] - - for agents in [(a, d), (c,), (b,)]: - for payload in get_dummy_tx_payloads_(frozenset(agents)): - test_round.process_payload(payload) - - with pytest.raises(ValueError): - test_round.vote_count - - -class TestCollectDifferentUntilThresholdRound(_BaseRoundTestClass): - """Test CollectDifferentUntilThresholdRound.""" - - @pytest.mark.parametrize( - "required_confirmations", (MAX_PARTICIPANTS, MAX_PARTICIPANTS + 1) - ) - def test_run( - self, - required_confirmations: int, - ) -> None: - """Run tests.""" - - test_round = DummyCollectDifferentUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - test_round.block_confirmations = 0 - test_round.required_block_confirmations = required_confirmations - test_round.collection_key = "collection_key" - test_round.done_event = 0 - assert ( - test_round.synchronized_data.consensus_threshold <= required_confirmations - ), "Incorrect test parametrization: required confirmations cannot be set with a smalled value than the consensus threshold" - - first_payload, *payloads = get_dummy_tx_payloads(self.participants, vote=False) - test_round.process_payload(first_payload) - - assert not test_round.collection_threshold_reached - for payload in payloads: - test_round.process_payload(payload) - res = test_round.end_block() - assert test_round.block_confirmations <= required_confirmations - assert res is None - assert test_round.collection_threshold_reached - payloads_since_consensus = 2 - confirmations_remaining = required_confirmations - payloads_since_consensus - for _ in range(confirmations_remaining): - res = test_round.end_block() - assert test_round.block_confirmations <= required_confirmations - assert res is None - - res = test_round.end_block() - assert test_round.block_confirmations > required_confirmations - assert res is not None - assert res[1] == test_round.done_event - - assert test_round.collection_threshold_reached - self._test_payload_with_wrong_round_count(test_round) - - def test_end_round(self) -> None: - """Test end round""" - - test_round = DummyCollectDifferentUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - test_round.collection_key = "dummy_collection_key" - test_round.done_event = DummyEvent.DONE - - assert test_round.end_block() is None - for participant in self.participants: - payload = DummyTxPayload(participant, value=participant) - test_round.process_payload(payload) - return_value = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert return_value[-1] == test_round.done_event - - -class TestCollectNonEmptyUntilThresholdRound(_BaseRoundTestClass): - """Test `CollectNonEmptyUntilThresholdRound`.""" - - def test_get_non_empty_values(self) -> None: - """Test `_get_non_empty_values`.""" - test_round = DummyCollectNonEmptyUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - payloads = get_dummy_tx_payloads(self.participants) - none_payload_idx = 3 - object.__setattr__(payloads[none_payload_idx], "value", None) - for payload in payloads: - test_round.process_payload(payload) - - non_empty_values = test_round._get_non_empty_values() - assert non_empty_values == { - tuple(sorted(self.participants))[i]: (f"agent_{i}", False) - if i != none_payload_idx - else (False,) - for i in range(4) - } - - self._test_payload_with_wrong_round_count(test_round) - - def test_process_payload(self) -> None: - """Test `process_payload`.""" - test_round = DummyCollectNonEmptyUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - first_payload, *payloads = get_dummy_tx_payloads(self.participants) - test_round.process_payload(first_payload) - - assert not test_round.collection_threshold_reached - for payload in payloads: - test_round.process_payload(payload) - - assert test_round.collection_threshold_reached - - @pytest.mark.parametrize( - "selection_key", - ("dummy_selection_key", tuple(f"dummy_selection_key_{i}" for i in range(2))), - ) - @pytest.mark.parametrize( - "is_value_none, expected_event", - ((True, DummyEvent.NONE), (False, DummyEvent.DONE)), - ) - def test_end_block( - self, - selection_key: Union[str, Tuple[str, ...]], - is_value_none: bool, - expected_event: str, - ) -> None: - """Test `end_block` when collection threshold is reached.""" - test_round = DummyCollectNonEmptyUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - test_round.selection_key = selection_key - payloads = get_dummy_tx_payloads( - self.participants, is_value_none=is_value_none, is_vote_none=True - ) - for payload in payloads: - test_round.process_payload(payload) - - test_round.collection = {f"test_{i}": payloads[i] for i in range(len(payloads))} - test_round.collection_key = "test" - test_round.done_event = DummyEvent.DONE - test_round.none_event = DummyEvent.NONE - - res = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert res[0].db == self.synchronized_data.db - assert res[1] == expected_event diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_behaviours.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_behaviours.py deleted file mode 100644 index 1065189c4..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_behaviours.py +++ /dev/null @@ -1,951 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the behaviours.py module of the skill.""" -# pylint: skip-file - -import platform -from abc import ABC -from calendar import timegm -from datetime import datetime -from pathlib import Path -from typing import Any, Dict, Generator, Optional, Tuple -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from hypothesis import given, settings -from hypothesis import strategies as st - -from packages.valory.skills.abstract_round_abci import PUBLIC_ID -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciApp, - AbstractRound, - BaseSynchronizedData, - BaseTxPayload, - DegenerateRound, - EventType, - OffenseType, - PendingOffense, - RoundSequence, -) -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - BaseBehaviour, - DegenerateBehaviour, - TmManager, -) -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - PendingOffencesBehaviour, - _MetaRoundBehaviour, -) -from packages.valory.skills.abstract_round_abci.models import TendermintRecoveryParams -from packages.valory.skills.abstract_round_abci.tests.conftest import profile_name - - -BEHAVIOUR_A_ID = "behaviour_a" -BEHAVIOUR_B_ID = "behaviour_b" -BEHAVIOUR_C_ID = "behaviour_c" -CONCRETE_BACKGROUND_BEHAVIOUR_ID = "background_behaviour" -ROUND_A_ID = "round_a" -ROUND_B_ID = "round_b" -CONCRETE_BACKGROUND_ROUND_ID = "background_round" - - -settings.load_profile(profile_name) - - -def test_skill_public_id() -> None: - """Test skill module public ID""" - - assert PUBLIC_ID.name == Path(__file__).parents[1].name - assert PUBLIC_ID.author == Path(__file__).parents[3].name - - -class RoundA(AbstractRound): - """Round A.""" - - round_id = ROUND_A_ID - payload_class = BaseTxPayload - payload_attribute = "" - synchronized_data_class = BaseSynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, EventType]]: - """End block.""" - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - - -class RoundB(AbstractRound): - """Round B.""" - - round_id = ROUND_B_ID - payload_class = BaseTxPayload - payload_attribute = "" - synchronized_data_class = BaseSynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, EventType]]: - """End block.""" - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - - -class ConcreteBackgroundRound(AbstractRound): - """Concrete Background Round.""" - - round_id = ROUND_B_ID - payload_class = BaseTxPayload - payload_attribute = "" - synchronized_data_class = BaseSynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, EventType]]: - """End block.""" - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - - -class BehaviourA(BaseBehaviour): - """Dummy behaviour.""" - - behaviour_id = BEHAVIOUR_A_ID - matching_round = RoundA - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize behaviour.""" - super().__init__(*args, **kwargs) - self.count = 0 - - def setup(self) -> None: - """Setup behaviour.""" - self.count += 1 - - def async_act(self) -> Generator: - """Dummy act method.""" - yield - - -class BehaviourB(BaseBehaviour): - """Dummy behaviour.""" - - behaviour_id = BEHAVIOUR_B_ID - matching_round = RoundB - - def async_act(self) -> Generator: - """Dummy act method.""" - yield - - -class BehaviourC(BaseBehaviour, ABC): - """Dummy behaviour.""" - - matching_round = MagicMock() - - -def test_auto_behaviour_id() -> None: - """Test that the 'auto_behaviour_id()' method works as expected.""" - - assert BehaviourB.auto_behaviour_id() == BEHAVIOUR_B_ID - assert BehaviourB.behaviour_id == BEHAVIOUR_B_ID - assert BehaviourC.auto_behaviour_id() == "behaviour_c" - assert isinstance(BehaviourC.behaviour_id, property) - - -class ConcreteBackgroundBehaviour(BaseBehaviour): - """Dummy behaviour.""" - - behaviour_id = CONCRETE_BACKGROUND_BEHAVIOUR_ID - matching_round = ConcreteBackgroundRound - - def async_act(self) -> Generator: - """Dummy act method.""" - yield - - -class ConcreteAbciApp(AbciApp): - """Concrete ABCI App.""" - - initial_round_cls = RoundA - transition_function = {RoundA: {MagicMock(): RoundB}} - event_to_timeout: Dict = {} - - -class ConcreteRoundBehaviour(AbstractRoundBehaviour): - """Concrete round behaviour.""" - - abci_app_cls = ConcreteAbciApp - behaviours = {BehaviourA, BehaviourB} # type: ignore - initial_behaviour_cls = BehaviourA - background_behaviours_cls = {ConcreteBackgroundBehaviour} # type: ignore - - -class TestAbstractRoundBehaviour: - """Test 'AbstractRoundBehaviour' class.""" - - def setup(self) -> None: - """Set up the tests.""" - self.round_sequence_mock = MagicMock() - context_mock = MagicMock(params=MagicMock()) - context_mock.state.round_sequence = self.round_sequence_mock - context_mock.state.round_sequence.syncing_up = False - self.round_sequence_mock.block_stall_deadline_expired = False - self.behaviour = ConcreteRoundBehaviour(name="", skill_context=context_mock) - - @pytest.mark.parametrize("use_termination", (True, False)) - def test_setup(self, use_termination: bool) -> None: - """Test 'setup' method.""" - assert self.behaviour.background_behaviours == set() - self.behaviour.context.params.use_termination = use_termination - self.behaviour.setup() - assert self.behaviour.background_behaviours_cls == {ConcreteBackgroundBehaviour} - assert ( - isinstance( - self.behaviour.background_behaviours.pop(), ConcreteBackgroundBehaviour - ) - if use_termination - else self.behaviour.background_behaviours == set() - ) - - def test_teardown(self) -> None: - """Test 'teardown' method.""" - self.behaviour.teardown() - - def test_current_behaviour_return_none(self) -> None: - """Test 'current_behaviour' property return None.""" - assert self.behaviour.current_behaviour is None - - def test_act_current_behaviour_name_is_none(self) -> None: - """Test 'act' with current behaviour None.""" - self.behaviour.tm_manager = self.behaviour.instantiate_behaviour_cls(TmManager) # type: ignore - self.behaviour.current_behaviour = None - with mock.patch.object(self.behaviour, "_process_current_round"): - self.behaviour.act() - - @pytest.mark.parametrize( - "no_round, error", - ( - ( - True, - "Behaviour 'behaviour_without_round' specifies unknown 'unknown' as a matching round. " - "Please make sure that the round is implemented and belongs to the FSM. " - "If 'behaviour_without_round' is a background behaviour, please make sure that it is set correctly, " - "by overriding the corresponding attribute of the chained skill's behaviour.", - ), - (False, "round round_1 is not a matching round of any behaviour"), - ), - ) - def test_check_matching_round_consistency_no_behaviour( - self, no_round: bool, error: str - ) -> None: - """Test classmethod '_check_matching_round_consistency', when no behaviour or round is specified.""" - rounds = [ - MagicMock(**{"auto_round_id.return_value": f"round_{i}"}) for i in range(3) - ] - mock_behaviours = [ - MagicMock(matching_round=round, behaviour_id=f"behaviour_{i}") - for i, round in enumerate(rounds[2:]) - ] - if no_round: - mock_behaviours.append( - MagicMock( - matching_round="unknown", behaviour_id="behaviour_without_round" - ) - ) - - with mock.patch.object( - _MetaRoundBehaviour, "_check_all_required_classattributes_are_set" - ), mock.patch.object( - _MetaRoundBehaviour, "_check_behaviour_id_uniqueness" - ), mock.patch.object( - _MetaRoundBehaviour, "_check_initial_behaviour_in_set_of_behaviours" - ), pytest.raises( - ABCIAppInternalError, - match=error, - ): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = MagicMock( - get_all_round_classes=lambda _, include_background_rounds: rounds, - final_states={ - rounds[0], - }, - ) - behaviours = mock_behaviours # type: ignore - initial_behaviour_cls = MagicMock() - - def test_check_matching_round_consistency(self) -> None: - """Test classmethod '_check_matching_round_consistency', negative case.""" - rounds = [ - MagicMock(**{"auto_round_id.return_value": f"round_{i}"}) for i in range(3) - ] - mock_behaviours = [ - MagicMock(matching_round=round, behaviour_id=f"behaviour_{i}") - for i, round in enumerate(rounds) - ] - - with mock.patch.object( - _MetaRoundBehaviour, "_check_all_required_classattributes_are_set" - ), mock.patch.object( - _MetaRoundBehaviour, "_check_behaviour_id_uniqueness" - ), mock.patch.object( - _MetaRoundBehaviour, "_check_initial_behaviour_in_set_of_behaviours" - ), pytest.raises( - ABCIAppInternalError, - match="internal error: round round_0 is a final round it shouldn't have any matching behaviours", - ): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = MagicMock( - get_all_round_classes=lambda _, include_background_rounds: rounds, - final_states={ - rounds[0], - }, - ) - behaviours = mock_behaviours # type: ignore - initial_behaviour_cls = MagicMock() - - @pytest.mark.parametrize("behaviour_cls", (set(), {MagicMock()})) - def test_check_matching_round_consistency_with_bg_rounds( - self, behaviour_cls: set - ) -> None: - """Test classmethod '_check_matching_round_consistency' when a background behaviour class is set.""" - rounds = [ - MagicMock(**{"auto_round_id.return_value": f"round_{i}"}) for i in range(3) - ] - mock_behaviours = ( - [ - MagicMock(matching_round=round_, behaviour_id=f"behaviour_{i}") - for i, round_ in enumerate(rounds[1:]) - ] - if behaviour_cls - else [] - ) - - with mock.patch.object( - _MetaRoundBehaviour, "_check_all_required_classattributes_are_set" - ), mock.patch.object( - _MetaRoundBehaviour, "_check_behaviour_id_uniqueness" - ), mock.patch.object( - _MetaRoundBehaviour, "_check_initial_behaviour_in_set_of_behaviours" - ): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = MagicMock( - get_all_round_classes=lambda _, include_background_rounds: rounds - if include_background_rounds - else [], - final_states={ - rounds[0], - } - if behaviour_cls - else {}, - ) - behaviours = mock_behaviours # type: ignore - initial_behaviour_cls = MagicMock() - background_behaviours_cls = behaviour_cls - - def test_get_behaviour_id_to_behaviour_mapping_negative(self) -> None: - """Test classmethod '_get_behaviour_id_to_behaviour_mapping', negative case.""" - behaviour_id = "behaviour_id" - behaviour_1 = MagicMock(**{"auto_behaviour_id.return_value": behaviour_id}) - behaviour_2 = MagicMock(**{"auto_behaviour_id.return_value": behaviour_id}) - - with pytest.raises( - ValueError, - match=f"cannot have two behaviours with the same id; got {behaviour_2} and {behaviour_1} both with id '{behaviour_id}'", - ): - with mock.patch.object(_MetaRoundBehaviour, "_check_consistency"): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = MagicMock - behaviours = [behaviour_1, behaviour_2] # type: ignore - initial_behaviour_cls = MagicMock() - - MyRoundBehaviour(name=MagicMock(), skill_context=MagicMock()) - - def test_get_round_to_behaviour_mapping_two_behaviours_same_round(self) -> None: - """Test classmethod '_get_round_to_behaviour_mapping' when two different behaviours point to the same round.""" - behaviour_id_1 = "behaviour_id_1" - behaviour_id_2 = "behaviour_id_2" - round_cls = RoundA - round_id = round_cls.auto_round_id() - behaviour_1 = MagicMock( - matching_round=round_cls, - **{"auto_behaviour_id.return_value": behaviour_id_1}, - ) - behaviour_2 = MagicMock( - matching_round=round_cls, - **{"auto_behaviour_id.return_value": behaviour_id_2}, - ) - - with pytest.raises( - ValueError, - match=f"the behaviours '{behaviour_2.auto_behaviour_id()}' and '{behaviour_1.auto_behaviour_id()}' point to the same matching round '{round_id}'", - ): - with mock.patch.object(_MetaRoundBehaviour, "_check_consistency"): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = ConcreteAbciApp - behaviours = [behaviour_1, behaviour_2] # type: ignore - initial_behaviour_cls = behaviour_1 - - MyRoundBehaviour(name=MagicMock(), skill_context=MagicMock()) - - def test_get_round_to_behaviour_mapping_with_final_rounds(self) -> None: - """Test classmethod '_get_round_to_behaviour_mapping' with final rounds.""" - - class FinalRound(DegenerateRound, ABC): - """A final round for testing.""" - - behaviour_id_1 = "behaviour_id_1" - behaviour_1 = MagicMock(behaviour_id=behaviour_id_1, matching_round=RoundA) - - class AbciAppTest(AbciApp): - """Abci App for testing.""" - - initial_round_cls = RoundA - transition_function = {RoundA: {MagicMock(): FinalRound}, FinalRound: {}} - event_to_timeout: Dict = {} - final_states = {FinalRound} - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = AbciAppTest - behaviours = {behaviour_1} - initial_behaviour_cls = behaviour_1 - matching_round = FinalRound - - behaviour = MyRoundBehaviour(name=MagicMock(), skill_context=MagicMock()) - final_behaviour = behaviour._round_to_behaviour[FinalRound] - assert issubclass(final_behaviour, DegenerateBehaviour) - assert ( - final_behaviour.auto_behaviour_id() - == f"degenerate_behaviour_{FinalRound.auto_round_id()}" - ) - - def test_check_behaviour_id_uniqueness_negative(self) -> None: - """Test metaclass method '_check_consistency', negative case.""" - behaviour_id = "behaviour_id" - behaviour_1_cls_name = "Behaviour1" - behaviour_2_cls_name = "Behaviour2" - behaviour_1 = MagicMock( - __name__=behaviour_1_cls_name, - **{"auto_behaviour_id.return_value": behaviour_id}, - ) - behaviour_2 = MagicMock( - __name__=behaviour_2_cls_name, - **{"auto_behaviour_id.return_value": behaviour_id}, - ) - - with pytest.raises( - ABCIAppInternalError, - match=rf"behaviours \['{behaviour_1_cls_name}', '{behaviour_2_cls_name}'\] have the same behaviour id '{behaviour_id}'", - ): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = MagicMock - behaviours = [behaviour_1, behaviour_2] # type: ignore - initial_behaviour_cls = MagicMock() - - def test_check_consistency_two_behaviours_same_round(self) -> None: - """Test metaclass method '_check_consistency' when two different behaviours point to the same round.""" - behaviour_id_1 = "behaviour_id_1" - behaviour_id_2 = "behaviour_id_2" - round_cls = RoundA - round_id = round_cls.auto_round_id() - behaviour_1 = MagicMock( - matching_round=round_cls, - **{"auto_behaviour_id.return_value": "behaviour_id_1"}, - ) - behaviour_2 = MagicMock( - matching_round=round_cls, - **{"auto_behaviour_id.return_value": "behaviour_id_2"}, - ) - - with pytest.raises( - ABCIAppInternalError, - match=rf"internal error: behaviours \['{behaviour_id_1}', '{behaviour_id_2}'\] have the same matching round '{round_id}'", - ): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = ConcreteAbciApp - behaviours = [behaviour_1, behaviour_2] # type: ignore - initial_behaviour_cls = behaviour_1 - - def test_check_initial_behaviour_in_set_of_behaviours_negative_case(self) -> None: - """Test classmethod '_check_initial_behaviour_in_set_of_behaviours' when initial behaviour is NOT in the set.""" - behaviour_1 = MagicMock( - matching_round=MagicMock(), - **{"auto_behaviour_id.return_value": "behaviour_id_1"}, - ) - behaviour_2 = MagicMock( - matching_round=MagicMock(), - **{"auto_behaviour_id.return_value": "behaviour_id_2"}, - ) - - with pytest.raises( - ABCIAppInternalError, - match=f"initial behaviour {behaviour_2.auto_behaviour_id()} is not in the set of behaviours", - ): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = ConcreteAbciApp - behaviours = {behaviour_1} - initial_behaviour_cls = behaviour_2 - - def test_act_no_round_change(self) -> None: - """Test the 'act' method of the behaviour, with no round change.""" - self.round_sequence_mock.current_round = RoundA(MagicMock(), MagicMock()) - self.round_sequence_mock.current_round_height = 0 - - # check that after setup(), current behaviour is initial behaviour - self.behaviour.setup() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - - with mock.patch.object( - self.behaviour.current_behaviour, "clean_up" - ) as clean_up_mock: - # check that after act(), current behaviour is initial behaviour and `clean_up()` has not been called - self.behaviour.act() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - clean_up_mock.assert_not_called() - - # check that once the flag done is set, the `clean_up()` has been called - # and `current_behaviour` is set to `None`. - self.behaviour.current_behaviour.set_done() - self.behaviour.act() - assert self.behaviour.current_behaviour is None - clean_up_mock.assert_called_once() - - def test_act_behaviour_setup(self) -> None: - """Test the 'act' method of the FSM behaviour triggers setup() of the behaviour.""" - self.round_sequence_mock.current_round = RoundA(MagicMock(), MagicMock()) - self.round_sequence_mock.current_round_height = 0 - - # check that after setup(), current behaviour is initial behaviour - self.behaviour.setup() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - - assert self.behaviour.current_behaviour.count == 0 - - with mock.patch.object( - self.behaviour.current_behaviour, "clean_up" - ) as clean_up_mock: - # check that after act() first time, a call to setup has been made - self.behaviour.act() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - assert self.behaviour.current_behaviour.count == 1 - - # check that after act() second time, no further call to setup - self.behaviour.act() - assert self.behaviour.current_behaviour.count == 1 - - # check that the `clean_up()` has not been called - clean_up_mock.assert_not_called() - - def test_act_with_round_change(self) -> None: - """Test the 'act' method of the behaviour, with round change.""" - self.round_sequence_mock.current_round = RoundA(MagicMock(), MagicMock()) - self.round_sequence_mock.current_round_height = 0 - - # check that after setup(), current behaviour is initial behaviour - self.behaviour.setup() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - - # check that after act(), current behaviour is initial behaviour - with mock.patch.object( - self.behaviour.current_behaviour, "clean_up" - ) as clean_up_mock: - self.behaviour.act() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - clean_up_mock.assert_not_called() - - # change the round - self.round_sequence_mock.current_round = RoundB(MagicMock(), MagicMock()) - self.round_sequence_mock.current_round_height = ( - self.round_sequence_mock.current_round_height + 1 - ) - - # check that if the round is changed, the behaviour transition is performed and the clean-up is called - self.behaviour.act() - assert isinstance(self.behaviour.current_behaviour, BehaviourB) - clean_up_mock.assert_called_once() - - def test_act_with_round_change_after_current_behaviour_is_none(self) -> None: - """Test the 'act' method of the behaviour, with round change, after cur behaviour is none.""" - self.behaviour.tm_manager = self.behaviour.instantiate_behaviour_cls(TmManager) # type: ignore - self.round_sequence_mock.current_round = RoundA(MagicMock(), MagicMock()) - self.round_sequence_mock.current_round_height = 0 - - # instantiate behaviour - self.behaviour.current_behaviour = self.behaviour.instantiate_behaviour_cls( - BehaviourA - ) - - with mock.patch.object( - self.behaviour.current_behaviour, "clean_up" - ) as clean_up_mock: - # check that after act(), current behaviour is same behaviour - self.behaviour.act() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - clean_up_mock.assert_not_called() - - # check that after the behaviour is done, current behaviour is None - self.behaviour.current_behaviour.set_done() - self.behaviour.act() - assert self.behaviour.current_behaviour is None - clean_up_mock.assert_called_once() - - # change the round - self.round_sequence_mock.current_round = RoundB(MagicMock(), MagicMock()) - self.round_sequence_mock.current_round_height = ( - self.round_sequence_mock.current_round_height + 1 - ) - - # check that if the round is changed, the behaviour transition is taken - self.behaviour.act() - assert isinstance(self.behaviour.current_behaviour, BehaviourB) - clean_up_mock.assert_called_once() - - @mock.patch.object( - AbstractRoundBehaviour, - "_process_current_round", - ) - @mock.patch.object( - TmManager, - "tm_communication_unhealthy", - new_callable=mock.PropertyMock, - return_value=False, - ) - @mock.patch.object( - TmManager, - "is_acting", - new_callable=mock.PropertyMock, - return_value=False, - ) - @pytest.mark.parametrize("expected_termination_acting", (True, False)) - def test_termination_behaviour_acting( - self, - _: mock._patch, - __: mock._patch, - ___: mock._patch, - expected_termination_acting: bool, - ) -> None: - """Test if the termination background behaviour is acting only when it should.""" - self.behaviour.context.params.use_termination = expected_termination_acting - self.behaviour.setup() - if expected_termination_acting: - with mock.patch.object( - ConcreteBackgroundBehaviour, - "act_wrapper", - ) as mock_background_act: - self.behaviour.act() - mock_background_act.assert_called() - else: - assert self.behaviour.background_behaviours == set() - - @mock.patch.object( - AbstractRoundBehaviour, - "_process_current_round", - ) - @pytest.mark.parametrize( - ("mock_tm_communication_unhealthy", "mock_is_acting", "expected_fix"), - [ - (True, True, True), - (False, True, True), - (True, False, True), - (False, False, False), - ], - ) - def test_try_fix_call( - self, - _: mock._patch, - mock_tm_communication_unhealthy: bool, - mock_is_acting: bool, - expected_fix: bool, - ) -> None: - """Test that `try_fix` is called when necessary.""" - self.behaviour.tm_manager = self.behaviour.instantiate_behaviour_cls(TmManager) # type: ignore - with mock.patch.object( - TmManager, - "tm_communication_unhealthy", - new_callable=mock.PropertyMock, - return_value=mock_tm_communication_unhealthy, - ), mock.patch.object( - TmManager, - "is_acting", - new_callable=mock.PropertyMock, - return_value=mock_is_acting, - ), mock.patch.object( - TmManager, - "try_fix", - ) as mock_try_fix: - self.behaviour.act() - if expected_fix: - mock_try_fix.assert_called() - else: - mock_try_fix.assert_not_called() - - -def test_meta_round_behaviour_when_instance_not_subclass_of_abstract_round_behaviour() -> ( - None -): - """Test instantiation of meta class when instance not a subclass of abstract round behaviour.""" - - class MyRoundBehaviour(metaclass=_MetaRoundBehaviour): - pass - - -def test_abstract_round_behaviour_instantiation_without_attributes_raises_error() -> ( - None -): - """Test that definition of concrete subclass of AbstractRoundBehavior without attributes raises error.""" - with pytest.raises(ABCIAppInternalError): - - class MyRoundBehaviour(AbstractRoundBehaviour): - pass - - -def test_abstract_round_behaviour_matching_rounds_not_covered() -> None: - """Test that definition of concrete subclass of AbstractRoundBehavior when matching round not covered.""" - with pytest.raises(ABCIAppInternalError): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = ConcreteAbciApp - behaviours = {BehaviourA} - initial_behaviour_cls = BehaviourA - - -@mock.patch.object( - BaseBehaviour, - "tm_communication_unhealthy", - new_callable=mock.PropertyMock, - return_value=False, -) -def test_self_loops_in_abci_app_reinstantiate_behaviour(_: mock._patch) -> None: - """Test that a self-loop transition in the AbciApp will trigger a transition in the round behaviour.""" - event = MagicMock() - - class AbciAppTest(AbciApp): - initial_round_cls = RoundA - transition_function = {RoundA: {event: RoundA}} - - class RoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = AbciAppTest - behaviours = {BehaviourA} - initial_behaviour_cls = BehaviourA - - round_sequence = RoundSequence(MagicMock(), AbciAppTest) - round_sequence.end_sync() - round_sequence.setup(MagicMock(), MagicMock()) - context_mock = MagicMock() - context_mock.state.round_sequence = round_sequence - behaviour = RoundBehaviour(name="", skill_context=context_mock) - behaviour.setup() - - behaviour_1 = behaviour.current_behaviour - assert isinstance(behaviour_1, BehaviourA) - - round_sequence.abci_app.process_event(event) - - behaviour.act() - behaviour_2 = behaviour.current_behaviour - assert isinstance(behaviour_2, BehaviourA) - assert id(behaviour_1) != id(behaviour_2) - assert behaviour_1 != behaviour_2 - - -class LongRunningBehaviour(BaseBehaviour): - """A behaviour that runs forevever.""" - - behaviour_id = "long_running_behaviour" - matching_round = RoundA - - def async_act(self) -> Generator: - """An act method that simply cycles forever.""" - while True: - # cycle forever - yield - - -def test_reset_should_be_performed_when_tm_unhealthy() -> None: - """Test that hard reset is performed while a behaviour is running, and tendermint communication is unhealthy.""" - event = MagicMock() - - class AbciAppTest(AbciApp): - initial_round_cls = RoundA - transition_function = {RoundA: {event: RoundA}} - - class RoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = AbciAppTest - behaviours = {LongRunningBehaviour} # type: ignore - initial_behaviour_cls = LongRunningBehaviour - - round_sequence = RoundSequence(MagicMock(), AbciAppTest) - round_sequence.end_sync() - round_sequence.setup(MagicMock(), MagicMock()) - context_mock = MagicMock() - context_mock.state.round_sequence = round_sequence - tm_recovery_params = TendermintRecoveryParams( - reset_from_round=RoundA.auto_round_id() - ) - context_mock.state.get_acn_result = MagicMock(return_value=tm_recovery_params) - context_mock.params.ipfs_domain_name = None - behaviour = RoundBehaviour(name="", skill_context=context_mock) - behaviour.setup() - - current_behaviour = behaviour.current_behaviour - assert isinstance(current_behaviour, LongRunningBehaviour) - - # upon entering the behaviour, the tendermint node communication is working well - with mock.patch.object( - RoundSequence, - "block_stall_deadline_expired", - new_callable=mock.PropertyMock, - return_value=False, - ): - behaviour.act() - - def dummy_num_peers( - timeout: Optional[float] = None, - ) -> Generator[None, None, Optional[int]]: - """A dummy method for num_active_peers.""" - # a None response is acceptable here, because tendermint is not healthy - return None - yield - - def dummy_reset_tendermint_with_wait( - on_startup: bool = False, - is_recovery: bool = False, - ) -> Generator[None, None, bool]: - """A dummy method for reset_tendermint_with_wait.""" - # we assume the reset goes through successfully - return True - yield - - # at this point LongRunningBehaviour is running - # while the behaviour is running, the tendermint node - # becomes unhealthy, we expect the node to be reset - with mock.patch.object( - RoundSequence, - "block_stall_deadline_expired", - new_callable=mock.PropertyMock, - return_value=True, - ), mock.patch.object( - BaseBehaviour, - "num_active_peers", - side_effect=dummy_num_peers, - ), mock.patch.object( - BaseBehaviour, - "reset_tendermint_with_wait", - side_effect=dummy_reset_tendermint_with_wait, - ) as mock_reset_tendermint: - behaviour.tm_manager.synchronized_data.max_participants = 3 # type: ignore - assert behaviour.tm_manager is not None - behaviour.tm_manager.gentle_reset_attempted = True - behaviour.act() - mock_reset_tendermint.assert_called() - - -class TestPendingOffencesBehaviour: - """Tests for `PendingOffencesBehaviour`.""" - - behaviour: PendingOffencesBehaviour - - @classmethod - def setup_class(cls) -> None: - """Setup the test class.""" - cls.behaviour = PendingOffencesBehaviour( - name="test", - skill_context=MagicMock(), - ) - - @pytest.mark.skipif( - platform.system() == "Windows", - reason="`timegm` behaves differently on Windows. " - "As a result, the generation of `last_transition_timestamp` is invalid.", - ) - @given( - offence=st.builds( - PendingOffense, - accused_agent_address=st.text(), - round_count=st.integers(min_value=0), - offense_type=st.sampled_from(OffenseType), - last_transition_timestamp=st.floats( - min_value=timegm(datetime(1971, 1, 1).utctimetuple()), - max_value=timegm(datetime(8000, 1, 1).utctimetuple()) - 2000, - ), - time_to_live=st.floats(min_value=1, max_value=2000), - ), - wait_ticks=st.integers(min_value=0, max_value=1000), - expired=st.booleans(), - ) - def test_pending_offences_act( - self, - offence: PendingOffense, - wait_ticks: int, - expired: bool, - ) -> None: - """Test `PendingOffencesBehaviour`.""" - offence_expiration = offence.last_transition_timestamp + offence.time_to_live - offence_expiration += 1 if expired else -1 - self.behaviour.round_sequence.last_round_transition_timestamp = datetime.fromtimestamp( # type: ignore - offence_expiration - ) - - gen = self.behaviour.async_act() - - with mock.patch.object( - self.behaviour, - "send_a2a_transaction", - ) as mock_send_a2a_transaction, mock.patch.object( - self.behaviour, - "wait_until_round_end", - ) as mock_wait_until_round_end, mock.patch.object( - self.behaviour, - "set_done", - ) as mock_set_done: - # while pending offences are empty, the behaviour simply waits - for _ in range(wait_ticks): - next(gen) - - self.behaviour.round_sequence.pending_offences = {offence} - - with pytest.raises(StopIteration): - next(gen) - - check = "assert_not_called" if expired else "assert_called_once" - - for mocked in ( - mock_send_a2a_transaction, - mock_wait_until_round_end, - mock_set_done, - ): - getattr(mocked, check)() diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_behaviours_utils.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_behaviours_utils.py deleted file mode 100644 index 1991586ac..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_behaviours_utils.py +++ /dev/null @@ -1,2681 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the behaviours_utils.py module of the skill.""" - -import json -import logging -import platform -import time -from abc import ABC -from datetime import datetime -from enum import Enum -from pathlib import Path -from typing import ( - Any, - Callable, - Dict, - Generator, - List, - Optional, - Tuple, - Type, - Union, - cast, -) -from unittest import mock -from unittest.mock import MagicMock - -import pytest -import pytz # pylint: disable=import-error -from _pytest.logging import LogCaptureFixture - -# pylint: skip-file -from aea.common import JSONLike -from aea.protocols.base import Message -from aea.test_tools.utils import as_context -from aea_test_autonomy.helpers.base import try_send -from hypothesis import given, settings -from hypothesis import strategies as st - -from packages.open_aea.protocols.signing import SigningMessage -from packages.valory.connections.http_client.connection import HttpDialogues -from packages.valory.connections.ipfs.connection import IpfsDialogues -from packages.valory.connections.ipfs.connection import PUBLIC_ID as IPFS_CONNECTION_ID -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.protocols.ipfs.dialogues import IpfsDialogue -from packages.valory.protocols.ledger_api.custom_types import ( - SignedTransaction, - SignedTransactions, - TransactionDigest, - TransactionDigests, -) -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.protocols.tendermint import TendermintMessage -from packages.valory.skills.abstract_round_abci import behaviour_utils -from packages.valory.skills.abstract_round_abci.base import ( - AbstractRound, - BaseSynchronizedData, - BaseTxPayload, - DegenerateRound, - LEDGER_API_ADDRESS, - OK_CODE, - Transaction, -) -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - AsyncBehaviour, - BaseBehaviour, - BaseBehaviourInternalError, - DegenerateBehaviour, - GENESIS_TIME_FMT, - INITIAL_HEIGHT, - IPFSBehaviour, - NON_200_RETURN_CODE_DURING_RESET_THRESHOLD, - RPCResponseStatus, - SendException, - TimeoutException, - TmManager, - _MetaBaseBehaviour, - make_degenerate_behaviour, -) -from packages.valory.skills.abstract_round_abci.io_.ipfs import ( - IPFSInteract, - IPFSInteractionError, -) -from packages.valory.skills.abstract_round_abci.models import ( - SharedState, - TendermintRecoveryParams, -) -from packages.valory.skills.abstract_round_abci.tests.conftest import profile_name - - -_DEFAULT_REQUEST_TIMEOUT = 10.0 -_DEFAULT_REQUEST_RETRY_DELAY = 1.0 -_DEFAULT_TX_MAX_ATTEMPTS = 10 -_DEFAULT_TX_TIMEOUT = 10.0 - -settings.load_profile(profile_name) - - -PACKAGE_DIR = Path(__file__).parent.parent - -# https://github.com/python/cpython/issues/94414 -# https://stackoverflow.com/questions/46133223/maximum-value-of-timestamp -# NOTE: timezone in behaviour_utils._get_reset_params set to UTC -# but hypothesis does not allow passing of the `tzinfo` argument -# hence we add and subtract a day from the actual min / max datetime -MIN_DATETIME_WINDOWS = datetime(1970, 1, 3, 1, 0, 0) -MAX_DATETIME_WINDOWS = datetime(3000, 12, 30, 23, 59, 59) - - -def mock_yield_and_return( - return_value: Any, -) -> Callable[[], Generator[None, None, Any]]: - """Wrapper for a Dummy generator that returns a `bool`.""" - - def yield_and_return(*_: Any, **__: Any) -> Generator[None, None, Any]: - """Dummy generator that returns a `bool`.""" - yield - return return_value - - return yield_and_return - - -def yield_and_return_bool_wrapper( - flag_value: bool, -) -> Callable[[], Generator[None, None, Optional[bool]]]: - """Wrapper for a Dummy generator that returns a `bool`.""" - - def yield_and_return_bool( - **_: bool, - ) -> Generator[None, None, Optional[bool]]: - """Dummy generator that returns a `bool`.""" - yield - return flag_value - - return yield_and_return_bool - - -def yield_and_return_int_wrapper( - value: Optional[int], -) -> Callable[[], Generator[None, None, Optional[int]]]: - """Wrapper for a Dummy generator that returns an `int`.""" - - def yield_and_return_int( - **_: int, - ) -> Generator[None, None, Optional[int]]: - """Dummy generator that returns an `int`.""" - yield - return value - - return yield_and_return_int - - -class AsyncBehaviourTest(AsyncBehaviour, ABC): - """Concrete AsyncBehaviour class for testing purposes.""" - - def async_act_wrapper(self) -> Generator: - """Do async act wrapper. Forwards to 'async_act'.""" - yield from self.async_act() - - def async_act(self) -> Generator: - """Do 'async_act'.""" - yield None - - -def test_async_behaviour_ticks() -> None: - """Test "AsyncBehaviour", only ticks.""" - - class MyAsyncBehaviour(AsyncBehaviourTest): - counter = 0 - - def async_act(self) -> Generator: - self.counter += 1 - yield - self.counter += 1 - yield - self.counter += 1 - - behaviour = MyAsyncBehaviour() - assert behaviour.counter == 0 - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - behaviour.act() - assert behaviour.counter == 2 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - behaviour.act() - assert behaviour.counter == 3 - assert behaviour.state == AsyncBehaviour.AsyncState.READY - - -def test_async_behaviour_wait_for_message() -> None: - """Test 'wait_for_message'.""" - - expected_message = "message" - - class MyAsyncBehaviour(AsyncBehaviourTest): - counter = 0 - message = None - - def async_act(self) -> Generator: - self.counter += 1 - self.message = yield from self.wait_for_message( - lambda message: message == expected_message - ) - self.counter += 1 - - behaviour = MyAsyncBehaviour() - assert behaviour.counter == 0 - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.WAITING_MESSAGE - - # another call to act doesn't change the state (still waiting for message) - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.WAITING_MESSAGE - - # sending a message that does not satisfy the condition won't change state - behaviour.try_send("wrong_message") - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.WAITING_MESSAGE - - # sending a message before it is processed raises an exception - behaviour.try_send("wrong_message") - with pytest.raises(SendException, match="cannot send message"): - behaviour.try_send("wrong_message") - behaviour.act() - - # sending the right message will transition to the next state, - # but only when calling act() - behaviour.try_send(expected_message) - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.WAITING_MESSAGE - behaviour.act() - assert behaviour.counter == 2 - assert behaviour.message == expected_message - assert behaviour.state == AsyncBehaviour.AsyncState.READY - - -def test_async_behaviour_wait_for_message_raises_timeout_exception() -> None: - """Test 'wait_for_message' when it raises TimeoutException.""" - - with pytest.raises(TimeoutException): - behaviour = AsyncBehaviourTest() - gen = behaviour.wait_for_message(lambda _: False, timeout=0.01) - # trigger function - try_send(gen) - # sleep so to run out the timeout - time.sleep(0.02) - # trigger function and make the exception to raise - try_send(gen) - - -def test_async_behaviour_wait_for_condition() -> None: - """Test 'wait_for_condition' method.""" - - condition = False - - class MyAsyncBehaviour(AsyncBehaviourTest): - counter = 0 - - def async_act(self) -> Generator: - self.counter += 1 - yield from self.wait_for_condition(lambda: condition) - self.counter += 1 - - behaviour = MyAsyncBehaviour() - assert behaviour.counter == 0 - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - - # if condition is false, execution remains at the same point - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - - # if condition is true, execution continues - condition = True - behaviour.act() - assert behaviour.counter == 2 - assert behaviour.state == AsyncBehaviour.AsyncState.READY - - -def test_async_behaviour_wait_for_condition_with_timeout() -> None: - """Test 'wait_for_condition' method with timeout expired.""" - - class MyAsyncBehaviour(AsyncBehaviourTest): - counter = 0 - - def async_act(self) -> Generator: - self.counter += 1 - yield from self.wait_for_condition(lambda: False, timeout=0.05) - - behaviour = MyAsyncBehaviour() - assert behaviour.counter == 0 - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - - # sleep so the timeout expires - time.sleep(0.1) - - # the next call to act raises TimeoutException - with pytest.raises(TimeoutException): - behaviour.act() - - -def test_async_behaviour_sleep() -> None: - """Test 'sleep' method.""" - - timedelta = 0.5 - - class MyAsyncBehaviour(AsyncBehaviourTest): - counter = 0 - first_datetime = None - last_datetime = None - - def async_act_wrapper(self) -> Generator: - yield from self.async_act() - - def async_act(self) -> Generator: - self.first_datetime = datetime.now() - self.counter += 1 - yield from self.sleep(timedelta) - self.counter += 1 - self.last_datetime = datetime.now() - - behaviour = MyAsyncBehaviour() - assert behaviour.counter == 0 - - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - - # calling 'act()' before the sleep interval will keep the behaviour in the same state - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - - # wait the sleep timeout, we give twice the amount of time it takes the behaviour - time.sleep(timedelta * 2) - - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - behaviour.act() - assert behaviour.counter == 2 - assert behaviour.state == AsyncBehaviour.AsyncState.READY - assert behaviour.last_datetime is not None and behaviour.first_datetime is not None - assert ( - behaviour.last_datetime - behaviour.first_datetime - ).total_seconds() > timedelta - - -def test_async_behaviour_without_yield() -> None: - """Test AsyncBehaviour, async_act without yield/yield from.""" - - class MyAsyncBehaviour(AsyncBehaviourTest): - def async_act_wrapper(self) -> Generator: - return None # type: ignore # need to check design, not sure it's proper case with return None - - behaviour = MyAsyncBehaviour() - behaviour.act() - assert behaviour.state == AsyncBehaviour.AsyncState.READY - - -def test_async_behaviour_raise_stopiteration() -> None: - """Test AsyncBehaviour, async_act raising 'StopIteration'.""" - - class MyAsyncBehaviour(AsyncBehaviourTest): - def async_act_wrapper(self) -> Generator: - raise StopIteration - - behaviour = MyAsyncBehaviour() - behaviour.act() - assert behaviour.state == AsyncBehaviour.AsyncState.READY - - -def test_async_behaviour_stop() -> None: - """Test AsyncBehaviour.stop method.""" - - class MyAsyncBehaviour(AsyncBehaviourTest): - def async_act(self) -> Generator: - yield - - behaviour = MyAsyncBehaviour() - assert behaviour.is_stopped - behaviour.act() - assert not behaviour.is_stopped - behaviour.stop() - assert behaviour.is_stopped - behaviour.stop() - assert behaviour.is_stopped - - -class RoundA(AbstractRound): - """Concrete ABCI round.""" - - round_id = "round_a" - synchronized_data_class = BaseSynchronizedData - payload_class = MagicMock() - payload_attribute = MagicMock() - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Handle end block.""" - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - - -class BehaviourATest(BaseBehaviour): - """Concrete BaseBehaviour class.""" - - matching_round: Type[RoundA] = RoundA - - def async_act(self) -> Generator: - """Do the 'async_act'.""" - yield None - - -def _get_status_patch_wrapper( - latest_block_height: int, - app_hash: str, -) -> Callable[[Any, Any], Generator[None, None, MagicMock]]: - """Wrapper for `_get_status` method patch.""" - - def _get_status_patch(*_: Any, **__: Any) -> Generator[None, None, MagicMock]: - """Patch `_get_status` method""" - yield - return MagicMock( - body=json.dumps( - { - "result": { - "sync_info": { - "latest_block_height": latest_block_height, - "latest_app_hash": app_hash, - } - } - } - ).encode() - ) - - return _get_status_patch - - -def _get_status_wrong_patch( - *args: Any, **kwargs: Any -) -> Generator[None, None, MagicMock]: - """Patch `_get_status` method""" - return MagicMock( - body=json.dumps({"result": {"sync_info": {"latest_block_height": -1}}}).encode() - ) - yield - - -def _wait_until_transaction_delivered_patch( - *args: Any, **kwargs: Any -) -> Generator[None, None, Tuple]: - """Patch `_wait_until_transaction_delivered` method""" - return False, HttpMessage( - performative=HttpMessage.Performative.RESPONSE, # type: ignore - body=json.dumps({"tx_result": {"info": "TransactionNotValidError"}}), - ) - yield - - -def dummy_generator_wrapper(return_value: Any = None) -> Callable[[Any], Generator]: - """A wrapper around a dummy generator that yields nothing and returns the given return value.""" - - def dummy_generator(*_: Any, **__: Any) -> Generator[None, None, Any]: - """A dummy generator that yields nothing and returns the given return value.""" - yield - return return_value - - return dummy_generator - - -class TestBaseBehaviour: - """Tests for the 'BaseBehaviour' class.""" - - _DUMMY_CONSENSUS_THRESHOLD = 3 - - def setup(self) -> None: - """Set up the tests.""" - self.context_mock = MagicMock() - self.context_params_mock = MagicMock( - request_timeout=_DEFAULT_REQUEST_TIMEOUT, - request_retry_delay=_DEFAULT_REQUEST_RETRY_DELAY, - tx_timeout=_DEFAULT_TX_TIMEOUT, - max_attempts=_DEFAULT_TX_MAX_ATTEMPTS, - ) - self.context_mock.shared_state = {} - self.context_state_synchronized_data_mock = MagicMock() - self.context_mock.params = self.context_params_mock - self.context_mock.state.synchronized_data = ( - self.context_state_synchronized_data_mock - ) - self.current_round_count = 10 - self.current_reset_index = 10 - self.context_mock.state.synchronized_data.db = MagicMock( - round_count=self.current_round_count, reset_index=self.current_reset_index - ) - self.context_mock.state.round_sequence.current_round_id = "round_a" - self.context_mock.state.round_sequence.syncing_up = False - self.context_mock.state.round_sequence.block_stall_deadline_expired = False - self.context_mock.http_dialogues = HttpDialogues() - self.context_mock.ipfs_dialogues = IpfsDialogues( - connection_id=str(IPFS_CONNECTION_ID) - ) - self.context_mock.outbox = MagicMock(put_message=self.dummy_put_message) - self.context_mock.requests = MagicMock(request_id_to_callback={}) - self.context_mock.handlers.__dict__ = {"http": MagicMock()} - self.behaviour = BehaviourATest(name="", skill_context=self.context_mock) - self.behaviour.context.logger = logging # type: ignore - self.behaviour.params.sleep_time = 0.01 # type: ignore - - def dummy_put_message(self, *args: Any, **kwargs: Any) -> None: - """A dummy implementation of Outbox.put_message""" - return - - def test_behaviour_id(self) -> None: - """Test behaviour_id on instance.""" - assert self.behaviour.behaviour_id == BehaviourATest.auto_behaviour_id() - - @pytest.mark.parametrize( - "ipfs_response, expected_log", - [ - ( - MagicMock( - ipfs_hash="test", performative=IpfsMessage.Performative.IPFS_HASH - ), - "Successfully stored dummy_filename to IPFS with hash: test", - ), - ( - MagicMock( - ipfs_hash="test", performative=IpfsMessage.Performative.ERROR - ), - f"Expected performative {IpfsMessage.Performative.IPFS_HASH} but got {IpfsMessage.Performative.ERROR}.", - ), - ], - ) - def test_send_to_ipfs( - self, - caplog: LogCaptureFixture, - ipfs_response: IpfsMessage, - expected_log: str, - ) -> None: - """Test send_to_ipfs""" - - def dummy_do_ipfs_req( - *args: Any, **kwargs: Any - ) -> Generator[None, None, Optional[IpfsMessage]]: - """A dummy method to be used in mocks.""" - return ipfs_response - yield - - with mock.patch.object( - IPFSBehaviour, - "_build_ipfs_store_file_req", - return_value=(MagicMock(), MagicMock()), - ) as build_req, mock.patch.object( - BaseBehaviour, "_do_ipfs_request", side_effect=dummy_do_ipfs_req - ) as do_req: - generator = self.behaviour.send_to_ipfs("dummy_filename", {}) - try_send(generator) - build_req.assert_called() - do_req.assert_called() - assert expected_log in caplog.text - - def test_ipfs_store_fails(self, caplog: LogCaptureFixture) -> None: - """Test for failure during building store_file_req.""" - expected_logs = "An error occurred while trying to send a file to IPFS:" - with mock.patch.object( - IPFSBehaviour, - "_build_ipfs_store_file_req", - side_effect=IPFSInteractionError, - ), caplog.at_level(logging.ERROR): - generator = self.behaviour.send_to_ipfs("dummy_filename", {}) - try_send(generator) - assert expected_logs in caplog.text - - def test_do_ipfs_request(self) -> None: - """Test _do_ipfs_request""" - message, dialogue = cast( - IpfsDialogues, self.context_mock.ipfs_dialogues - ).create(str(IPFS_CONNECTION_ID), IpfsMessage.Performative.GET_FILES) - message = cast(IpfsMessage, message) - dialogue = cast(IpfsDialogue, dialogue) - - def dummy_wait_for_message( - *args: Any, **kwargs: Any - ) -> Generator[None, None, Message]: - """A dummy implementation of AsyncBehaviour.wait_for_message to be used for mocks.""" - return MagicMock() - yield - - with mock.patch.object( - AsyncBehaviour, "wait_for_message", side_effect=dummy_wait_for_message - ): - gen = self.behaviour._do_ipfs_request( - dialogue, - message, - ) - try_send(gen) - - @pytest.mark.parametrize( - "ipfs_response, expected_log", - [ - ( - MagicMock( - files={"dummy_file_name": "test"}, - performative=IpfsMessage.Performative.FILES, - ), - "Retrieved 1 objects from ipfs.", - ), - ( - MagicMock( - ipfs_hash="test", performative=IpfsMessage.Performative.ERROR - ), - f"Expected performative {IpfsMessage.Performative.FILES} but got {IpfsMessage.Performative.ERROR}.", - ), - ], - ) - def test_get_from_ipfs( - self, - caplog: LogCaptureFixture, - ipfs_response: IpfsMessage, - expected_log: str, - ) -> None: - """Test get_from_ipfs""" - - def dummy_do_ipfs_req( - *args: Any, **kwargs: Any - ) -> Generator[None, None, Optional[IpfsMessage]]: - """A dummy method to be used in mocks.""" - return ipfs_response - yield - - with mock.patch.object( - IPFSBehaviour, - "_build_ipfs_get_file_req", - return_value=(MagicMock(), MagicMock()), - ) as build_req, mock.patch.object( - IPFSBehaviour, - "_deserialize_ipfs_objects", - return_value=MagicMock(), - ), mock.patch.object( - BaseBehaviour, "_do_ipfs_request", side_effect=dummy_do_ipfs_req - ) as do_req: - generator = self.behaviour.get_from_ipfs("dummy_ipfs_hash") - try_send(generator) - build_req.assert_called() - do_req.assert_called() - assert expected_log in caplog.text - - def test_ipfs_get_fails(self, caplog: LogCaptureFixture) -> None: - """Test for failure during building get_files req.""" - expected_logs = "An error occurred while trying to fetch a file from IPFS:" - with mock.patch.object( - IPFSBehaviour, "_build_ipfs_get_file_req", side_effect=IPFSInteractionError - ), caplog.at_level(logging.ERROR): - generator = self.behaviour.get_from_ipfs("dummy_ipfs_hash") - try_send(generator) - assert expected_logs in caplog.text - - def test_params_property(self) -> None: - """Test the 'params' property.""" - assert self.behaviour.params == self.context_params_mock - - def test_synchronized_data_property(self) -> None: - """Test the 'synchronized_data' property.""" - assert ( - self.behaviour.synchronized_data - == self.context_state_synchronized_data_mock - ) - - def test_check_in_round(self) -> None: - """Test 'BaseBehaviour' initialization.""" - expected_round_id = "round" - self.context_mock.state.round_sequence.current_round_id = expected_round_id - assert self.behaviour.check_in_round(expected_round_id) - assert not self.behaviour.check_in_round("wrong round") - - assert not self.behaviour.check_not_in_round(expected_round_id) - assert self.behaviour.check_not_in_round("wrong round") - - func = self.behaviour.is_round_ended(expected_round_id) - assert not func() - - def test_check_in_last_round(self) -> None: - """Test 'BaseBehaviour' initialization.""" - expected_round_id = "round" - self.context_mock.state.round_sequence.last_round_id = expected_round_id - assert self.behaviour.check_in_last_round(expected_round_id) - assert not self.behaviour.check_in_last_round("wrong round") - - assert not self.behaviour.check_not_in_last_round(expected_round_id) - assert self.behaviour.check_not_in_last_round("wrong round") - - assert self.behaviour.check_round_has_finished(expected_round_id) - - def test_check_round_height_has_changed(self) -> None: - """Test 'check_round_height_has_changed'.""" - current_height = 0 - self.context_mock.state.round_sequence.current_round_height = current_height - assert not self.behaviour.check_round_height_has_changed(current_height) - new_height = current_height + 1 - self.context_mock.state.round_sequence.current_round_height = new_height - assert self.behaviour.check_round_height_has_changed(current_height) - assert not self.behaviour.check_round_height_has_changed(new_height) - - def test_wait_until_round_end_negative_last_round_or_matching_round(self) -> None: - """Test 'wait_until_round_end' method, negative case (not in matching nor last round).""" - self.behaviour.context.state.round_sequence.current_round_id = ( - "current_round_id" - ) - self.behaviour.context.state.round_sequence.last_round_id = "last_round_id" - self.behaviour.matching_round.round_id = "matching_round" - generator = self.behaviour.wait_until_round_end() - with pytest.raises( - ValueError, - match=r"Should be in matching round \(matching_round\) or last round \(last_round_id\), actual round current_round_id!", - ): - generator.send(None) - - @mock.patch.object(BaseBehaviour, "wait_for_condition") - @mock.patch.object(BaseBehaviour, "check_not_in_round", return_value=False) - @mock.patch.object(BaseBehaviour, "check_not_in_last_round", return_value=False) - def test_wait_until_round_end_positive(self, *_: Any) -> None: - """Test 'wait_until_round_end' method, positive case.""" - gen = self.behaviour.wait_until_round_end() - try_send(gen) - - def test_wait_from_last_timestamp(self) -> None: - """Test 'wait_from_last_timestamp'.""" - timeout = 1.0 - last_timestamp = datetime.now() - self.behaviour.context.state.round_sequence.abci_app.last_timestamp = ( - last_timestamp - ) - gen = self.behaviour.wait_from_last_timestamp(timeout) - # trigger first execution - try_send(gen) - # at the time this line is executed, the generator is not empty - # as the timeout has not run out yet - try_send(gen) - # sleep enough time to make the timeout to run out - time.sleep(timeout) - # the next iteration of the generator raises StopIteration - # because its execution terminates - with pytest.raises(StopIteration): - gen.send(MagicMock()) - - def test_wait_from_last_timestamp_negative(self) -> None: - """Test 'wait_from_last_timestamp'.""" - timeout = -1.0 - last_timestamp = datetime.now() - self.behaviour.context.state.round_sequence.abci_app.last_timestamp = ( - last_timestamp - ) - with pytest.raises(ValueError): - gen = self.behaviour.wait_from_last_timestamp(timeout) - # trigger first execution - try_send(gen) - - def test_set_done(self) -> None: - """Test 'set_done' method.""" - assert not self.behaviour.is_done() - self.behaviour.set_done() - assert self.behaviour.is_done() - - @mock.patch.object(BaseBehaviour, "_send_transaction") - def test_send_a2a_transaction_positive(self, *_: Any) -> None: - """Test 'send_a2a_transaction' method, positive case.""" - gen = self.behaviour.send_a2a_transaction(MagicMock()) - try_send(gen) - - def test_async_act_wrapper_agent_sync_mode( - self, - ) -> None: - """Test 'async_act_wrapper' in sync mode.""" - self.behaviour.context.state.round_sequence.syncing_up = True - self.behaviour.context.state.round_sequence.height = 0 - self.behaviour.matching_round = MagicMock() - - with mock.patch.object(logging, "info") as log_mock, mock.patch.object( - BaseBehaviour, - "_get_status", - _get_status_patch_wrapper(0, "test"), - ): - gen = self.behaviour.async_act_wrapper() - for __ in range(3): - try_send(gen) - log_mock.assert_called_with( - "local height == remote == 0; Synchronization complete." - ) - - @mock.patch.object(BaseBehaviour, "_get_status", _get_status_wrong_patch) - def test_async_act_wrapper_agent_sync_mode_where_height_dont_match(self) -> None: - """Test 'async_act_wrapper' in sync mode.""" - self.behaviour.context.state.round_sequence.syncing_up = True - self.behaviour.context.state.round_sequence.height = 0 - self.behaviour.context.params.tendermint_check_sleep_delay = 3 - self.behaviour.matching_round = MagicMock() - - gen = self.behaviour.async_act_wrapper() - try_send(gen) - - @pytest.mark.parametrize("exception_cls", [StopIteration]) - def test_async_act_wrapper_exception(self, exception_cls: Exception) -> None: - """Test 'async_act_wrapper'.""" - with mock.patch.object(self.behaviour, "async_act", side_effect=exception_cls): - with mock.patch.object(self.behaviour, "clean_up") as clean_up_mock: - gen = self.behaviour.async_act_wrapper() - try_send(gen) - try_send(gen) - clean_up_mock.assert_called() - - def test_get_request_nonce_from_dialogue(self) -> None: - """Test '_get_request_nonce_from_dialogue' helper method.""" - dialogue_mock = MagicMock() - expected_value = "dialogue_reference" - dialogue_mock.dialogue_label.dialogue_reference = (expected_value, None) - result = BaseBehaviour._get_request_nonce_from_dialogue(dialogue_mock) - assert result == expected_value - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=False) - def test_send_transaction_stop_condition(self, *_: Any) -> None: - """Test '_send_transaction' method's `stop_condition` as provided by `send_a2a_transaction`.""" - request_retry_delay = 0.01 - # set the current round's id so that it does not meet the requirements for a `stop_condition` - self.behaviour.context.state.round_sequence.current_round_id = ( - self.behaviour.matching_round.round_id - ) = "round_a" - # assert that everything is pre-set correctly - assert ( - self.behaviour.context.state.round_sequence.current_round_id - == self.behaviour.matching_round.auto_round_id() - == "round_a" - ) - - # create the exact same stop condition that we create in the `send_a2a_transaction` method - stop_condition = self.behaviour.is_round_ended( - self.behaviour.matching_round.auto_round_id() - ) - gen = self.behaviour._send_transaction( - MagicMock(), - request_retry_delay=request_retry_delay, - stop_condition=stop_condition, - ) - # assert that the stop condition does not apply yet - assert not stop_condition() - # trigger the generator function so that we enter the `stop_condition` loop - try_send(gen) - - # set the current round's id so that it meets the requirements for a `stop_condition` - self.behaviour.context.state.round_sequence.current_round_id = "test" - - # assert that everything was set as expected - assert ( - self.behaviour.context.state.round_sequence.current_round_id - != self.behaviour.matching_round.auto_round_id() - and self.behaviour.context.state.round_sequence.current_round_id == "test" - ) - # assert that the stop condition now applies - assert stop_condition() - - # test with a non-200 response in order to cause the execution to re-enter the while `stop_condition` - # we expect that the second time we will not enter, since we have caused the `stop_condition` to be `True` - with mock.patch.object( - self.behaviour.context.logger, "debug" - ) as mock_debug, mock.patch.object( - self.behaviour.context.logger, "error" - ) as mock_error: - # send message to 'wait_for_message' - try_send(gen, obj=MagicMock(status_code=200)) - # send message to '_submit_tx' - response = MagicMock(body='{"result": {"hash": "", "code": 0}}') - try_send(gen, obj=response) - mock_error.assert_called_with( - f"Received return code != 200 with response {response} with body {str(response.body)}. " - f"Retrying in {request_retry_delay} seconds..." - ) - time.sleep(request_retry_delay) - try_send(gen) - # assert that the stop condition is now `True` and we reach at the end of the method - mock_debug.assert_called_with( - "Stop condition is true, no more attempts to send the transaction." - ) - - def test_send_transaction_positive_false_condition(self) -> None: - """Test '_send_transaction', positive case (false condition)""" - with mock.patch.object(self.behaviour.context.logger, "debug") as mock_debug: - try_send( - self.behaviour._send_transaction( - MagicMock(), stop_condition=lambda: True - ) - ) - mock_debug.assert_called_with( - "Stop condition is true, no more attempts to send the transaction." - ) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - def test_send_transaction_positive(self, *_: Any) -> None: - """Test '_send_transaction', positive case.""" - m = MagicMock(status_code=200) - gen = self.behaviour._send_transaction(m) - # trigger generator function - try_send(gen, obj=None) - # send message to 'wait_for_message' - try_send(gen, obj=m) - # send message to '_submit_tx' - try_send(gen, obj=MagicMock(body='{"result": {"hash": "", "code": 0}}')) - # send message to '_wait_until_transaction_delivered' - success_response = MagicMock( - status_code=200, body='{"result": {"tx_result": {"code": 0}}}' - ) - try_send(gen, obj=success_response) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - @mock.patch.object( - BaseBehaviour, - "_wait_until_transaction_delivered", - new=_wait_until_transaction_delivered_patch, - ) - def test_send_transaction_invalid_transaction(self, *_: Any) -> None: - """Test '_send_transaction', positive case.""" - m = MagicMock(status_code=200) - gen = self.behaviour._send_transaction(m) - try_send(gen, obj=None) - try_send(gen, obj=m) - try_send(gen, obj=MagicMock(body='{"result": {"hash": "", "code": 0}}')) - success_response = MagicMock( - status_code=200, body='{"result": {"tx_result": {"code": 0}}}' - ) - try_send(gen, obj=success_response) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(BaseBehaviour, "_is_invalid_transaction", return_value=False) - @mock.patch.object(BaseBehaviour, "_tx_not_found", return_value=True) - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - @mock.patch.object( - BaseBehaviour, - "_wait_until_transaction_delivered", - new=_wait_until_transaction_delivered_patch, - ) - def test_send_transaction_valid_transaction(self, *_: Any) -> None: - """Test '_send_transaction', positive case.""" - m = MagicMock(status_code=200) - gen = self.behaviour._send_transaction(m) - try_send(gen, obj=None) - try_send(gen, obj=m) - try_send(gen, obj=MagicMock(body='{"result": {"hash": "", "code": 0}}')) - success_response = MagicMock( - status_code=200, body='{"result": {"tx_result": {"code": 0}}}' - ) - try_send(gen, obj=success_response) - - def test_tx_not_found(self, *_: Any) -> None: - """Test _tx_not_found""" - res = MagicMock( - body='{"error": {"code": "dummy_code", "message": "dummy_message", "data": "dummy_data"}}' - ) - self.behaviour._tx_not_found(tx_hash="tx_hash", res=res) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - def test_send_transaction_signing_error(self, *_: Any) -> None: - """Test '_send_transaction', signing error.""" - m = MagicMock(performative=SigningMessage.Performative.ERROR) - gen = self.behaviour._send_transaction(m) - # trigger generator function - try_send(gen, obj=None) - with pytest.raises(RuntimeError): - try_send(gen, obj=m) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - def test_send_transaction_timeout_exception_submit_tx(self, *_: Any) -> None: - """Test '_send_transaction', timeout exception.""" - timeout = 0.05 - delay = 0.1 - m = MagicMock() - with mock.patch.object( - self.behaviour.context.logger, "warning" - ) as mock_warning: - gen = self.behaviour._send_transaction( - m, request_timeout=timeout, request_retry_delay=delay - ) - # trigger generator function - try_send(gen, obj=None) - try_send(gen, obj=m) - time.sleep(timeout) - try_send(gen, obj=m) - time.sleep(delay) - mock_warning.assert_called_with( - f"Timeout expired for submit tx. Retrying in {delay} seconds..." - ) - try_send(gen, obj=None) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - def test_send_transaction_timeout_exception_wait_until_transaction_delivered( - self, *_: Any - ) -> None: - """Test '_send_transaction', timeout exception.""" - timeout = 0.05 - delay = 0.1 - m = MagicMock() - with mock.patch.object( - self.behaviour.context.logger, "warning" - ) as mock_warning: - gen = self.behaviour._send_transaction( - m, request_retry_delay=delay, tx_timeout=timeout - ) - # trigger generator function - try_send(gen, obj=None) - # send message to 'wait_for_message' - try_send(gen, obj=m) - # send message to '_submit_tx' - try_send(gen, obj=MagicMock(body='{"result": {"hash": "", "code": 0}}')) - # send message to '_wait_until_transaction_delivered' - time.sleep(timeout) - try_send(gen, obj=m) - - mock_warning.assert_called_with( - f"Timeout expired for wait until transaction delivered. Retrying in {delay} seconds..." - ) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - def test_send_transaction_transaction_not_delivered(self, *_: Any) -> None: - """Test '_send_transaction', timeout exception.""" - timeout = 0.05 - delay = 0.1 - m = MagicMock() - with mock.patch.object( - self.behaviour.context.logger, "warning" - ) as mock_warning: - gen = self.behaviour._send_transaction( - m, request_retry_delay=delay, tx_timeout=timeout, max_attempts=0 - ) - # trigger generator function - try_send(gen, obj=None) - # send message to 'wait_for_message' - try_send(gen, obj=m) - # send message to '_submit_tx' - try_send(gen, obj=MagicMock(body='{"result": {"hash": "", "code": 0}}')) - # send message to '_wait_until_transaction_delivered' - time.sleep(timeout) - try_send(gen, obj=m) - - mock_warning.assert_called_with( - "Tx sent but not delivered. Response = None" - ) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - def test_send_transaction_wrong_ok_code(self, *_: Any) -> None: - """Test '_send_transaction', positive case.""" - m = MagicMock(status_code=200) - gen = self.behaviour._send_transaction(m) - - with mock.patch.object(self.behaviour.context.logger, "error") as mock_error: - # trigger generator function - try_send(gen, obj=None) - # send message to 'wait_for_message' - try_send(gen, obj=m) - # send message to '_submit_tx' - try_send(gen, obj=MagicMock(body='{"result": {"hash": "", "code": -1}}')) - # send message to '_wait_until_transaction_delivered' - success_response = MagicMock( - status_code=200, body='{"result": {"tx_result": {"code": 0}}}' - ) - try_send(gen, obj=success_response) - - mock_error.assert_called_with( - "Received tendermint code != 0. Retrying in 1.0 seconds..." - ) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object( - BaseBehaviour, - "_check_http_return_code_200", - return_value=True, - ) - @mock.patch("json.loads", return_value={"result": {"hash": "", "code": OK_CODE}}) - def test_send_transaction_wait_delivery_timeout_exception(self, *_: Any) -> None: - """Test '_send_transaction', timeout exception on tx delivery.""" - timeout = 0.05 - delay = 0.1 - m = MagicMock() - with mock.patch.object( - self.behaviour.context.logger, "warning" - ) as mock_warning: - gen = self.behaviour._send_transaction( - m, - request_timeout=timeout, - request_retry_delay=delay, - tx_timeout=timeout, - ) - # trigger generator function - try_send(gen, obj=None) - try_send(gen, obj=m) - try_send(gen, obj=m) - time.sleep(timeout) - try_send(gen, obj=m) - mock_warning.assert_called_with( - f"Timeout expired for wait until transaction delivered. Retrying in {delay} seconds..." - ) - time.sleep(delay) - try_send(gen, obj=m) - - @pytest.mark.parametrize("resetting", (True, False)) - @pytest.mark.parametrize( - "non_200_count", - ( - 0, - NON_200_RETURN_CODE_DURING_RESET_THRESHOLD, - NON_200_RETURN_CODE_DURING_RESET_THRESHOLD + 1, - ), - ) - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch("json.loads") - def test_send_transaction_error_status_code( - self, _: Any, __: Any, ___: Any, ____: Any, resetting: bool, non_200_count: int - ) -> None: - """Test '_send_transaction', error status code.""" - delay = 0.1 - self.behaviour._non_200_return_code_count = non_200_count - m = MagicMock() - with mock.patch.object(self.behaviour.context.logger, "error") as mock_error: - gen = self.behaviour._send_transaction( - m, resetting, request_retry_delay=delay - ) - # trigger generator function - try_send(gen, obj=None) - try_send(gen, obj=m) - # send message to '_submit_tx' - res = MagicMock(body="{'test': 'test'}") - try_send(gen, obj=res) - if ( - resetting - and non_200_count <= NON_200_RETURN_CODE_DURING_RESET_THRESHOLD - ): - mock_error.assert_not_called() - else: - mock_error.assert_called_with( - f"Received return code != 200 with response {res} with body {str(res.body)}. " - f"Retrying in {delay} seconds..." - ) - time.sleep(delay) - try_send(gen, obj=None) - - @mock.patch.object(BaseBehaviour, "_get_request_nonce_from_dialogue") - @mock.patch.object(behaviour_utils, "RawMessage") - @mock.patch.object(behaviour_utils, "Terms") - def test_send_signing_request(self, *_: Any) -> None: - """Test '_send_signing_request'.""" - with mock.patch.object( - self.behaviour.context.signing_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ): - self.behaviour._send_signing_request(b"") - - @given(st.binary()) - def test_fuzz_send_signing_request(self, input_bytes: bytes) -> None: - """Fuzz '_send_signing_request'. - - Mock context manager decorators don't work here. - - :param input_bytes: fuzz input - """ - with mock.patch.object( - self.behaviour.context.signing_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ): - with mock.patch.object(behaviour_utils, "RawMessage"): - with mock.patch.object(behaviour_utils, "Terms"): - self.behaviour._send_signing_request(input_bytes) - - @mock.patch.object(BaseBehaviour, "_get_request_nonce_from_dialogue") - @mock.patch.object(behaviour_utils, "RawMessage") - @mock.patch.object(behaviour_utils, "Terms") - def test_send_transaction_signing_request(self, *_: Any) -> None: - """Test '_send_signing_request'.""" - with mock.patch.object( - self.behaviour.context.signing_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ): - self.behaviour._send_transaction_signing_request(MagicMock(), MagicMock()) - - @pytest.mark.parametrize( - "use_flashbots, target_block_numbers, expected_kwargs", - ( - ( - True, - None, - dict( - counterparty=LEDGER_API_ADDRESS, - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS, - signed_transactions=SignedTransactions( - ledger_id="ethereum_flashbots", - signed_transactions=[{"test_tx": "test_tx"}], - ), - kwargs=LedgerApiMessage.Kwargs( - { - "chain_id": None, - "raise_on_failed_simulation": False, - "use_all_builders": True, - } - ), - ), - ), - ( - True, - [1, 2, 3], - dict( - counterparty=LEDGER_API_ADDRESS, - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS, - signed_transactions=SignedTransactions( - ledger_id="ethereum_flashbots", - signed_transactions=[{"test_tx": "test_tx"}], - ), - kwargs=LedgerApiMessage.Kwargs( - { - "chain_id": None, - "raise_on_failed_simulation": False, - "use_all_builders": True, - "target_block_numbers": [1, 2, 3], - } - ), - ), - ), - ( - False, - None, - dict( - counterparty=LEDGER_API_ADDRESS, - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, - signed_transaction=SignedTransaction( - ledger_id="ethereum", body={"test_tx": "test_tx"} - ), - ), - ), - ), - ) - def test_send_transaction_request( - self, - use_flashbots: bool, - target_block_numbers: Optional[List[int]], - expected_kwargs: Any, - ) -> None: - """Test '_send_transaction_request'.""" - with mock.patch.object( - self.behaviour.context.ledger_api_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ) as create_mock: - self.behaviour._send_transaction_request( - MagicMock( - signed_transaction=SignedTransaction( - ledger_id="ethereum", body={"test_tx": "test_tx"} - ) - ), - use_flashbots, - target_block_numbers, - ) - create_mock.assert_called_once() - # not using `create_mock.call_args.kwargs` because it is not compatible with Python 3.7 - actual_kwargs = create_mock.call_args[1] - assert actual_kwargs == expected_kwargs - - def test_send_transaction_receipt_request(self) -> None: - """Test '_send_transaction_receipt_request'.""" - with mock.patch.object( - self.behaviour.context.ledger_api_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ): - self.behaviour.context.default_ledger_id = "default_ledger_id" - self.behaviour._send_transaction_receipt_request("digest") - - def test_build_http_request_message(self, *_: Any) -> None: - """Test '_build_http_request_message'.""" - with mock.patch.object( - self.behaviour.context.http_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ): - self.behaviour._build_http_request_message( - "", - "", - parameters={"foo": "bar"}, - headers={"foo": "foo_val", "bar": "bar_val"}, - ) - - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - @mock.patch.object(BaseBehaviour, "sleep") - @mock.patch("json.loads") - def test_wait_until_transaction_delivered(self, *_: Any) -> None: - """Test '_wait_until_transaction_delivered' method.""" - gen = self.behaviour._wait_until_transaction_delivered(MagicMock()) - # trigger generator function - try_send(gen, obj=None) - - # first check attempt fails - failure_response = MagicMock(status_code=500) - try_send(gen, failure_response) - - # second check attempt succeeds - success_response = MagicMock( - status_code=200, body='{"result": {"tx_result": {"code": 0}}}' - ) - try_send(gen, success_response) - - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - @mock.patch.object(BaseBehaviour, "sleep") - @mock.patch("json.loads") - def test_wait_until_transaction_delivered_failed(self, *_: Any) -> None: - """Test '_wait_until_transaction_delivered' method.""" - gen = self.behaviour._wait_until_transaction_delivered( - MagicMock(), max_attempts=0 - ) - # trigger generator function - try_send(gen, obj=None) - - # first check attempt fails - failure_response = MagicMock(status_code=500) - try_send(gen, failure_response) - - # second check attempt succeeds - success_response = MagicMock( - status_code=200, body='{"result": {"tx_result": {"code": -1}}}' - ) - try_send(gen, success_response) - - @pytest.mark.skipif( - platform.system() == "Windows", - reason="https://github.com/valory-xyz/open-autonomy/issues/1477", - ) - def test_wait_until_transaction_delivered_raises_timeout(self, *_: Any) -> None: - """Test '_wait_until_transaction_delivered' method.""" - gen = self.behaviour._wait_until_transaction_delivered(MagicMock(), timeout=0.0) - with pytest.raises(TimeoutException): - # trigger generator function - try_send(gen, obj=None) - - @mock.patch.object(behaviour_utils, "Terms") - def test_get_default_terms(self, *_: Any) -> None: - """Test '_get_default_terms'.""" - self.behaviour._get_default_terms() - - @mock.patch.object(BaseBehaviour, "_send_transaction_signing_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_receipt_request") - @mock.patch.object(behaviour_utils, "Terms") - @pytest.mark.parametrize( - "ledger_message, expected_hash, expected_response_status", - ( - ( - LedgerApiMessage( - cast( - LedgerApiMessage.Performative, - LedgerApiMessage.Performative.TRANSACTION_DIGEST, - ), - ("", ""), - transaction_digest=TransactionDigest("ledger_id", body="test"), - ), - "test", - RPCResponseStatus.SUCCESS, - ), - ( - LedgerApiMessage( - cast( - LedgerApiMessage.Performative, - LedgerApiMessage.Performative.TRANSACTION_DIGESTS, - ), - ("", ""), - # Only the first hash will be considered - # because we do not support sending multiple messages and receiving multiple tx hashes yet - transaction_digests=TransactionDigests( - "ledger_id", - transaction_digests=["test", "will_not_be_considered"], - ), - ), - "test", - RPCResponseStatus.SUCCESS, - ), - ), - ) - def test_send_raw_transaction( - self, - _send_transaction_signing_request: Any, - _send_transaction_request: Any, - _send_transaction_receipt_request: Any, - _terms: Any, - ledger_message: LedgerApiMessage, - expected_hash: str, - expected_response_status: RPCResponseStatus, - ) -> None: - """Test 'send_raw_transaction'.""" - m = MagicMock() - gen = self.behaviour.send_raw_transaction(m) - # trigger generator function - gen.send(None) - gen.send( - SigningMessage( - cast( - SigningMessage.Performative, - SigningMessage.Performative.SIGNED_TRANSACTION, - ), - ("", ""), - signed_transaction=SignedTransaction( - "ledger_id", body={"hash": expected_hash} - ), - ) - ) - try: - gen.send(ledger_message) - raise ValueError("Generator was expected to have reached its end!") - except StopIteration as e: - tx_hash, status = e.value - - assert tx_hash == expected_hash - assert status == expected_response_status - - @mock.patch.object(BaseBehaviour, "_send_transaction_signing_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_receipt_request") - @mock.patch.object(behaviour_utils, "Terms") - def test_send_raw_transaction_with_wrong_signing_performative( - self, *_: Any - ) -> None: - """Test 'send_raw_transaction'.""" - m = MagicMock() - gen = self.behaviour.send_raw_transaction(m) - # trigger generator function - gen.send(None) - try: - gen.send(MagicMock(performative=SigningMessage.Performative.ERROR)) - raise ValueError("Generator was expected to have reached its end!") - except StopIteration as e: - tx_hash, status = e.value - - assert tx_hash is None - assert status == RPCResponseStatus.UNCLASSIFIED_ERROR - - @pytest.mark.parametrize( - "message, expected_rpc_status", - ( - ("Simulation failed for bundle", RPCResponseStatus.SIMULATION_FAILED), - ("replacement transaction underpriced", RPCResponseStatus.UNDERPRICED), - ("nonce too low", RPCResponseStatus.INCORRECT_NONCE), - ("insufficient funds", RPCResponseStatus.INSUFFICIENT_FUNDS), - ("already known", RPCResponseStatus.ALREADY_KNOWN), - ("test", RPCResponseStatus.UNCLASSIFIED_ERROR), - ), - ) - @mock.patch.object(BaseBehaviour, "_send_transaction_signing_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_receipt_request") - @mock.patch.object(behaviour_utils, "Terms") - def test_send_raw_transaction_errors( - self, - _: Any, - __: Any, - ___: Any, - ____: Any, - message: str, - expected_rpc_status: RPCResponseStatus, - ) -> None: - """Test 'send_raw_transaction'.""" - m = MagicMock() - gen = self.behaviour.send_raw_transaction(m) - # trigger generator function - gen.send(None) - gen.send( - SigningMessage( - cast( - SigningMessage.Performative, - SigningMessage.Performative.SIGNED_TRANSACTION, - ), - ("", ""), - signed_transaction=SignedTransaction( - "ledger_id", body={"hash": "test"} - ), - ) - ) - try: - gen.send( - LedgerApiMessage( - cast( - LedgerApiMessage.Performative, - LedgerApiMessage.Performative.ERROR, - ), - ("", ""), - message=message, - ) - ) - raise ValueError("Generator was expected to have reached its end!") - except StopIteration as e: - tx_hash, status = e.value - - assert tx_hash == "test" - assert status == expected_rpc_status - - @mock.patch.object(BaseBehaviour, "_send_transaction_signing_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_receipt_request") - @mock.patch.object(behaviour_utils, "Terms") - def test_send_raw_transaction_hashes_mismatch(self, *_: Any) -> None: - """Test 'send_raw_transaction' when signature and tx responses' hashes mismatch.""" - m = MagicMock() - gen = self.behaviour.send_raw_transaction(m) - # trigger generator function - gen.send(None) - gen.send( - SigningMessage( - cast( - SigningMessage.Performative, - SigningMessage.Performative.SIGNED_TRANSACTION, - ), - ("", ""), - signed_transaction=SignedTransaction( - "ledger_id", body={"hash": "signed"} - ), - ) - ) - try: - gen.send( - LedgerApiMessage( - cast( - LedgerApiMessage.Performative, - LedgerApiMessage.Performative.TRANSACTION_DIGEST, - ), - ("", ""), - transaction_digest=TransactionDigest("ledger_id", body="tx"), - ) - ) - raise ValueError("Generator was expected to have reached its end!") - except StopIteration as e: - tx_hash, status = e.value - - assert tx_hash is None - assert status == RPCResponseStatus.UNCLASSIFIED_ERROR - - def test_get_transaction_receipt(self, caplog: LogCaptureFixture) -> None: - """Test get_transaction_receipt.""" - - expected: JSONLike = {"dummy": "tx_receipt"} - transaction_receipt = LedgerApiMessage.TransactionReceipt("", expected, {}) - tx_receipt_message = LedgerApiMessage( - LedgerApiMessage.Performative.TRANSACTION_RECEIPT, # type: ignore - transaction_receipt=transaction_receipt, - ) - side_effect = mock_yield_and_return(tx_receipt_message) - with as_context( - mock.patch.object(self.behaviour, "_send_transaction_receipt_request"), - mock.patch.object( - self.behaviour, "wait_for_message", side_effect=side_effect - ), - ): - gen = self.behaviour.get_transaction_receipt("tx_digest") - try: - while True: - next(gen) - except StopIteration as e: - assert e.value == expected - - def test_get_transaction_receipt_error(self, caplog: LogCaptureFixture) -> None: - """Test get_transaction_receipt with error performative.""" - - error_message = LedgerApiMessage(LedgerApiMessage.Performative.ERROR, code=0) # type: ignore - side_effect = mock_yield_and_return(error_message) - with as_context( - mock.patch.object(self.behaviour, "_send_transaction_receipt_request"), - mock.patch.object( - self.behaviour, "wait_for_message", side_effect=side_effect - ), - ): - gen = self.behaviour.get_transaction_receipt("tx_digest") - try_send(gen) - try_send(gen) - assert "Error when requesting transaction receipt" in caplog.text - - @pytest.mark.parametrize("contract_address", [None, "contract_address"]) - def test_get_contract_api_response(self, contract_address: Optional[str]) -> None: - """Test 'get_contract_api_response'.""" - with mock.patch.object( - self.behaviour.context.contract_api_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ), mock.patch.object(behaviour_utils, "Terms"), mock.patch.object( - BaseBehaviour, "_send_transaction_signing_request" - ), mock.patch.object( - BaseBehaviour, "_send_transaction_request" - ): - gen = self.behaviour.get_contract_api_response( - MagicMock(), contract_address, "contract_id", "contract_callable" - ) - # first trigger - try_send(gen, obj=None) - # wait for message - try_send(gen, obj=MagicMock()) - - @mock.patch.object( - BaseBehaviour, "_build_http_request_message", return_value=(None, None) - ) - def test_get_status(self, _: mock.Mock) -> None: - """Test '_get_status'.""" - expected_result = json.dumps("Test result.").encode() - - def dummy_do_request(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_do_request` method.""" - yield - return mock.MagicMock(body=expected_result) - - with mock.patch.object( - BaseBehaviour, "_do_request", side_effect=dummy_do_request - ): - get_status_generator = self.behaviour._get_status() - next(get_status_generator) - with pytest.raises(StopIteration) as e: - next(get_status_generator) - res = e.value.args[0] - assert isinstance(res, MagicMock) - assert res.body == expected_result - - def test_get_netinfo(self) -> None: - """Test _get_netinfo method""" - dummy_res = { - "result": { - "n_peers": "1", - } - } - expected_result = json.dumps(dummy_res).encode() - - def dummy_do_request(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_do_request` method.""" - yield - return mock.MagicMock(body=expected_result) - - with mock.patch.object( - BaseBehaviour, "_do_request", side_effect=dummy_do_request - ): - get_netinfo_generator = self.behaviour._get_netinfo() - next(get_netinfo_generator) - with pytest.raises(StopIteration) as e: - next(get_netinfo_generator) - res = e.value.args[0] - assert isinstance(res, MagicMock) - assert res.body == expected_result - - @pytest.mark.parametrize( - ("num_peers", "expected_num_peers", "netinfo_status_code"), - [ - ("0", 1, 200), - ("0", None, 500), - ("0", None, None), - (None, None, 200), - ], - ) - def test_num_active_peers( - self, - num_peers: Optional[str], - expected_num_peers: Optional[int], - netinfo_status_code: Optional[int], - ) -> None: - """Test num_active_peers.""" - dummy_res = { - "result": { - "n_peers": num_peers, - } - } - - def dummy_get_netinfo(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_get_netinfo` method.""" - yield - - if netinfo_status_code is None: - raise TimeoutException() - - return mock.MagicMock( - status_code=netinfo_status_code, - body=json.dumps(dummy_res).encode(), - ) - - with mock.patch.object( - BaseBehaviour, - "_get_netinfo", - side_effect=dummy_get_netinfo, - ): - num_active_peers_generator = self.behaviour.num_active_peers() - next(num_active_peers_generator) - with pytest.raises(StopIteration) as e: - next(num_active_peers_generator) - actual_num_peers = e.value.value - assert actual_num_peers == expected_num_peers - - def test_default_callback_request_stopped(self) -> None: - """Test 'default_callback_request' when stopped.""" - message = MagicMock() - current_behaviour = self.behaviour - with mock.patch.object(self.behaviour.context.logger, "debug") as debug_mock: - self.behaviour.get_callback_request()(message, current_behaviour) - debug_mock.assert_called_with( - "Dropping message as behaviour has stopped: %s", message - ) - - def test_default_callback_late_arriving_message(self, *_: Any) -> None: - """Test 'default_callback_request' when a message arrives late.""" - self.behaviour._AsyncBehaviour__stopped = False - message = MagicMock() - current_behaviour = MagicMock() - with mock.patch.object(self.behaviour.context.logger, "warning") as info_mock: - self.behaviour.get_callback_request()(message, current_behaviour) - info_mock.assert_called_with( - "No callback defined for request with nonce: " - f"{message.dialogue_reference.__getitem__()}, " - f"arriving for behaviour: {self.behaviour.behaviour_id}" - ) - - def test_default_callback_request_waiting_message(self, *_: Any) -> None: - """Test 'default_callback_request' when waiting message.""" - self.behaviour._AsyncBehaviour__stopped = False # type: ignore - self.behaviour._AsyncBehaviour__state = ( # type: ignore - AsyncBehaviour.AsyncState.WAITING_MESSAGE - ) - message = MagicMock() - current_behaviour = self.behaviour - self.behaviour.get_callback_request()(message, current_behaviour) - - def test_default_callback_request_else(self, *_: Any) -> None: - """Test 'default_callback_request' else branch.""" - self.behaviour._AsyncBehaviour__stopped = False # type: ignore - message = MagicMock() - current_behaviour = self.behaviour - with mock.patch.object( - self.behaviour.context.logger, "warning" - ) as warning_mock: - self.behaviour.get_callback_request()(message, current_behaviour) - warning_mock.assert_called_with( - "Could not send message to FSMBehaviour: %s", message - ) - - def test_stop(self) -> None: - """Test the stop method.""" - self.behaviour.stop() - - @pytest.mark.parametrize( - "performative", - ( - TendermintMessage.Performative.GET_GENESIS_INFO, - TendermintMessage.Performative.GET_RECOVERY_PARAMS, - ), - ) - @pytest.mark.parametrize( - "address_to_acn_deliverable, n_pending", - ( - ({}, 0), - ({i: None for i in range(3)}, 3), - ({0: "test", 1: None, 2: None}, 2), - ({i: "test" for i in range(3)}, 0), - ), - ) - def test_acn_request_from_pending( - self, - performative: TendermintMessage.Performative, - address_to_acn_deliverable: Dict[str, Any], - n_pending: int, - ) -> None: - """Test the `_acn_request_from_pending` method.""" - self.behaviour.context.state.address_to_acn_deliverable = ( - address_to_acn_deliverable - ) - gen = self.behaviour._acn_request_from_pending(performative) - - if n_pending == 0: - with pytest.raises(StopIteration): - next(gen) - return - - with mock.patch.object( - self.behaviour.context.tendermint_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ) as dialogues_mock: - dialogues_mock.assert_not_called() - self.behaviour.context.outbox.put_message = MagicMock() - self.behaviour.context.outbox.put_message.assert_not_called() - - next(gen) - - dialogues_expected_calls = tuple( - mock.call(counterparty=address, performative=performative) - for address, deliverable in address_to_acn_deliverable.items() - if deliverable is None - ) - dialogues_mock.assert_has_calls(dialogues_expected_calls) - assert self.behaviour.context.outbox.put_message.call_count == len( - dialogues_expected_calls - ) - - time.sleep(self.behaviour.params.sleep_time) - with pytest.raises(StopIteration): - next(gen) - - @pytest.mark.parametrize( - "performative", - ( - TendermintMessage.Performative.GET_GENESIS_INFO, - TendermintMessage.Performative.GET_RECOVERY_PARAMS, - ), - ) - @pytest.mark.parametrize( - "address_to_acn_deliverable_per_attempt, expected_result", - ( - ( - tuple({"address": None} for _ in range(10)), - None, - ), # an example in which no agent responds - ( - ( - {f"address{i}": None for i in range(3)}, - {"address1": None, "address2": "test", "address3": None}, - ) - + tuple( - {"address1": None, "address2": "test", "address3": "malicious"} - for _ in range(8) - ), - None, - ), # an example in which no majority is reached - ( - tuple({f"address{i}": None for i in range(3)} for _ in range(3)) - + ({"address1": "test", "address2": "test", "address3": None},), - "test", - ), # an example in which majority is reached during the 4th ACN attempt - ), - ) - def test_perform_acn_request( - self, - performative: TendermintMessage.Performative, - address_to_acn_deliverable_per_attempt: Tuple[Dict[str, Any], ...], - expected_result: Any, - ) -> None: - """Test the `_perform_acn_request` method.""" - final_attempt_idx = len(address_to_acn_deliverable_per_attempt) - 1 - gen = self.behaviour._perform_acn_request(performative) - - with mock.patch.object( - self.behaviour, - "_acn_request_from_pending", - side_effect=dummy_generator_wrapper(), - ) as _acn_request_from_pending_mock: - for i in range(self.behaviour.params.max_attempts): - acn_result = expected_result if i == final_attempt_idx + 1 else None - with mock.patch.object( - self.behaviour.context.state, - "get_acn_result", - return_value=acn_result, - ): - if i != final_attempt_idx + 1: - self.behaviour.context.state.address_to_acn_deliverable = ( - address_to_acn_deliverable_per_attempt[i] - ) - next(gen) - continue - - try: - next(gen) - except StopIteration as exc: - assert exc.value == expected_result - else: - raise AssertionError( - "The `_perform_acn_request` was expected to yield for the last time." - ) - - break - - n_expected_calls = final_attempt_idx + 1 - expected_calls = tuple( - mock.call(performative) for _ in range(n_expected_calls) - ) - assert _acn_request_from_pending_mock.call_count == n_expected_calls - _acn_request_from_pending_mock.assert_has_calls(expected_calls) - - @pytest.mark.parametrize("expected_result", (True, False)) - def test_request_recovery_params(self, expected_result: bool) -> None: - """Test `request_recovery_params`.""" - acn_result = "not None ACN result" if expected_result else None - request_recovery_params = self.behaviour.request_recovery_params(False) - - with mock.patch.object( - self.behaviour, - "_perform_acn_request", - side_effect=dummy_generator_wrapper(acn_result), - ) as perform_acn_request_mock: - next(request_recovery_params) - - try: - next(request_recovery_params) - except StopIteration as exc: - assert exc.value is expected_result - else: - raise AssertionError( - "The `request_recovery_params` was expected to yield for the last time." - ) - - perform_acn_request_mock.assert_called_once_with( - TendermintMessage.Performative.GET_RECOVERY_PARAMS - ) - - def test_start_reset(self) -> None: - """Test the `_start_reset` method.""" - with mock.patch.object( - BaseBehaviour, - "wait_from_last_timestamp", - new_callable=lambda *_: dummy_generator_wrapper(), - ): - res = self.behaviour._start_reset() - for _ in range(2): - next(res) - assert self.behaviour._check_started is not None - assert self.behaviour._check_started <= datetime.now() - assert self.behaviour._timeout == self.behaviour.params.max_healthcheck - assert not self.behaviour._is_healthy - - def test_end_reset(self) -> None: - """Test the `_end_reset` method.""" - self.behaviour._end_reset() - assert self.behaviour._check_started is None - assert self.behaviour._timeout == -1.0 - assert self.behaviour._is_healthy - - @pytest.mark.parametrize( - "check_started, is_healthy, timeout, expiration_expected", - ( - (None, True, 0, False), - (None, False, 0, False), - (datetime(1, 1, 1), True, 0, False), - (datetime.now(), False, 3000, False), - (datetime(1, 1, 1), False, 0, True), - ), - ) - def test_is_timeout_expired( - self, - check_started: Optional[datetime], - is_healthy: bool, - timeout: float, - expiration_expected: bool, - ) -> None: - """Test the `_is_timeout_expired` method.""" - self.behaviour._check_started = check_started - self.behaviour._is_healthy = is_healthy - self.behaviour._timeout = timeout - assert self.behaviour._is_timeout_expired() == expiration_expected - - @pytest.mark.parametrize("default", (True, False)) - @given( - st.datetimes( - min_value=MIN_DATETIME_WINDOWS, - max_value=MAX_DATETIME_WINDOWS, - ), - st.integers(), - st.integers(), - st.integers(), - ) - def test_get_reset_params( - self, - default: bool, - timestamp: datetime, - height: int, - interval: int, - period: int, - ) -> None: - """Test `_get_reset_params` method.""" - self.context_mock.state.round_sequence.last_round_transition_timestamp = ( - timestamp - ) - self.context_mock.state.round_sequence.last_round_transition_tm_height = height - self.behaviour.params.reset_pause_duration = interval - self.context_state_synchronized_data_mock.period_count = period - - actual = self.behaviour._get_reset_params(default) - - if default: - assert actual is None - - else: - initial_height = INITIAL_HEIGHT - genesis_time = timestamp.astimezone(pytz.UTC).strftime(GENESIS_TIME_FMT) - period_count = str(period) - - expected = { - "genesis_time": genesis_time, - "initial_height": initial_height, - "period_count": period_count, - } - - assert actual == expected - - @mock.patch.object(BaseBehaviour, "_start_reset") - @mock.patch.object(BaseBehaviour, "_is_timeout_expired") - def test_reset_tendermint_with_wait_timeout_expired(self, *_: mock.Mock) -> None: - """Test tendermint reset.""" - with pytest.raises(RuntimeError, match="Error resetting tendermint node."): - next(self.behaviour.reset_tendermint_with_wait()) - - @mock.patch.object(BaseBehaviour, "_start_reset") - @mock.patch.object( - BaseBehaviour, "_build_http_request_message", return_value=(None, None) - ) - @pytest.mark.parametrize( - "reset_response, status_response, local_height, on_startup, n_iter, expecting_success", - ( - ( - {"message": "Tendermint reset was successful.", "status": True}, - {"result": {"sync_info": {"latest_block_height": 1}}}, - 1, - False, - 3, - True, - ), - ( - {"message": "Tendermint reset was successful.", "status": True}, - {"result": {"sync_info": {"latest_block_height": 1}}}, - 1, - True, - 2, - True, - ), - ( - { - "message": "Tendermint reset was successful.", - "status": True, - "is_replay": True, - }, - {"result": {"sync_info": {"latest_block_height": 1}}}, - 1, - False, - 3, - True, - ), - ( - {"message": "Tendermint reset was successful.", "status": True}, - {"result": {"sync_info": {"latest_block_height": 1}}}, - 3, - False, - 3, - False, - ), - ( - {"message": "Error resetting tendermint.", "status": False}, - {}, - 0, - False, - 2, - False, - ), - ("wrong_response", {}, 0, False, 2, False), - ( - {"message": "Reset Successful.", "status": True}, - "not_accepting_txs_yet", - 0, - False, - 3, - False, - ), - ), - ) - def test_reset_tendermint_with_wait( - self, - build_http_request_message_mock: mock.Mock, - _start_reset: mock.Mock, - reset_response: Union[Dict[str, Union[bool, str]], str], - status_response: Union[Dict[str, Union[int, str]], str], - local_height: int, - on_startup: bool, - n_iter: int, - expecting_success: bool, - ) -> None: - """Test tendermint reset.""" - - def dummy_do_request(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_do_request` method.""" - yield - if reset_response == "wrong_response": - return mock.MagicMock(body=b"") - return mock.MagicMock(body=json.dumps(reset_response).encode()) - - def dummy_get_status(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_get_status` method.""" - yield - if status_response == "not_accepting_txs_yet": - return mock.MagicMock(body=b"") - return mock.MagicMock(body=json.dumps(status_response).encode()) - - period_count_mock = MagicMock() - self.context_state_synchronized_data_mock.period_count = period_count_mock - self.behaviour.params.reset_pause_duration = 1 - with mock.patch.object( - BaseBehaviour, "_is_timeout_expired", return_value=False - ), mock.patch.object( - BaseBehaviour, - "wait_from_last_timestamp", - new_callable=lambda *_: dummy_generator_wrapper(), - ), mock.patch.object( - BaseBehaviour, "_do_request", new_callable=lambda *_: dummy_do_request - ), mock.patch.object( - BaseBehaviour, "_get_status", new_callable=lambda *_: dummy_get_status - ), mock.patch.object( - BaseBehaviour, "sleep", new_callable=lambda *_: dummy_generator_wrapper() - ): - self.behaviour.context.state.round_sequence.height = local_height - reset = self.behaviour.reset_tendermint_with_wait(on_startup=on_startup) - for _ in range(n_iter): - next(reset) - initial_height = INITIAL_HEIGHT - genesis_time = self.behaviour.context.state.round_sequence.last_round_transition_timestamp.astimezone( - pytz.UTC - ).strftime( - "%Y-%m-%dT%H:%M:%S.%fZ" - ) - - expected_parameters = ( - { - "genesis_time": genesis_time, - "initial_height": initial_height, - "period_count": str(period_count_mock), - } - if not on_startup - else None - ) - - build_http_request_message_mock.assert_called_with( - "GET", - self.behaviour.context.params.tendermint_com_url + "/hard_reset", - parameters=expected_parameters, - ) - - should_be_healthy = isinstance(reset_response, dict) and reset_response.get( - "status", False - ) - assert self.behaviour._is_healthy is should_be_healthy - - # perform the last iteration which also returns the result - try: - next(reset) - except StopIteration as e: - assert e.value == expecting_success - if expecting_success: - # upon having a successful reset we expect the reset params of that - # reset to be stored in the shared state, as they could be used - # later for performing hard reset in cases when the agent <-> tendermint - # communication is broken - shared_state = cast(SharedState, self.behaviour.context.state) - tm_recovery_params = shared_state.tm_recovery_params - assert tm_recovery_params.reset_params == expected_parameters - assert ( - tm_recovery_params.round_count - == shared_state.synchronized_data.db.round_count - 1 - ) - assert ( - tm_recovery_params.reset_from_round - == self.behaviour.matching_round.auto_round_id() - ) - assert not self.behaviour._is_healthy - else: - pytest.fail("`reset_tendermint_with_wait` did not finish!") - - @given(st.binary()) - def test_fuzz_submit_tx(self, input_bytes: bytes) -> None: - """Fuzz '_submit_tx'. - - Mock context manager decorators don't work here. - - :param input_bytes: fuzz input - """ - self.behaviour._submit_tx(input_bytes) - - -def test_degenerate_behaviour_async_act() -> None: - """Test DegenerateBehaviour.async_act.""" - - class ConcreteDegenerateBehaviour(DegenerateBehaviour): - """Concrete DegenerateBehaviour class.""" - - behaviour_id = "concrete_degenerate_behaviour" - matching_round = MagicMock() - sleep_time_before_exit = 0.01 - - context = MagicMock() - # this is needed to trigger execution of async_act - context.state.round_sequence.syncing_up = False - context.state.round_sequence.block_stall_deadline_expired = False - behaviour = ConcreteDegenerateBehaviour( - name=ConcreteDegenerateBehaviour.auto_behaviour_id(), skill_context=context - ) - with pytest.raises( - SystemExit, - ): - behaviour.act() - time.sleep(0.02) - behaviour.act() - - -def test_make_degenerate_behaviour() -> None: - """Test 'make_degenerate_behaviour'.""" - - class FinalRound(DegenerateRound, ABC): - """A final round for testing.""" - - new_cls = make_degenerate_behaviour(FinalRound) - - assert isinstance(new_cls, type) - assert issubclass(new_cls, DegenerateBehaviour) - assert new_cls.matching_round == FinalRound - - assert ( - new_cls.auto_behaviour_id() - == f"degenerate_behaviour_{FinalRound.auto_round_id()}" - ) - - -class TestTmManager: - """Class to test the TmManager behaviour.""" - - _DUMMY_CONSENSUS_THRESHOLD = 3 - - def setup(self) -> None: - """Set up the tests.""" - self.context_mock = MagicMock() - self.context_params_mock = MagicMock( - request_timeout=_DEFAULT_REQUEST_TIMEOUT, - request_retry_delay=_DEFAULT_REQUEST_RETRY_DELAY, - tx_timeout=_DEFAULT_TX_TIMEOUT, - max_attempts=_DEFAULT_TX_MAX_ATTEMPTS, - consensus_params=MagicMock( - consensus_threshold=self._DUMMY_CONSENSUS_THRESHOLD - ), - ) - self.context_state_synchronized_data_mock = MagicMock( - consensus_threshold=self._DUMMY_CONSENSUS_THRESHOLD - ) - self.context_mock.params = self.context_params_mock - self.context_mock.state.synchronized_data = ( - self.context_state_synchronized_data_mock - ) - self.recovery_params = TendermintRecoveryParams(MagicMock()) - self.context_mock.state.tm_recovery_params = self.recovery_params - self.context_mock.state.round_sequence.current_round_id = "round_a" - self.context_mock.state.round_sequence.syncing_up = False - self.context_mock.state.round_sequence.block_stall_deadline_expired = False - self.context_mock.http_dialogues = HttpDialogues() - self.context_mock.handlers.__dict__ = {"http": MagicMock()} - self.tm_manager = TmManager(name="", skill_context=self.context_mock) - self.tm_manager._max_reset_retry = 1 - self.tm_manager.synchronized_data.max_participants = 3 # type: ignore - - def test_async_act(self) -> None: - """Test the async_act method of the TmManager.""" - self.tm_manager.act_wrapper() - with pytest.raises( - SystemExit, - ): - self.tm_manager.act_wrapper() - - @given(latest_block_height=st.integers(min_value=0)) - @pytest.mark.parametrize( - "acn_communication_success", - ( - True, - False, - ), - ) - @pytest.mark.parametrize( - "gentle_reset_attempted", - ( - True, - False, - ), - ) - @pytest.mark.parametrize( - ("tm_reset_success", "num_active_peers"), - [ - (True, 4), - (False, 4), - (True, 2), - (False, None), - ], - ) - def test_handle_unhealthy_tm( - self, - latest_block_height: int, - acn_communication_success: bool, - gentle_reset_attempted: bool, - tm_reset_success: bool, - num_active_peers: Optional[int], - ) -> None: - """Test _handle_unhealthy_tm.""" - - self.tm_manager.gentle_reset_attempted = gentle_reset_attempted - self.tm_manager.context.state.round_sequence.height = latest_block_height - - def mock_sleep(_seconds: int) -> Generator: - """A method that mocks sleep.""" - return - yield - - def dummy_do_request(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_do_request` method.""" - yield - return mock.MagicMock() - - def dummy_get_status(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_get_status` method.""" - yield - return mock.MagicMock( - body=json.dumps( - { - "result": { - "sync_info": {"latest_block_height": latest_block_height} - } - } - ).encode() - ) - - gen = self.tm_manager._handle_unhealthy_tm() - with mock.patch.object( - self.tm_manager, - "reset_tendermint_with_wait", - side_effect=yield_and_return_bool_wrapper(tm_reset_success), - ), mock.patch.object( - self.tm_manager, - "num_active_peers", - side_effect=yield_and_return_int_wrapper(num_active_peers), - ), mock.patch.object( - self.tm_manager, "sleep", side_effect=mock_sleep - ), mock.patch.object( - BaseBehaviour, - "request_recovery_params", - side_effect=dummy_generator_wrapper(acn_communication_success), - ), mock.patch.object( - BaseBehaviour, "_do_request", new_callable=lambda *_: dummy_do_request - ), mock.patch.object( - BaseBehaviour, "_get_status", new_callable=lambda *_: dummy_get_status - ), mock.patch.object( - self.tm_manager.round_sequence, "set_block_stall_deadline" - ) as set_block_stall_deadline_mock: - next(gen) - - if not gentle_reset_attempted: - next(gen) - assert self.tm_manager.gentle_reset_attempted - with pytest.raises(StopIteration): - next(gen) - set_block_stall_deadline_mock.assert_called_once() - assert self.tm_manager.gentle_reset_attempted - return - - if not acn_communication_success: - with pytest.raises(StopIteration): - next(gen) - set_block_stall_deadline_mock.assert_not_called() - return - - next(gen) - with pytest.raises(StopIteration): - next(gen) - - set_block_stall_deadline_mock.assert_not_called() - assert self.tm_manager.informed is True - - @pytest.mark.parametrize( - "n_repetitions", - ( - 1, - 2, - 1000, - ), - ) - def test_handle_unhealthy_tm_logging(self, n_repetitions: int) -> None: - """Verify if unintended logging repetition occurs during the execution of `_handle_unhealthy_tm`.""" - - self.tm_manager.gentle_reset_attempted = False - self.tm_manager.context.state.round_sequence.height = 10 - - def mock_sleep(_seconds: int) -> Generator: - """A method that mocks sleep.""" - return - yield - - def dummy_do_request(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_do_request` method.""" - yield - return mock.MagicMock() - - def dummy_get_status(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_get_status` method.""" - yield - return mock.MagicMock( - body=json.dumps( - {"result": {"sync_info": {"latest_block_height": 0}}} - ).encode() - ) - - with mock.patch.object( - self.tm_manager, - "reset_tendermint_with_wait", - side_effect=yield_and_return_bool_wrapper(True), - ), mock.patch.object( - self.tm_manager, - "num_active_peers", - side_effect=yield_and_return_int_wrapper(4), - ), mock.patch.object( - self.tm_manager, "sleep", side_effect=mock_sleep - ), mock.patch.object( - BaseBehaviour, "_do_request", new_callable=lambda *_: dummy_do_request - ), mock.patch.object( - BaseBehaviour, "_get_status", new_callable=lambda *_: dummy_get_status - ): - assert self.tm_manager.informed is False - for _ in range(n_repetitions): - gen = self.tm_manager._handle_unhealthy_tm() - next(gen) - assert self.tm_manager.informed is True - - @pytest.mark.parametrize( - "expected_reset_params", - ( - {"genesis_time": "genesis-time", "initial_height": "1"}, - None, - ), - ) - def test_get_reset_params( - self, expected_reset_params: Optional[Dict[str, str]] - ) -> None: - """Test that reset params returns the correct params.""" - self.context_mock.state.tm_recovery_params = TendermintRecoveryParams( - reset_from_round="does not matter", reset_params=expected_reset_params - ) - actual_reset_params = self.tm_manager._get_reset_params(False) - assert expected_reset_params == actual_reset_params - - # setting the "default" arg to true should have no effect - actual_reset_params = self.tm_manager._get_reset_params(True) - assert expected_reset_params == actual_reset_params - - def test_sleep_after_hard_reset(self) -> None: - """Check that hard_reset_sleep returns the expected amount of time.""" - expected = self.tm_manager._hard_reset_sleep - actual = self.tm_manager.hard_reset_sleep - assert actual == expected - - @pytest.mark.parametrize( - ("state", "notified", "message", "num_iter"), - [ - (AsyncBehaviour.AsyncState.READY, False, None, 1), - (AsyncBehaviour.AsyncState.WAITING_MESSAGE, True, Message(), 2), - (AsyncBehaviour.AsyncState.WAITING_MESSAGE, True, Message(), 1), - ], - ) - def test_try_fix( - self, - state: AsyncBehaviour.AsyncState, - notified: bool, - message: Optional[Message], - num_iter: int, - ) -> None: - """Tests try_fix.""" - - def mock_handle_unhealthy_tm() -> Generator: - """A mock implementation of _handle_unhealthy_tm.""" - for _ in range(num_iter): - msg = yield - if msg is not None: - # if a message is recieved, the state of the behviour should be "RUNNING" - self.tm_manager._AsyncBehaviour__state = ( - AsyncBehaviour.AsyncState.RUNNING - ) - return - - with mock.patch.object( - self.tm_manager, - "_handle_unhealthy_tm", - side_effect=mock_handle_unhealthy_tm, - ): - # there is no active generator in the beginning - assert not self.tm_manager.is_acting - - # a generator should be created, and be active - self.tm_manager.try_fix() - assert self.tm_manager.is_acting - - # a message may (or may not) arrive - self.tm_manager._AsyncBehaviour__notified = notified - self.tm_manager._AsyncBehaviour__state = state - self.tm_manager._AsyncBehaviour__message = message - - # the generator has a single yield statement, - # a second try_fix() call should finish it - for _ in range(num_iter): - self.tm_manager.try_fix() - assert not self.tm_manager.is_acting, num_iter - - @pytest.mark.parametrize( - "state", - [ - AsyncBehaviour.AsyncState.WAITING_MESSAGE, - AsyncBehaviour.AsyncState.READY, - ], - ) - def test_get_callback_request(self, state: AsyncBehaviour.AsyncState) -> None: - """Tests get_callback_request.""" - self.tm_manager._AsyncBehaviour__state = state - dummy_msg, dummy_behaviour = MagicMock(), MagicMock() - callback_req = self.tm_manager.get_callback_request() - with mock.patch.object(self.tm_manager, "try_send"): - callback_req(dummy_msg, dummy_behaviour) - - def test_is_acting(self) -> None: - """Test is_acting.""" - self.tm_manager._active_generator = MagicMock() - assert self.tm_manager.is_acting - - self.tm_manager._active_generator = None - assert not self.tm_manager.is_acting - - -def test_meta_base_behaviour_when_instance_not_subclass_of_base_behaviour() -> None: - """Test instantiation of meta class when instance not a subclass of BaseBehaviour.""" - - class MyBaseBehaviour(metaclass=_MetaBaseBehaviour): - pass - - -def test_base_behaviour_instantiation_without_attributes_raises_error() -> None: - """Test that definition of concrete subclass of BaseBehaviour without attributes raises error.""" - with pytest.raises(BaseBehaviourInternalError): - - class MyBaseBehaviour(BaseBehaviour): - pass - - -class TestIPFSBehaviour: - """Test IPFSBehaviour tests.""" - - def setup(self) -> None: - """Sets up the tests.""" - self.context_mock = MagicMock() - self.context_mock.ipfs_dialogues = IpfsDialogues( - connection_id=str(IPFS_CONNECTION_ID) - ) - self.behaviour = BehaviourATest(name="", skill_context=self.context_mock) - - def test_build_ipfs_message(self) -> None: - """Tests _build_ipfs_message.""" - res = self.behaviour._build_ipfs_message(IpfsMessage.Performative.GET_FILES) # type: ignore - assert res is not None - - def test_build_ipfs_store_file_req(self) -> None: - """Tests _build_ipfs_store_file_req.""" - with mock.patch.object( - IPFSInteract, "store", return_value=MagicMock() - ) as mock_store: - res = self.behaviour._build_ipfs_store_file_req("dummy_filename", {}) - mock_store.assert_called() - assert res is not None - - def test_build_ipfs_get_file_req(self) -> None: - """Tests _build_ipfs_get_file_req.""" - res = self.behaviour._build_ipfs_get_file_req("dummy_ipfs_hash") - assert res is not None - - def test_deserialize_ipfs_objects(self) -> None: - """Tests _deserialize_ipfs_objects""" - with mock.patch.object( - IPFSInteract, "load", return_value=MagicMock() - ) as mock_load: - res = self.behaviour._deserialize_ipfs_objects({}) - mock_load.assert_called() - assert res is not None diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_common.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_common.py deleted file mode 100644 index 427aa81e1..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_common.py +++ /dev/null @@ -1,407 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the common.py module of the skill.""" - -import random -import re -from typing import ( - Any, - Callable, - Dict, - FrozenSet, - Generator, - Optional, - Set, - Type, - TypeVar, - Union, -) -from unittest import mock -from unittest.mock import MagicMock - -import pytest - -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.common import ( - RandomnessBehaviour, - SelectKeeperBehaviour, - random_selection, -) -from packages.valory.skills.abstract_round_abci.models import BaseParams -from packages.valory.skills.abstract_round_abci.tests.conftest import irrelevant_config -from packages.valory.skills.abstract_round_abci.utils import VerifyDrand - - -ReturnValueType = TypeVar("ReturnValueType") - - -def test_random_selection() -> None: - """Test 'random_selection'""" - assert random_selection(elements=[0, 1, 2], randomness=0.25) == 0 - assert random_selection(elements=[0, 1, 2], randomness=0.5) == 1 - assert random_selection(elements=[0, 1, 2], randomness=0.75) == 2 - - with pytest.raises( - ValueError, match=re.escape("Randomness should lie in the [0,1) interval") - ): - random_selection(elements=[0, 1], randomness=-1) - - with pytest.raises( - ValueError, match=re.escape("Randomness should lie in the [0,1) interval") - ): - random_selection(elements=[0, 1], randomness=1) - - with pytest.raises( - ValueError, match=re.escape("Randomness should lie in the [0,1) interval") - ): - random_selection(elements=[0, 1], randomness=2) - - with pytest.raises(ValueError, match="No elements to randomly select among"): - random_selection(elements=[], randomness=0.5) - - -class DummyRandomnessBehaviour(RandomnessBehaviour): - """Dummy randomness behaviour.""" - - behaviour_id = "dummy_randomness" - payload_class = MagicMock() - matching_round = MagicMock() - - -class DummySelectKeeperBehaviour(SelectKeeperBehaviour): - """Dummy select keeper behaviour.""" - - behaviour_id = "dummy_select_keeper" - payload_class = MagicMock() - matching_round = MagicMock() - - -DummyBehaviourType = Union[DummyRandomnessBehaviour, DummySelectKeeperBehaviour] - - -class BaseDummyBehaviour: # pylint: disable=too-few-public-methods - """A Base dummy behaviour class.""" - - behaviour: DummyBehaviourType - dummy_behaviour_cls: Type[DummyBehaviourType] - - @classmethod - def setup_class(cls) -> None: - """Setup the test class.""" - cls.behaviour = cls.dummy_behaviour_cls( - name="test", - skill_context=MagicMock( - params=BaseParams( - name="test", - skill_context=MagicMock(), - service_id="test_id", - consensus=dict(max_participants=1), - **irrelevant_config, - ), - ), - ) - - -def dummy_generator( - return_value: ReturnValueType, -) -> Callable[[Any, Any], Generator[None, None, ReturnValueType]]: - """A method that returns a dummy generator which yields nothing once and then returns the given `return_value`.""" - - def dummy_generator_wrapped( - *_: Any, **__: Any - ) -> Generator[None, None, ReturnValueType]: - """A wrapped method which yields nothing once and then returns the given `return_value`.""" - yield - return return_value - - return dummy_generator_wrapped - - -def last_iteration(gen: Generator) -> None: - """Perform a generator iteration and ensure that it is the last one.""" - with pytest.raises(StopIteration): - next(gen) - - -class TestRandomnessBehaviour(BaseDummyBehaviour): - """Test `RandomnessBehaviour`.""" - - @classmethod - def setup_class(cls) -> None: - """Setup the test class.""" - cls.dummy_behaviour_cls = DummyRandomnessBehaviour - super().setup_class() - - @pytest.mark.parametrize( - "return_value, expected_hash", - ( - (MagicMock(performative=LedgerApiMessage.Performative.ERROR), None), - (MagicMock(state=MagicMock(body={"hash_key_is_not_in_body": ""})), None), - ( - MagicMock(state=MagicMock(body={"hash": "test_randomness"})), - { - "randomness": "d067b86fa5235e7e5225e8328e8faac5c279cbf57131d647e4da0a70df6d3d7b", - "round": 0, - }, - ), - ), - ) - def test_failsafe_randomness( - self, return_value: MagicMock, expected_hash: Optional[str] - ) -> None: - """Test `failsafe_randomness`.""" - gen = self.behaviour.failsafe_randomness() - - with mock.patch.object( - DummyRandomnessBehaviour, - "get_ledger_api_response", - dummy_generator(return_value), - ): - next(gen) - try: - next(gen) - except StopIteration as e: - assert e.value == expected_hash - else: - raise AssertionError( - "`get_ledger_api_response`'s generator should have been exhausted." - ) - - @pytest.mark.parametrize("randomness_response", ("test", None)) - @pytest.mark.parametrize("verified", (True, False)) - def test_get_randomness_from_api( - self, randomness_response: Optional[str], verified: bool - ) -> None: - """Test `get_randomness_from_api`.""" - # create a dummy `process_response` for `MagicMock`ed `randomness_api` - self.behaviour.context.randomness_api.process_response = ( - lambda res: res + "_processed" if res is not None else None - ) - gen = self.behaviour.get_randomness_from_api() - - with mock.patch.object( - DummyRandomnessBehaviour, - "get_http_response", - dummy_generator(randomness_response), - ), mock.patch.object( - VerifyDrand, - "verify", - return_value=(verified, "Error message."), - ): - next(gen) - try: - next(gen) - except StopIteration as e: - if randomness_response is None or not verified: - assert e.value is None - else: - assert e.value == randomness_response + "_processed" - else: - raise AssertionError( - "`get_randomness_from_api`'s generator should have been exhausted." - ) - - @pytest.mark.parametrize( - "retries_exceeded, failsafe_succeeds", - # (False, False) is not tested, because it does not make sense - ((True, False), (True, True), (False, True)), - ) - @pytest.mark.parametrize( - "observation", - ( - None, - {}, - { - "randomness": "d067b86fa5235e7e5225e8328e8faac5c279cbf57131d647e4da0a70df6d3d7b", - "round": 0, - }, - ), - ) - def test_async_act( - self, - retries_exceeded: bool, - failsafe_succeeds: bool, - observation: Optional[Dict[str, Union[str, int]]], - ) -> None: - """Test `async_act`.""" - # create a dummy `is_retries_exceeded` for `MagicMock`ed `randomness_api` - self.behaviour.context.randomness_api.is_retries_exceeded = ( - lambda: retries_exceeded - ) - gen = self.behaviour.async_act() - - with mock.patch.object( - self.behaviour, - "failsafe_randomness", - dummy_generator(observation), - ), mock.patch.object( - self.behaviour, - "get_randomness_from_api", - dummy_generator(observation), - ), mock.patch.object( - self.behaviour, - "send_a2a_transaction", - ) as send_a2a_transaction_mocked, mock.patch.object( - self.behaviour, - "wait_until_round_end", - ) as wait_until_round_end_mocked, mock.patch.object( - self.behaviour, - "set_done", - ) as set_done_mocked, mock.patch.object( - self.behaviour, - "sleep", - ) as sleep_mocked: - next(gen) - last_iteration(gen) - - if not failsafe_succeeds or failsafe_succeeds and observation is None: - return - - # here, the observation is retrieved from either `failsafe_randomness` or `get_randomness_from_api` - # depending on the test's parametrization - if not observation: - sleep_mocked.assert_called_once_with( - self.behaviour.context.randomness_api.retries_info.suggested_sleep_time - ) - self.behaviour.context.randomness_api.increment_retries.assert_called_once() - return - - send_a2a_transaction_mocked.assert_called_once() - wait_until_round_end_mocked.assert_called_once() - set_done_mocked.assert_called_once() - - def test_clean_up(self) -> None: - """Test `clean_up`.""" - self.behaviour.clean_up() - self.behaviour.context.randomness_api.reset_retries.assert_called_once() - - def teardown(self) -> None: - """Teardown run after each test method.""" - self.behaviour.context.randomness_api.increment_retries.reset_mock() - - -class TestSelectKeeperBehaviour(BaseDummyBehaviour): - """Tests for `SelectKeeperBehaviour`.""" - - @classmethod - def setup_class(cls) -> None: - """Setup the test class.""" - cls.dummy_behaviour_cls = DummySelectKeeperBehaviour - super().setup_class() - - @mock.patch.object(random, "shuffle", lambda do_not_shuffle: do_not_shuffle) - @pytest.mark.parametrize( - "participants, blacklisted_keepers, most_voted_keeper_address, expected_keeper", - ( - ( - frozenset((f"test_p{i}" for i in range(4))), - set(), - "test_p0", - "test_p1", - ), - ( - frozenset((f"test_p{i}" for i in range(4))), - set(), - "test_p1", - "test_p2", - ), - ( - frozenset((f"test_p{i}" for i in range(4))), - set(), - "test_p2", - "test_p3", - ), - ( - frozenset((f"test_p{i}" for i in range(4))), - set(), - "test_p3", - "test_p0", - ), - ( - frozenset((f"test_p{i}" for i in range(4))), - {f"test_p{i}" for i in range(1)}, - "test_p1", - "test_p2", - ), - ( - frozenset((f"test_p{i}" for i in range(4))), - {f"test_p{i}" for i in range(4)}, - "", - "", - ), - ), - ) - def test_select_keeper( - self, - participants: FrozenSet[str], - blacklisted_keepers: Set[str], - most_voted_keeper_address: str, # pylint: disable=unused-argument - expected_keeper: str, - ) -> None: - """Test `_select_keeper`.""" - for sync_data_name in ( - "participants", - "blacklisted_keepers", - "most_voted_keeper_address", - ): - setattr( - self.behaviour.context.state.synchronized_data, - sync_data_name, - locals()[sync_data_name], - ) - - select_keeper_method = ( - self.behaviour._select_keeper # pylint: disable=protected-access - ) - - if not participants - blacklisted_keepers: - with pytest.raises( - RuntimeError, - match="Cannot continue if all the keepers have been blacklisted!", - ): - select_keeper_method() - return - - with mock.patch("random.seed"): - actual_keeper = select_keeper_method() - assert actual_keeper == expected_keeper - - def test_async_act(self) -> None: - """Test `async_act`.""" - gen = self.behaviour.async_act() - - with mock.patch.object( - self.behaviour, - "_select_keeper", - return_value="test_keeper", - ), mock.patch.object( - self.behaviour, - "send_a2a_transaction", - ) as send_a2a_transaction_mocked, mock.patch.object( - self.behaviour, - "wait_until_round_end", - ) as wait_until_round_end_mocked, mock.patch.object( - self.behaviour, - "set_done", - ) as set_done_mocked: - last_iteration(gen) - send_a2a_transaction_mocked.assert_called_once() - wait_until_round_end_mocked.assert_called_once() - set_done_mocked.assert_called_once() diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_dialogues.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_dialogues.py deleted file mode 100644 index 12aeeaaa5..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_dialogues.py +++ /dev/null @@ -1,100 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -from enum import Enum -from typing import Type, cast -from unittest.mock import MagicMock - -import pytest -from aea.protocols.dialogue.base import Dialogues -from aea.skills.base import Model - -from packages.valory.connections.ipfs.connection import PUBLIC_ID as IPFS_CONNECTION_ID -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue, - AbciDialogues, - ContractApiDialogue, - ContractApiDialogues, - HttpDialogue, - HttpDialogues, - IpfsDialogues, - LedgerApiDialogue, - LedgerApiDialogues, - SigningDialogue, - SigningDialogues, - TendermintDialogue, - TendermintDialogues, -) - - -@pytest.mark.parametrize( - "dialogues_cls,expected_role_from_first_message", - [ - (AbciDialogues, AbciDialogue.Role.CLIENT), - (HttpDialogues, HttpDialogue.Role.CLIENT), - (SigningDialogues, SigningDialogue.Role.SKILL), - (LedgerApiDialogues, LedgerApiDialogue.Role.AGENT), - (ContractApiDialogues, ContractApiDialogue.Role.AGENT), - (TendermintDialogues, TendermintDialogue.Role.AGENT), - ], -) -def test_dialogues_creation( - dialogues_cls: Type[Model], expected_role_from_first_message: Enum -) -> None: - """Test XDialogues creations.""" - dialogues = cast(Dialogues, dialogues_cls(name="", skill_context=MagicMock())) - assert expected_role_from_first_message == dialogues._role_from_first_message( - MagicMock(), MagicMock() - ) - - -def test_ledger_api_dialogue() -> None: - """Test 'LedgerApiDialogue' creation.""" - dialogue = LedgerApiDialogue(MagicMock(), "", MagicMock()) - with pytest.raises(ValueError, match="Terms not set!"): - dialogue.terms - - expected_terms = MagicMock() - dialogue.terms = expected_terms - assert expected_terms == dialogue.terms - - -def test_contract_api_dialogue() -> None: - """Test 'ContractApiDialogue' creation.""" - dialogue = ContractApiDialogue(MagicMock(), "", MagicMock()) - with pytest.raises(ValueError, match="Terms not set!"): - dialogue.terms - - expected_terms = MagicMock() - dialogue.terms = expected_terms - assert expected_terms == dialogue.terms - - -def test_ipfs_dialogue() -> None: - """Test 'IpfsDialogues' creation.""" - dialogues = IpfsDialogues(name="", skill_context=MagicMock()) - dialogues.create( - counterparty=str(IPFS_CONNECTION_ID), - performative=IpfsMessage.Performative.GET_FILES, - ) diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_handlers.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_handlers.py deleted file mode 100644 index 415f11ced..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_handlers.py +++ /dev/null @@ -1,596 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the handlers.py module of the skill.""" - -# pylint: skip-file - -import json -import logging -from dataclasses import asdict -from datetime import datetime -from typing import Any, Dict, cast -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from _pytest.logging import LogCaptureFixture -from aea.configurations.data_types import PublicId -from aea.protocols.base import Message - -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import ( - CheckTxType, - CheckTxTypeEnum, - ConsensusParams, - Evidences, - Header, - LastCommitInfo, - Timestamp, - ValidatorUpdates, -) -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.tendermint import TendermintMessage -from packages.valory.skills.abstract_round_abci import handlers -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AddBlockError, - ERROR_CODE, - OK_CODE, - SignatureNotValidError, - TransactionNotValidError, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue, - AbciDialogues, - TendermintDialogue, - TendermintDialogues, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler, - AbstractResponseHandler, - TendermintHandler, - Transaction, - exception_to_info_msg, -) -from packages.valory.skills.abstract_round_abci.models import TendermintRecoveryParams -from packages.valory.skills.abstract_round_abci.test_tools.rounds import DummyRound - - -def test_exception_to_info_msg() -> None: - """Test 'exception_to_info_msg' helper function.""" - exception = Exception("exception message") - expected_string = f"{exception.__class__.__name__}: {str(exception)}" - actual_string = exception_to_info_msg(exception) - assert expected_string == actual_string - - -class TestABCIRoundHandler: - """Test 'ABCIRoundHandler'.""" - - def setup(self) -> None: - """Set up the tests.""" - self.context = MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")) - self.dialogues = AbciDialogues(name="", skill_context=self.context) - self.handler = ABCIRoundHandler(name="", skill_context=self.context) - self.context.state.round_sequence.height = 0 - self.context.state.round_sequence.root_hash = b"root_hash" - self.context.state.round_sequence.last_round_transition_timestamp = ( - datetime.now() - ) - - def test_info(self) -> None: - """Test the 'info' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_INFO, - version="", - block_version=0, - p2p_version=0, - ) - response = self.handler.info( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_INFO - - @pytest.mark.parametrize("app_hash", (b"", b"test")) - def test_init_chain(self, app_hash: bytes) -> None: - """Test the 'init_chain' handler method.""" - time = Timestamp(0, 0) - consensus_params = ConsensusParams(*(mock.MagicMock() for _ in range(4))) - validators = ValidatorUpdates(mock.MagicMock()) - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_INIT_CHAIN, - time=time, - chain_id="test_chain_id", - consensus_params=consensus_params, - validators=validators, - app_state_bytes=b"", - initial_height=10, - ) - self.context.state.round_sequence.last_round_transition_root_hash = app_hash - response = self.handler.init_chain( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_INIT_CHAIN - assert response.validators == ValidatorUpdates([]) - assert response.app_hash == app_hash - - def test_begin_block(self) -> None: - """Test the 'begin_block' handler method.""" - header = Header(*(MagicMock() for _ in range(14))) - last_commit_info = LastCommitInfo(*(MagicMock() for _ in range(2))) - byzantine_validators = Evidences(MagicMock()) - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_BEGIN_BLOCK, - hash=b"", - header=header, - last_commit_info=last_commit_info, - byzantine_validators=byzantine_validators, - ) - response = self.handler.begin_block( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_BEGIN_BLOCK - - @mock.patch.object(handlers, "Transaction") - def test_check_tx(self, *_: Any) -> None: - """Test the 'check_tx' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_CHECK_TX, - tx=b"", - type=CheckTxType(CheckTxTypeEnum.NEW), - ) - response = self.handler.check_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_CHECK_TX - assert response.code == OK_CODE - - @mock.patch.object( - Transaction, - "decode", - side_effect=SignatureNotValidError, - ) - def test_check_tx_negative(self, *_: Any) -> None: - """Test the 'check_tx' handler method, negative case.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_CHECK_TX, - tx=b"", - type=CheckTxType(CheckTxTypeEnum.NEW), - ) - response = self.handler.check_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_CHECK_TX - assert response.code == ERROR_CODE - - @mock.patch.object(handlers, "Transaction") - def test_deliver_tx(self, *_: Any) -> None: - """Test the 'deliver_tx' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - tx=b"", - ) - with mock.patch.object( - self.context.state.round_sequence, "add_pending_offence" - ) as mock_add_pending_offence: - response = self.handler.deliver_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - mock_add_pending_offence.assert_called_once() - - assert response.performative == AbciMessage.Performative.RESPONSE_DELIVER_TX - assert response.code == OK_CODE - - @mock.patch.object( - Transaction, - "decode", - side_effect=SignatureNotValidError, - ) - def test_deliver_tx_negative(self, *_: Any) -> None: - """Test the 'deliver_tx' handler method, negative case.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - tx=b"", - ) - with mock.patch.object( - self.context.state.round_sequence, "add_pending_offence" - ) as mock_add_pending_offence: - response = self.handler.deliver_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - mock_add_pending_offence.assert_not_called() - - assert response.performative == AbciMessage.Performative.RESPONSE_DELIVER_TX - assert response.code == ERROR_CODE - - @mock.patch.object(handlers, "Transaction") - def test_deliver_bad_tx(self, *_: Any) -> None: - """Test the 'deliver_tx' handler method, when the transaction is not ok.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - tx=b"", - ) - with mock.patch.object( - self.context.state.round_sequence, - "check_is_finished", - side_effect=TransactionNotValidError, - ), mock.patch.object( - self.context.state.round_sequence, "add_pending_offence" - ) as mock_add_pending_offence: - response = self.handler.deliver_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - mock_add_pending_offence.assert_called_once() - - assert response.performative == AbciMessage.Performative.RESPONSE_DELIVER_TX - assert response.code == ERROR_CODE - - @pytest.mark.parametrize("request_height", tuple(range(3))) - def test_end_block(self, request_height: int) -> None: - """Test the 'end_block' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_END_BLOCK, - height=request_height, - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) - assert message.height == request_height - assert self.context.state.round_sequence.tm_height != request_height - response = self.handler.end_block(message, dialogue) - assert response.performative == AbciMessage.Performative.RESPONSE_END_BLOCK - assert self.context.state.round_sequence.tm_height == request_height - - def test_commit(self) -> None: - """Test the 'commit' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_COMMIT, - ) - response = self.handler.commit( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_COMMIT - - def test_commit_negative(self) -> None: - """Test the 'commit' handler method, negative case.""" - self.context.state.round_sequence.commit.side_effect = AddBlockError() - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_COMMIT, - ) - with pytest.raises(AddBlockError): - self.handler.commit( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - - -class ConcreteResponseHandler(AbstractResponseHandler): - """A concrete response handler for testing purposes.""" - - SUPPORTED_PROTOCOL = HttpMessage.protocol_id - allowed_response_performatives = frozenset({HttpMessage.Performative.RESPONSE}) - - -class TestAbstractResponseHandler: - """Test 'AbstractResponseHandler'.""" - - def setup(self) -> None: - """Set up the tests.""" - self.context = MagicMock() - self.handler = ConcreteResponseHandler(name="", skill_context=self.context) - - def test_handle(self) -> None: - """Test the 'handle' method.""" - callback = MagicMock() - request_reference = "reference" - self.context.requests.request_id_to_callback = {} - self.context.requests.request_id_to_callback[request_reference] = callback - with mock.patch.object( - self.handler, "_recover_protocol_dialogues" - ) as mock_dialogues_fn: - mock_dialogue = MagicMock() - mock_dialogue.dialogue_label.dialogue_reference = (request_reference, "") - mock_dialogues = MagicMock() - mock_dialogues.update = MagicMock(return_value=mock_dialogue) - mock_dialogues_fn.return_value = mock_dialogues - mock_message = MagicMock(performative=HttpMessage.Performative.RESPONSE) - self.handler.handle(mock_message) - callback.assert_called() - - @mock.patch.object( - AbstractResponseHandler, "_recover_protocol_dialogues", return_value=None - ) - def test_handle_negative_cannot_recover_dialogues(self, *_: Any) -> None: - """Test the 'handle' method, negative case (cannot recover dialogues).""" - self.handler.handle(MagicMock()) - - @mock.patch.object(AbstractResponseHandler, "_recover_protocol_dialogues") - def test_handle_negative_cannot_update_dialogues( - self, mock_dialogues_fn: Any - ) -> None: - """Test the 'handle' method, negative case (cannot update dialogues).""" - mock_dialogues = MagicMock(update=MagicMock(return_value=None)) - mock_dialogues_fn.return_value = mock_dialogues - self.handler.handle(MagicMock()) - - def test_handle_negative_performative_not_allowed(self) -> None: - """Test the 'handle' method, negative case (performative not allowed).""" - self.handler.handle(MagicMock()) - - def test_handle_negative_cannot_find_callback(self) -> None: - """Test the 'handle' method, negative case (cannot find callback).""" - self.context.requests.request_id_to_callback = {} - with pytest.raises( - ABCIAppInternalError, match="No callback defined for request with nonce: " - ): - self.handler.handle( - MagicMock(performative=HttpMessage.Performative.RESPONSE) - ) - - -class TestTendermintHandler: - """Test Tendermint Handler""" - - def setup(self) -> None: - """Set up the tests.""" - self.agent_name = "Alice" - self.context = MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")) - other_agents = ["Alice", "Bob", "Charlie"] - self.context.state = MagicMock(acn_container=lambda: other_agents) - self.handler = TendermintHandler(name="dummy", skill_context=self.context) - self.handler.context.logger = logging.getLogger() - self.dialogues = TendermintDialogues(name="dummy", skill_context=self.context) - - @property - def dummy_validator_config(self) -> Dict[str, Dict[str, str]]: - """Dummy validator config""" - return { - self.agent_name: { - "hostname": "localhost", - "address": "address", - "pub_key": "pub_key", - "peer_id": "peer_id", - } - } - - @staticmethod - def make_error_message() -> TendermintMessage: - """Make dummy error message""" - performative = TendermintMessage.Performative.ERROR - error_code = TendermintMessage.ErrorCode.INVALID_REQUEST - error_msg, error_data = "", {} # type: ignore - message = TendermintMessage( - performative, # type: ignore - error_code=error_code, - error_msg=error_msg, - error_data=error_data, - ) - message.sender = "Alice" - return message - - # pre-condition checks - def test_handle_unidentified_tendermint_dialogue( - self, caplog: LogCaptureFixture - ) -> None: - """Test unidentified tendermint dialogue""" - message = Message() - with mock.patch.object(self.handler.dialogues, "update", return_value=None): - self.handler.handle(message) - log_message = self.handler.LogMessages.unidentified_dialogue.value - assert log_message in caplog.text - - def test_handle_no_addresses_retrieved_yet(self, caplog: LogCaptureFixture) -> None: - """Test handle request no registered addresses""" - performative = TendermintMessage.Performative.GET_GENESIS_INFO - message = TendermintMessage(performative) # type: ignore - message.sender = "Alice" - self.handler.initial_tm_configs = {} - self.handler.handle(message) - log_message = self.handler.LogMessages.no_addresses_retrieved_yet.value - assert log_message in caplog.text - log_message = self.handler.LogMessages.sending_error_response.value - assert log_message in caplog.text - - def test_handle_not_in_registered_addresses( - self, caplog: LogCaptureFixture - ) -> None: - """Test handle response sender not in registered addresses""" - performative = TendermintMessage.Performative.GENESIS_INFO - message = TendermintMessage(performative, info="info") # type: ignore - message.sender = "NotAlice" - self.handler.handle(message) - log_message = self.handler.LogMessages.not_in_registered_addresses.value - assert log_message in caplog.text - - # request - def test_handle_get_genesis_info(self, caplog: LogCaptureFixture) -> None: - """Test handle request for genesis info""" - performative = TendermintMessage.Performative.GET_GENESIS_INFO - message = TendermintMessage(performative) # type: ignore - self.context.agent_address = message.sender = self.agent_name - self.handler.initial_tm_configs = self.dummy_validator_config - self.handler.handle(message) - log_message = self.handler.LogMessages.sending_request_response.value - assert log_message in caplog.text - - # response - def test_handle_response_invalid_addresses(self, caplog: LogCaptureFixture) -> None: - """Test handle response for genesis info with invalid address.""" - validator_config = self.dummy_validator_config - validator_config[self.agent_name]["hostname"] = "random" - performative = TendermintMessage.Performative.GENESIS_INFO - info = json.dumps(validator_config[self.agent_name]) - message = TendermintMessage(performative, info=info) # type: ignore - self.context.agent_address = message.sender = self.agent_name - self.handler.initial_tm_configs = validator_config - self.handler.handle(message) - log_message = self.handler.LogMessages.failed_to_parse_address.value - assert log_message in caplog.text - - def test_handle_genesis_info(self, caplog: LogCaptureFixture) -> None: - """Test handle response for genesis info with valid address""" - performative = TendermintMessage.Performative.GENESIS_INFO - info = json.dumps(self.dummy_validator_config[self.agent_name]) - message = TendermintMessage(performative, info=info) # type: ignore - self.context.agent_address = message.sender = self.agent_name - self.handler.initial_tm_configs = self.dummy_validator_config - self.handler.handle(message) - log_message = self.handler.LogMessages.collected_config_info.value - assert log_message in caplog.text - - @pytest.mark.parametrize("registered", (True, False)) - @pytest.mark.parametrize( - "performative", - ( - TendermintMessage.Performative.RECOVERY_PARAMS, - TendermintMessage.Performative.GET_RECOVERY_PARAMS, - ), - ) - def test_recovery_params( - self, - registered: bool, - performative: TendermintMessage.Performative, - caplog: LogCaptureFixture, - ) -> None: - """Test handle response for recovery parameters.""" - if not registered: - self.agent_name = "not-registered" - - if performative == TendermintMessage.Performative.GET_RECOVERY_PARAMS: - self.context.state.tm_recovery_params = TendermintRecoveryParams( - "DummyRound" - ) - message = TendermintMessage(performative) # type: ignore - log_message = self.handler.LogMessages.sending_request_response.value - elif performative == TendermintMessage.Performative.RECOVERY_PARAMS: - params = json.dumps( - asdict(TendermintRecoveryParams(DummyRound.auto_round_id())) - ) - message = TendermintMessage(performative, params=params) # type: ignore - log_message = self.handler.LogMessages.collected_params.value - else: - raise AssertionError( - f"Invalid performative {performative} for `test_recovery_params`." - ) - - self.context.agent_address = message.sender = self.agent_name - tm_configs = {self.agent_name: {"dummy": "value"}} if registered else {} - - self.handler.initial_tm_configs = tm_configs - self.handler.handle(message) - - if not registered: - log_message = self.handler.LogMessages.not_in_registered_addresses.value - - assert log_message in caplog.text - - @pytest.mark.parametrize( - "side_effect, expected_exception", - ( - ( - json.decoder.JSONDecodeError("", "", 0), - ": line 1 column 1 (char 0)", - ), - ( - {"not a dict"}, - "argument after ** must be a mapping, not str", - ), - ), - ) - def test_recovery_params_error( - self, - side_effect: Any, - expected_exception: str, - caplog: LogCaptureFixture, - ) -> None: - """Test handle response for recovery parameters.""" - message = TendermintMessage( - TendermintMessage.Performative.RECOVERY_PARAMS, params=MagicMock() # type: ignore - ) - - self.context.agent_address = message.sender = self.agent_name - tm_configs = {self.agent_name: {"dummy": "value"}} - self.handler.initial_tm_configs = tm_configs - with mock.patch.object(json, "loads", side_effect=side_effect): - self.handler.handle(message) - - log_message = self.handler.LogMessages.failed_to_parse_params.value - assert log_message in caplog.text - assert expected_exception in caplog.text - - # error - def test_handle_error(self, caplog: LogCaptureFixture) -> None: - """Test handle error""" - message = self.make_error_message() - self.handler.initial_tm_configs = self.dummy_validator_config - self.handler.handle(message) - log_message = self.handler.LogMessages.received_error_response.value - assert log_message in caplog.text - - def test_handle_error_no_target_message_retrieved( - self, caplog: LogCaptureFixture - ) -> None: - """Test handle error no target message retrieved""" - message, nonce = self.make_error_message(), "0" - dialogue = TendermintDialogue(mock.Mock(), "Bob", mock.Mock()) - dialogue.dialogue_label.dialogue_reference = nonce, "stub" - self.handler.dialogues.update = lambda _: dialogue # type: ignore - callback = lambda *args, **kwargs: None # noqa: E731 - self.context.requests.request_id_to_callback = {nonce: callback} - self.handler.initial_tm_configs = self.dummy_validator_config - self.handler.handle(message) - log_message = ( - self.handler.LogMessages.received_error_without_target_message.value - ) - assert log_message in caplog.text - - # performative - def test_handle_performative_not_recognized( - self, caplog: LogCaptureFixture - ) -> None: - """Test performative no recognized""" - message = self.make_error_message() - message._slots.performative = MagicMock(value="wacky") - self.handler.initial_tm_configs = self.dummy_validator_config - self.handler.handle(message) - log_message = self.handler.LogMessages.performative_not_recognized.value - assert log_message in caplog.text - - def test_sender_not_in_registered_addresses( - self, caplog: LogCaptureFixture - ) -> None: - """Test sender not in registered addresses.""" - - performative = TendermintMessage.Performative.GET_GENESIS_INFO - message = TendermintMessage(performative) # type: ignore - self.context.agent_address = message.sender = "dummy" - self.handler.initial_tm_configs = self.dummy_validator_config - self.handler.handle(message) - log_message = self.handler.LogMessages.not_in_registered_addresses.value - assert log_message in caplog.text diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/__init__.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/__init__.py deleted file mode 100644 index b640bcf74..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Package for `io` testing.""" diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/test_ipfs.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/test_ipfs.py deleted file mode 100644 index ce81b61a7..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/test_ipfs.py +++ /dev/null @@ -1,110 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 tests for the `IPFS` interactions.""" - -# pylint: skip-file - -import os -from pathlib import PosixPath -from typing import Any, Dict, cast -from unittest import mock - -import pytest - -from packages.valory.skills.abstract_round_abci.io_.ipfs import ( - IPFSInteract, - IPFSInteractionError, -) -from packages.valory.skills.abstract_round_abci.io_.load import AbstractLoader -from packages.valory.skills.abstract_round_abci.io_.store import ( - AbstractStorer, - StoredJSONType, - SupportedFiletype, -) - - -use_ipfs_daemon = pytest.mark.usefixtures("ipfs_daemon") - - -class TestIPFSInteract: - """Test `IPFSInteract`.""" - - def setup(self) -> None: - """Setup test class.""" - self.ipfs_interact = IPFSInteract() - - @pytest.mark.parametrize("multiple", (True, False)) - def test_store_and_send_and_back( - self, - multiple: bool, - dummy_obj: StoredJSONType, - dummy_multiple_obj: Dict[str, StoredJSONType], - tmp_path: PosixPath, - ) -> None: - """Test store -> send -> download -> read of objects.""" - obj: StoredJSONType - if multiple: - obj = dummy_multiple_obj - filepath = "dummy_dir" - else: - obj = dummy_obj - filepath = "test_file.json" - - filepath = str(tmp_path / filepath) - serialized_objects = self.ipfs_interact.store( - filepath, obj, multiple, SupportedFiletype.JSON - ) - expected_objects = obj - actual_objects = cast( - Dict[str, Any], - self.ipfs_interact.load( - serialized_objects, - SupportedFiletype.JSON, - ), - ) - if multiple: - # here we manually remove the trailing the dir from the name. - # This is done by the IPFS connection under normal circumstances. - actual_objects = {os.path.basename(k): v for k, v in actual_objects.items()} - - assert actual_objects == expected_objects - - def test_store_fails(self, dummy_multiple_obj: Dict[str, StoredJSONType]) -> None: - """Tests when "store" fails.""" - dummy_filepath = "dummy_dir" - multiple = False - with mock.patch.object( - AbstractStorer, - "store", - side_effect=ValueError, - ), pytest.raises(IPFSInteractionError): - self.ipfs_interact.store( - dummy_filepath, dummy_multiple_obj, multiple, SupportedFiletype.JSON - ) - - def test_load_fails(self, dummy_multiple_obj: Dict[str, StoredJSONType]) -> None: - """Tests when "load" fails.""" - dummy_object = {"test": "test"} - with mock.patch.object( - AbstractLoader, - "load", - side_effect=ValueError, - ), pytest.raises(IPFSInteractionError): - self.ipfs_interact.load(dummy_object) diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/test_load.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/test_load.py deleted file mode 100644 index ae48cefca..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/test_load.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for the loading functionality of abstract round abci.""" - -# pylint: skip-file - -import json -from typing import Optional, cast - -import pytest - -from packages.valory.skills.abstract_round_abci.io_.load import ( - CustomLoaderType, - JSONLoader, - Loader, - SupportedLoaderType, -) -from packages.valory.skills.abstract_round_abci.io_.store import SupportedFiletype - - -class TestLoader: - """Tests for the `Loader`.""" - - def setup(self) -> None: - """Setup the tests.""" - self.json_loader = Loader(SupportedFiletype.JSON, None) - - def __dummy_custom_loader(self) -> None: - """A dummy custom loading function to use for the tests.""" - - @staticmethod - @pytest.mark.parametrize( - "filetype, custom_loader, expected_loader", - ( - (None, None, None), - (SupportedFiletype.JSON, None, JSONLoader.load_single_object), - ( - SupportedFiletype.JSON, - __dummy_custom_loader, - JSONLoader.load_single_object, - ), - (None, __dummy_custom_loader, __dummy_custom_loader), - ), - ) - def test__get_loader_from_filetype( - filetype: Optional[SupportedFiletype], - custom_loader: CustomLoaderType, - expected_loader: Optional[SupportedLoaderType], - ) -> None: - """Test `_get_loader_from_filetype`.""" - if all( - test_arg is None for test_arg in (filetype, custom_loader, expected_loader) - ): - with pytest.raises( - ValueError, - match="Please provide either a supported filetype or a custom loader function.", - ): - Loader(filetype, custom_loader)._get_single_loader_from_filetype() - - else: - expected_loader = cast(SupportedLoaderType, expected_loader) - loader = Loader(filetype, custom_loader) - assert ( - loader._get_single_loader_from_filetype().__code__.co_code - == expected_loader.__code__.co_code - ) - - def test_load(self) -> None: - """Test `load`.""" - expected_object = dummy_object = {"test": "test"} - filename = "test" - serialized_object = json.dumps(dummy_object) - actual_object = self.json_loader.load({filename: serialized_object}) - assert expected_object == actual_object - - def test_no_object(self) -> None: - """Test `load` throws error when no object is provided.""" - with pytest.raises( - ValueError, - match='"serialized_objects" does not contain any objects', - ): - self.json_loader.load({}) - - def test_load_multiple_objects(self) -> None: - """Test `load` when multiple objects are to be deserialized.""" - dummy_object = {"test": "test"} - serialized_object = json.dumps(dummy_object) - serialized_objects = { - "obj1": serialized_object, - "obj2": serialized_object, - } - expected_objects = { - "obj1": dummy_object, - "obj2": dummy_object, - } - actual_objects = self.json_loader.load(serialized_objects) - assert expected_objects == actual_objects diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/test_store.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/test_store.py deleted file mode 100644 index eae3d53b0..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_io/test_store.py +++ /dev/null @@ -1,104 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for the storing functionality of abstract round abci.""" - -# pylint: skip-file - -import json -from pathlib import Path, PosixPath -from typing import Optional, cast - -import pytest - -from packages.valory.skills.abstract_round_abci.io_.store import ( - CustomStorerType, - JSONStorer, - Storer, - SupportedFiletype, - SupportedStorerType, -) - - -class TestStorer: - """Tests for the `Storer`.""" - - def setup(self) -> None: - """Setup the tests.""" - self.path = "tmp" - self.json_storer = Storer(SupportedFiletype.JSON, None, self.path) - - def __dummy_custom_storer(self) -> None: - """A dummy custom storing function to use for the tests.""" - - @staticmethod - @pytest.mark.parametrize( - "filetype, custom_storer, expected_storer", - ( - (None, None, None), - (SupportedFiletype.JSON, None, JSONStorer.serialize_object), - ( - SupportedFiletype.JSON, - __dummy_custom_storer, - JSONStorer.serialize_object, - ), - (None, __dummy_custom_storer, __dummy_custom_storer), - ), - ) - def test__get_single_storer_from_filetype( - filetype: Optional[SupportedFiletype], - custom_storer: Optional[CustomStorerType], - expected_storer: Optional[SupportedStorerType], - tmp_path: PosixPath, - ) -> None: - """Test `_get_single_storer_from_filetype`.""" - if all( - test_arg is None for test_arg in (filetype, custom_storer, expected_storer) - ): - with pytest.raises( - ValueError, - match="Please provide either a supported filetype or a custom storing function.", - ): - Storer( - filetype, custom_storer, str(tmp_path) - )._get_single_storer_from_filetype() - - else: - expected_storer = cast(SupportedStorerType, expected_storer) - storer = Storer(filetype, custom_storer, str(tmp_path)) - assert ( - storer._get_single_storer_from_filetype().__code__.co_code - == expected_storer.__code__.co_code - ) - - def test_store(self) -> None: - """Test `store`.""" - dummy_object = {"test": "test"} - expected_object = {self.path: json.dumps(dummy_object, indent=4)} - actual_object = self.json_storer.store(dummy_object, False) - assert expected_object == actual_object - - def test_store_multiple(self) -> None: - """Test `store` when multiple files are present.""" - dummy_object = {"test": "test"} - dummy_filename = "test" - expected_path = Path(f"{self.path}/{dummy_filename}").__str__() - expected_object = {expected_path: json.dumps(dummy_object, indent=4)} - actual_object = self.json_storer.store({dummy_filename: dummy_object}, True) - assert expected_object == actual_object diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_models.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_models.py deleted file mode 100644 index ee598b722..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_models.py +++ /dev/null @@ -1,901 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the models.py module of the skill.""" - -# pylint: skip-file - -import builtins -import json -import logging -import re -from collections import OrderedDict -from dataclasses import dataclass -from enum import Enum -from pathlib import Path -from tempfile import TemporaryDirectory -from time import sleep -from typing import Any, Dict, List, Optional, Set, Tuple, Type, cast -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from aea.exceptions import AEAEnforceError -from typing_extensions import Literal, TypedDict - -from packages.valory.skills.abstract_round_abci.base import ( - AbstractRound, - BaseSynchronizedData, - OffenceStatus, - OffenseStatusEncoder, - ROUND_COUNT_DEFAULT, -) -from packages.valory.skills.abstract_round_abci.models import ( - ApiSpecs, - BaseParams, - BenchmarkTool, - DEFAULT_BACKOFF_FACTOR, - GenesisBlock, - GenesisConfig, - GenesisConsensusParams, - GenesisEvidence, - GenesisValidator, - MIN_RESET_PAUSE_DURATION, - NUMBER_OF_RETRIES, - Requests, -) -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.abstract_round_abci.models import ( - TendermintRecoveryParams, - _MetaSharedState, - check_type, -) -from packages.valory.skills.abstract_round_abci.test_tools.abci_app import AbciAppTest -from packages.valory.skills.abstract_round_abci.tests.conftest import ( - irrelevant_genesis_config, -) - - -BASE_DUMMY_SPECS_CONFIG = dict( - name="dummy", - skill_context=MagicMock(), - url="http://dummy", - api_id="api_id", - method="GET", - headers=OrderedDict([("Dummy-Header", "dummy_value")]), - parameters=OrderedDict([("Dummy-Param", "dummy_param")]), -) - -BASE_DUMMY_PARAMS = dict( - name="", - skill_context=MagicMock(is_abstract_component=True), - setup={}, - tendermint_url="", - max_healthcheck=1, - round_timeout_seconds=1.0, - sleep_time=1, - retry_timeout=1, - retry_attempts=1, - reset_pause_duration=MIN_RESET_PAUSE_DURATION, - drand_public_key="", - tendermint_com_url="", - reset_tendermint_after=1, - service_id="abstract_round_abci", - service_registry_address="0xa51c1fc2f0d1a1b8494ed1fe312d7c3a78ed91c0", - keeper_timeout=1.0, - tendermint_check_sleep_delay=3, - tendermint_max_retries=5, - cleanup_history_depth=0, - genesis_config=irrelevant_genesis_config, - cleanup_history_depth_current=None, - request_timeout=0.0, - request_retry_delay=0.0, - tx_timeout=0.0, - max_attempts=0, - on_chain_service_id=None, - share_tm_config_on_startup=False, - tendermint_p2p_url="", - use_termination=False, - use_slashing=False, - slash_cooldown_hours=3, - slash_threshold_amount=10_000_000_000_000_000, - light_slash_unit_amount=5_000_000_000_000_000, - serious_slash_unit_amount=8_000_000_000_000_000, -) - - -class TestApiSpecsModel: - """Test ApiSpecsModel.""" - - api_specs: ApiSpecs - - def setup( - self, - ) -> None: - """Setup test.""" - - self.api_specs = ApiSpecs( - **BASE_DUMMY_SPECS_CONFIG, - response_key="value", - response_index=0, - response_type="float", - error_key="error", - error_index=None, - error_type="str", - error_data="error text", - ) - - def test_init( - self, - ) -> None: - """Test initialization.""" - - # test ensure method. - with pytest.raises( - AEAEnforceError, - match="'url' of type '' required, but it is not set in `models.params.args` of `skill.yaml` of", - ): - _ = ApiSpecs( - name="dummy", - skill_context=MagicMock(), - ) - - assert self.api_specs.retries_info.backoff_factor == DEFAULT_BACKOFF_FACTOR - assert self.api_specs.retries_info.retries == NUMBER_OF_RETRIES - assert self.api_specs.retries_info.retries_attempted == 0 - - assert self.api_specs.url == "http://dummy" - assert self.api_specs.api_id == "api_id" - assert self.api_specs.method == "GET" - assert self.api_specs.headers == {"Dummy-Header": "dummy_value"} - assert self.api_specs.parameters == {"Dummy-Param": "dummy_param"} - assert self.api_specs.response_info.response_key == "value" - assert self.api_specs.response_info.response_index == 0 - assert self.api_specs.response_info.response_type == "float" - assert self.api_specs.response_info.error_key == "error" - assert self.api_specs.response_info.error_index is None - assert self.api_specs.response_info.error_type == "str" - assert self.api_specs.response_info.error_data is None - - @pytest.mark.parametrize("retries", range(10)) - def test_suggested_sleep_time(self, retries: int) -> None: - """Test `suggested_sleep_time`""" - self.api_specs.retries_info.retries_attempted = retries - assert ( - self.api_specs.retries_info.suggested_sleep_time - == DEFAULT_BACKOFF_FACTOR**retries - ) - - def test_retries( - self, - ) -> None: - """Tests for retries.""" - - self.api_specs.increment_retries() - assert self.api_specs.retries_info.retries_attempted == 1 - assert not self.api_specs.is_retries_exceeded() - - for _ in range(NUMBER_OF_RETRIES): - self.api_specs.increment_retries() - assert self.api_specs.is_retries_exceeded() - self.api_specs.reset_retries() - assert self.api_specs.retries_info.retries_attempted == 0 - - def test_get_spec( - self, - ) -> None: - """Test get_spec method.""" - - actual_specs = { - "url": "http://dummy", - "method": "GET", - "headers": {"Dummy-Header": "dummy_value"}, - "parameters": {"Dummy-Param": "dummy_param"}, - } - - specs = self.api_specs.get_spec() - assert all([key in specs for key in actual_specs.keys()]) - assert all([specs[key] == actual_specs[key] for key in actual_specs]) - - @pytest.mark.parametrize( - "api_specs_config, message, expected_res, expected_error", - ( - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="value", - response_index=None, - response_type="float", - error_key=None, - error_index=None, - error_data=None, - ), - MagicMock(body=b'{"value": "10.232"}'), - 10.232, - None, - ), - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="test:response:key", - response_index=2, - response_type="dict", - error_key="error:key", - error_index=3, - error_type="str", - error_data=None, - ), - MagicMock( - body=b'{"test": {"response": {"key": ["does_not_matter", "does_not_matter", {"this": "matters"}]}}}' - ), - {"this": "matters"}, - None, - ), - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="test:response:key", - response_index=2, - error_key="error:key", - error_index=3, - error_type="str", - error_data=None, - ), - MagicMock(body=b'{"cannot be parsed'), - None, - None, - ), - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="test:response:key", - response_index=2, - error_key="error:key", - error_index=3, - error_type="str", - error_data=None, - ), - MagicMock( - # the null will raise `TypeError` and we test that it is handled - body=b'{"test": {"response": {"key": ["does_not_matter", "does_not_matter", null]}}}' - ), - "None", - None, - ), - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="test:response:key", - response_index=2, # this will raise `IndexError` and we test that it is handled - error_key="error:key", - error_index=3, - error_type="str", - error_data=None, - ), - MagicMock( - body=b'{"test": {"response": {"key": ["does_not_matter", "does_not_matter"]}}}' - ), - None, - None, - ), - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="test:response:key", # this will raise `KeyError` and we test that it is handled - response_index=2, - error_key="error:key", - error_index=3, - error_type="str", - error_data=None, - ), - MagicMock( - body=b'{"test": {"response": {"key_does_not_match": ["does_not_matter", "does_not_matter"]}}}' - ), - None, - None, - ), - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="test:response:key", - response_index=2, - error_key="error:key", - error_index=3, - error_type="str", - error_data=None, - ), - MagicMock( - body=b'{"test": {"response": {"key_does_not_match": ["does_not_matter", "does_not_matter"]}}, ' - b'"error": {"key": [0, 1, 2, "test that the error is being parsed correctly"]}}' - ), - None, - "test that the error is being parsed correctly", - ), - ), - ) - def test_process_response( - self, - api_specs_config: dict, - message: MagicMock, - expected_res: Any, - expected_error: Any, - ) -> None: - """Test `process_response` method.""" - api_specs = ApiSpecs(**api_specs_config) - actual = api_specs.process_response(message) - assert actual == expected_res - response_type = api_specs_config.get("response_type", None) - if response_type is not None: - assert type(actual) == getattr(builtins, response_type) - assert api_specs.response_info.error_data == expected_error - - def test_attribute_manipulation(self) -> None: - """Test manipulating the attributes.""" - with pytest.raises(AttributeError, match="This object is frozen!"): - del self.api_specs.url - - with pytest.raises(AttributeError, match="This object is frozen!"): - self.api_specs.url = "" - - self.api_specs.__dict__["_frozen"] = False - self.api_specs.url = "" - del self.api_specs.url - - -class ConcreteRound(AbstractRound): - """A ConcreteRoundA for testing purposes.""" - - synchronized_data_class = MagicMock() - payload_attribute = MagicMock() - payload_class = MagicMock() - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Handle the end of the block.""" - - -class SharedState(BaseSharedState): - """Shared State for testing purposes.""" - - abci_app_cls = AbciAppTest - - -class TestSharedState: - """Test SharedState(Model) class.""" - - def test_initialization(self, *_: Any) -> None: - """Test the initialization of the shared state.""" - SharedState(name="", skill_context=MagicMock()) - - @staticmethod - def dummy_state_setup(shared_state: SharedState) -> None: - """Setup a shared state instance with dummy params.""" - shared_state.context.params.setup_params = { - "test": [], - "all_participants": list(range(4)), - } - shared_state.setup() - - @pytest.mark.parametrize( - "acn_configured_agents, validator_to_agent, raises", - ( - ( - {i for i in range(4)}, - {f"validator_address_{i}": i for i in range(4)}, - False, - ), - ( - {i for i in range(5)}, - {f"validator_address_{i}": i for i in range(4)}, - True, - ), - ( - {i for i in range(4)}, - {f"validator_address_{i}": i for i in range(5)}, - True, - ), - ), - ) - def test_setup_slashing( - self, - acn_configured_agents: Set[str], - validator_to_agent: Dict[str, str], - raises: bool, - ) -> None: - """Test the `validator_to_agent` properties.""" - shared_state = SharedState(name="", skill_context=MagicMock()) - self.dummy_state_setup(shared_state) - - if not raises: - shared_state.initial_tm_configs = dict.fromkeys(acn_configured_agents) - shared_state.setup_slashing(validator_to_agent) - assert shared_state.round_sequence.validator_to_agent == validator_to_agent - - status = shared_state.round_sequence.offence_status - encoded_status = json.dumps( - status, - cls=OffenseStatusEncoder, - ) - expected_status = { - agent: OffenceStatus() for agent in acn_configured_agents - } - encoded_expected_status = json.dumps( - expected_status, cls=OffenseStatusEncoder - ) - - assert encoded_status == encoded_expected_status - - random_agent = acn_configured_agents.pop() - status[random_agent].num_unknown_offenses = 10 - assert status[random_agent].num_unknown_offenses == 10 - - for other_agent in acn_configured_agents - {random_agent}: - assert status[other_agent].num_unknown_offenses == 0 - - return - - expected_diff = acn_configured_agents.symmetric_difference( - validator_to_agent.values() - ) - with pytest.raises( - ValueError, - match=re.escape( - f"Trying to use the mapping `{validator_to_agent}`, which contains validators for non-configured " - "agents and/or does not contain validators for some configured agents. The agents which have been " - f"configured via ACN are `{acn_configured_agents}` and the diff was for {expected_diff}." - ), - ): - shared_state.initial_tm_configs = dict.fromkeys(acn_configured_agents) - shared_state.setup_slashing(validator_to_agent) - - def test_setup(self, *_: Any) -> None: - """Test setup method.""" - shared_state = SharedState( - name="", skill_context=MagicMock(is_abstract_component=False) - ) - assert shared_state.initial_tm_configs == {} - self.dummy_state_setup(shared_state) - assert shared_state.initial_tm_configs == {i: None for i in range(4)} - - @pytest.mark.parametrize( - "initial_tm_configs, address_input, exception, expected", - ( - ( - {}, - "0x1", - "The validator address of non-participating agent `0x1` was requested.", - None, - ), - ({}, "0x0", "SharedState's setup was not performed successfully.", None), - ( - {"0x0": None}, - "0x0", - "ACN registration has not been successfully performed for agent `0x0`. " - "Have you set the `share_tm_config_on_startup` flag to `true` in the configuration?", - None, - ), - ( - {"0x0": {}}, - "0x0", - "The tendermint configuration for agent `0x0` is invalid: `{}`.", - None, - ), - ( - {"0x0": {"address": None}}, - "0x0", - "The tendermint configuration for agent `0x0` is invalid: `{'address': None}`.", - None, - ), - ( - {"0x0": {"address": "test_validator_address"}}, - "0x0", - None, - "test_validator_address", - ), - ), - ) - def test_get_validator_address( - self, - initial_tm_configs: Dict[str, Optional[Dict[str, Any]]], - address_input: str, - exception: Optional[str], - expected: Optional[str], - ) -> None: - """Test `get_validator_address` method.""" - shared_state = SharedState(name="", skill_context=MagicMock()) - with mock.patch.object(shared_state.context, "params") as mock_params: - mock_params.setup_params = { - "all_participants": ["0x0"], - } - shared_state.setup() - shared_state.initial_tm_configs = initial_tm_configs - if exception is None: - assert shared_state.get_validator_address(address_input) == expected - return - with pytest.raises(ValueError, match=exception): - shared_state.get_validator_address(address_input) - - @pytest.mark.parametrize("self_idx", (range(4))) - def test_acn_container(self, self_idx: int) -> None: - """Test the `acn_container` method.""" - - shared_state = SharedState( - name="", skill_context=MagicMock(agent_address=self_idx) - ) - self.dummy_state_setup(shared_state) - expected = {i: None for i in range(4) if i != self_idx} - assert shared_state.acn_container() == expected - - def test_synchronized_data_negative_not_available(self, *_: Any) -> None: - """Test 'synchronized_data' property getter, negative case (not available).""" - shared_state = SharedState(name="", skill_context=MagicMock()) - with pytest.raises(ValueError, match="round sequence not available"): - shared_state.synchronized_data - - def test_synchronized_data_positive(self, *_: Any) -> None: - """Test 'synchronized_data' property getter, negative case (not available).""" - shared_state = SharedState(name="", skill_context=MagicMock()) - shared_state.context.params.setup_params = { - "test": [], - "all_participants": [["0x0"]], - } - shared_state.setup() - shared_state.round_sequence.abci_app._round_results = [MagicMock()] - shared_state.synchronized_data - - def test_synchronized_data_db(self, *_: Any) -> None: - """Test 'synchronized_data' AbciAppDB.""" - shared_state = SharedState(name="", skill_context=MagicMock()) - with mock.patch.object(shared_state.context, "params") as mock_params: - mock_params.setup_params = { - "safe_contract_address": "0xsafe", - "oracle_contract_address": "0xoracle", - "all_participants": "0x0", - } - shared_state.setup() - for key, value in mock_params.setup_params.items(): - assert shared_state.synchronized_data.db.get_strict(key) == value - - @pytest.mark.parametrize( - "address_to_acn_deliverable, n_participants, expected", - ( - ({}, 4, None), - ({i: "test" for i in range(4)}, 4, "test"), - ( - {i: TendermintRecoveryParams("test") for i in range(4)}, - 4, - TendermintRecoveryParams("test"), - ), - ({1: "test", 2: "non-matching", 3: "test", 4: "test"}, 4, "test"), - ({i: "test" for i in range(4)}, 4, "test"), - ({1: "no", 2: "result", 3: "matches", 4: ""}, 4, None), - ), - ) - def test_get_acn_result( - self, - address_to_acn_deliverable: Dict[str, Any], - n_participants: int, - expected: Optional[str], - ) -> None: - """Test `get_acn_result`.""" - shared_state = SharedState( - abci_app_cls=AbciAppTest, name="", skill_context=MagicMock() - ) - shared_state.context.params.setup_params = { - "test": [], - "all_participants": ["0x0"], - } - shared_state.setup() - shared_state.synchronized_data.update(participants=tuple(range(n_participants))) - shared_state.address_to_acn_deliverable = address_to_acn_deliverable - actual = shared_state.get_acn_result() - - assert actual == expected - - def test_recovery_params_on_init(self) -> None: - """Test that `tm_recovery_params` get initialized correctly.""" - shared_state = SharedState(name="", skill_context=MagicMock()) - assert shared_state.tm_recovery_params is not None - assert shared_state.tm_recovery_params.round_count == ROUND_COUNT_DEFAULT - assert ( - shared_state.tm_recovery_params.reset_from_round - == AbciAppTest.initial_round_cls.auto_round_id() - ) - assert shared_state.tm_recovery_params.reset_params is None - - def test_set_last_reset_params(self) -> None: - """Test that `last_reset_params` get set correctly.""" - shared_state = SharedState(name="", skill_context=MagicMock()) - test_params = [("genesis_time", "some-time"), ("initial_height", "0")] - shared_state.last_reset_params = test_params - assert shared_state.last_reset_params == test_params - - -class TestBenchmarkTool: - """Test BenchmarkTool""" - - @staticmethod - def _check_behaviour_data(data: List, agent_name: str) -> None: - """Check behaviour data.""" - assert len(data) == 1 - - (behaviour_data,) = data - assert behaviour_data["behaviour"] == agent_name - assert all( - [key in behaviour_data["data"] for key in ("local", "consensus", "total")] - ) - - def test_end_2_end(self) -> None: - """Test end 2 end of the tool.""" - - agent_name = "agent" - skill_context = MagicMock( - agent_address=agent_name, logger=MagicMock(info=logging.info) - ) - - with TemporaryDirectory() as temp_dir: - benchmark = BenchmarkTool( - name=agent_name, skill_context=skill_context, log_dir=temp_dir - ) - - with benchmark.measure(agent_name).local(): - sleep(1.0) - - with benchmark.measure(agent_name).consensus(): - sleep(1.0) - - self._check_behaviour_data(benchmark.data, agent_name) - - benchmark.save() - - benchmark_dir = Path(temp_dir, agent_name) - benchmark_file = benchmark_dir / "0.json" - assert (benchmark_file).is_file() - - behaviour_data = json.loads(benchmark_file.read_text()) - self._check_behaviour_data(behaviour_data, agent_name) - - -def test_requests_model_initialization() -> None: - """Test initialization of the 'Requests(Model)' class.""" - Requests(name="", skill_context=MagicMock()) - - -def test_base_params_model_initialization() -> None: - """Test initialization of the 'BaseParams(Model)' class.""" - kwargs = BASE_DUMMY_PARAMS.copy() - bp = BaseParams(**kwargs) - - with pytest.raises(AttributeError, match="This object is frozen!"): - bp.request_timeout = 0.1 - - with pytest.raises(AttributeError, match="This object is frozen!"): - del bp.request_timeout - - bp.__dict__["_frozen"] = False - del bp.request_timeout - - assert getattr(bp, "request_timeout", None) is None - - kwargs["skill_context"] = MagicMock(is_abstract_component=False) - required_setup_params = { - "safe_contract_address": "0x0", - "all_participants": ["0x0"], - "consensus_threshold": 1, - } - kwargs["setup"] = required_setup_params - BaseParams(**kwargs) - - -@pytest.mark.parametrize( - "setup, error_text", - ( - ({}, "`setup` params contain no values!"), - ( - {"a": "b"}, - "Value for `safe_contract_address` missing from the `setup` params.", - ), - ), -) -def test_incorrect_setup(setup: Dict[str, Any], error_text: str) -> None: - """Test BaseParams model initialization with incorrect setup data.""" - kwargs = BASE_DUMMY_PARAMS.copy() - - with pytest.raises( - AEAEnforceError, - match=error_text, - ): - kwargs["skill_context"] = MagicMock(is_abstract_component=False) - kwargs["setup"] = setup - BaseParams(**kwargs) - - with pytest.raises( - AEAEnforceError, - match=f"`reset_pause_duration` must be greater than or equal to {MIN_RESET_PAUSE_DURATION}", - ): - kwargs["reset_pause_duration"] = MIN_RESET_PAUSE_DURATION - 1 - BaseParams(**kwargs) - - -def test_genesis_block() -> None: - """Test genesis block methods.""" - json = {"max_bytes": "a", "max_gas": "b", "time_iota_ms": "c"} - gb = GenesisBlock(**json) - assert gb.to_json() == json - - with pytest.raises(TypeError, match="Error in field 'max_bytes'. Expected type .*"): - json["max_bytes"] = 0 # type: ignore - GenesisBlock(**json) - - -def test_genesis_evidence() -> None: - """Test genesis evidence methods.""" - json = {"max_age_num_blocks": "a", "max_age_duration": "b", "max_bytes": "c"} - ge = GenesisEvidence(**json) - assert ge.to_json() == json - - -def test_genesis_validator() -> None: - """Test genesis validator methods.""" - json = {"pub_key_types": ["a", "b"]} - ge = GenesisValidator(pub_key_types=tuple(json["pub_key_types"])) - assert ge.to_json() == json - - with pytest.raises( - TypeError, match="Error in field 'pub_key_types'. Expected type .*" - ): - GenesisValidator(**json) # type: ignore - - -def test_genesis_consensus_params() -> None: - """Test genesis consensus params methods.""" - consensus_params = cast(Dict, irrelevant_genesis_config["consensus_params"]) - gcp = GenesisConsensusParams.from_json_dict(consensus_params) - assert gcp.to_json() == consensus_params - - -def test_genesis_config() -> None: - """Test genesis config methods.""" - gcp = GenesisConfig.from_json_dict(irrelevant_genesis_config) - assert gcp.to_json() == irrelevant_genesis_config - - -def test_meta_shared_state_when_instance_not_subclass_of_shared_state() -> None: - """Test instantiation of meta class when instance not a subclass of shared state.""" - - class MySharedState(metaclass=_MetaSharedState): - pass - - -def test_shared_state_instantiation_without_attributes_raises_error() -> None: - """Test that definition of concrete subclass of SharedState without attributes raises error.""" - with pytest.raises(AttributeError, match="'abci_app_cls' not set on .*"): - - class MySharedState(BaseSharedState): - pass - - with pytest.raises(AttributeError, match="The object `None` is not a class"): - - class MySharedStateB(BaseSharedState): - abci_app_cls = None # type: ignore - - with pytest.raises( - AttributeError, - match="The class is not an instance of packages.valory.skills.abstract_round_abci.base.AbciApp", - ): - - class MySharedStateC(BaseSharedState): - abci_app_cls = MagicMock - - -@dataclass -class A: - """Class for testing.""" - - value: int - - -@dataclass -class B: - """Class for testing.""" - - value: str - - -class C(TypedDict): - """Class for testing.""" - - name: str - year: int - - -class D(TypedDict, total=False): - """Class for testing.""" - - name: str - year: int - - -testdata_positive = [ - ("test_arg", 1, int), - ("test_arg", "1", str), - ("test_arg", True, bool), - ("test_arg", 1, Optional[int]), - ("test_arg", None, Optional[int]), - ("test_arg", "1", Optional[str]), - ("test_arg", None, Optional[str]), - ("test_arg", None, Optional[bool]), - ("test_arg", None, Optional[List[int]]), - ("test_arg", [], Optional[List[int]]), - ("test_arg", [1], Optional[List[int]]), - ("test_arg", {"str": 1}, Optional[Dict[str, int]]), - ("test_arg", {"str": A(1)}, Dict[str, A]), - ("test_arg", [("1", "2")], List[Tuple[str, str]]), - ("test_arg", [1], List[Optional[int]]), - ("test_arg", [1, None], List[Optional[int]]), - ("test_arg", A, Type[A]), - ("test_arg", A, Optional[Type[A]]), - ("test_arg", None, Optional[Type[A]]), - ("test_arg", MagicMock(), Optional[Type[A]]), # any type allowed - ("test_arg", {"name": "str", "year": 1}, C), - ("test_arg", 42, Literal[42]), - ("test_arg", {"name": "str"}, D), -] - - -@pytest.mark.parametrize("name,value,type_hint", testdata_positive) -def test_type_check_positive(name: str, value: Any, type_hint: Any) -> None: - """Test the type check mixin.""" - - check_type(name, value, type_hint) - - -testdata_negative = [ - ("test_arg", "1", int), - ("test_arg", 1, str), - ("test_arg", None, bool), - ("test_arg", "1", Optional[int]), - ("test_arg", 1, Optional[str]), - ("test_arg", 1, Optional[bool]), - ("test_arg", ["1"], Optional[List[int]]), - ("test_arg", {"str": "1"}, Optional[Dict[str, int]]), - ("test_arg", {1: 1}, Optional[Dict[str, int]]), - ("test_arg", {"str": B("1")}, Dict[str, A]), - ("test_arg", [()], List[Tuple[str, str]]), - ("test_arg", [("1",)], List[Tuple[str, str]]), - ("test_arg", [("1", 1)], List[Tuple[str, str]]), - ("test_arg", [("1", 1, "1")], List[Tuple[str, ...]]), - ("test_arg", ["1"], List[Optional[int]]), - ("test_arg", [1, None, "1"], List[Optional[int]]), - ("test_arg", B, Type[A]), - ("test_arg", B, Optional[Type[A]]), - ("test_arg", {"name": "str", "year": "1"}, C), - ("test_arg", 41, Literal[42]), - ("test_arg", C({"name": "str", "year": 1}), A), - ("test_arg", {"name": "str"}, C), -] - - -@pytest.mark.parametrize("name,value,type_hint", testdata_negative) -def test_type_check_negative(name: str, value: Any, type_hint: Any) -> None: - """Test the type check mixin.""" - - with pytest.raises(TypeError): - check_type(name, value, type_hint) diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/__init__.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/__init__.py deleted file mode 100644 index 261d2d3cb..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Package for `test_tools` testing.""" diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/base.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/base.py deleted file mode 100644 index 859557464..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/base.py +++ /dev/null @@ -1,86 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for abstract_round_abci/test_tools/common.py""" - -from pathlib import Path -from typing import Any, Dict, Type, cast - -from aea.helpers.base import cd -from aea.test_tools.utils import copy_class - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload, _MetaPayload -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci import ( - PATH_TO_SKILL, -) - - -class FSMBehaviourTestToolSetup: - """BaseRandomnessBehaviourTestSetup""" - - test_cls: Type[FSMBehaviourBaseCase] - __test_cls: Type[FSMBehaviourBaseCase] - __old_value: Dict[str, Type[BaseTxPayload]] - - @classmethod - def setup_class(cls) -> None: - """Setup class""" - - if not hasattr(cls, "test_cls"): - raise AttributeError(f"{cls} must set `test_cls`") - - cls.__test_cls = cls.test_cls - cls.__old_value = _MetaPayload.registry.copy() - _MetaPayload.registry.clear() - - @classmethod - def teardown_class(cls) -> None: - """Teardown class""" - _MetaPayload.registry = cls.__old_value - - def setup(self) -> None: - """Setup test""" - test_cls = copy_class(self.__test_cls) - self.test_cls = cast(Type[FSMBehaviourBaseCase], test_cls) - - def teardown(self) -> None: - """Teardown test""" - self.test_cls.teardown_class() - - def set_path_to_skill(self, path_to_skill: Path = PATH_TO_SKILL) -> None: - """Set path_to_skill""" - self.test_cls.path_to_skill = path_to_skill - - def setup_test_cls(self, **kwargs: Any) -> FSMBehaviourBaseCase: - """Helper method to setup test to be tested""" - - # different test tools will require the setting of - # different class attributes (such as path_to_skill). - # One should write a test that sets these, - # and subsequently invoke this method to test the setup. - - with cd(self.test_cls.path_to_skill): - self.test_cls.setup_class(**kwargs) - - test_instance = self.test_cls() - test_instance.setup() - return test_instance diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_base.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_base.py deleted file mode 100644 index 294c84660..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_base.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for abstract_round_abci/test_tools/base.py""" - -from enum import Enum -from typing import Any, Dict, cast - -import pytest -from aea.mail.base import Envelope - -from packages.valory.connections.ledger.connection import ( - PUBLIC_ID as LEDGER_CONNECTION_PUBLIC_ID, -) -from packages.valory.protocols.contract_api.message import ContractApiMessage -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.behaviours import BaseBehaviour -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - DummyContext, - FSMBehaviourBaseCase, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci import PUBLIC_ID -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.behaviours import ( - DummyRoundBehaviour, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.models import ( - SharedState, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.rounds import ( - Event, - SynchronizedData, -) -from packages.valory.skills.abstract_round_abci.tests.test_tools.base import ( - FSMBehaviourTestToolSetup, -) - - -class TestFSMBehaviourBaseCaseSetup(FSMBehaviourTestToolSetup): - """test TestFSMBehaviourBaseCaseSetup setup""" - - test_cls = FSMBehaviourBaseCase - - @pytest.mark.parametrize("kwargs", [{}]) - def test_setup_fails_without_path(self, kwargs: Dict[str, Dict[str, Any]]) -> None: - """Test setup""" - with pytest.raises(ValueError): - self.test_cls.setup_class(**kwargs) - - @pytest.mark.parametrize("kwargs", [{}, {"param_overrides": {"new_p": None}}]) - def test_setup(self, kwargs: Dict[str, Dict[str, Any]]) -> None: - """Test setup""" - - self.set_path_to_skill() - test_instance = self.setup_test_cls(**kwargs) - assert test_instance - assert hasattr(test_instance.behaviour.context.params, "new_p") == bool(kwargs) - - @pytest.mark.parametrize("behaviour", DummyRoundBehaviour.behaviours) - def test_fast_forward_to_behaviour(self, behaviour: BaseBehaviour) -> None: - """Test fast_forward_to_behaviour""" - self.set_path_to_skill() - test_instance = self.setup_test_cls() - - skill = test_instance._skill # pylint: disable=protected-access - round_behaviour = skill.skill_context.behaviours.main - behaviour_id = behaviour.behaviour_id - synchronized_data = SynchronizedData( - AbciAppDB(setup_data=dict(participants=[tuple("abcd")])) - ) - - test_instance.fast_forward_to_behaviour( - behaviour=round_behaviour, - behaviour_id=behaviour_id, - synchronized_data=synchronized_data, - ) - - current_behaviour = test_instance.behaviour.current_behaviour - assert current_behaviour is not None - assert isinstance( - current_behaviour.synchronized_data, - SynchronizedData, - ) - assert current_behaviour.behaviour_id == behaviour.behaviour_id - assert ( # pylint: disable=protected-access - test_instance.skill.skill_context.state.round_sequence.abci_app._current_round_cls - == current_behaviour.matching_round - == behaviour.matching_round - ) - - @pytest.mark.parametrize("event", Event) - @pytest.mark.parametrize("set_none", [False, True]) - def test_end_round(self, event: Enum, set_none: bool) -> None: - """Test end_round""" - - self.set_path_to_skill() - test_instance = self.setup_test_cls() - current_behaviour = cast( - BaseBehaviour, test_instance.behaviour.current_behaviour - ) - abci_app = current_behaviour.context.state.round_sequence.abci_app - if set_none: - test_instance.behaviour.current_behaviour = None - assert abci_app.current_round_height == 0 - test_instance.end_round(event) - assert abci_app.current_round_height == 1 - int(set_none) - - def test_mock_ledger_api_request(self) -> None: - """Test mock_ledger_api_request""" - - self.set_path_to_skill() - test_instance = self.setup_test_cls() - - request_kwargs = dict(performative=LedgerApiMessage.Performative.GET_BALANCE) - response_kwargs = dict(performative=LedgerApiMessage.Performative.BALANCE) - with pytest.raises( - AssertionError, - match="Invalid number of messages in outbox. Expected 1. Found 0.", - ): - test_instance.mock_ledger_api_request(request_kwargs, response_kwargs) - - message = LedgerApiMessage(**request_kwargs, dialogue_reference=("a", "b")) # type: ignore - envelope = Envelope( - to=str(LEDGER_CONNECTION_PUBLIC_ID), - sender=str(PUBLIC_ID), - protocol_specification_id=LedgerApiMessage.protocol_specification_id, - message=message, - ) - multiplexer = test_instance._multiplexer # pylint: disable=protected-access - multiplexer.out_queue.put_nowait(envelope) - test_instance.mock_ledger_api_request(request_kwargs, response_kwargs) - - def test_mock_contract_api_request(self) -> None: - """Test mock_contract_api_request""" - - self.set_path_to_skill() - test_instance = self.setup_test_cls() - - contract_id = "dummy_contract" - request_kwargs = dict(performative=ContractApiMessage.Performative.GET_STATE) - response_kwargs = dict(performative=ContractApiMessage.Performative.STATE) - with pytest.raises( - AssertionError, - match="Invalid number of messages in outbox. Expected 1. Found 0.", - ): - test_instance.mock_contract_api_request( - contract_id, request_kwargs, response_kwargs - ) - - message = ContractApiMessage( - **request_kwargs, # type: ignore - dialogue_reference=("a", "b"), - ledger_id="ethereum", - contract_id=contract_id - ) - envelope = Envelope( - to=str(LEDGER_CONNECTION_PUBLIC_ID), - sender=str(PUBLIC_ID), - protocol_specification_id=ContractApiMessage.protocol_specification_id, - message=message, - ) - multiplexer = test_instance._multiplexer # pylint: disable=protected-access - multiplexer.out_queue.put_nowait(envelope) - test_instance.mock_contract_api_request( - contract_id, request_kwargs, response_kwargs - ) - - -def test_dummy_context_is_abstract_component() -> None: - """Test dummy context is abstract component""" - - shared_state = SharedState(name="dummy_shared_state", skill_context=DummyContext()) - assert shared_state.context.is_abstract_component diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_common.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_common.py deleted file mode 100644 index b5cb5d272..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_common.py +++ /dev/null @@ -1,183 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for abstract_round_abci/test_tools/common.py""" - -from typing import Type, Union, cast - -import pytest - -from packages.valory.skills.abstract_round_abci.test_tools.common import ( - BaseRandomnessBehaviourTest, - BaseSelectKeeperBehaviourTest, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci import ( - PATH_TO_SKILL, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.behaviours import ( - DummyFinalBehaviour, - DummyKeeperSelectionBehaviour, - DummyRandomnessBehaviour, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.rounds import ( - Event, -) -from packages.valory.skills.abstract_round_abci.tests.test_tools.base import ( - FSMBehaviourTestToolSetup, -) - - -class BaseCommonBaseCaseTestSetup(FSMBehaviourTestToolSetup): - """BaseRandomnessBehaviourTestSetup""" - - test_cls: Type[Union[BaseRandomnessBehaviourTest, BaseSelectKeeperBehaviourTest]] - - def set_done_event(self) -> None: - """Set done_event""" - self.test_cls.done_event = Event.DONE - - def set_next_behaviour_class(self, next_behaviour_class: Type) -> None: - """Set next_behaviour_class""" - self.test_cls.next_behaviour_class = next_behaviour_class - - -class TestBaseRandomnessBehaviourTestSetup(BaseCommonBaseCaseTestSetup): - """Test BaseRandomnessBehaviourTest setup.""" - - test_cls: Type[BaseRandomnessBehaviourTest] = BaseRandomnessBehaviourTest - - def set_randomness_behaviour_class(self) -> None: - """Set randomness_behaviour_class""" - self.test_cls.randomness_behaviour_class = DummyRandomnessBehaviour # type: ignore - - def test_setup_randomness_behaviour_class_not_set(self) -> None: - """Test setup randomness_behaviour_class not set.""" - - self.set_path_to_skill() - test_instance = cast(BaseRandomnessBehaviourTest, self.setup_test_cls()) - expected = f"'{self.test_cls.__name__}' object has no attribute 'randomness_behaviour_class'" - with pytest.raises(AttributeError, match=expected): - test_instance.test_randomness_behaviour() - - def test_setup_done_event_not_set(self) -> None: - """Test setup done_event = Event.DONE not set.""" - - self.set_path_to_skill() - self.set_randomness_behaviour_class() - - test_instance = cast(BaseRandomnessBehaviourTest, self.setup_test_cls()) - expected = f"'{self.test_cls.__name__}' object has no attribute 'done_event'" - with pytest.raises(AttributeError, match=expected): - test_instance.test_randomness_behaviour() - - def test_setup_next_behaviour_class_not_set(self) -> None: - """Test setup next_behaviour_class not set.""" - - self.set_path_to_skill() - self.set_randomness_behaviour_class() - self.set_done_event() - - test_instance = cast(BaseRandomnessBehaviourTest, self.setup_test_cls()) - expected = ( - f"'{self.test_cls.__name__}' object has no attribute 'next_behaviour_class'" - ) - with pytest.raises(AttributeError, match=expected): - test_instance.test_randomness_behaviour() - - def test_successful_setup_randomness_behaviour_test(self) -> None: - """Test successful setup of the test class inheriting from BaseRandomnessBehaviourTest.""" - - self.set_path_to_skill() - self.set_randomness_behaviour_class() - self.set_done_event() - self.set_next_behaviour_class(DummyKeeperSelectionBehaviour) - test_instance = cast(BaseRandomnessBehaviourTest, self.setup_test_cls()) - test_instance.test_randomness_behaviour() - - -class TestBaseRandomnessBehaviourTestRunning(BaseRandomnessBehaviourTest): - """Test TestBaseRandomnessBehaviourTestRunning running.""" - - path_to_skill = PATH_TO_SKILL - randomness_behaviour_class = DummyRandomnessBehaviour - next_behaviour_class = DummyKeeperSelectionBehaviour - done_event = Event.DONE - - -class TestBaseSelectKeeperBehaviourTestSetup(BaseCommonBaseCaseTestSetup): - """Test BaseRandomnessBehaviourTest setup.""" - - test_cls: Type[BaseSelectKeeperBehaviourTest] = BaseSelectKeeperBehaviourTest - - def set_select_keeper_behaviour_class(self) -> None: - """Set select_keeper_behaviour_class""" - self.test_cls.select_keeper_behaviour_class = DummyKeeperSelectionBehaviour # type: ignore - - def test_setup_select_keeper_behaviour_class_not_set(self) -> None: - """Test setup select_keeper_behaviour_class not set.""" - - self.set_path_to_skill() - test_instance = cast(BaseSelectKeeperBehaviourTest, self.setup_test_cls()) - expected = f"'{self.test_cls.__name__}' object has no attribute 'select_keeper_behaviour_class'" - with pytest.raises(AttributeError, match=expected): - test_instance.test_select_keeper_preexisting_keeper() - - def test_setup_done_event_not_set(self) -> None: - """Test setup done_event = Event.DONE not set.""" - - self.set_path_to_skill() - self.set_select_keeper_behaviour_class() - - test_instance = cast(BaseSelectKeeperBehaviourTest, self.setup_test_cls()) - expected = f"'{self.test_cls.__name__}' object has no attribute 'done_event'" - with pytest.raises(AttributeError, match=expected): - test_instance.test_select_keeper_preexisting_keeper() - - def test_setup_next_behaviour_class_not_set(self) -> None: - """Test setup next_behaviour_class not set.""" - - self.set_path_to_skill() - self.set_select_keeper_behaviour_class() - self.set_done_event() - - test_instance = cast(BaseSelectKeeperBehaviourTest, self.setup_test_cls()) - expected = ( - f"'{self.test_cls.__name__}' object has no attribute 'next_behaviour_class'" - ) - with pytest.raises(AttributeError, match=expected): - test_instance.test_select_keeper_preexisting_keeper() - - def test_successful_setup_select_keeper_behaviour_test(self) -> None: - """Test successful setup of the test class inheriting from BaseSelectKeeperBehaviourTest.""" - - self.set_path_to_skill() - self.set_select_keeper_behaviour_class() - self.set_done_event() - self.set_next_behaviour_class(DummyFinalBehaviour) - test_instance = cast(BaseSelectKeeperBehaviourTest, self.setup_test_cls()) - test_instance.test_select_keeper_preexisting_keeper() - - -class TestBaseSelectKeeperBehaviourTestRunning(BaseSelectKeeperBehaviourTest): - """Test BaseSelectKeeperBehaviourTest running.""" - - path_to_skill = PATH_TO_SKILL - select_keeper_behaviour_class = DummyKeeperSelectionBehaviour - next_behaviour_class = DummyFinalBehaviour - done_event = Event.DONE diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_integration.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_integration.py deleted file mode 100644 index e71ed9258..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_integration.py +++ /dev/null @@ -1,143 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for abstract_round_abci/test_tools/integration.py""" - -from typing import cast - -import pytest - -from packages.open_aea.protocols.signing import SigningMessage -from packages.open_aea.protocols.signing.custom_types import SignedMessage -from packages.valory.connections.ledger.connection import ( - PUBLIC_ID as LEDGER_CONNECTION_PUBLIC_ID, -) -from packages.valory.connections.ledger.tests.conftest import make_ledger_api_connection -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.protocols.ledger_api.dialogues import LedgerApiDialogue -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.behaviours import BaseBehaviour -from packages.valory.skills.abstract_round_abci.models import Requests -from packages.valory.skills.abstract_round_abci.test_tools.integration import ( - IntegrationBaseCase, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.behaviours import ( - DummyStartingBehaviour, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.rounds import ( - SynchronizedData, -) -from packages.valory.skills.abstract_round_abci.tests.test_tools.base import ( - FSMBehaviourTestToolSetup, -) - - -def simulate_ledger_get_balance_request(test_instance: IntegrationBaseCase) -> None: - """Simulate ledger GET_BALANCE request""" - - ledger_api_dialogues = test_instance.skill.skill_context.ledger_api_dialogues - ledger_api_msg, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(LEDGER_CONNECTION_PUBLIC_ID), - performative=LedgerApiMessage.Performative.GET_BALANCE, - ledger_id="ethereum", - address="0x" + "0" * 40, - ) - ledger_api_dialogue = cast(LedgerApiDialogue, ledger_api_dialogue) - current_behaviour = cast(BaseBehaviour, test_instance.behaviour.current_behaviour) - request_nonce = current_behaviour._get_request_nonce_from_dialogue( # pylint: disable=protected-access - ledger_api_dialogue - ) - cast(Requests, current_behaviour.context.requests).request_id_to_callback[ - request_nonce - ] = current_behaviour.get_callback_request() - current_behaviour.context.outbox.put_message(message=ledger_api_msg) - - -class TestIntegrationBaseCase(FSMBehaviourTestToolSetup): - """TestIntegrationBaseCase""" - - test_cls = IntegrationBaseCase - - def test_instantiation(self) -> None: - """Test instantiation""" - - self.set_path_to_skill() - self.test_cls.make_ledger_api_connection_callable = make_ledger_api_connection - test_instance = cast(IntegrationBaseCase, self.setup_test_cls()) - - assert test_instance - assert test_instance.get_message_from_outbox() is None - assert test_instance.get_message_from_decision_maker_inbox() is None - assert test_instance.process_n_messages(ncycles=0) is tuple() - - expected = "Invalid number of messages in outbox. Expected 1. Found 0." - with pytest.raises(AssertionError, match=expected): - assert test_instance.process_message_cycle() - with pytest.raises(AssertionError, match=expected): - assert test_instance.process_n_messages(ncycles=1) - - def test_process_messages_cycle(self) -> None: - """Test process_message_cycle""" - - self.set_path_to_skill() - self.test_cls.make_ledger_api_connection_callable = make_ledger_api_connection - test_instance = cast(IntegrationBaseCase, self.setup_test_cls()) - - simulate_ledger_get_balance_request(test_instance) - message = test_instance.process_message_cycle( - handler=None, - ) - assert message is None - - simulate_ledger_get_balance_request(test_instance) - # connection error - cannot dynamically mix in an autouse fixture - message = test_instance.process_message_cycle( - handler=test_instance.ledger_handler, - expected_content={"performative": LedgerApiMessage.Performative.ERROR}, - ) - assert message - - def test_process_n_messages(self) -> None: - """Test process_n_messages""" - - self.set_path_to_skill() - self.test_cls.make_ledger_api_connection_callable = make_ledger_api_connection - test_instance = cast(IntegrationBaseCase, self.setup_test_cls()) - - behaviour_id = DummyStartingBehaviour.auto_behaviour_id() - synchronized_data = SynchronizedData( - AbciAppDB(setup_data=dict(participants=[tuple("abcd")])) - ) - - handlers = [test_instance.signing_handler] - expected_content = [ - {"performative": SigningMessage.Performative.SIGNED_MESSAGE} - ] - expected_types = [{"signed_message": SignedMessage}] - - messages = test_instance.process_n_messages( - ncycles=1, - behaviour_id=behaviour_id, - synchronized_data=synchronized_data, - handlers=handlers, # type: ignore - expected_content=expected_content, # type: ignore - expected_types=expected_types, # type: ignore - fail_send_a2a=True, - ) - assert len(messages) == 1 diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_rounds.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_rounds.py deleted file mode 100644 index 9fbbde9ac..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_rounds.py +++ /dev/null @@ -1,659 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - - -"""Test the `rounds` test tool module of the skill.""" - -import re -from enum import Enum -from typing import Any, FrozenSet, Generator, List, Optional, Tuple, Type, cast -from unittest.mock import MagicMock - -import pytest -from hypothesis import given, settings -from hypothesis import strategies as st - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - BaseSynchronizedData, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectDifferentUntilAllRoundTest, - BaseCollectDifferentUntilThresholdRoundTest, - BaseCollectSameUntilAllRoundTest, - BaseCollectSameUntilThresholdRoundTest, - BaseOnlyKeeperSendsRoundTest, - BaseRoundTestClass, - BaseVotingRoundTest, - DummyCollectDifferentUntilAllRound, - DummyCollectDifferentUntilThresholdRound, - DummyCollectSameUntilAllRound, - DummyCollectSameUntilThresholdRound, - DummyEvent, - DummyOnlyKeeperSendsRound, - DummySynchronizedData, - DummyTxPayload, - DummyVotingRound, - MAX_PARTICIPANTS, - get_dummy_tx_payloads, - get_participants, -) -from packages.valory.skills.abstract_round_abci.tests.conftest import profile_name -from packages.valory.skills.abstract_round_abci.tests.test_common import last_iteration - - -settings.load_profile(profile_name) - -# this is how many times we need to iterate before reaching the last iteration for a base test. -BASE_TEST_GEN_ITERATIONS = 4 - - -def test_get_participants() -> None: - """Test `get_participants`.""" - participants = get_participants() - assert isinstance(participants, frozenset) - assert all(isinstance(p, str) for p in participants) - assert len(participants) == MAX_PARTICIPANTS - - -class DummyTxPayloadMatcher: - """A `DummyTxPayload` matcher for assertion comparisons.""" - - expected: DummyTxPayload - - def __init__(self, expected: DummyTxPayload) -> None: - """Initialize the matcher.""" - self.expected = expected - - def __repr__(self) -> str: - """Needs to be implemented for better assertion messages.""" - return ( - "DummyTxPayload(" - f"id={repr(self.expected.id_)}, " - f"round_count={repr(self.expected.round_count)}, " - f"sender={repr(self.expected.sender)}, " - f"value={repr(self.expected.value)}, " - f"vote={repr(self.expected.vote)}" - ")" - ) - - def __eq__(self, other: Any) -> bool: - """The method that will be used for the assertion comparisons.""" - return ( - self.expected.round_count == other.round_count - and self.expected.sender == other.sender - and self.expected.value == other.value - and self.expected.vote == other.vote - ) - - -@given( - st.frozensets(st.text(max_size=200), max_size=100), - st.text(max_size=500), - st.one_of(st.none(), st.booleans()), - st.booleans(), -) -def test_get_dummy_tx_payloads( - participants: FrozenSet[str], - value: str, - vote: Optional[bool], - is_value_none: bool, -) -> None: - """Test `get_dummy_tx_payloads`.""" - expected = [ - DummyTxPayloadMatcher( - DummyTxPayload( - sender=agent, - value=(value or agent) if not is_value_none else value, - vote=vote, - ) - ) - for agent in sorted(participants) - ] - - actual = get_dummy_tx_payloads(participants, value, vote, is_value_none) - - assert len(actual) == len(expected) == len(participants) - assert actual == expected - - -class TestDummyTxPayload: # pylint: disable=too-few-public-methods - """Test class for `DummyTxPayload`""" - - @staticmethod - @given(st.text(max_size=200), st.text(max_size=500), st.booleans()) - def test_properties( - sender: str, - value: str, - vote: bool, - ) -> None: - """Test all the properties.""" - dummy_tx_payload = DummyTxPayload(sender, value, vote) - assert dummy_tx_payload.value == value - assert dummy_tx_payload.vote == vote - assert dummy_tx_payload.data == {"value": value, "vote": vote} - - -class TestDummySynchronizedData: # pylint: disable=too-few-public-methods - """Test class for `DummySynchronizedData`.""" - - @staticmethod - @given(st.lists(st.text(max_size=200), max_size=100)) - def test_most_voted_keeper_address( - most_voted_keeper_address_data: List[str], - ) -> None: - """Test `most_voted_keeper_address`.""" - most_voted_keeper_address_key = "most_voted_keeper_address" - - dummy_synchronized_data = DummySynchronizedData( - db=AbciAppDB( - setup_data={ - most_voted_keeper_address_key: most_voted_keeper_address_data - } - ) - ) - - if len(most_voted_keeper_address_data) == 0: - with pytest.raises( - ValueError, - match=re.escape( - f"'{most_voted_keeper_address_key}' " - "field is not set for this period [0] and no default value was provided.", - ), - ): - _ = dummy_synchronized_data.most_voted_keeper_address - return - - assert ( - dummy_synchronized_data.most_voted_keeper_address - == most_voted_keeper_address_data[-1] - ) - - -class TestBaseRoundTestClass: - """Test `BaseRoundTestClass`.""" - - @staticmethod - def test_test_no_majority_event() -> None: - """Test `_test_no_majority_event`.""" - base_round_test = BaseRoundTestClass() - base_round_test._event_class = DummyEvent # pylint: disable=protected-access - - base_round_test._test_no_majority_event( # pylint: disable=protected-access - MagicMock( - end_block=lambda: ( - MagicMock(), - DummyEvent.NO_MAJORITY, - ) - ) - ) - - @staticmethod - @given(st.integers(min_value=0, max_value=100), st.integers(min_value=1)) - def test_complete_run(iter_count: int, shift: int) -> None: - """Test `_complete_run`.""" - - def dummy_gen() -> Generator[MagicMock, None, None]: - """A dummy generator.""" - return (MagicMock() for _ in range(iter_count)) - - # test with the same number as the generator's contents - gen = dummy_gen() - BaseRoundTestClass._complete_run( # pylint: disable=protected-access - gen, iter_count - ) - - # assert that the generator has been fully consumed - with pytest.raises(StopIteration): - next(gen) - - # test with a larger count than a generator's - with pytest.raises(StopIteration): - BaseRoundTestClass._complete_run( # pylint: disable=protected-access - dummy_gen(), iter_count + shift - ) - - -class BaseTestBase: - """Base class for the Base tests.""" - - gen: Generator - base_round_test: BaseRoundTestClass - base_round_test_cls: Type[BaseRoundTestClass] - test_method_name = "_test_round" - - def setup(self) -> None: - """Setup that is run before each test.""" - self.base_round_test = self.base_round_test_cls() - self.base_round_test._synchronized_data_class = ( # pylint: disable=protected-access - DummySynchronizedData - ) - self.base_round_test.setup() - self.base_round_test._event_class = ( # pylint: disable=protected-access - DummyEvent - ) - - def create_test_gen(self, **kwargs: Any) -> None: - """Create the base test generator.""" - test_method = getattr(self.base_round_test, self.test_method_name) - self.gen = test_method(**kwargs) - - def exhaust_base_test_gen(self) -> None: - """Exhaust the base test generator.""" - for _ in range(BASE_TEST_GEN_ITERATIONS): - next(self.gen) - last_iteration(self.gen) - - def run_test(self, **kwargs: Any) -> None: - """Run a test for a base test.""" - self.create_test_gen(**kwargs) - self.exhaust_base_test_gen() - - -class DummyCollectDifferentUntilAllRoundWithEndBlock( - DummyCollectDifferentUntilAllRound -): - """A `DummyCollectDifferentUntilAllRound` with `end_block` implemented.""" - - def __init__(self, dummy_exit_event: DummyEvent, *args: Any, **kwargs: Any): - """Initialize the dummy class.""" - super().__init__(*args, **kwargs) - self.dummy_exit_event = dummy_exit_event - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """A dummy `end_block` implementation.""" - if self.collection_threshold_reached and self.dummy_exit_event is not None: - return ( - cast( - DummySynchronizedData, - self.synchronized_data.update( - most_voted_keeper_address=list(self.collection.keys()) - ), - ), - self.dummy_exit_event, - ) - return None - - -class TestBaseCollectDifferentUntilAllRoundTest(BaseTestBase): - """Test `BaseCollectDifferentUntilAllRoundTest`.""" - - base_round_test: BaseCollectDifferentUntilAllRoundTest - base_round_test_cls = BaseCollectDifferentUntilAllRoundTest - - @given( - st.one_of(st.none(), st.sampled_from(DummyEvent)), - ) - def test_test_round(self, exit_event: DummyEvent) -> None: - """Test `_test_round`.""" - test_round = DummyCollectDifferentUntilAllRoundWithEndBlock( - exit_event, - self.base_round_test.synchronized_data, - context=MagicMock(), - ) - round_payloads = [ - DummyTxPayload(f"agent_{i}", str(i)) for i in range(MAX_PARTICIPANTS) - ] - synchronized_data_attr_checks = [ - lambda _synchronized_data: _synchronized_data.most_voted_keeper_address - ] - - self.run_test( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - most_voted_keeper_address=[ - f"agent_{i}" for i in range(MAX_PARTICIPANTS) - ] - ), - synchronized_data_attr_checks=synchronized_data_attr_checks, - exit_event=exit_event, - ) - - -class DummyCollectSameUntilAllRoundWithEndBlock(DummyCollectSameUntilAllRound): - """A `DummyCollectSameUntilAllRound` with `end_block` implemented.""" - - def __init__(self, dummy_exit_event: DummyEvent, *args: Any, **kwargs: Any): - """Initialize the dummy class.""" - super().__init__(*args, **kwargs) - self.dummy_exit_event = dummy_exit_event - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """A dummy `end_block` implementation.""" - if self.collection_threshold_reached: - return ( - cast( - DummySynchronizedData, - self.synchronized_data.update( - most_voted_keeper_address=self.common_payload - ), - ), - self.dummy_exit_event, - ) - return None - - -class TestBaseCollectSameUntilAllRoundTest(BaseTestBase): - """Test `BaseCollectSameUntilAllRoundTest`.""" - - base_round_test: BaseCollectSameUntilAllRoundTest - base_round_test_cls: Type[ - BaseCollectSameUntilAllRoundTest - ] = BaseCollectSameUntilAllRoundTest - - @given( - st.sampled_from(DummyEvent), - st.text(max_size=500), - st.booleans(), - ) - def test_test_round( - self, exit_event: DummyEvent, common_value: str, finished: bool - ) -> None: - """Test `_test_round`.""" - test_round = DummyCollectSameUntilAllRoundWithEndBlock( - exit_event, - self.base_round_test.synchronized_data, - context=MagicMock(), - ) - round_payloads = { - f"test{i}": DummyTxPayload(f"agent_{i}", common_value) - for i in range(MAX_PARTICIPANTS) - } - synchronized_data_attr_checks = [ - lambda _synchronized_data: _synchronized_data.most_voted_keeper_address - ] - - self.run_test( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - most_voted_keeper_address=common_value - ), - synchronized_data_attr_checks=synchronized_data_attr_checks, - most_voted_payload=common_value, - exit_event=exit_event, - finished=finished, - ) - - -class DummyCollectSameUntilThresholdRoundWithEndBlock( - DummyCollectSameUntilThresholdRound -): - """A `DummyCollectSameUntilThresholdRound` with `end_block` overriden.""" - - def __init__(self, dummy_exit_event: DummyEvent, *args: Any, **kwargs: Any): - """Initialize the dummy class.""" - super().__init__(*args, **kwargs) - self.dummy_exit_event = dummy_exit_event - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """A dummy `end_block` override.""" - if self.threshold_reached: - return ( - cast( - DummySynchronizedData, - self.synchronized_data.update( - most_voted_keeper_address=self.most_voted_payload - ), - ), - self.dummy_exit_event, - ) - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, DummyEvent.NO_MAJORITY - return None - - -class TestBaseCollectSameUntilThresholdRoundTest(BaseTestBase): - """Test `BaseCollectSameUntilThresholdRoundTest`.""" - - base_round_test: BaseCollectSameUntilThresholdRoundTest - base_round_test_cls: Type[ - BaseCollectSameUntilThresholdRoundTest - ] = BaseCollectSameUntilThresholdRoundTest - - @given( - st.sampled_from(DummyEvent), - st.text(max_size=500), - ) - def test_test_round(self, exit_event: DummyEvent, most_voted_payload: str) -> None: - """Test `_test_round`.""" - test_round = DummyCollectSameUntilThresholdRoundWithEndBlock( - exit_event, - self.base_round_test.synchronized_data, - context=MagicMock(), - ) - round_payloads = { - f"test{i}": DummyTxPayload(f"agent_{i}", most_voted_payload) - for i in range(MAX_PARTICIPANTS) - } - synchronized_data_attr_checks = [ - lambda _synchronized_data: _synchronized_data.most_voted_keeper_address - ] - - self.run_test( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - most_voted_keeper_address=most_voted_payload - ), - synchronized_data_attr_checks=synchronized_data_attr_checks, - most_voted_payload=most_voted_payload, - exit_event=exit_event, - ) - - -class DummyOnlyKeeperSendsRoundTest(DummyOnlyKeeperSendsRound): - """A `DummyOnlyKeeperSendsRound` with `end_block` implemented.""" - - def __init__(self, dummy_exit_event: DummyEvent, *args: Any, **kwargs: Any): - """Initialize the dummy class.""" - super().__init__(*args, **kwargs) - self.dummy_exit_event = dummy_exit_event - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """A dummy `end_block` implementation.""" - if self.keeper_payload is not None and any( - [val is not None for val in self.keeper_payload.values] - ): - return ( - cast( - DummySynchronizedData, - self.synchronized_data.update( - blacklisted_keepers=self.keeper_payload.values[0] - ), - ), - self.dummy_exit_event, - ) - return None - - -class TestBaseOnlyKeeperSendsRoundTest(BaseTestBase): - """Test `BaseOnlyKeeperSendsRoundTest`.""" - - base_round_test: BaseOnlyKeeperSendsRoundTest - base_round_test_cls: Type[ - BaseOnlyKeeperSendsRoundTest - ] = BaseOnlyKeeperSendsRoundTest - most_voted_keeper_address: str = "agent_0" - - def setup(self) -> None: - """Setup that is run before each test.""" - super().setup() - self.base_round_test.synchronized_data.update( - most_voted_keeper_address=self.most_voted_keeper_address - ) - - @given( - st.sampled_from(DummyEvent), - st.text(), - ) - def test_test_round(self, exit_event: DummyEvent, keeper_value: str) -> None: - """Test `_test_round`.""" - test_round = DummyOnlyKeeperSendsRoundTest( - exit_event, - self.base_round_test.synchronized_data, - context=MagicMock(), - ) - keeper_payload = DummyTxPayload(self.most_voted_keeper_address, keeper_value) - synchronized_data_attr_checks = [ - lambda _synchronized_data: _synchronized_data.blacklisted_keepers - ] - - self.run_test( - test_round=test_round, - keeper_payloads=keeper_payload, - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - blacklisted_keepers=keeper_value - ), - synchronized_data_attr_checks=synchronized_data_attr_checks, - exit_event=exit_event, - ) - - -class DummyBaseVotingRoundTestWithEndBlock(DummyVotingRound): - """A `DummyVotingRound` with `end_block` overriden.""" - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """A dummy `end_block` override.""" - if self.positive_vote_threshold_reached: - synchronized_data = cast( - DummySynchronizedData, - self.synchronized_data.update( - is_keeper_set=bool(self.collection), - ), - ) - return synchronized_data, DummyEvent.DONE - if self.negative_vote_threshold_reached: - return self.synchronized_data, DummyEvent.NEGATIVE - if self.none_vote_threshold_reached: - return self.synchronized_data, DummyEvent.NONE - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, DummyEvent.NO_MAJORITY - return None - - -class TestBaseVotingRoundTest(BaseTestBase): - """Test `BaseVotingRoundTest`.""" - - base_round_test: BaseVotingRoundTest - base_round_test_cls: Type[BaseVotingRoundTest] = BaseVotingRoundTest - - @given( - st.one_of(st.none(), st.booleans()), - ) - def test_test_round(self, is_keeper_set: Optional[bool]) -> None: - """Test `_test_round`.""" - if is_keeper_set is None: - exit_event = DummyEvent.NONE - self.test_method_name = "_test_voting_round_none" - elif is_keeper_set: - exit_event = DummyEvent.DONE - self.test_method_name = "_test_voting_round_positive" - else: - exit_event = DummyEvent.NEGATIVE - self.test_method_name = "_test_voting_round_negative" - - test_round = DummyBaseVotingRoundTestWithEndBlock( - self.base_round_test.synchronized_data, - context=MagicMock(), - ) - round_payloads = { - f"test{i}": DummyTxPayload(f"agent_{i}", value="", vote=is_keeper_set) - for i in range(MAX_PARTICIPANTS) - } - synchronized_data_attr_checks = [ - lambda _synchronized_data: _synchronized_data.is_keeper_set - ] - - self.run_test( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - is_keeper_set=is_keeper_set - ), - synchronized_data_attr_checks=synchronized_data_attr_checks, - exit_event=exit_event, - ) - - -class DummyCollectDifferentUntilThresholdRoundWithEndBlock( - DummyCollectDifferentUntilThresholdRound -): - """A `DummyCollectDifferentUntilThresholdRound` with `end_block` implemented.""" - - def __init__(self, dummy_exit_event: DummyEvent, *args: Any, **kwargs: Any): - """Initialize the dummy class.""" - super().__init__(*args, **kwargs) - self.dummy_exit_event = dummy_exit_event - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """A dummy `end_block` implementation.""" - if self.collection_threshold_reached and self.dummy_exit_event is not None: - return ( - cast( - DummySynchronizedData, - self.synchronized_data.update( - most_voted_keeper_address=list(self.collection.keys()) - ), - ), - self.dummy_exit_event, - ) - return None - - -class TestBaseCollectDifferentUntilThresholdRoundTest(BaseTestBase): - """Test `BaseCollectDifferentUntilThresholdRoundTest`.""" - - base_round_test: BaseCollectDifferentUntilThresholdRoundTest - base_round_test_cls: Type[ - BaseCollectDifferentUntilThresholdRoundTest - ] = BaseCollectDifferentUntilThresholdRoundTest - - @given(st.sampled_from(DummyEvent)) - def test_test_round(self, exit_event: DummyEvent) -> None: - """Test `_test_round`.""" - test_round = DummyCollectDifferentUntilThresholdRoundWithEndBlock( - exit_event, - self.base_round_test.synchronized_data, - context=MagicMock(), - ) - round_payloads = { - f"test{i}": DummyTxPayload(f"agent_{i}", str(i)) - for i in range(MAX_PARTICIPANTS) - } - synchronized_data_attr_checks = [ - lambda _synchronized_data: _synchronized_data.most_voted_keeper_address - ] - - self.run_test( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - most_voted_keeper_address=[ - f"agent_{i}" for i in range(MAX_PARTICIPANTS) - ] - ), - synchronized_data_attr_checks=synchronized_data_attr_checks, - exit_event=exit_event, - ) diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_utils.py b/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_utils.py deleted file mode 100644 index 3f412733e..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/tests/test_utils.py +++ /dev/null @@ -1,307 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the utils.py module of the skill.""" - -from collections import defaultdict -from string import printable -from typing import Any, Dict, List, Tuple, Type -from unittest import mock - -import pytest -from hypothesis import assume, given, settings -from hypothesis import strategies as st - -from packages.valory.skills.abstract_round_abci.tests.conftest import profile_name -from packages.valory.skills.abstract_round_abci.utils import ( - DEFAULT_TENDERMINT_P2P_PORT, - KeyType, - MAX_UINT64, - ValueType, - VerifyDrand, - consensus_threshold, - filter_negative, - get_data_from_nested_dict, - get_value_with_type, - inverse, - is_json_serializable, - is_primitive_or_none, - parse_tendermint_p2p_url, -) - - -settings.load_profile(profile_name) - - -# pylint: skip-file - - -DRAND_PUBLIC_KEY: str = "868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31" - -DRAND_VALUE = { - "round": 1416669, - "randomness": "f6be4bf1fa229f22340c1a5b258f809ac4af558200775a67dacb05f0cb258a11", - "signature": ( - "b44d00516f46da3a503f9559a634869b6dc2e5d839e46ec61a090e3032172954929a5" - "d9bd7197d7739fe55db770543c71182562bd0ad20922eb4fe6b8a1062ed21df3b68de" - "44694eb4f20b35262fa9d63aa80ad3f6172dd4d33a663f21179604" - ), - "previous_signature": ( - "903c60a4b937a804001032499a855025573040cb86017c38e2b1c3725286756ce8f33" - "61188789c17336beaf3f9dbf84b0ad3c86add187987a9a0685bc5a303e37b008fba8c" - "44f02a416480dd117a3ff8b8075b1b7362c58af195573623187463" - ), -} - - -class TestVerifyDrand: - """Test DrandVerify.""" - - drand_check: VerifyDrand - - def setup( - self, - ) -> None: - """Setup test.""" - self.drand_check = VerifyDrand() - - def test_verify( - self, - ) -> None: - """Test verify method.""" - - result, error = self.drand_check.verify(DRAND_VALUE, DRAND_PUBLIC_KEY) - assert result - assert error is None - - def test_verify_fails( - self, - ) -> None: - """Test verify method.""" - - drand_value = DRAND_VALUE.copy() - del drand_value["randomness"] - result, error = self.drand_check.verify(drand_value, DRAND_PUBLIC_KEY) - assert not result - assert error == "DRAND dict is missing value for 'randomness'" - - drand_value = DRAND_VALUE.copy() - drand_value["randomness"] = "".join( - list(drand_value["randomness"])[:-1] + ["0"] # type: ignore - ) - result, error = self.drand_check.verify(drand_value, DRAND_PUBLIC_KEY) - assert not result - assert error == "Failed randomness hash check." - - drand_value = DRAND_VALUE.copy() - with mock.patch.object( - self.drand_check, "_verify_signature", return_value=False - ): - result, error = self.drand_check.verify(drand_value, DRAND_PUBLIC_KEY) - - assert not result - assert error == "Failed bls.Verify check." - - @pytest.mark.parametrize("value", (-1, MAX_UINT64 + 1)) - def test_negative_and_overflow(self, value: int) -> None: - """Test verify method.""" - with pytest.raises(ValueError): - self.drand_check._int_to_bytes_big(value) - - -@given(st.integers(min_value=0, max_value=MAX_UINT64)) -def test_verify_int_to_bytes_big_fuzz(integer: int) -> None: - """Test VerifyDrand.""" - - VerifyDrand._int_to_bytes_big(integer) - - -@pytest.mark.parametrize("integer", [-1, MAX_UINT64 + 1]) -def test_verify_int_to_bytes_big_raises(integer: int) -> None: - """Test VerifyDrand._int_to_bytes_big""" - - expected = "VerifyDrand can only handle positive numbers representable with 8 bytes" - with pytest.raises(ValueError, match=expected): - VerifyDrand._int_to_bytes_big(integer) - - -@given(st.binary()) -def test_verify_randomness_hash_fuzz(input_bytes: bytes) -> None: - """Test VerifyDrand._verify_randomness_hash""" - - VerifyDrand._verify_randomness_hash(input_bytes, input_bytes) - - -@given( - st.lists(st.text(), min_size=1, max_size=50), - st.binary(), - st.characters(), -) -def test_get_data_from_nested_dict( - nested_keys: List[str], final_value: bytes, separator: str -) -> None: - """Test `get_data_from_nested_dict`""" - assume(not any(separator in key for key in nested_keys)) - - def create_nested_dict() -> defaultdict: - """Recursively create a nested dict of arbitrary size.""" - return defaultdict(create_nested_dict) - - nested_dict = create_nested_dict() - key_access = (f"[nested_keys[{i}]]" for i in range(len(nested_keys))) - expression = "nested_dict" + "".join(key_access) - expression += " = final_value" - exec(expression) # nosec - - serialized_keys = separator.join(nested_keys) - actual = get_data_from_nested_dict(nested_dict, serialized_keys, separator) - assert actual == final_value - - -@pytest.mark.parametrize( - "type_name, type_, value", - ( - ("str", str, "1"), - ("int", int, 1), - ("float", float, 1.1), - ("dict", dict, {1: 1}), - ("list", list, [1]), - ("non_existent", None, 1), - ), -) -def test_get_value_with_type(type_name: str, type_: Type, value: Any) -> None: - """Test `get_value_with_type`""" - if type_ is None: - with pytest.raises( - AttributeError, match=f"module 'builtins' has no attribute '{type_name}'" - ): - get_value_with_type(value, type_name) - return - - actual = get_value_with_type(value, type_name) - assert type(actual) == type_ - assert actual == value - - -@pytest.mark.parametrize( - ("url", "expected_output"), - ( - ("localhost", ("localhost", DEFAULT_TENDERMINT_P2P_PORT)), - ("localhost:80", ("localhost", 80)), - ("some.random.host:80", ("some.random.host", 80)), - ("1.1.1.1", ("1.1.1.1", DEFAULT_TENDERMINT_P2P_PORT)), - ("1.1.1.1:80", ("1.1.1.1", 80)), - ), -) -def test_parse_tendermint_p2p_url(url: str, expected_output: Tuple[str, int]) -> None: - """Test `parse_tendermint_p2p_url` method.""" - - assert parse_tendermint_p2p_url(url=url) == expected_output - - -@given( - st.one_of(st.none(), st.integers(), st.floats(), st.text(), st.booleans()), - st.one_of( - st.nothing(), - st.frozensets(st.integers()), - st.sets(st.integers()), - st.lists(st.integers()), - st.dictionaries(st.integers(), st.integers()), - st.dates(), - st.complex_numbers(), - st.just(object()), - ), -) -def test_is_primitive_or_none(valid_obj: Any, invalid_obj: Any) -> None: - """Test `is_primitive_or_none`.""" - assert is_primitive_or_none(valid_obj) - assert not is_primitive_or_none(invalid_obj) - - -@given( - st.recursive( - st.none() | st.booleans() | st.floats() | st.text(printable), - lambda children: st.lists(children) - | st.dictionaries(st.text(printable), children), - ), - st.one_of( - st.nothing(), - st.frozensets(st.integers()), - st.sets(st.integers()), - st.dates(), - st.complex_numbers(), - st.just(object()), - ), -) -def test_is_json_serializable(valid_obj: Any, invalid_obj: Any) -> None: - """Test `is_json_serializable`.""" - assert is_json_serializable(valid_obj) - assert not is_json_serializable(invalid_obj) - - -@given( - positive=st.dictionaries(st.text(), st.integers(min_value=0)), - negative=st.dictionaries(st.text(), st.integers(max_value=-1)), -) -def test_filter_negative(positive: Dict[str, int], negative: Dict[str, int]) -> None: - """Test `filter_negative`.""" - assert len(tuple(filter_negative(positive))) == 0 - assert set(filter_negative(negative)) == set(negative.keys()) - - -@pytest.mark.parametrize( - "nb, threshold", - ((1, 1), (2, 2), (3, 3), (4, 3), (5, 4), (6, 5), (100, 67), (300, 201)), -) -def test_consensus_threshold(nb: int, threshold: int) -> None: - """Test `consensus_threshold`.""" - assert consensus_threshold(nb) == threshold - - -@pytest.mark.parametrize( - "dict_, expected", - ( - ({}, {}), - ( - {"test": "this", "which?": "this"}, - {"this": ["test", "which?"]}, - ), - ( - {"test": "this", "which?": "this", "hm": "ok"}, - {"this": ["test", "which?"], "ok": ["hm"]}, - ), - ( - {"test": "this", "hm": "ok"}, - {"this": ["test"], "ok": ["hm"]}, - ), - ( - {"test": "this", "hm": "ok", "ok": "ok"}, - {"this": ["test"], "ok": ["hm", "ok"]}, - ), - ( - {"test": "this", "which?": "this", "hm": "ok", "ok": "ok"}, - {"this": ["test", "which?"], "ok": ["hm", "ok"]}, - ), - ), -) -def test_inverse( - dict_: Dict[KeyType, ValueType], expected: Dict[ValueType, List[KeyType]] -) -> None: - """Test `inverse`.""" - assert inverse(dict_) == expected diff --git a/trader_backup/vendor/valory/skills/abstract_round_abci/utils.py b/trader_backup/vendor/valory/skills/abstract_round_abci/utils.py deleted file mode 100644 index 864658c27..000000000 --- a/trader_backup/vendor/valory/skills/abstract_round_abci/utils.py +++ /dev/null @@ -1,504 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 utility functions for the 'abstract_round_abci' skill.""" - -import builtins -import collections -import dataclasses -import sys -import types -import typing -from hashlib import sha256 -from math import ceil -from typing import ( - Any, - Dict, - FrozenSet, - Iterator, - List, - Optional, - Set, - Tuple, - Type, - TypeVar, - Union, - cast, -) -from unittest.mock import MagicMock - -import typing_extensions -from eth_typing.bls import BLSPubkey, BLSSignature -from py_ecc.bls import G2Basic as bls -from typing_extensions import Literal, TypeGuard, TypedDict - - -MAX_UINT64 = 2**64 - 1 -DEFAULT_TENDERMINT_P2P_PORT = 26656 - - -class VerifyDrand: # pylint: disable=too-few-public-methods - """ - Tool to verify Randomness retrieved from various external APIs. - - The ciphersuite used is BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_ - - cryptographic-specification section in https://drand.love/docs/specification/ - https://github.com/ethereum/py_ecc - """ - - @classmethod - def _int_to_bytes_big(cls, value: int) -> bytes: - """Convert int to bytes.""" - if value < 0 or value > MAX_UINT64: - raise ValueError( - "VerifyDrand can only handle positive numbers representable with 8 bytes" - ) - return int.to_bytes(value, 8, byteorder="big", signed=False) - - @classmethod - def _verify_randomness_hash(cls, randomness: bytes, signature: bytes) -> bool: - """Verify randomness hash.""" - return sha256(signature).digest() == randomness - - @classmethod - def _verify_signature( - cls, - pubkey: Union[BLSPubkey, bytes], - message: bytes, - signature: Union[BLSSignature, bytes], - ) -> bool: - """Verify randomness signature.""" - return bls.Verify( - cast(BLSPubkey, pubkey), message, cast(BLSSignature, signature) - ) - - def verify(self, data: Dict, pubkey: str) -> Tuple[bool, Optional[str]]: - """ - Verify drand value retried from external APIs. - - :param data: dictionary containing drand parameters. - :param pubkey: league of entropy public key - public-endpoints section in https://drand.love/developer/http-api/ - :returns: bool, error message - """ - - encoded_pubkey = bytes.fromhex(pubkey) - try: - randomness = data["randomness"] - signature = data["signature"] - round_value = int(data["round"]) - except KeyError as e: - return False, f"DRAND dict is missing value for {e}" - - previous_signature = data.pop("previous_signature", "") - encoded_randomness = bytes.fromhex(randomness) - encoded_signature = bytes.fromhex(signature) - int_encoded_round = self._int_to_bytes_big(round_value) - encoded_previous_signature = bytes.fromhex(previous_signature) - - if not self._verify_randomness_hash(encoded_randomness, encoded_signature): - return False, "Failed randomness hash check." - - msg_b = encoded_previous_signature + int_encoded_round - msg_hash_b = sha256(msg_b).digest() - - if not self._verify_signature(encoded_pubkey, msg_hash_b, encoded_signature): - return False, "Failed bls.Verify check." - - return True, None - - -def get_data_from_nested_dict( - nested_dict: Dict, keys: str, separator: str = ":" -) -> Any: - """Gets content from a nested dictionary, using serialized response keys which are split by a given separator. - - :param nested_dict: the nested dictionary to get the content from - :param keys: the keys to use on the nested dictionary in order to get the content - :param separator: the separator to use in order to get the keys list. - Choose the separator carefully, so that it does not conflict with any character of the keys. - - :returns: the content result - """ - parsed_keys = keys.split(separator) - for key in parsed_keys: - nested_dict = nested_dict[key] - return nested_dict - - -def get_value_with_type(value: Any, type_name: str) -> Any: - """Get the given value as the specified type.""" - return getattr(builtins, type_name)(value) - - -def parse_tendermint_p2p_url(url: str) -> Tuple[str, int]: - """Parse tendermint P2P url.""" - hostname, *_port = url.split(":") - if len(_port) > 0: - port_str, *_ = _port - port = int(port_str) - else: - port = DEFAULT_TENDERMINT_P2P_PORT - - return hostname, port - - -## -# Typing utils - to be extracted to open-aea -## - - -try: - # Python >=3.8 should have these functions already - from typing import get_args as _get_args # pylint: disable=ungrouped-imports - from typing import get_origin as _get_origin # pylint: disable=ungrouped-imports -except ImportError: # pragma: nocover - # Python 3.7 - def _get_origin(tp): # type: ignore - """Copied from the Python 3.8 typing module""" - if isinstance(tp, typing._GenericAlias): # pylint: disable=protected-access - return tp.__origin__ - if tp is typing.Generic: - return typing.Generic - return None - - def _get_args(tp): # type: ignore - """Copied from the Python 3.8 typing module""" - if isinstance(tp, typing._GenericAlias): # pylint: disable=protected-access - res = tp.__args__ - if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis: - res = (list(res[:-1]), res[-1]) - return res - return () - - -def get_origin(tp): # type: ignore - """ - Get the unsubscripted version of a type. - - This supports generic types, Callable, Tuple, Union, Literal, Final and - ClassVar. Returns None for unsupported types. - Examples: - get_origin(Literal[42]) is Literal - get_origin(int) is None - get_origin(ClassVar[int]) is ClassVar - get_origin(Generic) is Generic - get_origin(Generic[T]) is Generic - get_origin(Union[T, int]) is Union - get_origin(List[Tuple[T, T]][int]) == list - """ - return _get_origin(tp) - - -def get_args(tp): # type: ignore - """ - Get type arguments with all substitutions performed. - - For unions, basic simplifications used by Union constructor are performed. - Examples: - get_args(Dict[str, int]) == (str, int) - get_args(int) == () - get_args(Union[int, Union[T, int], str][int]) == (int, str) - get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) - get_args(Callable[[], T][int]) == ([], int) - """ - return _get_args(tp) - - -## -# The following is borrowed from https://github.com/tamuhey/dataclass_utils/blob/81580d2c0c285081db06be02b4ecdd125532bef5/dataclass_utils/type_checker.py#L152 -## - - -def is_pep604_union(ty: Type[Any]) -> bool: - """Check if a type is a PEP 604 union.""" - return sys.version_info >= (3, 10) and ty is types.UnionType # type: ignore # noqa: E721 # pylint: disable=no-member - - -def _path_to_str(path: List[str]) -> str: - """Convert a path to a string.""" - return " -> ".join(reversed(path)) - - -class AutonomyTypeError(TypeError): - """Type Error for the Autonomy type check system.""" - - def __init__( - self, - ty: Type[Any], - value: Any, - path: Optional[List[str]] = None, - ): - """Initialize AutonomyTypeError.""" - self.ty = ty - self.value = value - self.path = path or [] - super().__init__() - - def __str__(self) -> str: - """Get string representation of AutonomyTypeError.""" - path = _path_to_str(self.path) - msg = f"Error in field '{path}'. Expected type {self.ty}, got {type(self.value)} (value: {self.value})" - return msg - - -Result = Optional[AutonomyTypeError] # returns error context - - -def check( # pylint: disable=too-many-return-statements - value: Any, ty: Type[Any] -) -> Result: - """ - Check a value against a type. - - # Examples - >>> assert is_error(check(1, str)) - >>> assert not is_error(check(1, int)) - >>> assert is_error(check(1, list)) - >>> assert is_error(check(1.3, int)) - >>> assert is_error(check(1.3, Union[str, int])) - """ - if isinstance(value, MagicMock): - # testing - any magic value is ignored - return None - if not isinstance(value, type) and dataclasses.is_dataclass(ty): - # dataclass - return check_dataclass(value, ty) - if is_typeddict(ty): - # should use `typing.is_typeddict` in future - return check_typeddict(value, ty) - to = get_origin(ty) - if to is not None: - # generics - err = check(value, to) - if is_error(err): - return err - - if to is list or to is set or to is frozenset: - err = check_mono_container(value, ty) - elif to is dict: - err = check_dict(value, ty) # type: ignore - elif to is tuple: - err = check_tuple(value, ty) - elif to is Literal: - err = check_literal(value, ty) - elif to is Union or is_pep604_union(to): - err = check_union(value, ty) - elif to is type: - err = check_class(value, ty) - return err - if isinstance(ty, type): - # concrete type - if is_pep604_union(ty): - pass # pragma: no cover - elif issubclass(ty, bool): - if not isinstance(value, ty): - return AutonomyTypeError(ty=ty, value=value) - elif issubclass(ty, int): # For boolean - return check_int(value, ty) - elif ty is typing.Any: - # `isinstance(value, typing.Any) fails on python 3.11` - # https://stackoverflow.com/questions/68031358/typeerror-typing-any-cannot-be-used-with-isinstance - pass - elif not isinstance(value, ty): - return AutonomyTypeError(ty=ty, value=value) - return None - - -def check_class(value: Any, ty: Type[Any]) -> Result: - """Check class type.""" - if not issubclass(value, get_args(ty)): - return AutonomyTypeError(ty=ty, value=value) - return None - - -def check_int(value: Any, ty: Type[Any]) -> Result: - """Check int type.""" - if isinstance(value, bool) or not isinstance(value, ty): - return AutonomyTypeError(ty=ty, value=value) - return None - - -def check_literal(value: Any, ty: Type[Any]) -> Result: - """Check literal type.""" - if all(value != t for t in get_args(ty)): - return AutonomyTypeError(ty=ty, value=value) - return None - - -def check_tuple(value: Any, ty: Type[Tuple[Any, ...]]) -> Result: - """Check tuple type.""" - types_ = get_args(ty) - if len(types_) == 2 and types_[1] == ...: - # arbitrary length tuple (e.g. Tuple[int, ...]) - for v in value: - err = check(v, types_[0]) - if is_error(err): - return err - return None - - if len(value) != len(types_): - return AutonomyTypeError(ty=ty, value=value) - for v, t in zip(value, types_): - err = check(v, t) - if is_error(err): - return err - return None - - -def check_union(value: Any, ty: Type[Any]) -> Result: - """Check union type.""" - if any(not is_error(check(value, t)) for t in get_args(ty)): - return None - return AutonomyTypeError(ty=ty, value=value) - - -def check_mono_container( - value: Any, ty: Union[Type[List[Any]], Type[Set[Any]], Type[FrozenSet[Any]]] -) -> Result: - """Check mono container type.""" - ty_item = get_args(ty)[0] - for v in value: - err = check(v, ty_item) - if is_error(err): - return err - return None - - -def check_dict(value: Dict[Any, Any], ty: Type[Dict[Any, Any]]) -> Result: - """Check dict type.""" - args = get_args(ty) - ty_key = args[0] - ty_item = args[1] - for k, v in value.items(): - err = check(k, ty_key) - if is_error(err): - return err - err = check(v, ty_item) - if err is not None: - err.path.append(k) - return err - return None - - -def check_dataclass(value: Any, ty: Type[Any]) -> Result: - """Check dataclass type.""" - if not dataclasses.is_dataclass(value): - return AutonomyTypeError(ty, value) - for k, ty_ in typing.get_type_hints(ty).items(): - v = getattr(value, k) - err = check(v, ty_) - if err is not None: - err.path.append(k) - return err - return None - - -def check_typeddict(value: Any, ty: Type[Any]) -> Result: - """Check typeddict type.""" - if not isinstance(value, dict): - return AutonomyTypeError(ty, value) # pragma: no cover - is_total: bool = ty.__total__ # type: ignore - for k, ty_ in typing.get_type_hints(ty).items(): - if k not in value: - if is_total: - return AutonomyTypeError(ty_, value, [k]) - continue - v = value[k] - err = check(v, ty_) - if err is not None: - err.path.append(k) - return err - return None - - -# TODO: incorporate -def is_typevar(ty: Type[Any]) -> TypeGuard[TypeVar]: - """Check typevar.""" - return isinstance(ty, TypeVar) # pragma: no cover - - -def is_error(ret: Result) -> TypeGuard[AutonomyTypeError]: - """Check error.""" - return ret is not None - - -def is_typeddict(ty: Type[Any]) -> TypeGuard[Type[TypedDict]]: # type: ignore - """Check typeddict.""" - # TODO: Should use `typing.is_typeddict` in future - # or, use publich API - T = "_TypedDictMeta" - for mod in [typing, typing_extensions]: - if hasattr(mod, T) and isinstance(ty, getattr(mod, T)): - return True - return False - - -def check_type(name: str, value: Any, type_hint: Any) -> None: - """Check value against type hint recursively""" - err = check(value, type_hint) - if err is not None: - err.path.append(name) - raise err - - -def is_primitive_or_none(obj: Any) -> bool: - """Checks if the given object is a primitive type or `None`.""" - primitives = (bool, int, float, str) - return isinstance(obj, primitives) or obj is None - - -def is_json_serializable(obj: Any) -> bool: - """Checks if the given object is json serializable.""" - if isinstance(obj, (tuple, list)): - return all(is_json_serializable(x) for x in obj) - if isinstance(obj, dict): - return all( - is_primitive_or_none(k) and is_json_serializable(v) for k, v in obj.items() - ) - - return is_primitive_or_none(obj) - - -def filter_negative(mapping: Dict[str, int]) -> Iterator[str]: - """Return the keys of a dictionary for which the values are negative integers.""" - return (key for key, number in mapping.items() if number < 0) - - -def consensus_threshold(nb: int) -> int: - """ - Get consensus threshold. - - :param nb: the number of participants - :return: the consensus threshold - """ - return ceil((2 * nb + 1) / 3) - - -KeyType = TypeVar("KeyType") -ValueType = TypeVar("ValueType") - - -def inverse(dict_: Dict[KeyType, ValueType]) -> Dict[ValueType, List[KeyType]]: - """Get the inverse of a dictionary.""" - inverse_: Dict[ValueType, List[KeyType]] = {val: [] for val in dict_.values()} - for key, value in dict_.items(): - inverse_[value].append(key) - return inverse_ diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/README.md b/trader_backup/vendor/valory/skills/check_stop_trading_abci/README.md deleted file mode 100644 index 02ad18706..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Check stop trading abci - -## Description - -This package contains the check stop trading skill for an AEA. diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/__init__.py b/trader_backup/vendor/valory/skills/check_stop_trading_abci/__init__.py deleted file mode 100644 index da4d21162..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the check stop trading skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/check_stop_trading_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/behaviours.py b/trader_backup/vendor/valory/skills/check_stop_trading_abci/behaviours.py deleted file mode 100644 index f1eac99e8..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/behaviours.py +++ /dev/null @@ -1,185 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the behaviours for the check stop trading skill.""" - -import math -from typing import Any, Generator, Set, Type, cast - -from packages.valory.contracts.mech.contract import Mech as MechContract -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.behaviours import AbstractRoundBehaviour -from packages.valory.skills.check_stop_trading_abci.models import CheckStopTradingParams -from packages.valory.skills.check_stop_trading_abci.payloads import ( - CheckStopTradingPayload, -) -from packages.valory.skills.check_stop_trading_abci.rounds import ( - CheckStopTradingAbciApp, - CheckStopTradingRound, -) -from packages.valory.skills.staking_abci.behaviours import ( - StakingInteractBaseBehaviour, - WaitableConditionType, -) -from packages.valory.skills.staking_abci.rounds import StakingState - - -# Liveness ratio from the staking contract is expressed in calls per 10**18 seconds. -LIVENESS_RATIO_SCALE_FACTOR = 10**18 - -# A safety margin in case there is a delay between the moment the KPI condition is -# satisfied, and the moment where the checkpoint is called. -REQUIRED_MECH_REQUESTS_SAFETY_MARGIN = 1 - - -class CheckStopTradingBehaviour(StakingInteractBaseBehaviour): - """A behaviour that checks stop trading conditions.""" - - matching_round = CheckStopTradingRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize the behaviour.""" - super().__init__(**kwargs) - self._mech_request_count: int = 0 - - @property - def mech_request_count(self) -> int: - """Get the liveness period.""" - return self._mech_request_count - - @mech_request_count.setter - def mech_request_count(self, mech_request_count: int) -> None: - """Set the liveness period.""" - self._mech_request_count = mech_request_count - - def _get_mech_request_count(self) -> WaitableConditionType: - """Get the mech request count.""" - status = yield from self.contract_interact( - contract_address=self.params.mech_contract_address, - contract_public_id=MechContract.contract_id, - contract_callable="get_requests_count", - data_key="requests_count", - placeholder=get_name(CheckStopTradingBehaviour.mech_request_count), - address=self.synchronized_data.safe_contract_address, - ) - return status - - @property - def is_first_period(self) -> bool: - """Return whether it is the first period of the service.""" - return self.synchronized_data.period_count == 0 - - @property - def params(self) -> CheckStopTradingParams: - """Return the params.""" - return cast(CheckStopTradingParams, self.context.params) - - def is_staking_kpi_met(self) -> Generator[None, None, bool]: - """Return whether the staking KPI has been met (only for staked services).""" - yield from self.wait_for_condition_with_sleep(self._check_service_staked) - self.context.logger.debug(f"{self.service_staking_state=}") - if self.service_staking_state != StakingState.STAKED: - return False - - yield from self.wait_for_condition_with_sleep(self._get_mech_request_count) - mech_request_count = self.mech_request_count - self.context.logger.debug(f"{mech_request_count=}") - - yield from self.wait_for_condition_with_sleep(self._get_service_info) - mech_request_count_on_last_checkpoint = self.service_info[2][1] - self.context.logger.debug(f"{mech_request_count_on_last_checkpoint=}") - - yield from self.wait_for_condition_with_sleep(self._get_ts_checkpoint) - last_ts_checkpoint = self.ts_checkpoint - self.context.logger.debug(f"{last_ts_checkpoint=}") - - yield from self.wait_for_condition_with_sleep(self._get_liveness_period) - liveness_period = self.liveness_period - self.context.logger.debug(f"{liveness_period=}") - - yield from self.wait_for_condition_with_sleep(self._get_liveness_ratio) - liveness_ratio = self.liveness_ratio - self.context.logger.debug(f"{liveness_ratio=}") - - mech_requests_since_last_cp = ( - mech_request_count - mech_request_count_on_last_checkpoint - ) - self.context.logger.debug(f"{mech_requests_since_last_cp=}") - - current_timestamp = self.synced_timestamp - self.context.logger.debug(f"{current_timestamp=}") - - required_mech_requests = ( - math.ceil( - max(liveness_period, (current_timestamp - last_ts_checkpoint)) - * liveness_ratio - / LIVENESS_RATIO_SCALE_FACTOR - ) - + REQUIRED_MECH_REQUESTS_SAFETY_MARGIN - ) - self.context.logger.debug(f"{required_mech_requests=}") - - if mech_requests_since_last_cp >= required_mech_requests: - return True - return False - - def _compute_stop_trading(self) -> Generator[None, None, bool]: - # This is a "hacky" way of getting required data initialized on - # the Trader: On first period, the FSM needs to initialize some - # data on the trading branch so that it is available in the - # cross-period persistent keys. - if self.is_first_period: - self.context.logger.debug(f"{self.is_first_period=}") - yield # ensures this is a generator - return False - - self.context.logger.debug(f"{self.params.disable_trading=}") - if self.params.disable_trading: - yield # ensures this is a generator - return True - - self.context.logger.debug(f"{self.params.stop_trading_if_staking_kpi_met=}") - if self.params.stop_trading_if_staking_kpi_met: - staking_kpi_met = yield from self.is_staking_kpi_met() - self.context.logger.debug(f"{staking_kpi_met=}") - return staking_kpi_met - - yield - return False - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - stop_trading = yield from self._compute_stop_trading() - self.context.logger.info(f"Computed {stop_trading=}") - payload = CheckStopTradingPayload(self.context.agent_address, stop_trading) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - self.set_done() - - -class CheckStopTradingRoundBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the check stop trading behaviour.""" - - initial_behaviour_cls = CheckStopTradingBehaviour - abci_app_cls = CheckStopTradingAbciApp - behaviours: Set[Type[BaseBehaviour]] = {CheckStopTradingBehaviour} # type: ignore diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/dialogues.py b/trader_backup/vendor/valory/skills/check_stop_trading_abci/dialogues.py deleted file mode 100644 index 74cc46dc5..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/dialogues.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/fsm_specification.yaml b/trader_backup/vendor/valory/skills/check_stop_trading_abci/fsm_specification.yaml deleted file mode 100644 index e71d9e9b8..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/fsm_specification.yaml +++ /dev/null @@ -1,23 +0,0 @@ -alphabet_in: -- DONE -- NONE -- NO_MAJORITY -- ROUND_TIMEOUT -- SKIP_TRADING -default_start_state: CheckStopTradingRound -final_states: -- FinishedCheckStopTradingRound -- FinishedWithSkipTradingRound -label: CheckStopTradingAbciApp -start_states: -- CheckStopTradingRound -states: -- CheckStopTradingRound -- FinishedCheckStopTradingRound -- FinishedWithSkipTradingRound -transition_func: - (CheckStopTradingRound, DONE): FinishedCheckStopTradingRound - (CheckStopTradingRound, NONE): CheckStopTradingRound - (CheckStopTradingRound, NO_MAJORITY): CheckStopTradingRound - (CheckStopTradingRound, ROUND_TIMEOUT): CheckStopTradingRound - (CheckStopTradingRound, SKIP_TRADING): FinishedWithSkipTradingRound diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/handlers.py b/trader_backup/vendor/valory/skills/check_stop_trading_abci/handlers.py deleted file mode 100644 index 64bac3a39..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/handlers.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the handlers for the check stop trading skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCICheckStopTradingHandler = ABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/models.py b/trader_backup/vendor/valory/skills/check_stop_trading_abci/models.py deleted file mode 100644 index 3d4728874..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/models.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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. -# -# ------------------------------------------------------------------------------ - - -"""Models for the check stop trading ABCI application.""" - -from typing import Any - -from aea.exceptions import enforce - -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.check_stop_trading_abci.rounds import ( - CheckStopTradingAbciApp, -) -from packages.valory.skills.staking_abci.models import StakingParams - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -class CheckStopTradingParams(StakingParams): - """CheckStopTrading parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the parameters' object.""" - mech_address = kwargs.get("mech_contract_address", None) - enforce(mech_address is not None, "Mech contract address not specified!") - self.mech_contract_address = mech_address - self.disable_trading: bool = self._ensure("disable_trading", kwargs, bool) - self.stop_trading_if_staking_kpi_met: bool = self._ensure( - "stop_trading_if_staking_kpi_met", kwargs, bool - ) - super().__init__(*args, **kwargs) - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = CheckStopTradingAbciApp diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/payloads.py b/trader_backup/vendor/valory/skills/check_stop_trading_abci/payloads.py deleted file mode 100644 index 5831cff87..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/payloads.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the transaction payloads for the check stop trading abci.""" - -from dataclasses import dataclass - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class CheckStopTradingPayload(BaseTxPayload): - """A transaction payload for the check stop trading abci.""" - - vote: bool diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/rounds.py b/trader_backup/vendor/valory/skills/check_stop_trading_abci/rounds.py deleted file mode 100644 index 21b93e89b..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/rounds.py +++ /dev/null @@ -1,147 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the rounds for the check stop trading ABCI application.""" - -from abc import ABC -from enum import Enum -from typing import Dict, Optional, Set, Tuple, Type - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AbstractRound, - AppState, - BaseSynchronizedData, - CollectionRound, - DegenerateRound, - DeserializedCollection, - VotingRound, - get_name, -) -from packages.valory.skills.check_stop_trading_abci.payloads import ( - CheckStopTradingPayload, -) - - -class Event(Enum): - """Event enumeration for the check stop trading skill.""" - - DONE = "done" - NONE = "none" - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - SKIP_TRADING = "skip_trading" - - -class SynchronizedData(BaseSynchronizedData): - """Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - def _get_deserialized(self, key: str) -> DeserializedCollection: - """Strictly get a collection and return it deserialized.""" - serialized = self.db.get_strict(key) - return CollectionRound.deserialize_collection(serialized) - - def is_staking_kpi_met(self) -> bool: - """Get the status of the staking kpi.""" - return bool(self.db.get("is_staking_kpi_met", False)) - - -class CheckStopTradingRound(VotingRound): - """A round for checking stop trading conditions.""" - - payload_class = CheckStopTradingPayload - synchronized_data_class = SynchronizedData - done_event = Event.SKIP_TRADING - negative_event = Event.DONE - none_event = Event.NONE - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_votes) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - - if res is None: - return None - - is_staking_kpi_met = self.positive_vote_threshold_reached - self.synchronized_data.update(is_staking_kpi_met=is_staking_kpi_met) - - return res - - -class FinishedCheckStopTradingRound(DegenerateRound, ABC): - """A round that represents check stop trading has finished.""" - - -class FinishedWithSkipTradingRound(DegenerateRound, ABC): - """A round that represents check stop trading has finished with skip trading.""" - - -class CheckStopTradingAbciApp(AbciApp[Event]): # pylint: disable=too-few-public-methods - """CheckStopTradingAbciApp - - Initial round: CheckStopTradingRound - - Initial states: {CheckStopTradingRound} - - Transition states: - 0. CheckStopTradingRound - - done: 1. - - none: 0. - - round timeout: 0. - - no majority: 0. - - skip trading: 2. - 1. FinishedCheckStopTradingRound - 2. FinishedWithSkipTradingRound - - Final states: {FinishedCheckStopTradingRound, FinishedWithSkipTradingRound} - - Timeouts: - round timeout: 30.0 - """ - - initial_round_cls: Type[AbstractRound] = CheckStopTradingRound - transition_function: AbciAppTransitionFunction = { - CheckStopTradingRound: { - Event.DONE: FinishedCheckStopTradingRound, - Event.NONE: CheckStopTradingRound, - Event.ROUND_TIMEOUT: CheckStopTradingRound, - Event.NO_MAJORITY: CheckStopTradingRound, - Event.SKIP_TRADING: FinishedWithSkipTradingRound, - }, - FinishedCheckStopTradingRound: {}, - FinishedWithSkipTradingRound: {}, - } - final_states: Set[AppState] = { - FinishedCheckStopTradingRound, - FinishedWithSkipTradingRound, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = {CheckStopTradingRound: set()} - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedCheckStopTradingRound: set(), - FinishedWithSkipTradingRound: set(), - } diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/skill.yaml b/trader_backup/vendor/valory/skills/check_stop_trading_abci/skill.yaml deleted file mode 100644 index d37ff0def..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/skill.yaml +++ /dev/null @@ -1,146 +0,0 @@ -name: check_stop_trading_abci -author: valory -version: 0.1.0 -type: skill -description: This skill implements the check for stop trading for an AEA. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeif2pq7fg5upl6vmfgfzpiwsh4nbk4zaeyz6upyucqi5tasrxgq4ee - __init__.py: bafybeifc23rlw2hzhplp3wfceixnmwq5ztnixhh7jp4dd5av3crwp3x22a - behaviours.py: bafybeie5mkpxsd6z3vjsoacvswin6zz4q4um5gqp6jhwtn65fepx2kma3m - dialogues.py: bafybeictrrnwcijiejczy23dfvbx5kujgef3dulzqhs3etl2juvz5spm2e - fsm_specification.yaml: bafybeihhau35a5xclncjpxh5lg7qiw34xs4d5qlez7dnjpkf45d3gc57ai - handlers.py: bafybeiard64fwxib3rtyp67ymhf222uongcyqhfhdyttpsyqkmyh5ajipu - models.py: bafybeigwdhgianx5rizlb7ebmm6pdtkixh4uehbvu5c24ysvyvojs74dfq - payloads.py: bafybeidh5bqywun4chrbsci2xbcrnnzuys5sswxwbxq3yl2ksawi3xsi5q - rounds.py: bafybeift7b2afck4e5so2cpgyoywa76t6el6d4qwfoitvfdjw6kgf4fwie - tests/__init__.py: bafybeihv2cjk4va5bc5ncqtppqg2xmmxcro34bma36trtvk32gtmhdycxu - tests/test_dialogues.py: bafybeia5ac27w7ijx2nyx5dqyrnv4troo4572gjq7nrcxdncexoxucnqti - tests/test_handlers.py: bafybeigpmtx2hyunzn6nxk2x4bvvybek7jvuhbk34fqlj7fgfsszcoqhxy - tests/test_payloads.py: bafybeih7q7kdfxsf4ejxxqwjumwglfwwcrbqcjnuy42mkhnfwccxuhiviy - tests/test_rounds.py: bafybeidgbc7mi7r2fpk7ak6xceohuoq2zkpkberkokcb3sb2uzwkxoluae -fingerprint_ignore_patterns: [] -connections: [] -contracts: -- valory/mech:0.1.0:bafybeiejfjfoxqggghcme43sx53q5gruefrws3k2jam2opkxl5uzffoarm -protocols: [] -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/staking_abci:0.1.0:bafybeicupccurmrg7qesivonlyt3nryarsmk5qf5yh6auno64wn45bybvq -behaviours: - main: - args: {} - class_name: CheckStopTradingRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCICheckStopTradingHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 350.0 - service_id: check_stop_trading - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - sleep_time: 5 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - termination_sleep: 900 - tx_timeout: 10.0 - use_termination: false - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - disable_trading: false - stop_trading_if_staking_kpi_met: true - class_name: CheckStopTradingParams - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState -dependencies: {} -is_abstract: true diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/__init__.py deleted file mode 100644 index 8b00b9e88..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/check_stop_trading skill.""" diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_dialogues.py b/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_dialogues.py deleted file mode 100644 index be3bcac1f..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.check_stop_trading_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_handlers.py b/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_handlers.py deleted file mode 100644 index bb1d25447..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_handlers.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 tests for the handlers for the check stop trading abci.""" - -from unittest.mock import MagicMock - -import pytest -from aea.configurations.data_types import PublicId -from aea.skills.base import Handler - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.check_stop_trading_abci.handlers import ( - ABCICheckStopTradingHandler, - ContractApiHandler, - HttpHandler, - IpfsHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, -) - - -@pytest.mark.parametrize( - "handler, base_handler", - [ - (ABCICheckStopTradingHandler, ABCIRoundHandler), - (HttpHandler, BaseHttpHandler), - (SigningHandler, BaseSigningHandler), - (LedgerApiHandler, BaseLedgerApiHandler), - (ContractApiHandler, BaseContractApiHandler), - (TendermintHandler, BaseTendermintHandler), - (IpfsHandler, BaseIpfsHandler), - ], -) -def test_handler(handler: Handler, base_handler: Handler) -> None: - """Test that the 'handlers.py' of the CheckStopTradingAbci can be imported.""" - handler = handler( - name="dummy_handler", - skill_context=MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")), - ) - - assert isinstance(handler, base_handler) diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_payloads.py b/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_payloads.py deleted file mode 100644 index de53b3995..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_payloads.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the transaction payloads for the check stop trading abci.""" - -from packages.valory.skills.check_stop_trading_abci.payloads import ( - CheckStopTradingPayload, -) - - -def test_check_stop_trading_payload() -> None: - """Test `CheckStopTradingPayload`.""" - - payload = CheckStopTradingPayload(sender="sender", vote=True) - - assert payload.vote - assert payload.data == {"vote": True} - assert CheckStopTradingPayload.from_json(payload.json) == payload diff --git a/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_rounds.py b/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_rounds.py deleted file mode 100644 index 8967831fa..000000000 --- a/trader_backup/vendor/valory/skills/check_stop_trading_abci/tests/test_rounds.py +++ /dev/null @@ -1,285 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 package contains the tests for the CheckStopTradingAbciApp.""" - -import json -from dataclasses import dataclass, field -from typing import ( - Any, - Callable, - Dict, - FrozenSet, - Hashable, - List, - Mapping, - Optional, - Type, -) -from unittest.mock import MagicMock, Mock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - CollectionRound, - VotingRound, - get_name, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseVotingRoundTest, -) -from packages.valory.skills.check_stop_trading_abci.payloads import ( - CheckStopTradingPayload, -) -from packages.valory.skills.check_stop_trading_abci.rounds import ( - CheckStopTradingAbciApp, - CheckStopTradingRound, - Event, - FinishedCheckStopTradingRound, - FinishedWithSkipTradingRound, - SynchronizedData, -) - - -DUMMY_PAYLOAD_DATA = {"example_key": "example_value"} - - -@pytest.fixture -def abci_app() -> CheckStopTradingAbciApp: - """Fixture for CheckStopTradingAbciApp.""" - synchronized_data = Mock() - logger = Mock() - context = Mock() - - return CheckStopTradingAbciApp( - synchronized_data=synchronized_data, logger=logger, context=context - ) - - -def get_participants() -> FrozenSet[str]: - """Participants""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -def get_participant_to_votes( - participants: FrozenSet[str], vote: bool -) -> Dict[str, CheckStopTradingPayload]: - """participant_to_votes""" - - return { - participant: CheckStopTradingPayload(sender=participant, vote=vote) - for participant in participants - } - - -def get_participant_to_votes_serialized( - participants: FrozenSet[str], vote: bool -) -> Dict[str, Dict[str, Any]]: - """participant_to_votes""" - - return CollectionRound.serialize_collection( - get_participant_to_votes(participants, vote) - ) - - -def get_payloads( - payload_cls: Type[CheckStopTradingPayload], - data: Optional[str], -) -> Mapping[str, CheckStopTradingPayload]: - """Get payloads.""" - return { - participant: payload_cls(participant, data is not None) - for participant in get_participants() - } - - -def get_dummy_check_stop_trading_payload_serialized() -> str: - """Dummy payload serialization""" - return json.dumps(DUMMY_PAYLOAD_DATA, sort_keys=True) - - -@dataclass -class RoundTestCase: - """RoundTestCase""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, CheckStopTradingPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -MAX_PARTICIPANTS: int = 4 - - -class BaseCheckStopTradingRoundTest(BaseVotingRoundTest): - """Base Test Class for CheckStopTradingRound""" - - test_class: Type[VotingRound] - test_payload: Type[CheckStopTradingPayload] - - def _test_voting_round( - self, vote: bool, expected_event: Any, threshold_check: Callable - ) -> None: - """Helper method to test voting rounds with positive or negative votes.""" - - test_round = self.test_class( - synchronized_data=self.synchronized_data, context=MagicMock() - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_votes(self.participants, vote=vote), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.update( - participant_to_votes=get_participant_to_votes_serialized( - self.participants, vote=vote - ) - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.participant_to_votes.keys() - ] - if vote - else [], - exit_event=expected_event, - threshold_check=threshold_check, - ) - ) - - def test_positive_votes(self) -> None: - """Test ValidateRound for positive votes.""" - self._test_voting_round( - vote=True, - expected_event=self._event_class.SKIP_TRADING, - threshold_check=lambda x: x.positive_vote_threshold_reached, - ) - - def test_negative_votes(self) -> None: - """Test ValidateRound for negative votes.""" - self._test_voting_round( - vote=False, - expected_event=self._event_class.DONE, - threshold_check=lambda x: x.negative_vote_threshold_reached, - ) - - -class TestCheckStopTradingRound(BaseCheckStopTradingRoundTest): - """Tests for CheckStopTradingRound.""" - - test_class = CheckStopTradingRound - _event_class = Event - _synchronized_data_class = SynchronizedData - - @pytest.mark.parametrize( - "test_case", - ( - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_payloads( - payload_cls=CheckStopTradingPayload, - data=get_dummy_check_stop_trading_payload_serialized(), - ), - final_data={}, - event=Event.SKIP_TRADING, - most_voted_payload=get_dummy_check_stop_trading_payload_serialized(), - synchronized_data_attr_checks=[ - lambda sync_data: sync_data.db.get( - get_name(SynchronizedData.participant_to_votes) - ) - == CollectionRound.deserialize_collection( - json.loads(get_dummy_check_stop_trading_payload_serialized()) - ) - ], - ), - RoundTestCase( - name="No majority", - initial_data={}, - payloads=get_payloads( - payload_cls=CheckStopTradingPayload, - data=get_dummy_check_stop_trading_payload_serialized(), - ), - final_data={}, - event=Event.NO_MAJORITY, - most_voted_payload=get_dummy_check_stop_trading_payload_serialized(), - synchronized_data_attr_checks=[], - ), - ), - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run tests.""" - if test_case.event == Event.SKIP_TRADING: - self.test_positive_votes() - elif test_case.event == Event.NO_MAJORITY: - self.test_negative_votes() - - """Tests for FinishedCheckStopTradingRound.""" - - def test_finished_check_stop_trading_round_initialization(self) -> None: - """Test the initialization of FinishedCheckStopTradingRound.""" - round_ = FinishedCheckStopTradingRound( - synchronized_data=MagicMock(), context=MagicMock() - ) - assert isinstance(round_, FinishedCheckStopTradingRound) - - -class TestFinishedWithSkipTradingRound: - """Tests for FinishedWithSkipTradingRound.""" - - def test_finished_with_skip_trading_round_initialization(self) -> None: - """Test the initialization of FinishedWithSkipTradingRound.""" - round_ = FinishedWithSkipTradingRound( - synchronized_data=MagicMock(), context=MagicMock() - ) - assert isinstance(round_, FinishedWithSkipTradingRound) - - -def test_abci_app_initialization(abci_app: CheckStopTradingAbciApp) -> None: - """Test the initialization of CheckStopTradingAbciApp.""" - assert abci_app.initial_round_cls is CheckStopTradingRound - assert abci_app.final_states == { - FinishedCheckStopTradingRound, - FinishedWithSkipTradingRound, - } - assert abci_app.transition_function == { - CheckStopTradingRound: { - Event.DONE: FinishedCheckStopTradingRound, - Event.NONE: CheckStopTradingRound, - Event.ROUND_TIMEOUT: CheckStopTradingRound, - Event.NO_MAJORITY: CheckStopTradingRound, - Event.SKIP_TRADING: FinishedWithSkipTradingRound, - }, - FinishedCheckStopTradingRound: {}, - FinishedWithSkipTradingRound: {}, - } - assert abci_app.event_to_timeout == {Event.ROUND_TIMEOUT: 30.0} - assert abci_app.db_pre_conditions == {CheckStopTradingRound: set()} - assert abci_app.db_post_conditions == { - FinishedCheckStopTradingRound: set(), - FinishedWithSkipTradingRound: set(), - } - - -def test_synchronized_data_initialization() -> None: - """Test the initialization and attributes of SynchronizedData.""" - data = SynchronizedData(db=AbciAppDB(setup_data={"test": ["test"]})) - assert data.db._data == {0: {"test": ["test"]}} diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/README.md b/trader_backup/vendor/valory/skills/decision_maker_abci/README.md deleted file mode 100644 index 93307c4d7..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# DecisionMaker abci - -## Description - -This module contains the ABCI decision-making skill for an AEA. diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/__init__.py b/trader_backup/vendor/valory/skills/decision_maker_abci/__init__.py deleted file mode 100644 index 17b61f59d..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- 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 the decision maker skill for the trader.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/decision_maker_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/__init__.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/__init__.py deleted file mode 100644 index c0db5476d..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 package contains the behaviours for the 'decision_maker_abci' skill.""" diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/base.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/base.py deleted file mode 100644 index bfef348b7..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/base.py +++ /dev/null @@ -1,875 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the base behaviour for the 'decision_maker_abci' skill.""" - -import dataclasses -import json -import os -from abc import ABC -from datetime import datetime, timedelta -from typing import Any, Callable, Dict, Generator, List, Optional, Set, Tuple, cast - -from aea.configurations.data_types import PublicId -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue -from hexbytes import HexBytes - -from packages.valory.contracts.erc20.contract import ERC20 -from packages.valory.contracts.gnosis_safe.contract import ( - GnosisSafeContract, - SafeOperation, -) -from packages.valory.contracts.mech.contract import Mech -from packages.valory.contracts.multisend.contract import MultiSendContract -from packages.valory.contracts.transfer_nft_condition.contract import ( - TransferNftCondition, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.abstract_round_abci.behaviour_utils import TimeoutException -from packages.valory.skills.decision_maker_abci.io_.loader import ComponentPackageLoader -from packages.valory.skills.decision_maker_abci.models import ( - AccuracyInfoFields, - BenchmarkingMockData, - BenchmarkingMode, - DecisionMakerParams, - L0_END_FIELD, - L0_START_FIELD, - L1_END_FIELD, - L1_START_FIELD, - LiquidityInfo, - MultisendBatch, - SharedState, -) -from packages.valory.skills.decision_maker_abci.policy import EGreedyPolicy -from packages.valory.skills.decision_maker_abci.states.base import SynchronizedData -from packages.valory.skills.decision_maker_abci.utils.nevermined import ( - no_did_prefixed, - zero_x_transformer, -) -from packages.valory.skills.market_manager_abci.behaviours import BetsManagerBehaviour -from packages.valory.skills.market_manager_abci.bets import ( - Bet, - CONFIDENCE_FIELD, - P_NO_FIELD, - P_YES_FIELD, - PredictionResponse, -) -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - hash_payload_to_hex, -) -from packages.valory.skills.transaction_settlement_abci.rounds import TX_HASH_LENGTH - - -WaitableConditionType = Generator[None, None, bool] - -# setting the safe gas to 0 means that all available gas will be used -# which is what we want in most cases -# more info here: https://safe-docs.dev.gnosisdev.com/safe/docs/contracts_tx_execution/ -SAFE_GAS = 0 -CID_PREFIX = "f01701220" -WXDAI = "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d" -BET_AMOUNT_FIELD = "bet_amount" -SUPPORTED_STRATEGY_LOG_LEVELS = ("info", "warning", "error") -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" -NEW_LINE = "\n" -QUOTE = '"' -TWO_QUOTES = '""' -INIT_LIQUIDITY_INFO = LiquidityInfo() - - -def remove_fraction_wei(amount: int, fraction: float) -> int: - """Removes the given fraction from the given integer amount and returns the value as an integer.""" - if 0 <= fraction <= 1: - keep_percentage = 1 - fraction - return int(amount * keep_percentage) - raise ValueError(f"The given fraction {fraction!r} is not in the range [0, 1].") - - -class DecisionMakerBaseBehaviour(BetsManagerBehaviour, ABC): - """Represents the base class for the decision-making FSM behaviour.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize the bet placement behaviour.""" - super().__init__(**kwargs) - self.token_balance = 0 - self.wallet_balance = 0 - self.multisend_batches: List[MultisendBatch] = [] - self.multisend_data = b"" - self._safe_tx_hash = "" - self._policy: Optional[EGreedyPolicy] = None - self._inflight_strategy_req: Optional[str] = None - - @property - def subscription_params(self) -> Dict[str, Any]: - """Get the subscription params.""" - return self.params.mech_to_subscription_params - - @property - def did(self) -> str: - """Get the did.""" - subscription_params = self.subscription_params - return subscription_params["did"] - - @property - def token_address(self) -> str: - """Get the token address.""" - subscription_params = self.subscription_params - return subscription_params["token_address"] - - def strategy_exec(self, strategy: str) -> Optional[Tuple[str, str]]: - """Get the executable strategy file's content.""" - return self.shared_state.strategies_executables.get(strategy, None) - - def execute_strategy(self, *args: Any, **kwargs: Any) -> Dict[str, Any]: - """Execute the strategy and return the results.""" - trading_strategy = kwargs.pop("trading_strategy", None) - if trading_strategy is None: - self.context.logger.error(f"No trading strategy was given in {kwargs=}!") - return {BET_AMOUNT_FIELD: 0} - - strategy = self.strategy_exec(trading_strategy) - if strategy is None: - self.context.logger.error( - f"No executable was found for {trading_strategy=}!" - ) - return {BET_AMOUNT_FIELD: 0} - - strategy_exec, callable_method = strategy - if callable_method in globals(): - del globals()[callable_method] - - exec(strategy_exec, globals()) # pylint: disable=W0122 # nosec - method = globals().get(callable_method, None) - if method is None: - self.context.logger.error( - f"No {callable_method!r} method was found in {trading_strategy} strategy's executable." - ) - return {BET_AMOUNT_FIELD: 0} - - return method(*args, **kwargs) - - @property - def params(self) -> DecisionMakerParams: - """Return the params.""" - return cast(DecisionMakerParams, self.context.params) - - @property - def benchmarking_mode(self) -> BenchmarkingMode: - """Return the benchmarking mode configurations.""" - return cast(BenchmarkingMode, self.context.benchmarking_mode) - - @property - def mock_data(self) -> BenchmarkingMockData: - """Return the mock data for the benchmarking mode.""" - mock_data = self.shared_state.mock_data - if mock_data is None: - raise ValueError("Attempted to access the mock data while being empty!") - return mock_data - - @property - def acc_info_fields(self) -> AccuracyInfoFields: - """Return the accuracy information fieldnames.""" - return cast(AccuracyInfoFields, self.context.acc_info_fields) - - @property - def shared_state(self) -> SharedState: - """Get the shared state.""" - return cast(SharedState, self.context.state) - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return SynchronizedData(super().synchronized_data.db) - - @property - def synced_timestamp(self) -> int: - """Return the synchronized timestamp across the agents.""" - return int(self.round_sequence.last_round_transition_timestamp.timestamp()) - - @property - def safe_tx_hash(self) -> str: - """Get the safe_tx_hash.""" - return self._safe_tx_hash - - @safe_tx_hash.setter - def safe_tx_hash(self, safe_hash: str) -> None: - """Set the safe_tx_hash.""" - length = len(safe_hash) - if length != TX_HASH_LENGTH: - raise ValueError( - f"Incorrect length {length} != {TX_HASH_LENGTH} detected " - f"when trying to assign a safe transaction hash: {safe_hash}" - ) - self._safe_tx_hash = safe_hash[2:] - - @property - def multi_send_txs(self) -> List[dict]: - """Get the multisend transactions as a list of dictionaries.""" - return [dataclasses.asdict(batch) for batch in self.multisend_batches] - - @property - def txs_value(self) -> int: - """Get the total value of the transactions.""" - return sum(batch.value for batch in self.multisend_batches) - - @property - def tx_hex(self) -> Optional[str]: - """Serialize the safe tx to a hex string.""" - if self.safe_tx_hash == "": - self.context.logger.error( - "Cannot prepare a transaction without a transaction hash." - ) - return None - return hash_payload_to_hex( - self.safe_tx_hash, - self.txs_value, - SAFE_GAS, - self.params.multisend_address, - self.multisend_data, - SafeOperation.DELEGATE_CALL.value, - ) - - @property - def policy(self) -> EGreedyPolicy: - """Get the policy.""" - if self._policy is None: - raise ValueError( - "Attempting to retrieve the policy before it has been established." - ) - return self._policy - - @property - def is_first_period(self) -> bool: - """Return whether it is the first period of the service.""" - return ( - self.synchronized_data.period_count == 0 - and not self.benchmarking_mode.enabled - or self.shared_state.mock_data is None - ) - - @property - def sampled_bet(self) -> Bet: - """Get the sampled bet and reset the bets list.""" - self.read_bets() - bet_index = self.synchronized_data.sampled_bet_index - return self.bets[bet_index] - - @property - def collateral_token(self) -> str: - """Get the contract address of the token that the market maker supports.""" - return self.sampled_bet.collateralToken - - @property - def is_wxdai(self) -> bool: - """Get whether the collateral address is wxDAI.""" - return self.collateral_token.lower() == WXDAI.lower() - - @staticmethod - def wei_to_native(wei: int) -> float: - """Convert WEI to native token.""" - return wei / 10**18 - - def get_active_sampled_bet(self) -> Bet: - """Function to get the selected bet that is active without reseting self.bets.""" - bet_index = self.synchronized_data.sampled_bet_index - if len(self.bets) == 0: - msg = "The length of self.bets is 0" - self.context.logger.info(msg) - self.read_bets() - - return self.bets[bet_index] - - def _collateral_amount_info(self, amount: int) -> str: - """Get a description of the collateral token's amount.""" - is_wxdai = True if self.benchmarking_mode.enabled else self.is_wxdai - - return ( - f"{self.wei_to_native(amount)} wxDAI" - if is_wxdai - else f"{amount} WEI of the collateral token with address {self.collateral_token}" - ) - - def _report_balance(self) -> None: - """Report the balances of the native and the collateral tokens.""" - native = self.wei_to_native(self.wallet_balance) - collateral = self._collateral_amount_info(self.token_balance) - self.context.logger.info(f"The safe has {native} xDAI and {collateral}.") - - def _mock_balance_check(self) -> None: - """Mock the balance of the native and the collateral tokens.""" - self.token_balance = self.benchmarking_mode.collateral_balance - self.wallet_balance = self.benchmarking_mode.native_balance - self._report_balance() - - def check_balance(self) -> WaitableConditionType: - """Check the safe's balance.""" - if self.benchmarking_mode.enabled: - self._mock_balance_check() - return True - - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.collateral_token, - contract_id=str(ERC20.contract_id), - contract_callable="check_balance", - account=self.synchronized_data.safe_contract_address, - ) - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.context.logger.error( - f"Could not calculate the balance of the safe: {response_msg}" - ) - return False - - token = response_msg.raw_transaction.body.get("token", None) - wallet = response_msg.raw_transaction.body.get("wallet", None) - if token is None or wallet is None: - self.context.logger.error( - f"Something went wrong while trying to get the balance of the safe: {response_msg}" - ) - return False - - self.token_balance = int(token) - self.wallet_balance = int(wallet) - self._report_balance() - return True - - def update_bet_transaction_information(self) -> None: - """Get whether the bet's invested amount should be updated.""" - sampled_bet = self.sampled_bet - - # Update the bet's invested amount - updated = sampled_bet.update_investments(self.synchronized_data.bet_amount) - if not updated: - self.context.logger.error("Could not update the investments!") - - # Update bet transaction timestamp - sampled_bet.processed_timestamp = self.synced_timestamp - # Update Queue number for priority logic - sampled_bet.queue_status = sampled_bet.queue_status.next_status() - - # the bets are stored here, but we do not update the hash in the synced db in the redeeming round - # this will need to change if this sovereign agent is ever converted to a multi-agent service - self.store_bets() - - def send_message( - self, msg: Message, dialogue: Dialogue, callback: Callable - ) -> None: - """Send a message.""" - self.context.outbox.put_message(message=msg) - nonce = dialogue.dialogue_label.dialogue_reference[0] - self.shared_state.req_to_callback[nonce] = callback - self.shared_state.in_flight_req = True - - def _handle_get_strategy(self, message: IpfsMessage, _: Dialogue) -> None: - """Handle get strategy response.""" - strategy_req = self._inflight_strategy_req - if strategy_req is None: - self.context.logger.error(f"No strategy request to handle for {message=}.") - return - - # store the executable and remove the hash from the mapping because we have downloaded it - _component_yaml, strategy_exec, callable_method = ComponentPackageLoader.load( - message.files - ) - - self.shared_state.strategies_executables[strategy_req] = ( - strategy_exec, - callable_method, - ) - self.shared_state.strategy_to_filehash.pop(strategy_req) - self._inflight_strategy_req = None - - def download_next_strategy(self) -> None: - """Download the strategies one by one. - - The next strategy in the list is downloaded each time this method is called. - - We download all the strategies, - because in the future we will perform some complicated logic, - where we utilize more than one, e.g., in case the default fails - or is weaker than another depending on the situation. - - :return: None - """ - if self._inflight_strategy_req is not None: - # there already is a req in flight - return - if len(self.shared_state.strategy_to_filehash) == 0: - # no strategies pending to be fetched - return - for strategy, file_hash in self.shared_state.strategy_to_filehash.items(): - self.context.logger.info(f"Fetching {strategy} strategy...") - ipfs_msg, message = self._build_ipfs_get_file_req(file_hash) - self._inflight_strategy_req = strategy - self.send_message(ipfs_msg, message, self._handle_get_strategy) - return - - def download_strategies(self) -> Generator: - """Download all the strategies, if not yet downloaded.""" - while len(self.shared_state.strategy_to_filehash) > 0: - self.download_next_strategy() - yield from self.sleep(self.params.sleep_time) - - def get_bet_amount( - self, - win_probability: float, - confidence: float, - selected_type_tokens_in_pool: int, - other_tokens_in_pool: int, - bet_fee: int, - weighted_accuracy: float, - ) -> Generator[None, None, int]: - """Get the bet amount given a specified trading strategy.""" - yield from self.download_strategies() - yield from self.wait_for_condition_with_sleep(self.check_balance) - - next_strategy = self.params.trading_strategy - tried_strategies: Set[str] = set() - while True: - self.context.logger.info(f"Used trading strategy: {next_strategy}") - # the following are always passed to a strategy script, which may choose to ignore any - kwargs: Dict[str, Any] = self.params.strategies_kwargs - kwargs.update( - { - "trading_strategy": next_strategy, - "bankroll": self.token_balance + self.wallet_balance, - "win_probability": win_probability, - "confidence": confidence, - "selected_type_tokens_in_pool": selected_type_tokens_in_pool, - "other_tokens_in_pool": other_tokens_in_pool, - "bet_fee": bet_fee, - "weighted_accuracy": weighted_accuracy, - } - ) - results = self.execute_strategy(**kwargs) - for level in SUPPORTED_STRATEGY_LOG_LEVELS: - logger = getattr(self.context.logger, level, None) - if logger is not None: - for log in results.get(level, []): - logger(log) - bet_amount = results.get(BET_AMOUNT_FIELD, None) - if bet_amount is None: - self.context.logger.error( - f"Required field {BET_AMOUNT_FIELD!r} was not returned by {next_strategy} strategy." - "Setting bet amount to 0." - ) - bet_amount = 0 - - tried_strategies.update({next_strategy}) - strategies_names = set(self.shared_state.strategies_executables) - remaining_strategies = strategies_names - tried_strategies - if ( - bet_amount > 0 - or len(remaining_strategies) == 0 - or not self.params.use_fallback_strategy - ): - break - - next_strategy = remaining_strategies.pop() - self.context.logger.warning( - f"Using fallback strategy {next_strategy} as the previous one returned {bet_amount}." - ) - - return bet_amount - - def default_error( - self, contract_id: str, contract_callable: str, response_msg: ContractApiMessage - ) -> None: - """Return a default contract interaction error message.""" - self.context.logger.error( - f"Could not successfully interact with the {contract_id} contract " - f"using {contract_callable!r}: {response_msg}" - ) - - def _propagate_contract_messages(self, response_msg: ContractApiMessage) -> bool: - """Propagate the contract's message to the logger, if exists. - - Contracts can only return one message at a time. - - :param response_msg: the response message from the contract method. - :return: whether a message has been propagated. - """ - for level in ("info", "warning", "error"): - msg = response_msg.raw_transaction.body.get(level, None) - if msg is not None: - logger = getattr(self.context.logger, level) - logger(msg) - return True - return False - - def contract_interact( - self, - performative: ContractApiMessage.Performative, - contract_address: str, - contract_public_id: PublicId, - contract_callable: str, - data_key: str, - placeholder: str, - **kwargs: Any, - ) -> WaitableConditionType: - """Interact with a contract.""" - contract_id = str(contract_public_id) - response_msg = yield from self.get_contract_api_response( - performative, - contract_address, - contract_id, - contract_callable, - **kwargs, - ) - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.default_error(contract_id, contract_callable, response_msg) - return False - - propagated = self._propagate_contract_messages(response_msg) - data = response_msg.raw_transaction.body.get(data_key, None) - if data is None: - if not propagated: - self.default_error(contract_id, contract_callable, response_msg) - return False - - setattr(self, placeholder, data) - return True - - def _mech_contract_interact( - self, contract_callable: str, data_key: str, placeholder: str, **kwargs: Any - ) -> WaitableConditionType: - """Interact with the mech contract.""" - status = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.mech_contract_address, - contract_public_id=Mech.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def _build_multisend_data( - self, - ) -> WaitableConditionType: - """Get the multisend tx.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.multisend_address, - contract_id=str(MultiSendContract.contract_id), - contract_callable="get_tx_data", - multi_send_txs=self.multi_send_txs, - ) - expected_performative = ContractApiMessage.Performative.RAW_TRANSACTION - if response_msg.performative != expected_performative: - self.context.logger.error( - "Couldn't compile the multisend tx. " # type: ignore - f"Expected response performative {expected_performative.value}, " # type: ignore - f"received {response_msg.performative.value}: {response_msg}" - ) - return False - - multisend_data_str = response_msg.raw_transaction.body.get("data", None) - if multisend_data_str is None: - self.context.logger.error( - f"Something went wrong while trying to prepare the multisend data: {response_msg}" - ) - return False - - # strip "0x" from the response - multisend_data_str = str(response_msg.raw_transaction.body["data"])[2:] - self.multisend_data = bytes.fromhex(multisend_data_str) - return True - - def _build_multisend_safe_tx_hash(self) -> WaitableConditionType: - """Prepares and returns the safe tx hash for a multisend tx.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_raw_safe_transaction_hash", - to_address=self.params.multisend_address, - value=self.txs_value, - data=self.multisend_data, - safe_tx_gas=SAFE_GAS, - operation=SafeOperation.DELEGATE_CALL.value, - ) - - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - "Couldn't get safe tx hash. Expected response performative " # type: ignore - f"{ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response_msg.performative.value}: {response_msg}." - ) - return False - - tx_hash = response_msg.state.body.get("tx_hash", None) - if tx_hash is None or len(tx_hash) != TX_HASH_LENGTH: - self.context.logger.error( - "Something went wrong while trying to get the buy transaction's hash. " - f"Invalid hash {tx_hash!r} was returned." - ) - return False - - # strip "0x" from the response hash - self.safe_tx_hash = tx_hash - return True - - def wait_for_condition_with_sleep( - self, - condition_gen: Callable[[], WaitableConditionType], - timeout: Optional[float] = None, - sleep_time_override: Optional[int] = None, - ) -> Generator[None, None, None]: - """Wait for a condition to happen and sleep in-between checks. - - This is a modified version of the base `wait_for_condition` method which: - 1. accepts a generator that creates the condition instead of a callable - 2. sleeps in-between checks - - :param condition_gen: a generator of the condition to wait for - :param timeout: the maximum amount of time to wait - :param sleep_time_override: override for the sleep time. - If None is given, the default value is used, which is the RPC timeout set in the configuration. - :yield: None - """ - - deadline = ( - datetime.now() + timedelta(0, timeout) - if timeout is not None - else datetime.max - ) - - sleep_time = sleep_time_override or self.params.rpc_sleep_time - while True: - condition_satisfied = yield from condition_gen() - if condition_satisfied: - break - if timeout is not None and datetime.now() > deadline: - raise TimeoutException() - self.context.logger.info(f"Retrying in {sleep_time} seconds.") - yield from self.sleep(sleep_time) - - def _write_benchmark_results( - self, - prediction_response: PredictionResponse, - bet_amount: Optional[float] = None, - liquidity_info: LiquidityInfo = INIT_LIQUIDITY_INFO, - ) -> None: - """Write the results to the benchmarking file.""" - add_headers = False - results_path = self.params.store_path / self.benchmarking_mode.results_filename - if not os.path.isfile(results_path): - add_headers = True - - with open(results_path, "a") as results_file: - if add_headers: - headers = ( - self.benchmarking_mode.question_id_field, - self.benchmarking_mode.question_field, - self.benchmarking_mode.answer_field, - P_YES_FIELD, - P_NO_FIELD, - CONFIDENCE_FIELD, - self.benchmarking_mode.bet_amount_field, - L0_START_FIELD, - L1_START_FIELD, - L0_END_FIELD, - L1_END_FIELD, - ) - row = ",".join(headers) + NEW_LINE - results_file.write(row) - - results = ( - self.mock_data.id, - # reintroduce duplicate quotes and quote the question - # as it may contain commas which are also used as separators - QUOTE + self.mock_data.question.replace(QUOTE, TWO_QUOTES) + QUOTE, - self.mock_data.answer, - prediction_response.p_yes, - prediction_response.p_no, - prediction_response.confidence, - bet_amount, - liquidity_info.l0_start, - liquidity_info.l1_start, - liquidity_info.l0_end, - liquidity_info.l1_end, - ) - results_text = tuple(str(res) for res in results) - row = ",".join(results_text) + NEW_LINE - results_file.write(row) - - def finish_behaviour(self, payload: BaseTxPayload) -> Generator: - """Finish the behaviour.""" - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - def build_approval_tx( - self, amount: int, spender: str, token: str - ) -> WaitableConditionType: - """Build an ERC20 approve transaction.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.collateral_token, - contract_id=str(ERC20.contract_id), - contract_callable="build_approval_tx", - spender=spender, - amount=amount, - ) - - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.info(f"Could not build approval tx: {response_msg}") - return False - - approval_data = response_msg.state.body.get("data") - if approval_data is None: - self.context.logger.info(f"Could not build approval tx: {response_msg}") - return False - - batch = MultisendBatch( - to=token, - data=HexBytes(approval_data), - ) - self.multisend_batches.append(batch) - return True - - -class BaseSubscriptionBehaviour(DecisionMakerBaseBehaviour, ABC): - """Base class for subscription behaviours.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize `BaseSubscriptionBehaviour`.""" - super().__init__(**kwargs) - self.balance: int = 0 - - @property - def escrow_payment_condition_address(self) -> str: - """Get the escrow payment address.""" - subscription_params = self.subscription_params - return subscription_params["escrow_payment_condition_address"] - - @property - def lock_payment_condition_address(self) -> str: - """Get the lock payment address.""" - subscription_params = self.subscription_params - return subscription_params["lock_payment_condition_address"] - - @property - def transfer_nft_condition_address(self) -> str: - """Get the transfer nft condition address.""" - subscription_params = self.subscription_params - return subscription_params["transfer_nft_condition_address"] - - @property - def order_address(self) -> str: - """Get the order address.""" - subscription_params = self.subscription_params - return subscription_params["order_address"] - - @property - def purchase_amount(self) -> int: - """Get the purchase amount.""" - subscription_params = self.subscription_params - return int(subscription_params["nft_amount"]) - - @property - def price(self) -> int: - """Get the price.""" - subscription_params = self.subscription_params - return int(subscription_params["price"]) - - @property - def payment_token(self) -> str: - """Get the payment token.""" - subscription_params = self.subscription_params - return subscription_params["payment_token"] - - @property - def is_xdai(self) -> bool: - """ - Check if the payment token is xDAI. - - When the payment token for the subscription is xdai (the native token of the chain), - nevermined sets the payment address to the zeroAddress. - - :return: True if the payment token is xDAI, False otherwise. - """ - return self.payment_token == ZERO_ADDRESS - - @property - def base_url(self) -> str: - """Get the base url.""" - subscription_params = self.subscription_params - return subscription_params["base_url"] - - def _resolve_did(self) -> Generator[None, None, Optional[Dict[str, Any]]]: - """Resolve and parse the did.""" - did_url = f"{self.base_url}/{self.did}" - response = yield from self.get_http_response( - method="GET", - url=did_url, - headers={"accept": "application/json"}, - ) - if response.status_code != 200: - self.context.logger.error( - f"Could not retrieve data from did url {did_url}. " - f"Received status code {response.status_code}." - ) - return None - try: - data = json.loads(response.body) - except (ValueError, TypeError) as e: - self.context.logger.error( - f"Could not parse response from nervermined api, " - f"the following error was encountered {type(e).__name__}: {e}" - ) - return None - - return data - - def _get_nft_balance( - self, token: str, address: str, did: str - ) -> Generator[None, None, bool]: - """Prepare an approval tx.""" - result = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=token, - contract_public_id=TransferNftCondition.contract_id, - contract_callable="balance_of", - data_key="data", - placeholder="balance", - address=address, - did=did, - ) - return result - - def _has_positive_nft_balance(self) -> Generator[None, None, bool]: - """Check if the agent has a non-zero balance of the NFT.""" - result = yield from self._get_nft_balance( - self.token_address, - self.synchronized_data.safe_contract_address, - zero_x_transformer(no_did_prefixed(self.did)), - ) - if not result: - self.context.logger.warning("Failed to get balance") - return False - - return self.balance > 0 diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/bet_placement.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/bet_placement.py deleted file mode 100644 index bfda67fd3..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/bet_placement.py +++ /dev/null @@ -1,225 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour for sampling a bet.""" - -from typing import Any, Generator, Optional, cast - -from hexbytes import HexBytes - -from packages.valory.contracts.erc20.contract import ERC20 -from packages.valory.contracts.market_maker.contract import ( - FixedProductMarketMakerContract, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, - WXDAI, - WaitableConditionType, - remove_fraction_wei, -) -from packages.valory.skills.decision_maker_abci.models import MultisendBatch -from packages.valory.skills.decision_maker_abci.payloads import BetPlacementPayload -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) - - -class BetPlacementBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents blacklist the sampled bet.""" - - matching_round = BetPlacementRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize the bet placement behaviour.""" - super().__init__(**kwargs) - self.buy_amount = 0 - - @property - def market_maker_contract_address(self) -> str: - """Get the contract address of the market maker on which the service is going to place the bet.""" - return self.sampled_bet.id - - @property - def investment_amount(self) -> int: - """Get the investment amount of the bet.""" - return self.synchronized_data.bet_amount - - @property - def w_xdai_deficit(self) -> int: - """Get the amount of missing wxDAI for placing the bet.""" - return self.investment_amount - self.token_balance - - @property - def outcome_index(self) -> int: - """Get the index of the outcome that the service is going to place a bet on.""" - return cast(int, self.synchronized_data.vote) - - def _build_exchange_tx(self) -> WaitableConditionType: - """Exchange xDAI to wxDAI.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=WXDAI, - contract_id=str(ERC20.contract_id), - contract_callable="build_deposit_tx", - ) - - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.info(f"Could not build deposit tx: {response_msg}") - return False - - approval_data = response_msg.state.body.get("data") - if approval_data is None: - self.context.logger.info(f"Could not build deposit tx: {response_msg}") - return False - - batch = MultisendBatch( - to=self.collateral_token, - data=HexBytes(approval_data), - value=self.w_xdai_deficit, - ) - self.multisend_batches.append(batch) - return True - - def _build_approval_tx(self) -> WaitableConditionType: - """Build an ERC20 approve transaction.""" - status = yield from self.build_approval_tx( - self.investment_amount, - self.market_maker_contract_address, - self.collateral_token, - ) - return status - - def _calc_buy_amount(self) -> WaitableConditionType: - """Calculate the buy amount of the conditional token.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.market_maker_contract_address, - contract_id=str(FixedProductMarketMakerContract.contract_id), - contract_callable="calc_buy_amount", - investment_amount=self.investment_amount, - outcome_index=self.outcome_index, - ) - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.context.logger.error( - f"Could not calculate the buy amount: {response_msg}" - ) - return False - - buy_amount = response_msg.raw_transaction.body.get("amount", None) - if buy_amount is None: - self.context.logger.error( - f"Something went wrong while trying to get the buy amount for the conditional token: {response_msg}" - ) - return False - - self.buy_amount = remove_fraction_wei(buy_amount, self.params.slippage) - return True - - def _build_buy_tx(self) -> WaitableConditionType: - """Get the buy tx data encoded.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.market_maker_contract_address, - contract_id=str(FixedProductMarketMakerContract.contract_id), - contract_callable="get_buy_data", - investment_amount=self.investment_amount, - outcome_index=self.outcome_index, - min_outcome_tokens_to_buy=self.buy_amount, - ) - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Could not get the data for the buy transaction: {response_msg}" - ) - return False - - buy_data = response_msg.state.body.get("data", None) - if buy_data is None: - self.context.logger.error( - f"Something went wrong while trying to encode the buy data: {response_msg}" - ) - return False - - batch = MultisendBatch( - to=self.market_maker_contract_address, - data=HexBytes(buy_data), - ) - self.multisend_batches.append(batch) - return True - - def _prepare_safe_tx(self) -> Generator[None, None, Optional[str]]: - """Prepare the safe transaction for placing a bet and return the hex for the tx settlement skill.""" - for step in ( - self._build_approval_tx, - self._calc_buy_amount, - self._build_buy_tx, - self._build_multisend_data, - self._build_multisend_safe_tx_hash, - ): - yield from self.wait_for_condition_with_sleep(step) - - outcome = self.sampled_bet.get_outcome(self.outcome_index) - investment = self._collateral_amount_info(self.investment_amount) - self.context.logger.info( - f"Preparing a multisig transaction to place a bet for {outcome!r}, with confidence " - f"{self.synchronized_data.confidence!r}, for the amount of {investment}, which is equal to the amount of " - f"{self.buy_amount!r} WEI of the conditional token corresponding to {outcome!r}." - ) - - return self.tx_hex - - def async_act(self) -> Generator: - """Do the action.""" - agent = self.context.agent_address - - if self.benchmarking_mode.enabled: - # simulate the bet placement - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - self.update_bet_transaction_information() - payload = BetPlacementPayload( - agent, None, None, True, self.wallet_balance - ) - yield from self.finish_behaviour(payload) - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - yield from self.wait_for_condition_with_sleep(self.check_balance) - tx_submitter = betting_tx_hex = mocking_mode = wallet_balance = None - - can_exchange = ( - self.is_wxdai - # no need to take fees into consideration because it is the safe's balance and the agents pay the fees - and self.wallet_balance >= self.w_xdai_deficit - ) - if self.token_balance < self.investment_amount and can_exchange: - yield from self.wait_for_condition_with_sleep(self._build_exchange_tx) - - if self.token_balance >= self.investment_amount or can_exchange: - tx_submitter = self.matching_round.auto_round_id() - betting_tx_hex = yield from self._prepare_safe_tx() - wallet_balance = self.wallet_balance - - payload = BetPlacementPayload( - agent, - tx_submitter, - betting_tx_hex, - mocking_mode, - wallet_balance, - ) - - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/blacklisting.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/blacklisting.py deleted file mode 100644 index baf8a8563..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/blacklisting.py +++ /dev/null @@ -1,86 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour for the blacklisting of the sampled bet.""" - -from typing import Generator - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import BlacklistingPayload -from packages.valory.skills.decision_maker_abci.states.blacklisting import ( - BlacklistingRound, -) -from packages.valory.skills.decision_maker_abci.states.handle_failed_tx import ( - HandleFailedTxRound, -) - - -class BlacklistingBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents blacklist the sampled bet.""" - - matching_round = BlacklistingRound - - @property - def synced_time(self) -> float: - """Get the synchronized time among agents.""" - synced_time = self.shared_state.round_sequence.last_round_transition_timestamp - return synced_time.timestamp() - - def _blacklist(self) -> None: - """Blacklist the sampled bet.""" - sampled_bet_index = self.synchronized_data.sampled_bet_index - sampled_bet = self.bets[sampled_bet_index] - - # the question is blacklisted, i.e., we did not place a bet on it, - # therefore, we bump the queue's status to the next one - sampled_bet.queue_status = sampled_bet.queue_status.next_status() - - def setup(self) -> None: - """Setup the behaviour""" - self._policy = self.synchronized_data.policy - - def async_act(self) -> Generator: - """Do the action.""" - # if the tool selection has not been run for the current period, do not do anything - if not self.synchronized_data.has_tool_selection_run: - policy = self.policy.serialize() - payload = BlacklistingPayload(self.context.agent_address, None, policy) - yield from self.finish_behaviour(payload) - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - self.read_bets() - self._blacklist() - self.store_bets() - bets_hash = ( - None if self.benchmarking_mode.enabled else self.hash_stored_bets() - ) - if ( - self.synchronized_data.tx_submitter - != HandleFailedTxRound.auto_round_id() - ): - # if we are here, then the tool has responded with an error - self.policy.tool_responded( - self.synchronized_data.mech_tool, self.synced_timestamp - ) - policy = self.policy.serialize() - payload = BlacklistingPayload(self.context.agent_address, bets_hash, policy) - - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/check_benchmarking.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/check_benchmarking.py deleted file mode 100644 index 4d8157f2c..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/check_benchmarking.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour for checking whether the benchmarking mode is enabled.""" - -from typing import Generator - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import VotingPayload -from packages.valory.skills.decision_maker_abci.states.check_benchmarking import ( - CheckBenchmarkingModeRound, -) - - -class CheckBenchmarkingModeBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents blacklist the sampled bet.""" - - matching_round = CheckBenchmarkingModeRound - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - payload = VotingPayload( - self.context.agent_address, self.benchmarking_mode.enabled - ) - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/claim_subscription.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/claim_subscription.py deleted file mode 100644 index f28a422bf..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/claim_subscription.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the behaviour for the decision-making of the skill.""" -import json -from typing import Any, Generator - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - BaseSubscriptionBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import ClaimPayload -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) -from packages.valory.skills.decision_maker_abci.utils.nevermined import ( - get_claim_endpoint, - get_creator, -) - - -SERVICE_INDEX = -1 -ERC1155 = 1155 - - -class ClaimSubscriptionBehaviour(BaseSubscriptionBehaviour): - """A behaviour in which the agents claim the subscription they purchased.""" - - matching_round = ClaimRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize `RedeemBehaviour`.""" - super().__init__(**kwargs) - self.order_tx: str = "" - self.approval_tx: str = "" - self.balance: int = 0 - - def _claim_subscription(self) -> Generator[None, None, bool]: - """Claim the subscription.""" - did_doc = yield from self._resolve_did() - if did_doc is None: - return False - - creator = get_creator(did_doc) - claim_endpoint = get_claim_endpoint(did_doc) - body = { - "agreementId": self.synchronized_data.agreement_id, - "did": self.did, - "nftHolder": creator, - "nftReceiver": self.synchronized_data.safe_contract_address, - "nftAmount": str(self.purchase_amount), - "nftType": ERC1155, - "serviceIndex": SERVICE_INDEX, - } - self.context.logger.info( - "Claiming subscription with body: %s", json.dumps(body) - ) - res = yield from self.get_http_response( - "POST", - claim_endpoint, - json.dumps(body).encode(), - headers={"Content-Type": "application/json"}, - ) - if res.status_code == 201: - self.context.logger.info( - f"Successfully claimed subscription: {res.status_code!r} - {res.body!r}", - ) - return True - - self.context.logger.warning( - f"Couldn't claim subscription: {res.status_code!r} - {res.body!r}" - f"Checking the balance of the safe on the NFT." - ) - has_balance = yield from self._has_positive_nft_balance() - if not has_balance: - self.context.logger.warning( - "Safe doesn't contain the NFT, claiming failed." - ) - return False - - self.context.logger.info("Safe contains the NFT, claiming succeeded.") - return True - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - claim = yield from self._claim_subscription() - sender = self.context.agent_address - payload = ClaimPayload( - sender, - vote=claim, - ) - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/decision_receive.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/decision_receive.py deleted file mode 100644 index fdc42a3e8..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/decision_receive.py +++ /dev/null @@ -1,612 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour for the decision-making of the skill.""" - -import csv -import json -from copy import deepcopy -from datetime import datetime -from math import prod -from typing import Any, Dict, Generator, List, Optional, Tuple, Union - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - remove_fraction_wei, -) -from packages.valory.skills.decision_maker_abci.behaviours.storage_manager import ( - StorageManagerBehaviour, -) -from packages.valory.skills.decision_maker_abci.io_.loader import ComponentPackageLoader -from packages.valory.skills.decision_maker_abci.models import ( - BenchmarkingMockData, - LiquidityInfo, -) -from packages.valory.skills.decision_maker_abci.payloads import DecisionReceivePayload -from packages.valory.skills.decision_maker_abci.states.decision_receive import ( - DecisionReceiveRound, -) -from packages.valory.skills.market_manager_abci.bets import ( - BINARY_N_SLOTS, - Bet, - CONFIDENCE_FIELD, - INFO_UTILITY_FIELD, - P_NO_FIELD, - P_YES_FIELD, - PredictionResponse, -) -from packages.valory.skills.mech_interact_abci.states.base import ( - MechInteractionResponse, -) - - -SLIPPAGE = 1.05 -WRITE_TEXT_MODE = "w+t" -COMMA = "," -TOKEN_PRECISION = 10**18 - - -class DecisionReceiveBehaviour(StorageManagerBehaviour): - """A behaviour in which the agents receive the mech response.""" - - matching_round = DecisionReceiveRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize Behaviour.""" - super().__init__(**kwargs, loader_cls=ComponentPackageLoader) - self._request_id: int = 0 - self._mech_response: Optional[MechInteractionResponse] = None - self._rows_exceeded: bool = False - - @property - def request_id(self) -> int: - """Get the request id.""" - return self._request_id - - @request_id.setter - def request_id(self, request_id: Union[str, int]) -> None: - """Set the request id.""" - try: - self._request_id = int(request_id) - except ValueError: - msg = f"Request id {request_id} is not a valid integer!" - self.context.logger.error(msg) - - @property - def mech_response(self) -> MechInteractionResponse: - """Get the mech's response.""" - if self._mech_response is None: - error = "The mech's response has not been set!" - return MechInteractionResponse(error=error) - return self._mech_response - - @property - def is_invalid_response(self) -> bool: - """Check if the response is invalid.""" - if self.mech_response.result is None: - self.context.logger.warning( - "Trying to check whether the mech's response is invalid but no response has been detected! " - "Assuming invalid response." - ) - return True - return self.mech_response.result == self.params.mech_invalid_response - - def _next_dataset_row(self) -> Optional[Dict[str, str]]: - """Read the next row from the input dataset which is used during the benchmarking mode. - - :return: a dictionary with the header fields mapped to the values of the first row. - If no rows are left to process in the file, returns `None`. - """ - sep = self.benchmarking_mode.sep - dataset_filepath = ( - self.params.store_path / self.benchmarking_mode.dataset_filename - ) - active_sampled_bet = self.get_active_sampled_bet() - sampled_bet_id = active_sampled_bet.id - - # we have now one reader pointer per market - available_rows_for_market = self.shared_state.bet_id_row_manager[sampled_bet_id] - if available_rows_for_market: - next_mock_data_row = available_rows_for_market[0] - else: - # no more bets available for this market - msg = f"No more mock responses for the market with id: {sampled_bet_id}" - self.sampled_bet.queue_status = ( - self.sampled_bet.queue_status.mark_benchmarking_done() - ) - self.context.logger.info(msg) - self.shared_state.last_benchmarking_has_run = True - self._rows_exceeded = True - return None - - row_with_headers: Optional[Dict[str, str]] = None - with open(dataset_filepath) as read_dataset: - reader = csv.DictReader(read_dataset, delimiter=sep) - - for _ in range(next_mock_data_row): - row_with_headers = next(reader, {}) - - if not row_with_headers: - # if no rows are in the file, then we finished the benchmarking - self._rows_exceeded = True - return None - - msg = f"Processing question in row with index {next_mock_data_row}: {row_with_headers}" - self.context.logger.info(msg) - return row_with_headers - - def _parse_dataset_row(self, row: Dict[str, str]) -> str: - """Parse a dataset's row to store the mock market data and to mock a prediction response.""" - mode = self.benchmarking_mode - mech_tool = self.synchronized_data.mech_tool - fields = {} - - for prediction_attribute, field_part in { - P_YES_FIELD: mode.p_yes_field_part, - P_NO_FIELD: mode.p_no_field_part, - CONFIDENCE_FIELD: mode.confidence_field_part, - }.items(): - if mode.part_prefix_mode: - fields[prediction_attribute] = row[field_part + mech_tool] - else: - fields[prediction_attribute] = row[mech_tool + field_part] - - # set the benchmarking mock data - self.shared_state.mock_data = BenchmarkingMockData( - row[mode.question_id_field], - row[mode.question_field], - row[mode.answer_field], - float(fields[P_YES_FIELD]), - ) - - # set the info utility to zero as it does not matter for the benchmark - fields[INFO_UTILITY_FIELD] = "0" - return json.dumps(fields) - - def _mock_response(self) -> None: - """Mock the response data.""" - dataset_row = self._next_dataset_row() - if dataset_row is None: - return - mech_response = self._parse_dataset_row(dataset_row) - self._mech_response = MechInteractionResponse(result=mech_response) - - def _get_response(self) -> None: - """Get the response data.""" - mech_responses = self.synchronized_data.mech_responses - if mech_responses: - self._mech_response = mech_responses[0] - return - error = "No Mech responses in synchronized_data." - self._mech_response = MechInteractionResponse(error=error) - - def _get_decision( - self, - ) -> Optional[PredictionResponse]: - """Get vote, win probability and confidence.""" - if self.benchmarking_mode.enabled: - self._mock_response() - else: - self._get_response() - - if self._mech_response is None: - self.context.logger.info("The mech response is None") - return None - - self.context.logger.info(f"Decision has been received:\n{self.mech_response}") - if self.mech_response.result is None: - self.context.logger.error( - f"There was an error on the mech's response: {self.mech_response.error}" - ) - return None - - try: - return PredictionResponse(**json.loads(self.mech_response.result)) - except (json.JSONDecodeError, ValueError) as exc: - self.context.logger.error(f"Could not parse the mech's response: {exc}") - return None - - @staticmethod - def _get_bet_sample_info(bet: Bet, vote: int) -> Tuple[int, int]: - """Get the bet sample information.""" - token_amounts = bet.outcomeTokenAmounts - selected_type_tokens_in_pool = token_amounts[vote] - opposite_vote = vote ^ 1 - other_tokens_in_pool = token_amounts[opposite_vote] - - return selected_type_tokens_in_pool, other_tokens_in_pool - - def _compute_new_tokens_distribution( - self, - token_amounts: List[int], - prices: List[float], - net_bet_amount: int, - vote: int, - ) -> Tuple[int, int, int, int, int]: - k = prod(token_amounts) - self.context.logger.info(f"k: {k}") - - # the OMEN market trades an equal amount of the investment to each of the tokens in the pool - # here we calculate the bet amount per pool's token - bet_per_token = net_bet_amount / BINARY_N_SLOTS - self.context.logger.info(f"Bet per token: {bet_per_token}") - - tokens_traded = [int(bet_per_token / prices[i]) for i in range(BINARY_N_SLOTS)] - self.context.logger.info(f"Tokens traded: {[x for x in tokens_traded]}") - - # get the shares for the answer that the service has selected - selected_shares = tokens_traded.pop(vote) - self.context.logger.info(f"Selected shares: {selected_shares}") - - # get the shares for the opposite answer - other_shares = tokens_traded.pop() - self.context.logger.info(f"Other shares: {other_shares}") - - # get the number of tokens in the pool for the answer that the service has selected - selected_type_tokens_in_pool = token_amounts.pop(vote) - self.context.logger.info( - f"Selected type tokens in pool: {selected_type_tokens_in_pool}" - ) - - # get the number of tokens in the pool for the opposite answer - other_tokens_in_pool = token_amounts.pop() - self.context.logger.info(f"Other tokens in pool: {other_tokens_in_pool}") - - # the OMEN market then trades the opposite tokens to the tokens of the answer that has been selected, - # preserving the balance of the pool - # here we calculate the number of shares that we get after trading the tokens for the opposite answer - tokens_remaining_in_pool = int(k / (other_tokens_in_pool + other_shares)) - self.context.logger.info( - f"Tokens remaining in pool: {tokens_remaining_in_pool}" - ) - - swapped_shares = selected_type_tokens_in_pool - tokens_remaining_in_pool - self.context.logger.info(f"Swapped shares: {swapped_shares}") - - # calculate the resulting number of shares if the service would take that position - num_shares = selected_shares + swapped_shares - self.context.logger.info(f"Number of shares: {num_shares}") - - # calculate the available number of shares - price = prices[vote] - self.context.logger.info(f"Price: {prices[vote]}") - - available_shares = int(selected_type_tokens_in_pool * price) - self.context.logger.info(f"Available shares: {available_shares}") - - return ( - selected_type_tokens_in_pool, - other_tokens_in_pool, - other_shares, - num_shares, - available_shares, - ) - - def _calc_binary_shares( - self, bet: Bet, net_bet_amount: int, vote: int - ) -> Tuple[int, int]: - """Calculate the claimed shares. This calculation only works for binary markets.""" - # calculate the pool's k (x*y=k) - token_amounts = bet.outcomeTokenAmounts - self.context.logger.info(f"Token amounts: {[x for x in token_amounts]}") - - # calculate the number of the traded tokens - prices = bet.outcomeTokenMarginalPrices - self.context.logger.info(f"Prices: {prices}") - - if prices is None: - return 0, 0 - - _, _, _, num_shares, available_shares = self._compute_new_tokens_distribution( - token_amounts.copy(), prices, net_bet_amount, vote - ) - - return num_shares, available_shares - - def _update_market_liquidity(self) -> None: - """Update the current market's liquidity information.""" - active_sampled_bet = self.get_active_sampled_bet() - question_id = active_sampled_bet.id - # check if share state information is empty and we need to initialize - empty_dict = len(self.shared_state.liquidity_amounts) == 0 - new_market = question_id not in self.shared_state.liquidity_amounts.keys() - if empty_dict or new_market: - self.shared_state.current_liquidity_amounts = ( - active_sampled_bet.outcomeTokenAmounts - ) - self.shared_state.current_liquidity_prices = ( - active_sampled_bet.outcomeTokenMarginalPrices - ) - self.shared_state.liquidity_cache[ - question_id - ] = active_sampled_bet.scaledLiquidityMeasure - - def _calculate_new_liquidity(self, net_bet_amount: int, vote: int) -> LiquidityInfo: - """Calculate and return the new liquidity information.""" - token_amounts = self.shared_state.current_liquidity_amounts - k = prod(token_amounts) - prices = self.shared_state.current_liquidity_prices - - ( - selected_type_tokens_in_pool, - other_tokens_in_pool, - other_shares, - _, - _, - ) = self._compute_new_tokens_distribution( - token_amounts.copy(), prices, net_bet_amount, vote - ) - - new_other = other_tokens_in_pool + other_shares - new_selected = int(k / new_other) - if vote == 0: - return LiquidityInfo( - selected_type_tokens_in_pool, - other_tokens_in_pool, - new_selected, - int(new_other), - ) - return LiquidityInfo( - other_tokens_in_pool, - selected_type_tokens_in_pool, - int(new_other), - new_selected, - ) - - def _compute_scaled_liquidity_measure( - self, token_amounts: List[int], token_prices: List[float] - ) -> float: - """Function to compute the scaled liquidity measure from token amounts and prices.""" - return ( - sum(amount * price for amount, price in zip(token_amounts, token_prices)) - / TOKEN_PRECISION - ) - - def _update_liquidity_info(self, net_bet_amount: int, vote: int) -> LiquidityInfo: - """Update the liquidity information at shared state and the prices after placing a bet for a market.""" - liquidity_info = self._calculate_new_liquidity(net_bet_amount, vote) - l0_start, l1_start = liquidity_info.validate_start_information() - - # to compute the new price we need the previous constants - prices = self.shared_state.current_liquidity_prices - - liquidity_constants = [ - l0_start * prices[0], - l1_start * prices[1], - ] - active_sampled_bet = self.get_active_sampled_bet() - market_id = active_sampled_bet.id - self.shared_state.current_liquidity_prices = liquidity_info.get_new_prices( - liquidity_constants - ) - self.shared_state.current_liquidity_amounts = liquidity_info.get_end_liquidity() - log_message = ( - f"New liquidity amounts: {self.shared_state.current_liquidity_amounts}" - ) - self.context.logger.info(log_message) - - # update the scaled liquidity Measure - self.shared_state.liquidity_cache[ - market_id - ] = self._compute_scaled_liquidity_measure( - self.shared_state.current_liquidity_amounts, - self.shared_state.current_liquidity_prices, - ) - - return liquidity_info - - def rebet_allowed( - self, prediction_response: PredictionResponse, potential_net_profit: int - ) -> bool: - """Whether a rebet is allowed or not.""" - # WARNING: Every time you call self.sampled_bet a reset in self.bets is done so any changes there will be lost - bet = self.sampled_bet - previous_response = deepcopy(bet.prediction_response) - previous_liquidity = bet.position_liquidity - previous_net_profit = bet.potential_net_profit - bet.prediction_response = prediction_response - vote = bet.prediction_response.vote - bet.position_liquidity = bet.outcomeTokenAmounts[vote] if vote else 0 - bet.potential_net_profit = potential_net_profit - rebet_allowed = bet.rebet_allowed( - previous_response, previous_liquidity, previous_net_profit - ) - if not rebet_allowed: - # reset the in-memory bets so that the updates of the sampled bet above are reverted - self.read_bets() - self.context.logger.info("Conditions for rebetting are not met!") - return rebet_allowed - - def _is_profitable( - self, prediction_response: PredictionResponse - ) -> Generator[None, None, Tuple[bool, int]]: - """Whether the decision is profitable or not.""" - if prediction_response.vote is None: - return False, 0 - - if self.benchmarking_mode.enabled: - bet = self.get_active_sampled_bet() # no reset - self.context.logger.info(f"Bet used for benchmarking: {bet}") - self._update_market_liquidity() - else: - # this call is destroying what it was in self.bets - bet = self.sampled_bet - - selected_type_tokens_in_pool, other_tokens_in_pool = self._get_bet_sample_info( - bet, prediction_response.vote - ) - - bet_amount = yield from self.get_bet_amount( - prediction_response.win_probability, - prediction_response.confidence, - selected_type_tokens_in_pool, - other_tokens_in_pool, - bet.fee, - self.synchronized_data.weighted_accuracy, - ) - bet_threshold = self.params.bet_threshold - bet_amount = max(bet_amount, bet_threshold) - - self.context.logger.info(f"Bet amount: {bet_amount}") - self.context.logger.info(f"Bet fee: {bet.fee}") - net_bet_amount = remove_fraction_wei(bet_amount, self.wei_to_native(bet.fee)) - self.context.logger.info(f"Net bet amount: {net_bet_amount}") - - num_shares, available_shares = self._calc_binary_shares( - bet, net_bet_amount, prediction_response.vote - ) - - self.context.logger.info(f"Adjusted available shares: {available_shares}") - if num_shares > available_shares * SLIPPAGE: - self.context.logger.warning( - "Kindly contemplate reducing your bet amount, as the pool's liquidity is low compared to your bet. " - "Consequently, this situation entails a higher level of risk as the obtained number of shares, " - "and therefore the potential net profit, will be lower than if the pool had higher liquidity!" - ) - if bet_threshold <= 0: - self.context.logger.warning( - f"A non-positive bet threshold was given ({bet_threshold}). The threshold will be disabled, " - f"which means that any non-negative potential profit will be considered profitable!" - ) - bet_threshold = 0 - - potential_net_profit = num_shares - net_bet_amount - bet_threshold - is_profitable = potential_net_profit >= 0 - - self.context.logger.info( - f"The current liquidity of the market is {bet.scaledLiquidityMeasure} xDAI. " - f"The potential net profit is {self.wei_to_native(potential_net_profit)} xDAI " - f"from buying {self.wei_to_native(num_shares)} shares for the option {bet.get_outcome(prediction_response.vote)}.\n" - f"Decision for profitability of this market: {is_profitable}." - ) - if is_profitable: - is_profitable = self.rebet_allowed( - prediction_response, potential_net_profit - ) - - if self.benchmarking_mode.enabled: - if is_profitable: - # update the information at the shared state - liquidity_info = self._update_liquidity_info( - net_bet_amount, prediction_response.vote - ) - bet.outcomeTokenAmounts = self.shared_state.current_liquidity_amounts - bet.outcomeTokenMarginalPrices = ( - self.shared_state.current_liquidity_prices - ) - bet.scaledLiquidityMeasure = self.shared_state.liquidity_cache[bet.id] - self.store_bets() - self._write_benchmark_results( - prediction_response, bet_amount, liquidity_info - ) - else: - self._write_benchmark_results(prediction_response) - - self.context.logger.info("Increasing Mech call count by 1") - self.shared_state.benchmarking_mech_calls += 1 - - return is_profitable, bet_amount - - def _update_selected_bet( - self, prediction_response: Optional[PredictionResponse] - ) -> None: - """Update the selected bet.""" - # update the bet's timestamp of processing and its number of bets for the given id - active_sampled_bet = self.get_active_sampled_bet() - active_sampled_bet.processed_timestamp = ( - self.shared_state.get_simulated_now_timestamp( - self.bets, self.params.safe_voting_range - ) - ) - self.context.logger.info(f"Updating bet id: {active_sampled_bet.id}") - self.context.logger.info( - f"with the timestamp:{datetime.fromtimestamp(active_sampled_bet.processed_timestamp)}" - ) - - self.store_bets() - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - success = yield from self._setup_policy_and_tools() - if not success: - return None - - prediction_response = self._get_decision() - is_profitable = None - bet_amount = None - next_mock_data_row = None - bets_hash = None - decision_received_timestamp = None - policy = None - if prediction_response is not None and prediction_response.vote is not None: - is_profitable, bet_amount = yield from self._is_profitable( - prediction_response - ) - decision_received_timestamp = self.synced_timestamp - if is_profitable: - self.store_bets() - bets_hash = self.hash_stored_bets() - - elif ( - prediction_response is not None - and self.benchmarking_mode.enabled - and not self._rows_exceeded - ): - self._write_benchmark_results( - prediction_response, - bet_amount, - ) - self.context.logger.info("Increasing Mech call count by 1") - self.shared_state.benchmarking_mech_calls += 1 - - if prediction_response is not None: - self.policy.tool_responded( - self.synchronized_data.mech_tool, - self.synced_timestamp, - self.is_invalid_response, - ) - policy = self.policy.serialize() - - # always remove the processed trade from the benchmarking input file - # now there is one reader pointer per market - if self.benchmarking_mode.enabled: - # always remove the processed trade from the benchmarking input file - # now there is one reader pointer per market - bet = self.get_active_sampled_bet() - rows_queue = self.shared_state.bet_id_row_manager[bet.id] - if rows_queue: - rows_queue.pop(0) - - self._update_selected_bet(prediction_response) - - payload = DecisionReceivePayload( - self.context.agent_address, - bets_hash, - is_profitable, - prediction_response.vote if prediction_response else None, - prediction_response.confidence if prediction_response else None, - bet_amount, - next_mock_data_row, - policy, - decision_received_timestamp, - ) - - self._store_all() - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/decision_request.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/decision_request.py deleted file mode 100644 index b887fb660..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/decision_request.py +++ /dev/null @@ -1,110 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour of the skill which is responsible for requesting a decision from the mech.""" - -import csv -import json -from dataclasses import asdict -from typing import Any, Dict, Generator, List, Optional -from uuid import uuid4 - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import DecisionRequestPayload -from packages.valory.skills.decision_maker_abci.states.decision_request import ( - DecisionRequestRound, -) -from packages.valory.skills.market_manager_abci.bets import BINARY_N_SLOTS -from packages.valory.skills.mech_interact_abci.states.base import MechMetadata - - -class DecisionRequestBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents prepare a tx to initiate a request to a mech to determine the answer to a bet.""" - - matching_round = DecisionRequestRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize Behaviour.""" - super().__init__(**kwargs) - self._metadata: Optional[MechMetadata] = None - - @property - def metadata(self) -> Dict[str, str]: - """Get the metadata as a dictionary.""" - return asdict(self._metadata) - - @property - def n_slots_supported(self) -> bool: - """Whether the behaviour supports the current number of slots as it currently only supports binary decisions.""" - return self.params.slot_count == BINARY_N_SLOTS - - def setup(self) -> None: - """Setup behaviour.""" - if not self.n_slots_supported or self.benchmarking_mode.enabled: - return - - sampled_bet = self.sampled_bet - prompt_params = dict( - question=sampled_bet.title, yes=sampled_bet.yes, no=sampled_bet.no - ) - prompt = self.params.prompt_template.substitute(prompt_params) - tool = self.synchronized_data.mech_tool - nonce = str(uuid4()) - self._metadata = MechMetadata(prompt, tool, nonce) - msg = f"Prepared metadata {self.metadata!r} for the request." - self.context.logger.info(msg) - - def initialize_bet_id_row_manager(self) -> Dict[str, List[int]]: - """Initialization of the dictionary used to traverse mocked tool responses.""" - bets_mapping: Dict[str, List[int]] = {} - dataset_filepath = ( - self.params.store_path / self.benchmarking_mode.dataset_filename - ) - - with open(dataset_filepath, mode="r") as file: - reader = csv.DictReader(file) - for row_number, row in enumerate(reader, start=1): - question_id = row[self.benchmarking_mode.question_id_field] - if question_id not in bets_mapping: - bets_mapping[question_id] = [] - bets_mapping[question_id].append(row_number) - return bets_mapping - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - payload_content = None - mocking_mode: Optional[bool] = self.benchmarking_mode.enabled - if self._metadata and self.n_slots_supported: - mech_requests = [self.metadata] - payload_content = json.dumps(mech_requests, sort_keys=True) - if not self.n_slots_supported: - mocking_mode = None - - if self.benchmarking_mode.enabled: - # check if the bet_id_row_manager has been loaded already - if len(self.shared_state.bet_id_row_manager) == 0: - bets_mapping = self.initialize_bet_id_row_manager() - self.shared_state.bet_id_row_manager = bets_mapping - - agent = self.context.agent_address - payload = DecisionRequestPayload(agent, payload_content, mocking_mode) - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/handle_failed_tx.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/handle_failed_tx.py deleted file mode 100644 index 52a93b738..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/handle_failed_tx.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour for handling failed transactions.""" - -from typing import Generator - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import HandleFailedTxPayload -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) -from packages.valory.skills.decision_maker_abci.states.handle_failed_tx import ( - HandleFailedTxRound, -) -from packages.valory.skills.mech_interact_abci.states.request import MechRequestRound - - -class HandleFailedTxBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents handle a failed transaction.""" - - matching_round = HandleFailedTxRound - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - after_bet_attempt = self.synchronized_data.tx_submitter in ( - MechRequestRound.auto_round_id(), - BetPlacementRound.auto_round_id(), - ) - submitter = HandleFailedTxRound.auto_round_id() - payload = HandleFailedTxPayload( - self.context.agent_address, after_bet_attempt, submitter - ) - - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/order_subscription.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/order_subscription.py deleted file mode 100644 index 531485dde..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/order_subscription.py +++ /dev/null @@ -1,381 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the behaviour for the decision-making of the skill.""" -from typing import Any, Dict, Generator, List, Optional, cast - -from hexbytes import HexBytes - -from packages.valory.contracts.erc20.contract import ERC20 -from packages.valory.contracts.transfer_nft_condition.contract import ( - TransferNftCondition, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - BaseSubscriptionBehaviour, - WXDAI, - WaitableConditionType, -) -from packages.valory.skills.decision_maker_abci.models import MultisendBatch -from packages.valory.skills.decision_maker_abci.payloads import SubscriptionPayload -from packages.valory.skills.decision_maker_abci.states.order_subscription import ( - SubscriptionRound, -) -from packages.valory.skills.decision_maker_abci.utils.nevermined import ( - generate_id, - get_agreement_id, - get_escrow_payment_seed, - get_lock_payment_seed, - get_price, - get_timeouts_and_timelocks, - get_transfer_nft_condition_seed, - no_did_prefixed, - zero_x_transformer, -) - - -LOCK_CONDITION_INDEX = 0 - - -class OrderSubscriptionBehaviour(BaseSubscriptionBehaviour): - """A behaviour in which the agents purchase a subscriptions.""" - - matching_round = SubscriptionRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize `RedeemBehaviour`.""" - super().__init__(**kwargs) - self.order_tx: str = "" - self.approval_tx: str = "" - self.balance: int = 0 - self.agreement_id: str = "" - self.credits_per_req: int = 0 - self.pending_reqs: int = 0 - - def _get_condition_ids( - self, agreement_id_seed: str, did_doc: Dict[str, Any] - ) -> List[str]: - """Get the condition ids.""" - self.agreement_id = get_agreement_id( - agreement_id_seed, self.synchronized_data.safe_contract_address - ) - price = get_price(did_doc) - receivers = list(price.keys()) - amounts = list(price.values()) - lock_payment_seed, lock_payment_id = get_lock_payment_seed( - self.agreement_id, - did_doc, - self.lock_payment_condition_address, - self.escrow_payment_condition_address, - self.payment_token, - amounts, - receivers, - ) - ( - transfer_nft_condition_seed, - transfer_nft_condition_id, - ) = get_transfer_nft_condition_seed( - self.agreement_id, - did_doc, - self.synchronized_data.safe_contract_address, - self.purchase_amount, - self.transfer_nft_condition_address, - lock_payment_id, - self.token_address, - ) - escrow_payment_seed, _ = get_escrow_payment_seed( - self.agreement_id, - did_doc, - amounts, - receivers, - self.synchronized_data.safe_contract_address, - self.escrow_payment_condition_address, - self.payment_token, - lock_payment_id, - transfer_nft_condition_id, - ) - condition_ids = [ - lock_payment_seed, - transfer_nft_condition_seed, - escrow_payment_seed, - ] - return condition_ids - - def _get_purchase_params(self) -> Generator[None, None, Optional[Dict[str, Any]]]: - """Get purchase params.""" - agreement_id = zero_x_transformer(generate_id()) - did = zero_x_transformer(no_did_prefixed(self.did)) - did_doc = yield from self._resolve_did() - if did_doc is None: - # something went wrong - return None - condition_ids = self._get_condition_ids(agreement_id, did_doc) - timeouts, timelocks = get_timeouts_and_timelocks(did_doc) - price = get_price(did_doc) - receivers = list(price.keys()) - amounts = list(price.values()) - - return { - "agreement_id": agreement_id, - "did": did, - "condition_ids": condition_ids, - "consumer": self.synchronized_data.safe_contract_address, - "index": LOCK_CONDITION_INDEX, - "time_outs": timeouts, - "time_locks": timelocks, - "reward_address": self.escrow_payment_condition_address, - "receivers": receivers, - "amounts": amounts, - "contract_address": self.order_address, - "token_address": self.payment_token, - } - - def _get_approval_params(self) -> Dict[str, Any]: - """Get approval params.""" - approval_params = {} - approval_params["token"] = self.payment_token - approval_params["spender"] = self.lock_payment_condition_address - approval_params["amount"] = self.price # type: ignore - return approval_params - - def _build_withdraw_wxdai_tx(self, amount: int) -> WaitableConditionType: - """Exchange xDAI to wxDAI.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=WXDAI, - contract_id=str(ERC20.contract_id), - contract_callable="build_withdraw_tx", - amount=amount, - ) - - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.info(f"Could not build deposit tx: {response_msg}") - return False - - approval_data = response_msg.state.body.get("data") - if approval_data is None: - self.context.logger.info(f"Could not build deposit tx: {response_msg}") - return False - - batch = MultisendBatch( - to=WXDAI, - data=HexBytes(approval_data), - ) - self.multisend_batches.append(batch) - return True - - def _prepare_order_tx( - self, - contract_address: str, - agreement_id: str, - did: str, - condition_ids: List[str], - time_locks: List[int], - time_outs: List[int], - consumer: str, - index: int, - reward_address: str, - token_address: str, - amounts: List[int], - receivers: List[str], - ) -> Generator[None, None, bool]: - """Prepare a purchase tx.""" - result = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=contract_address, - contract_public_id=TransferNftCondition.contract_id, - contract_callable="build_order_tx", - data_key="data", - placeholder="order_tx", - agreement_id=agreement_id, - did=did, - condition_ids=condition_ids, - time_locks=time_locks, - time_outs=time_outs, - consumer=consumer, - index=index, - reward_address=reward_address, - token_address=token_address, - amounts=amounts, - receives=receivers, - ) - if not result: - return False - - value = self.price if self.is_xdai else 0 - self.multisend_batches.append( - MultisendBatch( - to=contract_address, - data=HexBytes(self.order_tx), - value=value, - ) - ) - return True - - def _prepare_approval_tx( - self, token: str, spender: str, amount: int - ) -> Generator[None, None, bool]: - """Prepare an approval tx.""" - result = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=token, - contract_public_id=ERC20.contract_id, - contract_callable="build_approval_tx", - data_key="data", - placeholder="approval_tx", - amount=amount, - spender=spender, - ) - if not result: - return False - - self.multisend_batches.append( - MultisendBatch( - to=token, - data=HexBytes(self.approval_tx), - ) - ) - return True - - def _get_pending_requests(self) -> Generator[None, None, bool]: - """Get the required balance for the subscription.""" - result = yield from self._mech_contract_interact( - contract_callable="get_pending_requests", - data_key="pending_requests", - placeholder="pending_reqs", - sender_address=self.synchronized_data.safe_contract_address, - ) - if not result: - self.context.logger.info("Could not get the pending requests.") - return False - - return result - - def _get_nevermined_price(self) -> Generator[None, None, bool]: - """Get the price of the subscription.""" - result = yield from self._mech_contract_interact( - contract_callable="get_price", - data_key="price", - placeholder="credits_per_req", - ) - if not result: - self.context.logger.info("Could not get the price.") - return False - - return result - - def _should_purchase(self) -> Generator[None, None, bool]: - """Check if the subscription should be purchased.""" - if not self.params.use_nevermined: - self.context.logger.info("Nevermined subscriptions are turned off.") - return False - - result = yield from self._get_nevermined_price() - if not result: - return False - - result = yield from self._get_pending_requests() - if not result: - return False - - result = yield from self._get_nft_balance( - self.token_address, - self.synchronized_data.safe_contract_address, - zero_x_transformer(no_did_prefixed(self.did)), - ) - if not result: - self.context.logger.warning("Failed to get balance") - return False - - credits_required = (self.pending_reqs + 1) * self.credits_per_req - - return credits_required > self.balance - - def get_payload_content(self) -> Generator[None, None, str]: - """Get the payload.""" - should_purchase = yield from self._should_purchase() - if not should_purchase: - return SubscriptionRound.NO_TX_PAYLOAD - - result = yield from self.check_balance() - if not result: - return SubscriptionRound.ERROR_PAYLOAD - - if not self.is_xdai: - self.context.logger.warning( - f"Subscription is not using xDAI: {self.is_xdai}" - ) - approval_params = self._get_approval_params() - result = yield from self._prepare_approval_tx(**approval_params) - if not result: - return SubscriptionRound.ERROR_PAYLOAD - - else: - self.context.logger.info( - f"Using wxDAI to purchase subscription: {self.wallet_balance} < {self.price}" - ) - if self.wallet_balance < self.price: - if self.wallet_balance + self.token_balance < self.price: - self.context.logger.info( - f"Insufficient funds to purchase subscription: {self.wallet_balance + self.token_balance} < {self.price}" - ) - return SubscriptionRound.ERROR_PAYLOAD - amount_to_withdraw = self.price - self.wallet_balance - self.context.logger.info(f"Withdrawing {amount_to_withdraw} from WxDAI") - result = yield from self._build_withdraw_wxdai_tx(amount_to_withdraw) - if not result: - return SubscriptionRound.ERROR_PAYLOAD - - purchase_params = yield from self._get_purchase_params() - self.context.logger.info( - f"Purchase params for subscription: {purchase_params}. Agreement ID: {self.agreement_id}" - ) - if purchase_params is None: - return SubscriptionRound.ERROR_PAYLOAD - - result = yield from self._prepare_order_tx(**purchase_params) - if not result: - return SubscriptionRound.ERROR_PAYLOAD - - for build_step in ( - self._build_multisend_data, - self._build_multisend_safe_tx_hash, - ): - yield from self.wait_for_condition_with_sleep(build_step) - - return cast(str, self.tx_hex) - - def async_act(self) -> Generator: - """Do the action.""" - sender = self.context.agent_address - - if self.context.benchmarking_mode.enabled: - payload = SubscriptionPayload(sender) - yield from self.finish_behaviour(payload) - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - payload_data = yield from self.get_payload_content() - payload = SubscriptionPayload( - sender, - tx_submitter=SubscriptionRound.auto_round_id(), - tx_hash=payload_data, - agreement_id=self.agreement_id, - wallet_balance=self.wallet_balance, - ) - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/randomness.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/randomness.py deleted file mode 100644 index bb580dfb7..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/randomness.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the behaviour of the skill which is responsible for gathering randomness.""" - -from packages.valory.skills.abstract_round_abci.common import ( - RandomnessBehaviour as RandomnessBehaviourBase, -) -from packages.valory.skills.decision_maker_abci.states.randomness import ( - BenchmarkingRandomnessRound, - RandomnessRound, -) -from packages.valory.skills.transaction_settlement_abci.payloads import ( - RandomnessPayload, -) - - -class RandomnessBehaviour(RandomnessBehaviourBase): - """Retrieve randomness.""" - - matching_round = RandomnessRound - payload_class = RandomnessPayload - - -class BenchmarkingRandomnessBehaviour(RandomnessBehaviour): - """Retrieve randomness in benchmarking mode.""" - - matching_round = BenchmarkingRandomnessRound diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/reedem.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/reedem.py deleted file mode 100644 index e6019516b..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/reedem.py +++ /dev/null @@ -1,993 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the redeeming state of the decision-making abci app.""" - -import json -import time -from abc import ABC -from sys import maxsize -from typing import Any, Dict, Generator, Iterator, List, Optional, Set, Union - -from hexbytes import HexBytes -from web3.constants import HASH_ZERO - -from packages.valory.contracts.conditional_tokens.contract import ( - ConditionalTokensContract, -) -from packages.valory.contracts.realitio.contract import RealitioContract -from packages.valory.contracts.realitio_proxy.contract import RealitioProxyContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload, get_name -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - WaitableConditionType, -) -from packages.valory.skills.decision_maker_abci.behaviours.storage_manager import ( - StorageManagerBehaviour, -) -from packages.valory.skills.decision_maker_abci.models import ( - MultisendBatch, - RedeemingProgress, -) -from packages.valory.skills.decision_maker_abci.payloads import RedeemPayload -from packages.valory.skills.decision_maker_abci.redeem_info import ( - Condition, - FPMM, - Trade, -) -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) -from packages.valory.skills.decision_maker_abci.states.redeem import RedeemRound -from packages.valory.skills.market_manager_abci.graph_tooling.requests import ( - FetchStatus, - MAX_LOG_SIZE, - QueryingBehaviour, -) -from packages.valory.skills.market_manager_abci.graph_tooling.utils import ( - filter_claimed_conditions, - get_condition_id_to_balances, -) - - -ZERO_HEX = HASH_ZERO[2:] -ZERO_BYTES = bytes.fromhex(ZERO_HEX) -BLOCK_NUMBER_KEY = "number" -DEFAULT_TO_BLOCK = "latest" - - -class RedeemInfoBehaviour(StorageManagerBehaviour, QueryingBehaviour, ABC): - """A behaviour responsible for building and handling the redeeming information.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize a `RedeemInfo` object.""" - super().__init__(**kwargs) - self.utilized_tools: Dict[str, str] = {} - self.redeemed_condition_ids: Set[str] = set() - self.payout_so_far: int = 0 - self.trades: Set[Trade] = set() - self.earliest_block_number: int = 0 - - # this is a mapping from condition id to amount - # the purpose of this attribute is to rectify the claimable amount within a redeeming information object. - # this adjustment is necessary because the redeeming information is generated based on a single trade - # per condition or question. - # consequently, the claimable amount must reflect the cumulative sum of claimable amounts - # from all trades associated with it. - self.claimable_amounts: Dict[HexBytes, int] = {} - - def setup(self) -> None: - """Setup the behaviour""" - super().setup() - self.redeemed_condition_ids = self.synchronized_data.redeemed_condition_ids - self.payout_so_far = self.synchronized_data.payout_so_far - - def _set_block_number(self, trade: Trade) -> Generator: - """Set the block number of the given trade's market.""" - timestamp = trade.fpmm.creationTimestamp - - while True: - block = yield from self._fetch_block_number(timestamp) - if self._fetch_status != FetchStatus.IN_PROGRESS: - break - - if self._fetch_status == FetchStatus.SUCCESS: - block_number = block.get("id", "") - if block_number.isdigit(): - self.earliest_block_number = int(block_number) - - self.context.logger.info( - f"Chose block number {self.earliest_block_number!r} as closest to timestamp {timestamp!r}" - ) - - def _try_update_policy(self, tool: str, winning: bool) -> None: - """Try to update the policy.""" - try: - self.policy.update_accuracy_store(tool, winning) - except KeyError: - self.context.logger.warning( - f"The stored utilized tools seem to be outdated as no {tool=} was found. " - "The policy will not be updated. " - "No action is required as this will be automatically resolved." - ) - - def _update_policy(self, update: Trade) -> None: - """Update the policy.""" - # the mapping might not contain a tool for a bet placement because it might have happened on a previous run - tool = self.utilized_tools.get(update.transactionHash, None) - if tool is None: - return - - # we try to avoid an ever-increasing dictionary of utilized tools by removing a tool when not needed anymore - del self.utilized_tools[update.transactionHash] - self._try_update_policy(tool, update.is_winning) - - def update_redeem_info(self, chunk: list) -> Generator: - """Update the redeeming information using the given chunk.""" - trades_updates: Iterator[Trade] = ( - Trade(**trade) - for trade in chunk - if int(trade.get("fpmm", {}).get("answerFinalizedTimestamp", maxsize)) - <= self.synced_timestamp - ) - - is_first_update = True - for update in trades_updates: - self._update_policy(update) - - # do not use the information if position is not winning - if not update.is_winning: - continue - - if is_first_update: - yield from self._set_block_number(update) - is_first_update = False - - condition_id = update.fpmm.condition.id - # If not in the trades, add it as is, along with its claimable amount - if update not in self.trades: - self.trades.add(update) - self.claimable_amounts[condition_id] = update.claimable_amount - continue - - # Find any matching object and combine them - for unique_obj in self.trades: - if update == unique_obj: - self.claimable_amounts[condition_id] += update.claimable_amount - - self.context.logger.info(self.policy.stats_report()) - - -class RedeemBehaviour(RedeemInfoBehaviour): - """Redeem the winnings.""" - - matching_round = RedeemRound - - UTILIZED_TOOLS_PATH = "utilized_tools.json" - - def __init__(self, **kwargs: Any) -> None: - """Initialize `RedeemBehaviour`.""" - super().__init__(**kwargs) - self._claim_params_batch: list = [] - self._latest_block_number: Optional[int] = None - self._finalized: bool = False - self._already_resolved: bool = False - self._payouts: Dict[str, int] = {} - self._built_data: Optional[HexBytes] = None - self._current_redeem_info: Optional[Trade] = None - self._expected_winnings: int = 0 - self._history_hash: bytes = ZERO_BYTES - self._claim_winnings_simulation_ok: bool = False - - @property - def redeeming_progress(self) -> RedeemingProgress: - """Get the redeeming check progress from the shared state.""" - return self.shared_state.redeeming_progress - - @redeeming_progress.setter - def redeeming_progress(self, progress: RedeemingProgress) -> None: - """Set the redeeming check progress in the shared state.""" - self.shared_state.redeeming_progress = progress - - @property - def latest_block_number(self) -> int: - """Get the latest block number.""" - if self._latest_block_number is None: - error = "Attempting to retrieve the latest block number, but it hasn't been set yet." - raise ValueError(error) - return self._latest_block_number - - @latest_block_number.setter - def latest_block_number(self, latest_block_number: str) -> None: - """Set the latest block number.""" - try: - self._latest_block_number = int(latest_block_number) - except (TypeError, ValueError) as exc: - error = f"{latest_block_number=} cannot be converted to a valid integer." - raise ValueError(error) from exc - - @property - def current_redeem_info(self) -> Trade: - """Get the current redeem info.""" - if self._current_redeem_info is None: - raise ValueError("Current redeem information have not been set.") - return self._current_redeem_info - - @property - def current_fpmm(self) -> FPMM: - """Get the current FPMM.""" - return self.current_redeem_info.fpmm - - @property - def current_condition(self) -> Condition: - """Get the current condition.""" - return self.current_fpmm.condition - - @property - def current_question_id(self) -> bytes: - """Get the current question's id.""" - return self.current_fpmm.question.id - - @property - def current_collateral_token(self) -> str: - """Get the current collateral token.""" - return self.current_fpmm.collateralToken - - @property - def current_condition_id(self) -> HexBytes: - """Get the current condition id.""" - return self.current_condition.id - - @property - def current_index_sets(self) -> List[int]: - """Get the current index sets.""" - return self.current_condition.index_sets - - @property - def current_claimable_amount(self) -> int: - """Return the current claimable amount.""" - return self.claimable_amounts[self.current_condition_id] - - @property - def is_dust(self) -> bool: - """Return whether the claimable amount of the given condition id is dust or not.""" - return self.current_claimable_amount < self.params.dust_threshold - - @property - def payouts_batch(self) -> Dict[str, int]: - """Get the trades' transaction hashes mapped to payouts for the current market.""" - return self._payouts - - @payouts_batch.setter - def payouts_batch(self, payouts: Dict[str, int]) -> None: - """Set the trades' transaction hashes mapped to payouts for the current market.""" - self._payouts = payouts - - @property - def finalized(self) -> bool: - """Get whether the current market has been finalized.""" - return self._finalized - - @finalized.setter - def finalized(self, flag: bool) -> None: - """Set whether the current market has been finalized.""" - self._finalized = flag - - @property - def history_hash(self) -> bytes: - """Get the history hash for the current question.""" - return self._history_hash - - @history_hash.setter - def history_hash(self, history_hash: bytes) -> None: - """Set the history hash for the current question.""" - self._history_hash = history_hash - - @property - def is_history_hash_null(self) -> bool: - """Return whether the current history hash is null.""" - return self.history_hash == b"\x00" * 32 - - @property - def already_resolved(self) -> bool: - """Get whether the current market has already been resolved.""" - return self._already_resolved - - @already_resolved.setter - def already_resolved(self, flag: bool) -> None: - """Set whether the current market has already been resolved.""" - self._already_resolved = flag - - @property - def claim_params_batch(self) -> list: - """Get the current batch of the claim parameters.""" - return self._claim_params_batch - - @claim_params_batch.setter - def claim_params_batch(self, claim_params_batch: list) -> None: - """Set the current batch of the claim parameters.""" - self._claim_params_batch = claim_params_batch - - @property - def built_data(self) -> HexBytes: - """Get the built transaction's data.""" - return self._built_data - - @built_data.setter - def built_data(self, built_data: Union[str, bytes]) -> None: - """Set the built transaction's data.""" - self._built_data = HexBytes(built_data) - - @property - def claim_winnings_simulation_ok(self) -> bool: - """Get whether the claim winnings simulation is ok.""" - return self._claim_winnings_simulation_ok - - @claim_winnings_simulation_ok.setter - def claim_winnings_simulation_ok(self, claim_winnings_simulation_ok: bool) -> None: - """Get whether the claim winnings simulation is ok.""" - self._claim_winnings_simulation_ok = claim_winnings_simulation_ok - - def _store_progress(self) -> None: - """Store the redeeming progress.""" - self.redeeming_progress.trades = self.trades - self.redeeming_progress.utilized_tools = self.utilized_tools - self.redeeming_progress.policy = self.policy - self.redeeming_progress.claimable_amounts = self.claimable_amounts - self.redeeming_progress.earliest_block_number = self.earliest_block_number - - def _load_progress(self) -> None: - """Load the redeeming progress.""" - self.trades = self.redeeming_progress.trades - self.utilized_tools = self.redeeming_progress.utilized_tools - self._policy = self.redeeming_progress.policy - self.claimable_amounts = self.redeeming_progress.claimable_amounts - self.earliest_block_number = self.redeeming_progress.earliest_block_number - - def _get_redeem_info( - self, - ) -> Generator: - """Fetch the trades from all the prediction markets and store them as redeeming information.""" - while True: - can_proceed = self._prepare_fetching() - if not can_proceed: - break - - trades_market_chunk = yield from self._fetch_redeem_info() - if trades_market_chunk is not None: - yield from self.update_redeem_info(trades_market_chunk) - - # truncate the trades, otherwise logs get too big - trades_str = str(self.trades)[:MAX_LOG_SIZE] - self.context.logger.info(f"Fetched redeeming information: {trades_str}") - - def _filter_trades(self) -> None: - """Filter the trades, removing the redeemed condition ids.""" - redeemed_condition_ids = [ - condition_id.lower() for condition_id in self.redeemed_condition_ids - ] - self.trades = { - trade - for trade in self.trades - if trade.fpmm.condition.id.hex().lower() not in redeemed_condition_ids - } - self.redeeming_progress.trades = self.trades - - def _conditional_tokens_interact( - self, contract_callable: str, data_key: str, placeholder: str, **kwargs: Any - ) -> WaitableConditionType: - """Interact with the conditional tokens contract.""" - status = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.conditional_tokens_address, - contract_public_id=ConditionalTokensContract.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def _get_latest_block(self) -> WaitableConditionType: - """Get the latest block's timestamp.""" - ledger_api_response = yield from self.get_ledger_api_response( - performative=LedgerApiMessage.Performative.GET_STATE, # type: ignore - ledger_callable="get_block", - block_identifier=DEFAULT_TO_BLOCK, - ) - if ledger_api_response.performative != LedgerApiMessage.Performative.STATE: - self.context.logger.error(f"Failed to get block: {ledger_api_response}") - return False - self.latest_block_number = ledger_api_response.state.body.get(BLOCK_NUMBER_KEY) - return True - - def _check_already_redeemed_via_events(self) -> WaitableConditionType: - """Check whether the condition ids have already been redeemed via events.""" - if len(self.trades) == 0: - return True - - safe_address_lower = self.synchronized_data.safe_contract_address.lower() - kwargs: Dict[str, Any] = { - key: [] - for key in ( - "collateral_tokens", - "parent_collection_ids", - "condition_ids", - "index_sets", - ) - } - for trade in self.trades: - kwargs["collateral_tokens"].append(trade.fpmm.collateralToken) - kwargs["parent_collection_ids"].append(ZERO_BYTES) - kwargs["condition_ids"].append(trade.fpmm.condition.id) - kwargs["index_sets"].append(trade.fpmm.condition.index_sets) - - if not self.redeeming_progress.check_started: - self.redeeming_progress.check_from_block = self.earliest_block_number - yield from self.wait_for_condition_with_sleep(self._get_latest_block) - self.redeeming_progress.check_to_block = self.latest_block_number - self.redeeming_progress.check_started = True - - n_retries = 0 - from_block = self.redeeming_progress.check_from_block - batch_size = self.redeeming_progress.event_filtering_batch_size - while from_block < self.redeeming_progress.check_to_block: - max_to_block = from_block + batch_size - to_block = min(max_to_block, self.redeeming_progress.check_to_block) - result = yield from self._conditional_tokens_interact( - contract_callable="check_redeemed", - data_key="payouts", - placeholder=get_name(RedeemBehaviour.payouts_batch), - redeemer=safe_address_lower, - from_block=from_block, - to_block=to_block, - timeout=self.params.contract_timeout, - **kwargs, - ) - - if not result and n_retries == self.params.max_filtering_retries: - err = "Skipping the redeeming round as the RPC is misbehaving." - self.context.logger.error(err) - return False - - if not result: - n_retries += 1 - keep_fraction = 1 - self.params.reduce_factor - reduced_batch_size = int(batch_size * keep_fraction) - # ensure that the batch size is at least the minimum batch size - batch_size = max(reduced_batch_size, self.params.minimum_batch_size) - self.redeeming_progress.event_filtering_batch_size = batch_size - self.context.logger.warning( - f"Repeating this call with a decreased batch size of {batch_size}." - ) - - continue - - self.redeeming_progress.payouts.update(self.payouts_batch) - self.redeeming_progress.check_from_block = to_block - from_block += batch_size - - return True - - def _check_already_redeemed_via_subgraph(self) -> WaitableConditionType: - """Check whether the condition ids have already been redeemed via subgraph.""" - safe_address = self.synchronized_data.safe_contract_address.lower() - from_timestamp, to_timestamp = 0.0, time.time() # from beginning to now - - # get the trades - trades = yield from self.fetch_trades( - safe_address, from_timestamp, to_timestamp - ) - if trades is None: - return False - - # get the user's positions - user_positions = yield from self.fetch_user_positions(safe_address) - if user_positions is None: - return False - - # process the positions - payouts, unredeemed_raw = get_condition_id_to_balances(trades, user_positions) - - # filter out positions that are already claimed - unredeemed = filter_claimed_conditions( - unredeemed_raw, self.redeeming_progress.claimed_condition_ids - ) - - self.redeeming_progress.payouts = payouts - self.redeeming_progress.unredeemed_trades = unredeemed - - return True - - def _check_already_redeemed(self) -> WaitableConditionType: - """Check whether we have already redeemed for this bet.""" - if self.params.use_subgraph_for_redeeming: - return self._check_already_redeemed_via_subgraph() - - return self._check_already_redeemed_via_events() - - def _clean_redeem_info(self) -> WaitableConditionType: - """Clean the redeeming information based on whether any positions have already been redeemed.""" - if self.payout_so_far > 0: - # filter the trades to avoid checking positions that we are already aware have been redeemed. - self._filter_trades() - - success = yield from self._check_already_redeemed() - if not success: - return False - - payouts = self.redeeming_progress.payouts - payouts_amount = sum(payouts.values()) - if payouts_amount > 0: - self.redeemed_condition_ids |= set(payouts.keys()) - if self.params.use_subgraph_for_redeeming: - self.payout_so_far = payouts_amount - else: - self.payout_so_far += payouts_amount - - # filter the trades again if new payouts have been found - self._filter_trades() - wxdai_amount = self.wei_to_native(self.payout_so_far) - msg = f"The total payout so far has been {wxdai_amount} wxDAI." - self.context.logger.info(msg) - - return True - - def _realitio_interact( - self, contract_callable: str, data_key: str, placeholder: str, **kwargs: Any - ) -> WaitableConditionType: - """Interact with the realitio contract.""" - status = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.realitio_address, - contract_public_id=RealitioContract.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def _check_finalized(self) -> WaitableConditionType: - """Check whether the question has been finalized.""" - result = yield from self._realitio_interact( - contract_callable="check_finalized", - data_key="finalized", - placeholder=get_name(RedeemBehaviour.finalized), - question_id=self.current_question_id, - ) - return result - - def _get_history_hash(self) -> WaitableConditionType: - """Get the history hash for the current question id.""" - result = yield from self._realitio_interact( - contract_callable="get_history_hash", - data_key="data", - placeholder=get_name(RedeemBehaviour.history_hash), - question_id=self.current_question_id, - ) - return result - - def _check_already_resolved(self) -> WaitableConditionType: - """Check whether someone has already resolved for this market.""" - result = yield from self._conditional_tokens_interact( - contract_callable="check_resolved", - data_key="resolved", - placeholder=get_name(RedeemBehaviour.already_resolved), - condition_id=self.current_condition_id, - ) - return result - - def _build_resolve_data(self) -> WaitableConditionType: - """Prepare the safe tx to resolve the condition.""" - result = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.realitio_proxy_address, - contract_public_id=RealitioProxyContract.contract_id, - contract_callable="build_resolve_tx", - data_key="data", - placeholder=get_name(RedeemBehaviour.built_data), - question_id=self.current_question_id, - template_id=self.current_fpmm.templateId, - question=self.current_fpmm.question.data, - num_outcomes=self.current_condition.outcomeSlotCount, - ) - - if not result: - return False - - batch = MultisendBatch( - to=self.params.realitio_proxy_address, - data=HexBytes(self.built_data), - ) - self.multisend_batches.append(batch) - return True - - def _simulate_claiming(self) -> WaitableConditionType: - """Check whether we have already claimed the winnings.""" - result = yield from self._realitio_interact( - contract_callable="simulate_claim_winnings", - data_key="data", - placeholder=get_name(RedeemBehaviour.claim_winnings_simulation_ok), - question_id=self.current_question_id, - claim_params=self.redeeming_progress.claim_params, - sender_address=self.synchronized_data.safe_contract_address, - ) - return result - - def _build_claim_data(self) -> WaitableConditionType: - """Prepare the safe tx to claim the winnings.""" - claim_params = self.redeeming_progress.claim_params - if claim_params is None: - self.context.logger.error( - f"Cannot parse incorrectly formatted realitio `LogNewAnswer` events: {self.redeeming_progress.answered}" - ) - return False - - result = yield from self._realitio_interact( - contract_callable="build_claim_winnings", - data_key="data", - placeholder=get_name(RedeemBehaviour.built_data), - question_id=self.current_question_id, - claim_params=self.redeeming_progress.claim_params, - ) - - if not result: - return False - - batch = MultisendBatch( - to=self.params.realitio_address, - data=HexBytes(self.built_data), - ) - self.multisend_batches.append(batch) - return True - - def get_claim_params(self) -> WaitableConditionType: - """Get the claim params for the current question id.""" - if self.params.use_subgraph_for_redeeming: - return self._get_claim_params_via_subgraph() - - return self._get_claim_params_via_events() - - def _get_claim_params_via_events(self) -> WaitableConditionType: - """Get claim params using an RPC to get the events.""" - if not self.redeeming_progress.claim_started: - self.redeeming_progress.claim_from_block = self.earliest_block_number - self.redeeming_progress.claim_to_block = ( - self.redeeming_progress.check_to_block - ) - self.redeeming_progress.claim_started = True - - n_retries = 0 - from_block = self.redeeming_progress.claim_from_block - batch_size = self.redeeming_progress.event_filtering_batch_size - while from_block < self.redeeming_progress.claim_to_block: - max_to_block = from_block + batch_size - to_block = min(max_to_block, self.redeeming_progress.claim_to_block) - result = yield from self._realitio_interact( - contract_callable="get_claim_params", - data_key="answered", - placeholder=get_name(RedeemBehaviour.claim_params_batch), - from_block=from_block, - to_block=to_block, - question_id=self.current_question_id, - timeout=self.params.contract_timeout, - ) - - if not result and n_retries == self.params.max_filtering_retries: - err = "Skipping redeeming for the current position as the RPC is misbehaving." - self.context.logger.error(err) - return False - - if not result: - n_retries += 1 - keep_fraction = 1 - self.params.reduce_factor - batch_size = int(batch_size * keep_fraction) - self.redeeming_progress.event_filtering_batch_size = batch_size - self.context.logger.warning( - f"Repeating this call with a decreased batch size of {batch_size}." - ) - continue - - self.redeeming_progress.answered.extend(self.claim_params_batch) - self.redeeming_progress.claim_from_block = to_block - from_block += batch_size - - return True - - def _get_claim_params_via_subgraph(self) -> WaitableConditionType: - """Get claim params using a subgraph.""" - question_id_str = "0x" + self.current_question_id.hex() - result = yield from self.fetch_claim_params(question_id_str) - if not result: - return False - - self.redeeming_progress.answered = result - return True - - def _build_redeem_data(self) -> WaitableConditionType: - """Prepare the safe tx to redeem the position.""" - result = yield from self._conditional_tokens_interact( - contract_callable="build_redeem_positions_tx", - data_key="data", - placeholder=get_name(RedeemBehaviour.built_data), - collateral_token=self.current_collateral_token, - parent_collection_id=ZERO_BYTES, - condition_id=self.current_condition_id, - index_sets=self.current_index_sets, - ) - - if not result: - return False - - batch = MultisendBatch( - to=self.params.conditional_tokens_address, - data=HexBytes(self.built_data), - ) - self.multisend_batches.append(batch) - return True - - def _prepare_single_redeem(self) -> WaitableConditionType: - """Prepare a multisend transaction for a single redeeming action.""" - yield from self.wait_for_condition_with_sleep(self._check_already_resolved) - steps = [] - if not self.already_resolved: - # 1. resolve the question if it hasn't been resolved yet - steps.append(self._build_resolve_data) - - yield from self.wait_for_condition_with_sleep(self._get_history_hash) - if not self.is_history_hash_null: - # 2. claim the winnings if claiming has not been done yet - if not self.redeeming_progress.claim_finished: - success = yield from self.get_claim_params() - if not success: - return False - - # simulate claiming to get the claim params - success = yield from self._simulate_claiming() - if not success: - return False - - if self.claim_winnings_simulation_ok: - steps.append(self._build_claim_data) - - # 3. we always redeem the position - steps.append(self._build_redeem_data) - for build_step in steps: - yield from self.wait_for_condition_with_sleep(build_step) - - return True - - def _process_candidate( - self, redeem_candidate: Trade - ) -> Generator[None, None, bool]: - """Process a redeeming candidate and return whether winnings were found.""" - self._current_redeem_info = redeem_candidate - - msg = f"Processing position with condition id {self.current_condition_id!r}..." - self.context.logger.info(msg) - - # double check whether the market is finalized - yield from self.wait_for_condition_with_sleep(self._check_finalized) - if not self.finalized: - self.context.logger.warning( - f"Conflict found! The current market, with condition id {self.current_condition_id!r}, " - f"is reported as not finalized by the realitio contract. " - f"However, an answer was finalized on {redeem_candidate.fpmm.answerFinalizedTimestamp}, " - f"and the last service transition occurred on {self.synced_timestamp}." - ) - return False - - if self.params.use_subgraph_for_redeeming: - condition_id = redeem_candidate.fpmm.condition.id.hex().lower() - if ( - condition_id not in self.redeeming_progress.unredeemed_trades - or self.redeeming_progress.unredeemed_trades[condition_id] == 0 - ): - return False - - # in case that the claimable amount is dust - if self.is_dust: - self.context.logger.info("Position's redeeming amount is dust.") - return False - - if self.params.use_subgraph_for_redeeming: - condition_id = redeem_candidate.fpmm.condition.id.hex().lower() - if ( - condition_id not in self.redeeming_progress.unredeemed_trades - or self.redeeming_progress.unredeemed_trades[condition_id] == 0 - ): - return False - - success = yield from self._prepare_single_redeem() - if not success: - return False - - self._expected_winnings += self.current_claimable_amount - return True - - def _prepare_safe_tx(self) -> Generator[None, None, Optional[str]]: - """ - Prepare the safe tx to redeem the positions of the trader. - - Steps: - 1. Get all the trades of the trader. - 2. For each trade, check if the trader has not already redeemed a non-dust winning position. - 3. If so, prepare a multisend transaction like this: - TXS: - 1. resolve (optional) - Check if the condition needs to be resolved. If so, add the tx to the multisend. - - 2. claimWinnings - Prepare a claim winnings tx for each winning position. Add it to the multisend. - - 3. redeemPositions - Prepare a redeem positions tx for each winning position. Add it to the multisend. - - We do not convert claimed wxDAI to xDAI, because this is the currency that the service is using to place bets. - - :yields: None - :returns: the safe's transaction hash for the redeeming operation. - """ - if len(self.trades) > 0: - self.context.logger.info("Preparing a multisend tx to redeem payout...") - - winnings_found = 0 - - for redeem_candidate in self.trades: - is_claimable = yield from self._process_candidate(redeem_candidate) - if not is_claimable: - msg = "Not redeeming position. Moving to the next one..." - self.context.logger.info(msg) - continue - - if self.params.redeeming_batch_size > 1: - self.context.logger.info("Adding position to the multisend batch...") - - winnings_found += 1 - # we mark this condition id as being claimed. - # once the transaction gets successfully through, it will be moved to - # self.redeeming_progress.claiming_condition_ids, and will no longer be taken into - # consideration. This is done to avoid cases where the subgraph is not up-to date - # and the same condition id is returned multiple times. - claiming_condition_id = redeem_candidate.fpmm.condition.id.hex() - self.redeeming_progress.claiming_condition_ids.append(claiming_condition_id) - - if winnings_found == self.params.redeeming_batch_size: - break - - if winnings_found == 0: - self.context.logger.info("No winnings to redeem.") - return None - - winnings = self.wei_to_native(self._expected_winnings) - self.context.logger.info( - "Preparing the multisend transaction to redeem winnings of " - f"{winnings} wxDAI for {winnings_found} position(s)." - ) - for build_step in ( - self._build_multisend_data, - self._build_multisend_safe_tx_hash, - ): - yield from self.wait_for_condition_with_sleep(build_step) - - self.context.logger.info("Transaction successfully prepared.") - return self.tx_hex - - def _store_utilized_tools(self) -> None: - """Store the tools utilized by the behaviour.""" - path = self.params.store_path / self.UTILIZED_TOOLS_PATH - with path.open("w") as f: - json.dump(self.utilized_tools, f) - - def finish_behaviour(self, payload: BaseTxPayload) -> Generator: - """Finish the behaviour.""" - self._store_utilized_tools() - yield from super().finish_behaviour(payload) - - def _setup_policy_and_tools(self) -> Generator[None, None, bool]: - """Set up the policy and tools.""" - if self.synchronized_data.is_policy_set: - self._policy = self.synchronized_data.policy - self.mech_tools = self.synchronized_data.available_mech_tools - return True - status = yield from super()._setup_policy_and_tools() - return status - - def _build_payload(self, redeem_tx_hex: Optional[str] = None) -> RedeemPayload: - """Build the redeeming round's payload.""" - agent = self.context.agent_address - tx_submitter = self.matching_round.auto_round_id() - benchmarking_enabled = self.benchmarking_mode.enabled - serialized_tools = json.dumps(self.mech_tools) - policy = self.policy.serialize() - utilized_tools = json.dumps(self.utilized_tools) - condition_ids = json.dumps(list(self.redeemed_condition_ids)) - payout = self.payout_so_far - return RedeemPayload( - agent, - tx_submitter, - redeem_tx_hex, - benchmarking_enabled, - serialized_tools, - policy, - utilized_tools, - condition_ids, - payout, - ) - - def _benchmarking_act(self) -> RedeemPayload: - """The act of the agent while running in benchmarking mode.""" - tool = self.synchronized_data.mech_tool - winning = self.mock_data.is_winning - self._try_update_policy(tool, winning) - return self._build_payload() - - def _normal_act(self) -> Generator[None, None, Optional[RedeemPayload]]: - """The act of the agent while running in normal mode.""" - if not self.redeeming_progress.check_started: - yield from self._get_redeem_info() - self._store_progress() - else: - msg = "Picking up progress from where it was left off before the timeout occurred." - self.context.logger.info(msg) - self._load_progress() - - if not self.redeeming_progress.check_finished: - self.redeeming_progress.cleaned = yield from self._clean_redeem_info() - - serialized_tools = json.dumps(self.mech_tools) - payload = RedeemPayload(self.context.agent_address, mech_tools=serialized_tools) - if self.redeeming_progress.cleaned: - redeem_tx_hex = yield from self._prepare_safe_tx() - if redeem_tx_hex is not None: - payload = self._build_payload(redeem_tx_hex) - - return payload - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - success = yield from self._setup_policy_and_tools() - if not success: - return None - - payload: Optional[RedeemPayload] - if self.benchmarking_mode.enabled: - payload = self._benchmarking_act() - else: - # Checking if the last round that submitted the transaction was the bet placement round - # If so, we need to update the bet transaction information, because the transaction was successful - # tx settlement multiplexer assures transitions from Post transaction to Redeem round - # only if the transaction was successful - if ( - self.synchronized_data.did_transact - and self.synchronized_data.tx_submitter - == BetPlacementRound.auto_round_id() - ): - self.update_bet_transaction_information() - - payload = yield from self._normal_act() - if payload is None: - return - - self._store_all() - - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/round_behaviour.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/round_behaviour.py deleted file mode 100644 index 706b62cf5..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/round_behaviour.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the round behaviour for the 'decision_maker_abci' skill.""" - -from typing import Set, Type - -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.bet_placement import ( - BetPlacementBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.blacklisting import ( - BlacklistingBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.check_benchmarking import ( - CheckBenchmarkingModeBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.claim_subscription import ( - ClaimSubscriptionBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.decision_receive import ( - DecisionReceiveBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.decision_request import ( - DecisionRequestBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.handle_failed_tx import ( - HandleFailedTxBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.order_subscription import ( - OrderSubscriptionBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.randomness import ( - BenchmarkingRandomnessBehaviour, - RandomnessBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.reedem import RedeemBehaviour -from packages.valory.skills.decision_maker_abci.behaviours.sampling import ( - SamplingBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.tool_selection import ( - ToolSelectionBehaviour, -) -from packages.valory.skills.decision_maker_abci.rounds import DecisionMakerAbciApp - - -class AgentDecisionMakerRoundBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the decision-making.""" - - initial_behaviour_cls = SamplingBehaviour - abci_app_cls = DecisionMakerAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - SamplingBehaviour, # type: ignore - DecisionRequestBehaviour, # type: ignore - DecisionReceiveBehaviour, # type: ignore - BlacklistingBehaviour, # type: ignore - BetPlacementBehaviour, # type: ignore - RedeemBehaviour, # type: ignore - HandleFailedTxBehaviour, # type: ignore - ToolSelectionBehaviour, # type: ignore - OrderSubscriptionBehaviour, - ClaimSubscriptionBehaviour, - RandomnessBehaviour, # type: ignore - BenchmarkingRandomnessBehaviour, # type: ignore - CheckBenchmarkingModeBehaviour, # type: ignore - } diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/sampling.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/sampling.py deleted file mode 100644 index dd8048076..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/sampling.py +++ /dev/null @@ -1,258 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour for sampling a bet.""" - -from collections import defaultdict -from datetime import datetime -from typing import Any, Dict, Generator, List, Optional, Tuple - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import SamplingPayload -from packages.valory.skills.decision_maker_abci.states.sampling import SamplingRound -from packages.valory.skills.market_manager_abci.bets import Bet, QueueStatus - - -WEEKDAYS = 7 -UNIX_DAY = 60 * 60 * 24 -UNIX_WEEK = WEEKDAYS * UNIX_DAY - - -class SamplingBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents blacklist the sampled bet.""" - - matching_round = SamplingRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize Behaviour.""" - super().__init__(**kwargs) - self.should_rebet: bool = False - - def setup(self) -> None: - """Setup the behaviour.""" - self.read_bets() - - def processable_bet(self, bet: Bet, now: int) -> bool: - """Whether we can process the given bet.""" - - within_opening_range = bet.openingTimestamp <= ( - now + self.params.sample_bets_closing_days * UNIX_DAY - ) - within_safe_range = ( - now - < bet.openingTimestamp - - self.params.opening_margin - - self.params.safe_voting_range - ) - - within_ranges = within_opening_range and within_safe_range - - # check if bet queue number is processable - processable_statuses = { - QueueStatus.TO_PROCESS, - QueueStatus.PROCESSED, - QueueStatus.REPROCESSED, - } - bet_queue_processable = bet.queue_status in processable_statuses - - return within_ranges and bet_queue_processable - - @staticmethod - def _sort_by_priority_logic(bets: List[Bet]) -> List[Bet]: - """ - Sort bets based on the priority logic. - - :param bets: the bets to sort. - :return: the sorted list of bets. - """ - return sorted( - bets, - key=lambda bet: ( - bet.invested_amount, - -bet.processed_timestamp, # Increasing order of processed_timestamp - bet.scaledLiquidityMeasure, - bet.openingTimestamp, - ), - reverse=True, - ) - - @staticmethod - def _get_bets_queue_wise(bets: List[Bet]) -> Tuple[List[Bet], List[Bet], List[Bet]]: - """Return a dictionary of bets with queue status as key.""" - - bets_by_status: Dict[QueueStatus, List[Bet]] = defaultdict(list) - - for bet in bets: - bets_by_status[bet.queue_status].append(bet) - - return ( - bets_by_status[QueueStatus.TO_PROCESS], - bets_by_status[QueueStatus.PROCESSED], - bets_by_status[QueueStatus.REPROCESSED], - ) - - def _sampled_bet_idx(self, bets: List[Bet]) -> int: - """ - Sample a bet and return its index. - - The sampling logic follows the specified priority logic: - 1. Filter out all the bets that have a processed_timestamp != 0 to get a list of new bets. - 2. If the list of new bets is not empty: - 2.1 Order the list in decreasing order of liquidity (highest liquidity first). - 2.2 For bets with the same liquidity, order them in decreasing order of market closing time (openingTimestamp). - 3. If the list of new bets is empty: - 3.1 Order the bets in decreasing order of invested_amount. - 3.2 For bets with the same invested_amount, order them in increasing order of processed_timestamp (least recently processed first). - 3.3 For bets with the same invested_amount and processed_timestamp, order them in decreasing order of liquidity. - 3.4 For bets with the same invested_amount, processed_timestamp, and liquidity, order them in decreasing order of market closing time (openingTimestamp). - - :param bets: the bets' values to compare for the sampling. - :return: the index of the sampled bet, out of all the available bets, not only the given ones. - """ - - to_process_bets, processed_bets, reprocessed_bets = self._get_bets_queue_wise( - bets - ) - # pick the first queue status that has bets in it - bets_to_sort: List[Bet] = to_process_bets or processed_bets or reprocessed_bets - - sorted_bets = self._sort_by_priority_logic(bets_to_sort) - - return self.bets.index(sorted_bets[0]) - - def _sampling_benchmarking_bet(self, bets: List[Bet]) -> Optional[int]: - """Sample bet for benchmarking""" - to_process_bets, processed_bets, reprocessed_bets = self._get_bets_queue_wise( - bets - ) - - self.context.logger.info(f"TO_PROCESS_LEN: {len(to_process_bets)}") - self.context.logger.info(f"PROCESSED_LEN: {len(processed_bets)}") - self.context.logger.info(f"REPROCESSED_LEN: {len(reprocessed_bets)}") - - self.context.logger.info( - f"MECH CALLS MADE: {self.shared_state.benchmarking_mech_calls}" - ) - - if ( - self.shared_state.benchmarking_mech_calls - == self.benchmarking_mode.nr_mech_calls - ): - return None - - bets_to_sort: List[Bet] = to_process_bets or processed_bets or reprocessed_bets - sorted_bets = self._sort_by_priority_logic(bets_to_sort) - - return self.bets.index(sorted_bets[0]) - - def _sample(self) -> Optional[int]: - """Sample a bet, mark it as processed, and return its index.""" - # modify time "NOW" in benchmarking mode - if self.benchmarking_mode.enabled: - safe_voting_range = ( - self.params.opening_margin + self.params.safe_voting_range - ) - now = self.shared_state.get_simulated_now_timestamp( - self.bets, safe_voting_range - ) - self.context.logger.info(f"Simulating date: {datetime.fromtimestamp(now)}") - else: - now = self.synced_timestamp - - # filter out only the bets that are processable and have a queue_status that allows them to be sampled - available_bets = list( - filter( - lambda bet: self.processable_bet(bet, now=now), - self.bets, - ) - ) - if len(available_bets) == 0: - msg = "There were no unprocessed bets available to sample from!" - self.context.logger.warning(msg) - return None - - if self.benchmarking_mode.enabled: - idx = self._sampling_benchmarking_bet(available_bets) - if not idx: - return None - - # sample a bet using the priority logic - idx = self._sampled_bet_idx(available_bets) - sampled_bet = self.bets[idx] - - # fetch the liquidity of the sampled bet and cache it - liquidity = sampled_bet.scaledLiquidityMeasure - if liquidity == 0: - msg = "There were no unprocessed bets with non-zero liquidity!" - self.context.logger.warning(msg) - return None - self.shared_state.liquidity_cache[sampled_bet.id] = liquidity - - msg = f"Sampled bet: {sampled_bet}" - self.context.logger.info(msg) - return idx - - def _benchmarking_inc_day(self) -> Tuple[bool, bool]: - """Increase the simulated day in benchmarking mode.""" - self.context.logger.info( - "No more markets to bet in the simulated day. Increasing simulated day." - ) - self.shared_state.increase_one_day_simulation() - benchmarking_finished = self.shared_state.check_benchmarking_finished() - if benchmarking_finished: - self.context.logger.info("No more days to simulate in benchmarking mode.") - - self.shared_state.benchmarking_mech_calls = 0 - - day_increased = True - - return benchmarking_finished, day_increased - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - idx = self._sample() - benchmarking_finished = None - day_increased = None - - # day increase simulation and benchmarking finished check - if idx is None and self.benchmarking_mode.enabled: - benchmarking_finished, day_increased = self._benchmarking_inc_day() - for bet in self.bets: - bet.queue_status = bet.queue_status.move_to_fresh() - bet.queue_status = bet.queue_status.move_to_process() - - self.store_bets() - - if idx is None: - bets_hash = None - else: - bets_hash = self.hash_stored_bets() - - payload = SamplingPayload( - self.context.agent_address, - bets_hash, - idx, - benchmarking_finished, - day_increased, - ) - - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/sell_outcome_token.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/sell_outcome_token.py deleted file mode 100644 index 0bf228d07..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/sell_outcome_token.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the behaviour for selling a token.""" -from typing import Any, Generator, Optional, cast - -from hexbytes import HexBytes - -from packages.valory.contracts.market_maker.contract import ( - FixedProductMarketMakerContract, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, - WaitableConditionType, -) -from packages.valory.skills.decision_maker_abci.models import MultisendBatch -from packages.valory.skills.decision_maker_abci.payloads import MultisigTxPayload -from packages.valory.skills.decision_maker_abci.states.sell_outcome_token import ( - SellOutcomeTokenRound, -) - - -class SellTokenBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents sell a token.""" - - matching_round = SellOutcomeTokenRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize the sell token behaviour.""" - super().__init__(**kwargs) - self.sell_amount: float = 0.0 - - @property - def market_maker_contract_address(self) -> str: - """Get the contract address of the market maker on which the service is going to place the bet.""" - return self.sampled_bet.id - - @property - def outcome_index(self) -> int: - """Get the index of the outcome for which the service is going to sell token.""" - return cast(int, self.synchronized_data.previous_vote) - - @property - def return_amount(self) -> int: - """Get the amount expected to be returned after the sell tx is completed.""" - previous_vote = self.synchronized_data.previous_vote - - if previous_vote == 0: - return self.sampled_bet.invested_amount_yes - - else: - return self.sampled_bet.invested_amount_no - - def _build_approval_tx(self) -> WaitableConditionType: - """Build an ERC20 approve transaction.""" - status = yield from self.build_approval_tx( - self.return_amount, - self.market_maker_contract_address, - self.sampled_bet.get_outcome(self.outcome_index), - ) - return status - - def _calc_sell_amount(self) -> WaitableConditionType: - """Calculate the sell amount of the conditional token.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.market_maker_contract_address, - contract_id=str(FixedProductMarketMakerContract.contract_id), - contract_callable="calc_sell_amount", - return_amount=self.return_amount, - outcome_index=self.outcome_index, - ) - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.context.logger.error( - f"Could not calculate the sell amount: {response_msg}" - ) - return False - - sell_amount = response_msg.raw_transaction.body.get( - "outcomeTokenSellAmount", None - ) - if sell_amount is None: - self.context.logger.error( - f"Something went wrong while trying to get the outcomeTokenSellAmount amount for the conditional token: {response_msg}" - ) - return False - - self.sell_amount = sell_amount - return True - - def _build_sell_tx(self) -> WaitableConditionType: - """Get the sell tx data encoded.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.market_maker_contract_address, - contract_id=str(FixedProductMarketMakerContract.contract_id), - contract_callable="get_sell_data", - return_amount=self.return_amount, - outcome_index=self.outcome_index, - max_outcome_tokens_to_sell=self.sell_amount, - ) - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Could not get the data for the buy transaction: {response_msg}" - ) - return False - - sell_data = response_msg.state.body.get("data", None) - if sell_data is None: - self.context.logger.error( - f"Something went wrong while trying to encode the buy data: {response_msg}" - ) - return False - - batch = MultisendBatch( - to=self.market_maker_contract_address, - data=HexBytes(sell_data), - ) - self.multisend_batches.append(batch) - return True - - def _prepare_safe_tx(self) -> Generator[None, None, Optional[str]]: - """Prepare the safe transaction for selling an outcome token and return the hex for the tx settlement skill.""" - for step in ( - self._build_approval_tx, - self._calc_sell_amount, - self._build_sell_tx, - self._build_multisend_data, - self._build_multisend_safe_tx_hash, - ): - yield from self.wait_for_condition_with_sleep(step) - - outcome = self.sampled_bet.get_outcome(self.outcome_index) - investment = self._collateral_amount_info(self.return_amount) - self.context.logger.info( - f"Preparing a multisig transaction to sell the outcome token for {outcome!r}, with confidence " - f"{self.synchronized_data.confidence!r}, for the amount of {investment}, which is equal to the amount of " - f"{self.sell_amount!r} WEI of the conditional token corresponding to {outcome!r}." - ) - - return self.tx_hex - - def async_act(self) -> Generator: - """Do the action.""" - - agent = self.context.agent_address - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - tx_submitter = betting_tx_hex = mocking_mode = None - - # if the vote is the same as the previous vote then there is no change in the supported outcome, so we - # should not sell - if self.synchronized_data.vote == self.synchronized_data.previous_vote: - payload = MultisigTxPayload( - agent, tx_submitter, betting_tx_hex, mocking_mode - ) - - yield from self.finish_behaviour(payload) - - tx_submitter = self.matching_round.auto_round_id() - betting_tx_hex = yield from self._prepare_safe_tx() - - payload = MultisigTxPayload( - agent, tx_submitter, betting_tx_hex, mocking_mode - ) - - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/storage_manager.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/storage_manager.py deleted file mode 100644 index 0fd9a8369..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/storage_manager.py +++ /dev/null @@ -1,471 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 behaviour for managing the storage of the agent.""" - -import csv -import json -from abc import ABC -from datetime import datetime -from io import StringIO -from typing import Any, Dict, Generator, List, Optional, Tuple - -from packages.valory.contracts.agent_registry.contract import AgentRegistryContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - CID_PREFIX, - DecisionMakerBaseBehaviour, - WaitableConditionType, -) -from packages.valory.skills.decision_maker_abci.models import AgentToolsSpecs -from packages.valory.skills.decision_maker_abci.policy import ( - AccuracyInfo, - EGreedyPolicy, -) - - -POLICY_STORE = "policy_store_multi_bet_failure_adjusting.json" -AVAILABLE_TOOLS_STORE = "available_tools_store.json" -UTILIZED_TOOLS_STORE = "utilized_tools.json" -GET = "GET" -OK_CODE = 200 - - -class StorageManagerBehaviour(DecisionMakerBaseBehaviour, ABC): - """Manages the storage of the policy and the tools.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize Behaviour.""" - super().__init__(**kwargs) - self._mech_id: int = 0 - self._mech_hash: str = "" - self._utilized_tools: Dict[str, str] = {} - self._mech_tools: Optional[List[str]] = None - self._remote_accuracy_information: StringIO = StringIO() - - @property - def mech_tools(self) -> List[str]: - """Get the mech agent's tools.""" - if self._mech_tools is None: - raise ValueError("The mech's tools have not been set.") - return self._mech_tools - - @mech_tools.setter - def mech_tools(self, mech_tools: List[str]) -> None: - """Set the mech agent's tools.""" - self._mech_tools = mech_tools - - @property - def remote_accuracy_information(self) -> StringIO: - """Get the accuracy information.""" - return self._remote_accuracy_information - - @remote_accuracy_information.setter - def remote_accuracy_information(self, accuracy_information: StringIO) -> None: - """Set the accuracy information.""" - self._remote_accuracy_information = accuracy_information - - @property - def mech_id(self) -> int: - """Get the mech's id.""" - return self._mech_id - - @mech_id.setter - def mech_id(self, mech_id: int) -> None: - """Set the mech's id.""" - self._mech_id = mech_id - - @property - def mech_hash(self) -> str: - """Get the hash of the mech agent.""" - return self._mech_hash - - @mech_hash.setter - def mech_hash(self, mech_hash: str) -> None: - """Set the hash of the mech agent.""" - self._mech_hash = mech_hash - - @property - def utilized_tools(self) -> Dict[str, str]: - """Get the utilized tools.""" - return self._utilized_tools - - @utilized_tools.setter - def utilized_tools(self, utilized_tools: Dict[str, str]) -> None: - """Get the utilized tools.""" - self._utilized_tools = utilized_tools - - @property - def mech_tools_api(self) -> AgentToolsSpecs: - """Get the mech agent api specs.""" - return self.context.agent_tools - - def setup(self) -> None: - """Set the behaviour up.""" - try: - self.utilized_tools = self.synchronized_data.utilized_tools - except Exception: - self.utilized_tools = self._try_recover_utilized_tools() - else: - if self.utilized_tools is None: - self.utilized_tools = self._try_recover_utilized_tools() - - def set_mech_agent_specs(self) -> None: - """Set the mech's agent specs.""" - full_ipfs_hash = CID_PREFIX + self.mech_hash - ipfs_link = self.params.ipfs_address + full_ipfs_hash - # The url needs to be dynamically generated as it depends on the ipfs hash - self.mech_tools_api.__dict__["_frozen"] = False - self.mech_tools_api.url = ipfs_link - self.mech_tools_api.__dict__["_frozen"] = True - - def _get_tools_from_benchmark_file(self) -> None: - """Get the tools from the benchmark dataset.""" - dataset_filepath = ( - self.params.store_path / self.benchmarking_mode.dataset_filename - ) - with open(dataset_filepath) as read_dataset: - row = read_dataset.readline() - if not row: - # if no headers are in the file, then we finished the benchmarking - self.context.logger.error("No headers in dataset file.") - return - - # parse tools from headers - headers = row.split(self.benchmarking_mode.sep) - p_yes_part = self.benchmarking_mode.p_yes_field_part - self.mech_tools = [ - header.replace(p_yes_part, "") for header in headers if p_yes_part in header - ] - - def _get_mech_id(self) -> WaitableConditionType: - """Get the mech's id.""" - result = yield from self._mech_contract_interact( - contract_callable="get_mech_id", - data_key="id", - placeholder=get_name(StorageManagerBehaviour.mech_id), - ) - - return result - - def _get_mech_hash(self) -> WaitableConditionType: - """Get the mech's hash.""" - result = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.agent_registry_address, - contract_public_id=AgentRegistryContract.contract_id, - contract_callable="get_hash", - data_key="hash", - placeholder=get_name(StorageManagerBehaviour.mech_hash), - agent_id=self.mech_id, - ) - return result - - def _get_mech_tools(self) -> WaitableConditionType: - """Get the mech agent's tools from IPFS.""" - self.set_mech_agent_specs() - specs = self.mech_tools_api.get_spec() - res_raw = yield from self.get_http_response(**specs) - res = self.mech_tools_api.process_response(res_raw) - - if self.mech_tools_api.is_retries_exceeded(): - error = "Retries were exceeded while trying to get the mech agent's data." - self.context.logger.error(error) - self.mech_tools_api.reset_retries() - return True - - if res is None: - url = self.mech_tools_api.url - msg = f"Could not get the mech agent's tools from {url}." - self.context.logger.error(msg) - self.mech_tools_api.increment_retries() - return False - - self.context.logger.info(f"Retrieved the mech agent's tools: {res}.") - # keep only the relevant mech tools, sorted - # we sort the tools to avoid using dictionaries in the policy implementation, - # so that we can easily assess which index corresponds to which tool - res = sorted(set(res) - self.params.irrelevant_tools) - self.context.logger.info(f"Relevant tools to the prediction task: {res}.") - - if len(res) == 0: - self.context.logger.error("The relevant mech agent's tools are empty!") - return False - self.mech_tools = res - self.mech_tools_api.reset_retries() - return True - - def _get_tools( - self, - ) -> Generator[None, None, None]: - """Get the Mech's tools.""" - if self.benchmarking_mode.enabled: - self._get_tools_from_benchmark_file() - return - - for step in ( - self._get_mech_id, - self._get_mech_hash, - self._get_mech_tools, - ): - yield from self.wait_for_condition_with_sleep(step) - - def _try_recover_policy(self) -> Optional[EGreedyPolicy]: - """Try to recover the policy from the policy store.""" - try: - policy_path = self.params.store_path / POLICY_STORE - with open(policy_path, "r") as f: - policy_raw = f.read() - policy = EGreedyPolicy.deserialize(policy_raw) - # overwrite the configurable parameters - policy.eps = self.params.epsilon - policy.consecutive_failures_threshold = self.params.policy_threshold - policy.quarantine_duration = self.params.tool_quarantine_duration - return policy - except Exception as e: - self.context.logger.warning(f"Could not recover the policy: {e}.") - return None - - def _get_init_policy(self) -> EGreedyPolicy: - """Get the initial policy.""" - # try to read the policy from the policy store, and if we cannot recover the policy, we create a new one - return self._try_recover_policy() or EGreedyPolicy( - self.params.epsilon, - self.params.policy_threshold, - self.params.tool_quarantine_duration, - ) - - def _fetch_accuracy_info(self) -> Generator[None, None, bool]: - """Fetch the latest accuracy information available.""" - # get the CSV file from IPFS - self.context.logger.info("Reading accuracy information from IPFS...") - accuracy_link = self.params.ipfs_address + self.params.tools_accuracy_hash - response = yield from self.get_http_response(method=GET, url=accuracy_link) - if response.status_code != OK_CODE: - self.context.logger.error( - f"Could not retrieve data from the url {accuracy_link}. " - f"Received status code {response.status_code}." - ) - return False - - self.context.logger.info("Parsing accuracy information of the tools...") - try: - self.remote_accuracy_information = StringIO(response.body.decode()) - except (ValueError, TypeError) as e: - self.context.logger.error( - f"Could not parse response from ipfs server, " - f"the following error was encountered {type(e).__name__}: {e}" - ) - return False - - return True - - def _remove_irrelevant_tools(self) -> None: - """Remove irrelevant tools from the accuracy store.""" - accuracy_store = self.policy.accuracy_store - for tool in accuracy_store.copy(): - if tool not in self.mech_tools: - accuracy_store.pop(tool, None) - - def _global_info_date_to_unix(self, tool_transaction_date: str) -> Optional[int]: - """Convert the global information date to unix.""" - datetime_format = self.acc_info_fields.datetime_format - try: - tool_transaction_datetime = datetime.strptime( - tool_transaction_date, datetime_format - ) - except (ValueError, TypeError): - self.context.logger.warning( - f"Could not parse the global info date {tool_transaction_date!r} using format {datetime_format!r}!" - ) - return None - - return int(tool_transaction_datetime.timestamp()) - - def _parse_global_info_row( - self, - row: Dict[str, str], - max_transaction_date: int, - tool_to_global_info: Dict[str, Dict[str, str]], - ) -> int: - """Parse a row of the global information.""" - tool = row[self.acc_info_fields.tool] - if tool not in self.mech_tools: - # skip irrelevant tools - return max_transaction_date - - # store the global information - tool_to_global_info[tool] = row - - # find the latest transaction date - tool_transaction_date = row[self.acc_info_fields.max] - tool_transaction_unix = self._global_info_date_to_unix(tool_transaction_date) - if ( - tool_transaction_unix is not None - and tool_transaction_unix > max_transaction_date - ): - return tool_transaction_unix - - return max_transaction_date - - def _parse_global_info(self) -> Tuple[int, Dict[str, Dict[str, str]]]: - """Parse the global information of the tools.""" - sep = self.acc_info_fields.sep - reader: csv.DictReader = csv.DictReader( - self.remote_accuracy_information, delimiter=sep - ) - - max_transaction_date = 0 - tool_to_global_info: Dict[str, Dict[str, str]] = {} - for row in reader: - max_transaction_date = self._parse_global_info_row( - row, max_transaction_date, tool_to_global_info - ) - - return max_transaction_date, tool_to_global_info - - def _should_use_global_info(self, global_update_timestamp: int) -> bool: - """Whether we should use the global information of the tools.""" - local_update_timestamp = self.policy.updated_ts - local_update_offset = self.params.policy_store_update_offset - return global_update_timestamp > local_update_timestamp - local_update_offset - - def _overwrite_local_info( - self, tool_to_global_info: Dict[str, Dict[str, str]] - ) -> None: - """Overwrite the local information with the global information.""" - self.context.logger.info( - "The local policy store will be overwritten with global information." - ) - - accuracy_store = self.policy.accuracy_store - for tool, row in tool_to_global_info.items(): - accuracy_store[tool] = AccuracyInfo( - int(row[self.acc_info_fields.requests]), - # naturally, no global information is available for pending. - # set it using the local policy if this information exists - accuracy_store.get(tool, AccuracyInfo()).pending, - float(row[self.acc_info_fields.accuracy]), - ) - self.policy.updated_ts = int(datetime.now().timestamp()) - - def _update_accuracy_store( - self, - global_update_timestamp: int, - tool_to_global_info: Dict[str, Dict[str, str]], - ) -> None: - """ - Update the accuracy store using the latest accuracy information. - - The current method should only be called at the first period. - - :param global_update_timestamp: the timestamp of the latest global information update - :param tool_to_global_info: the global information of the tools - """ - if self._should_use_global_info(global_update_timestamp): - self._overwrite_local_info(tool_to_global_info) - - # update the accuracy store by adding tools for which we do not have any global information yet - for tool in self.mech_tools: - self.policy.accuracy_store.setdefault(tool, AccuracyInfo()) - - def _update_policy_tools(self) -> None: - """Update the policy's tools and their accuracy with the latest information available if `with_global_info`.""" - self.context.logger.info("Updating information of the policy...") - self._remove_irrelevant_tools() - global_info = self._parse_global_info() - self._update_accuracy_store(*global_info) - self.policy.update_weighted_accuracy() - - def _set_policy(self) -> Generator: - """Set the E Greedy Policy.""" - if self.is_first_period or not self.synchronized_data.is_policy_set: - self.context.logger.debug("Setting initial policy") - self._policy = self._get_init_policy() - else: - self.context.logger.debug( - "Reading policy information from synchronized data" - ) - self._policy = self.synchronized_data.policy - - yield from self.wait_for_condition_with_sleep( - self._fetch_accuracy_info, sleep_time_override=self.params.sleep_time - ) - - if self.is_first_period: - self._update_policy_tools() - - def _try_recover_utilized_tools(self) -> Dict[str, str]: - """Try to recover the utilized tools from the tools store.""" - tools_path = self.params.store_path / UTILIZED_TOOLS_STORE - try: - with open(tools_path, "r") as tools_file: - return json.load(tools_file) - except FileNotFoundError: - msg = "No file with pending rewards for the policy were found in the local storage." - self.context.logger.info(msg) - except Exception as exc: - msg = f"Could not recover the pending rewards for the policy: {exc}." - self.context.logger.warning(msg) - return {} - - def _try_recover_mech_tools(self) -> Optional[List[str]]: - """Try to recover the available tools from the tools store.""" - try: - tools_path = self.params.store_path / AVAILABLE_TOOLS_STORE - with open(tools_path, "r") as f: - tools = json.load(f) - return tools - except Exception as e: - self.context.logger.warning(f"Could not recover the tools: {e}.") - return None - - def _setup_policy_and_tools(self) -> Generator[None, None, bool]: - """Set up the policy and tools.""" - yield from self._get_tools() - if self._mech_tools is None: - return False - - yield from self._set_policy() - return True - - def _store_policy(self) -> None: - """Store the policy""" - policy_path = self.params.store_path / POLICY_STORE - with open(policy_path, "w") as f: - f.write(self.policy.serialize()) - - def _store_available_mech_tools(self) -> None: - """Store the policy""" - policy_path = self.params.store_path / AVAILABLE_TOOLS_STORE - with open(policy_path, "w") as f: - json.dump(self.mech_tools, f) - - def _store_utilized_tools(self) -> None: - """Store the utilized tools.""" - tools_path = self.params.store_path / UTILIZED_TOOLS_STORE - with open(tools_path, "w") as f: - json.dump(self.utilized_tools, f) - - def _store_all(self) -> None: - """Store the policy, the available tools and the utilized tools.""" - self._store_policy() - self._store_available_mech_tools() - self._store_utilized_tools() diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/tool_selection.py b/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/tool_selection.py deleted file mode 100644 index 2fd1bbaa8..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/behaviours/tool_selection.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour of the skill which is responsible for selecting a mech tool.""" - -import json -from typing import Generator, Optional - -from packages.valory.skills.decision_maker_abci.behaviours.storage_manager import ( - StorageManagerBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import ToolSelectionPayload -from packages.valory.skills.decision_maker_abci.states.tool_selection import ( - ToolSelectionRound, -) - - -class ToolSelectionBehaviour(StorageManagerBehaviour): - """A behaviour in which the agents select a mech tool.""" - - matching_round = ToolSelectionRound - - def _select_tool(self) -> Generator[None, None, Optional[str]]: - """Select a Mech tool based on an e-greedy policy and return its index.""" - success = yield from self._setup_policy_and_tools() - if not success: - return None - - randomness = ( - (self.benchmarking_mode.randomness if self.is_first_period else None) - if self.benchmarking_mode.enabled - else self.synchronized_data.most_voted_randomness - ) - selected_tool = self.policy.select_tool(randomness) - self.context.logger.info(f"Selected the mech tool {selected_tool!r}.") - return selected_tool - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - mech_tools = policy = utilized_tools = None - selected_tool = yield from self._select_tool() - if selected_tool is not None: - # the period will increment when the benchmarking finishes - benchmarking_running = self.synchronized_data.period_count == 0 - if ( - self.benchmarking_mode.enabled - and benchmarking_running - and not self.shared_state.last_benchmarking_has_run - ): - self.policy.tool_used(selected_tool) - mech_tools = json.dumps(self.mech_tools) - policy = self.policy.serialize() - utilized_tools = json.dumps(self.utilized_tools, sort_keys=True) - self._store_all() - - payload = ToolSelectionPayload( - self.context.agent_address, - mech_tools, - policy, - utilized_tools, - selected_tool, - ) - - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/dialogues.py b/trader_backup/vendor/valory/skills/decision_maker_abci/dialogues.py deleted file mode 100644 index e985dc865..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/dialogues.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- 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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/fsm_specification.yaml b/trader_backup/vendor/valory/skills/decision_maker_abci/fsm_specification.yaml deleted file mode 100644 index ac3009546..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/fsm_specification.yaml +++ /dev/null @@ -1,133 +0,0 @@ -alphabet_in: -- BENCHMARKING_DISABLED -- BENCHMARKING_ENABLED -- BENCHMARKING_FINISHED -- BLACKLIST -- DONE -- FETCH_ERROR -- INSUFFICIENT_BALANCE -- MECH_RESPONSE_ERROR -- MOCK_MECH_REQUEST -- MOCK_TX -- NEW_SIMULATED_RESAMPLE -- NONE -- NO_MAJORITY -- NO_OP -- NO_REDEEMING -- NO_SUBSCRIPTION -- REDEEM_ROUND_TIMEOUT -- ROUND_TIMEOUT -- SLOTS_UNSUPPORTED_ERROR -- SUBSCRIPTION_ERROR -- TIE -- UNPROFITABLE -default_start_state: CheckBenchmarkingModeRound -final_states: -- BenchmarkingDoneRound -- BenchmarkingModeDisabledRound -- FinishedDecisionMakerRound -- FinishedDecisionRequestRound -- FinishedSubscriptionRound -- FinishedWithoutDecisionRound -- FinishedWithoutRedeemingRound -- ImpossibleRound -- RefillRequiredRound -label: DecisionMakerAbciApp -start_states: -- CheckBenchmarkingModeRound -- ClaimRound -- DecisionReceiveRound -- HandleFailedTxRound -- RandomnessRound -- RedeemRound -states: -- BenchmarkingDoneRound -- BenchmarkingModeDisabledRound -- BenchmarkingRandomnessRound -- BetPlacementRound -- BlacklistingRound -- CheckBenchmarkingModeRound -- ClaimRound -- DecisionReceiveRound -- DecisionRequestRound -- FinishedDecisionMakerRound -- FinishedDecisionRequestRound -- FinishedSubscriptionRound -- FinishedWithoutDecisionRound -- FinishedWithoutRedeemingRound -- HandleFailedTxRound -- ImpossibleRound -- RandomnessRound -- RedeemRound -- RefillRequiredRound -- SamplingRound -- SubscriptionRound -- ToolSelectionRound -transition_func: - (BenchmarkingRandomnessRound, DONE): SamplingRound - (BenchmarkingRandomnessRound, NO_MAJORITY): BenchmarkingRandomnessRound - (BenchmarkingRandomnessRound, ROUND_TIMEOUT): BenchmarkingRandomnessRound - (BetPlacementRound, DONE): FinishedDecisionMakerRound - (BetPlacementRound, INSUFFICIENT_BALANCE): RefillRequiredRound - (BetPlacementRound, MOCK_TX): RedeemRound - (BetPlacementRound, NONE): ImpossibleRound - (BetPlacementRound, NO_MAJORITY): BetPlacementRound - (BetPlacementRound, ROUND_TIMEOUT): BetPlacementRound - (BlacklistingRound, DONE): FinishedWithoutDecisionRound - (BlacklistingRound, FETCH_ERROR): ImpossibleRound - (BlacklistingRound, MOCK_TX): FinishedWithoutDecisionRound - (BlacklistingRound, NONE): ImpossibleRound - (BlacklistingRound, NO_MAJORITY): BlacklistingRound - (BlacklistingRound, ROUND_TIMEOUT): BlacklistingRound - (CheckBenchmarkingModeRound, BENCHMARKING_DISABLED): BenchmarkingModeDisabledRound - (CheckBenchmarkingModeRound, BENCHMARKING_ENABLED): BenchmarkingRandomnessRound - (CheckBenchmarkingModeRound, DONE): ImpossibleRound - (CheckBenchmarkingModeRound, NO_MAJORITY): CheckBenchmarkingModeRound - (CheckBenchmarkingModeRound, ROUND_TIMEOUT): CheckBenchmarkingModeRound - (CheckBenchmarkingModeRound, SUBSCRIPTION_ERROR): ImpossibleRound - (ClaimRound, DONE): ToolSelectionRound - (ClaimRound, NO_MAJORITY): ClaimRound - (ClaimRound, ROUND_TIMEOUT): ClaimRound - (ClaimRound, SUBSCRIPTION_ERROR): ClaimRound - (DecisionReceiveRound, DONE): BetPlacementRound - (DecisionReceiveRound, MECH_RESPONSE_ERROR): BlacklistingRound - (DecisionReceiveRound, NO_MAJORITY): DecisionReceiveRound - (DecisionReceiveRound, ROUND_TIMEOUT): DecisionReceiveRound - (DecisionReceiveRound, TIE): BlacklistingRound - (DecisionReceiveRound, UNPROFITABLE): BlacklistingRound - (DecisionRequestRound, DONE): FinishedDecisionRequestRound - (DecisionRequestRound, MOCK_MECH_REQUEST): DecisionReceiveRound - (DecisionRequestRound, NO_MAJORITY): DecisionRequestRound - (DecisionRequestRound, ROUND_TIMEOUT): DecisionRequestRound - (DecisionRequestRound, SLOTS_UNSUPPORTED_ERROR): BlacklistingRound - (HandleFailedTxRound, BLACKLIST): BlacklistingRound - (HandleFailedTxRound, NO_MAJORITY): HandleFailedTxRound - (HandleFailedTxRound, NO_OP): RedeemRound - (RandomnessRound, DONE): SamplingRound - (RandomnessRound, NO_MAJORITY): RandomnessRound - (RandomnessRound, ROUND_TIMEOUT): RandomnessRound - (RedeemRound, DONE): FinishedDecisionMakerRound - (RedeemRound, MOCK_TX): SamplingRound - (RedeemRound, NONE): ImpossibleRound - (RedeemRound, NO_MAJORITY): RedeemRound - (RedeemRound, NO_REDEEMING): FinishedWithoutRedeemingRound - (RedeemRound, REDEEM_ROUND_TIMEOUT): FinishedWithoutRedeemingRound - (SamplingRound, BENCHMARKING_ENABLED): ToolSelectionRound - (SamplingRound, BENCHMARKING_FINISHED): BenchmarkingDoneRound - (SamplingRound, DONE): SubscriptionRound - (SamplingRound, FETCH_ERROR): ImpossibleRound - (SamplingRound, NEW_SIMULATED_RESAMPLE): SamplingRound - (SamplingRound, NONE): FinishedWithoutDecisionRound - (SamplingRound, NO_MAJORITY): SamplingRound - (SamplingRound, ROUND_TIMEOUT): SamplingRound - (SubscriptionRound, DONE): FinishedSubscriptionRound - (SubscriptionRound, MOCK_TX): ToolSelectionRound - (SubscriptionRound, NONE): SubscriptionRound - (SubscriptionRound, NO_MAJORITY): SubscriptionRound - (SubscriptionRound, NO_SUBSCRIPTION): ToolSelectionRound - (SubscriptionRound, ROUND_TIMEOUT): SubscriptionRound - (SubscriptionRound, SUBSCRIPTION_ERROR): SubscriptionRound - (ToolSelectionRound, DONE): DecisionRequestRound - (ToolSelectionRound, NONE): ToolSelectionRound - (ToolSelectionRound, NO_MAJORITY): ToolSelectionRound - (ToolSelectionRound, ROUND_TIMEOUT): ToolSelectionRound diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/handlers.py b/trader_backup/vendor/valory/skills/decision_maker_abci/handlers.py deleted file mode 100644 index b0f6ad169..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/handlers.py +++ /dev/null @@ -1,366 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the handler for the 'decision_maker_abci' skill.""" - -import json -import re -from datetime import datetime -from enum import Enum -from typing import Callable, Dict, Optional, Tuple, cast -from urllib.parse import urlparse - -from aea.protocols.base import Message - -from packages.valory.connections.http_server.connection import ( - PUBLIC_ID as HTTP_SERVER_PUBLIC_ID, -) -from packages.valory.protocols.http.message import HttpMessage -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import AbstractResponseHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.decision_maker_abci.dialogues import ( - HttpDialogue, - HttpDialogues, -) -from packages.valory.skills.decision_maker_abci.models import SharedState -from packages.valory.skills.decision_maker_abci.rounds import SynchronizedData - - -ABCIHandler = BaseABCIRoundHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler - - -class IpfsHandler(AbstractResponseHandler): - """IPFS message handler.""" - - SUPPORTED_PROTOCOL = IpfsMessage.protocol_id - allowed_response_performatives = frozenset({IpfsMessage.Performative.IPFS_HASH}) - custom_support_performative = IpfsMessage.Performative.FILES - - @property - def shared_state(self) -> SharedState: - """Get the parameters.""" - return cast(SharedState, self.context.state) - - def handle(self, message: IpfsMessage) -> None: - """ - Implement the reaction to an IPFS message. - - :param message: the message - :return: None - """ - self.context.logger.debug(f"Received message: {message}") - self.shared_state.in_flight_req = False - - if message.performative != self.custom_support_performative: - return super().handle(message) - - dialogue = self.context.ipfs_dialogues.update(message) - nonce = dialogue.dialogue_label.dialogue_reference[0] - callback = self.shared_state.req_to_callback.pop(nonce) - callback(message, dialogue) - - -OK_CODE = 200 -NOT_FOUND_CODE = 404 -BAD_REQUEST_CODE = 400 -AVERAGE_PERIOD_SECONDS = 10 - - -class HttpMethod(Enum): - """Http methods""" - - GET = "get" - HEAD = "head" - POST = "post" - - -class HttpHandler(BaseHttpHandler): - """This implements the echo handler.""" - - SUPPORTED_PROTOCOL = HttpMessage.protocol_id - - def setup(self) -> None: - """Implement the setup.""" - config_uri_base_hostname = urlparse( - self.context.params.service_endpoint - ).hostname - - propel_uri_base_hostname = ( - r"https?:\/\/[a-zA-Z0-9]{16}.agent\.propel\.(staging\.)?autonolas\.tech" - ) - - local_ip_regex = r"192\.168(\.\d{1,3}){2}" - - # Route regexes - hostname_regex = rf".*({config_uri_base_hostname}|{propel_uri_base_hostname}|{local_ip_regex}|localhost|127.0.0.1|0.0.0.0)(:\d+)?" - self.handler_url_regex = rf"{hostname_regex}\/.*" - health_url_regex = rf"{hostname_regex}\/healthcheck" - - # Routes - self.routes = { - (HttpMethod.GET.value, HttpMethod.HEAD.value): [ - (health_url_regex, self._handle_get_health), - ], - } - - self.json_content_header = "Content-Type: application/json\n" - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return SynchronizedData( - db=self.context.state.round_sequence.latest_synchronized_data.db - ) - - def _get_handler(self, url: str, method: str) -> Tuple[Optional[Callable], Dict]: - """Check if an url is meant to be handled in this handler - - We expect url to match the pattern {hostname}/.*, - where hostname is allowed to be localhost, 127.0.0.1 or the service_endpoint's hostname. - - :param url: the url to check - :param method: the method - :returns: the handling method if the message is intended to be handled by this handler, None otherwise, and the regex captures - """ - # Check base url - if not re.match(self.handler_url_regex, url): - self.context.logger.info( - f"The url {url} does not match the DynamicNFT HttpHandler's pattern" - ) - return None, {} - - # Check if there is a route for this request - for methods, routes in self.routes.items(): - if method not in methods: - continue - - for route in routes: - # Routes are tuples like (route_regex, handle_method) - m = re.match(route[0], url) - if m: - return route[1], m.groupdict() - - # No route found - self.context.logger.info( - f"The message [{method}] {url} is intended for the DynamicNFT HttpHandler but did not match any valid pattern" - ) - return self._handle_bad_request, {} - - def handle(self, message: Message) -> None: - """ - Implement the reaction to an envelope. - - :param message: the message - """ - http_msg = cast(HttpMessage, message) - - # Check if this is a request sent from the http_server skill - if ( - http_msg.performative != HttpMessage.Performative.REQUEST - or message.sender != str(HTTP_SERVER_PUBLIC_ID.without_hash()) - ): - super().handle(message) - return - - # Check if this message is for this skill. If not, send to super() - handler, kwargs = self._get_handler(http_msg.url, http_msg.method) - if not handler: - super().handle(message) - return - - # Retrieve dialogues - http_dialogues = cast(HttpDialogues, self.context.http_dialogues) - http_dialogue = cast(HttpDialogue, http_dialogues.update(http_msg)) - - # Invalid message - if http_dialogue is None: - self.context.logger.info( - "Received invalid http message={}, unidentified dialogue.".format( - http_msg - ) - ) - return - - # Handle message - self.context.logger.info( - "Received http request with method={}, url={} and body={!r}".format( - http_msg.method, - http_msg.url, - http_msg.body, - ) - ) - handler(http_msg, http_dialogue, **kwargs) - - def _handle_bad_request( - self, http_msg: HttpMessage, http_dialogue: HttpDialogue - ) -> None: - """ - Handle a Http bad request. - - :param http_msg: the http message - :param http_dialogue: the http dialogue - """ - http_response = http_dialogue.reply( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_msg, - version=http_msg.version, - status_code=BAD_REQUEST_CODE, - status_text="Bad request", - headers=http_msg.headers, - body=b"", - ) - - # Send response - self.context.logger.info("Responding with: {}".format(http_response)) - self.context.outbox.put_message(message=http_response) - - def _handle_get_health( - self, http_msg: HttpMessage, http_dialogue: HttpDialogue - ) -> None: - """ - Handle a Http request of verb GET. - - :param http_msg: the http message - :param http_dialogue: the http dialogue - """ - seconds_since_last_transition = None - is_tm_unhealthy = None - is_transitioning_fast = None - current_round = None - rounds = None - has_required_funds = self._check_required_funds() - is_receiving_mech_responses = self._check_is_receiving_mech_responses() - is_staking_kpi_met = self.synchronized_data.is_staking_kpi_met - staking_status = self.synchronized_data.service_staking_state.name.lower() - - round_sequence = cast(SharedState, self.context.state).round_sequence - - if round_sequence._last_round_transition_timestamp: - is_tm_unhealthy = cast( - SharedState, self.context.state - ).round_sequence.block_stall_deadline_expired - - current_time = datetime.now().timestamp() - seconds_since_last_transition = current_time - datetime.timestamp( - round_sequence._last_round_transition_timestamp - ) - - is_transitioning_fast = ( - not is_tm_unhealthy - and seconds_since_last_transition - < 2 * self.context.params.reset_pause_duration - ) - - if round_sequence._abci_app: - current_round = round_sequence._abci_app.current_round.round_id - rounds = [ - r.round_id for r in round_sequence._abci_app._previous_rounds[-25:] - ] - rounds.append(current_round) - - data = { - "seconds_since_last_transition": seconds_since_last_transition, - "is_tm_healthy": not is_tm_unhealthy, - "period": self.synchronized_data.period_count, - "reset_pause_duration": self.context.params.reset_pause_duration, - "rounds": rounds, - "is_transitioning_fast": is_transitioning_fast, - "agent_health": { - "is_making_on_chain_transactions": is_receiving_mech_responses, - "is_staking_kpi_met": is_staking_kpi_met, - "has_required_funds": has_required_funds, - "staking_status": staking_status, - }, - } - - self._send_ok_response(http_msg, http_dialogue, data) - - def _send_ok_response( - self, http_msg: HttpMessage, http_dialogue: HttpDialogue, data: Dict - ) -> None: - """Send an OK response with the provided data""" - http_response = http_dialogue.reply( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_msg, - version=http_msg.version, - status_code=OK_CODE, - status_text="Success", - headers=f"{self.json_content_header}{http_msg.headers}", - body=json.dumps(data).encode("utf-8"), - ) - - # Send response - self.context.logger.info("Responding with: {}".format(http_response)) - self.context.outbox.put_message(message=http_response) - - def _send_not_found_response( - self, http_msg: HttpMessage, http_dialogue: HttpDialogue - ) -> None: - """Send an not found response""" - http_response = http_dialogue.reply( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_msg, - version=http_msg.version, - status_code=NOT_FOUND_CODE, - status_text="Not found", - headers=http_msg.headers, - body=b"", - ) - # Send response - self.context.logger.info("Responding with: {}".format(http_response)) - self.context.outbox.put_message(message=http_response) - - def _check_required_funds(self) -> bool: - """Check the agent has enough funds.""" - return ( - self.synchronized_data.wallet_balance - > self.context.params.agent_balance_threshold - ) - - def _check_is_receiving_mech_responses(self) -> bool: - """Check the agent is making on chain transactions.""" - # Checks the most recent decision receive timestamp, which can only be returned after making a mech call - # (an on chain transaction) - return ( - self.synchronized_data.decision_receive_timestamp - < int(datetime.utcnow().timestamp()) - - self.context.params.expected_mech_response_time - ) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/io_/__init__.py b/trader_backup/vendor/valory/skills/decision_maker_abci/io_/__init__.py deleted file mode 100644 index fd05584d0..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/io_/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- 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 helper classes for IPFS interaction.""" diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/io_/loader.py b/trader_backup/vendor/valory/skills/decision_maker_abci/io_/loader.py deleted file mode 100644 index ebb501cb4..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/io_/loader.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- 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 helper classes for IPFS interaction.""" -from typing import Dict - -import yaml - -from packages.valory.skills.abstract_round_abci.io_.store import SupportedObjectType - - -class ComponentPackageLoader: - """Component package loader.""" - - @staticmethod - def load(serialized_objects: Dict[str, str]) -> SupportedObjectType: - """ - Load a custom component package. - - :param serialized_objects: the serialized objects. - :return: the component.yaml, entry_point.py and callable as tuple. - """ - # the package MUST contain a component.yaml file - if "component.yaml" not in serialized_objects: - raise ValueError( - "Invalid component package. " - "The package MUST contain a component.yaml." - ) - - # load the component.yaml file - component_yaml = yaml.safe_load(serialized_objects["component.yaml"]) - if "entry_point" not in component_yaml or "callable" not in component_yaml: - raise ValueError( - "Invalid component package. " - "The component.yaml file MUST contain the 'entry_point' and 'callable' keys." - ) - - # the name of the script that needs to be executed - entry_point_name = component_yaml["entry_point"] - - # load the script - if entry_point_name not in serialized_objects: - raise ValueError( - f"Invalid component package. " - f"{entry_point_name} is not present in the component package." - ) - entry_point = serialized_objects[entry_point_name] - - # the method that needs to be called - callable_method = component_yaml["callable"] - - return component_yaml, entry_point, callable_method diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/models.py b/trader_backup/vendor/valory/skills/decision_maker_abci/models.py deleted file mode 100644 index e6cb54666..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/models.py +++ /dev/null @@ -1,623 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the models for the skill.""" - -import os -import re -import time -from dataclasses import dataclass, field -from datetime import datetime, timedelta -from pathlib import Path -from string import Template -from typing import ( - Any, - Callable, - Dict, - Iterable, - List, - Optional, - Set, - Tuple, - Type, - Union, -) - -from aea.skills.base import Model, SkillContext -from hexbytes import HexBytes -from web3.constants import HASH_ZERO -from web3.types import BlockIdentifier - -from packages.valory.contracts.multisend.contract import MultiSendOperation -from packages.valory.skills.abstract_round_abci.base import AbciApp -from packages.valory.skills.abstract_round_abci.models import ApiSpecs -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.abstract_round_abci.models import TypeCheckMixin -from packages.valory.skills.decision_maker_abci.policy import EGreedyPolicy -from packages.valory.skills.decision_maker_abci.redeem_info import Trade -from packages.valory.skills.decision_maker_abci.rounds import DecisionMakerAbciApp -from packages.valory.skills.market_manager_abci.bets import Bet -from packages.valory.skills.market_manager_abci.models import ( - MarketManagerParams, - Subgraph, -) -from packages.valory.skills.mech_interact_abci.models import ( - Params as MechInteractParams, -) - - -FromBlockMappingType = Dict[HexBytes, Union[int, str]] -ClaimParamsType = Tuple[List[bytes], List[str], List[int], List[bytes]] - - -RE_CONTENT_IN_BRACKETS = r"\{([^}]*)\}" -REQUIRED_BET_TEMPLATE_KEYS = {"yes", "no", "question"} -DEFAULT_FROM_BLOCK = "earliest" -ZERO_HEX = HASH_ZERO[2:] -ZERO_BYTES = bytes.fromhex(ZERO_HEX) -STRATEGY_KELLY_CRITERION = "kelly_criterion" -L0_START_FIELD = "l0_start" -L1_START_FIELD = "l1_start" -L0_END_FIELD = "l0_end" -L1_END_FIELD = "l1_end" -YES = "yes" -NO = "no" - - -class PromptTemplate(Template): - """A prompt template.""" - - delimiter = "@" - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -@dataclass -class LiquidityInfo: - """The structure to have liquidity information before and after a bet is done""" - - # Liquidity of tokens for option 0, before placing the bet - l0_start: Optional[int] = None - # Liquidity of tokens for option 1, before placing the bet - l1_start: Optional[int] = None - # Liquidity of tokens for option 0, after placing the bet - l0_end: Optional[int] = None - # Liquidity of tokens for option 1, after placing the bet - l1_end: Optional[int] = None - - def validate_start_information(self) -> Tuple[int, int]: - """Check if the start liquidity information is complete, otherwise raise an error.""" - if self.l0_start is None or self.l1_start is None: - raise ValueError("The liquidity information is incomplete!") - # return the values for type checking purposes (`mypy` would complain that they might be `None` otherwise) - return self.l0_start, self.l1_start - - def validate_end_information(self) -> Tuple[int, int]: - """Check if the end liquidity information is complete, otherwise raise an error.""" - if self.l0_end is None or self.l1_end is None: - raise ValueError("The liquidity information is incomplete!") - # return the values for type checking purposes (`mypy` would complain that they might be `None` otherwise) - return self.l0_end, self.l1_end - - def get_new_prices(self, liquidity_constants: List[float]) -> List[float]: - """Calculate and return the new prices based on the end liquidity and the liquidity constants of the market.""" - l0_end, l1_end = self.validate_end_information() - new_p0 = liquidity_constants[0] / l0_end - new_p1 = liquidity_constants[1] / l1_end - return [new_p0, new_p1] - - def get_end_liquidity(self) -> List[int]: - """Return the end liquidity.""" - l0_end, l1_end = self.validate_end_information() - return [l0_end, l1_end] - - -@dataclass -class RedeemingProgress: - """A structure to keep track of the redeeming check progress.""" - - trades: Set[Trade] = field(default_factory=set) - utilized_tools: Dict[str, str] = field(default_factory=dict) - policy: Optional[EGreedyPolicy] = None - claimable_amounts: Dict[HexBytes, int] = field(default_factory=dict) - earliest_block_number: int = 0 - event_filtering_batch_size: int = 0 - check_started: bool = False - check_from_block: BlockIdentifier = "earliest" - check_to_block: BlockIdentifier = "latest" - cleaned: bool = False - payouts: Dict[str, int] = field(default_factory=dict) - unredeemed_trades: Dict[str, int] = field(default_factory=dict) - claim_started: bool = False - claim_from_block: BlockIdentifier = "earliest" - claim_to_block: BlockIdentifier = "latest" - answered: list = field(default_factory=list) - claiming_condition_ids: List[str] = field(default_factory=list) - claimed_condition_ids: List[str] = field(default_factory=list) - - @property - def check_finished(self) -> bool: - """Whether the check has finished.""" - return self.check_started and self.check_from_block == self.check_to_block - - @property - def claim_finished(self) -> bool: - """Whether the claiming has finished.""" - return self.claim_started and self.claim_from_block == self.claim_to_block - - @property - def claim_params(self) -> Optional[ClaimParamsType]: - """The claim parameters, prepared for the `claimWinnings` call.""" - history_hashes = [] - addresses = [] - bonds = [] - answers = [] - try: - for i, answer in enumerate(reversed(self.answered)): - # history_hashes second-last-to-first, the hash of each history entry, calculated as described here: - # https://realitio.github.io/docs/html/contract_explanation.html#answer-history-entries. - if i == len(self.answered) - 1: - history_hashes.append(ZERO_BYTES) - else: - history_hashes.append(self.answered[i + 1]["args"]["history_hash"]) - - # last-to-first, the address of each answerer or commitment sender - addresses.append(answer["args"]["user"]) - # last-to-first, the bond supplied with each answer or commitment - bonds.append(answer["args"]["bond"]) - # last-to-first, each answer supplied, or commitment ID if the answer was supplied with commit->reveal - answers.append(answer["args"]["answer"]) - except KeyError: - return None - - return history_hashes, addresses, bonds, answers - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls: Type[AbciApp] = DecisionMakerAbciApp - - def __init__(self, *args: Any, skill_context: SkillContext, **kwargs: Any) -> None: - """Initialize the state.""" - super().__init__(*args, skill_context=skill_context, **kwargs) - self.redeeming_progress: RedeemingProgress = RedeemingProgress() - self.strategy_to_filehash: Dict[str, str] = {} - self.strategies_executables: Dict[str, Tuple[str, str]] = {} - self.in_flight_req: bool = False - self.req_to_callback: Dict[str, Callable] = {} - self.mock_data: Optional[BenchmarkingMockData] = None - # a mapping from market id to scaled liquidity measure - # also used for the benchmarking mode - self.liquidity_cache: Dict[str, float] = {} - # list with the simulated timestamps for the benchmarking mode - self.simulated_days: List[int] = [] - self.simulated_days_idx: int = 0 - # latest liquidity information (only relevant to the benchmarking mode) - self.liquidity_amounts: Dict[str, List[int]] = {} - self.liquidity_prices: Dict[str, List[float]] = {} - # whether this is the last run of the benchmarking mode - self.last_benchmarking_has_run: bool = False - - # the mapping from bet id to the row number in the dataset - # the key is the market id/question_id - self.bet_id_row_manager: Dict[str, List[int]] = {} - - ## mech call counter for benchmarking behaviour - self.benchmarking_mech_calls: int = 0 - - @property - def mock_question_id(self) -> Any: - """Get the mock question id.""" - mock_data = self.mock_data - if mock_data is None: - raise ValueError("The mock data have not been set!") - return mock_data.id - - def _get_liquidity_info( - self, liquidity_data: Union[Dict[str, List[int]], Dict[str, List[float]]] - ) -> Any: - """Get the current liquidity information from the given data.""" - _id = self.mock_question_id - if _id not in liquidity_data: - raise ValueError( - f"There are no liquidity information for benchmarking mock data with question id {_id!r}." - ) - return liquidity_data[_id] - - @property - def current_liquidity_prices(self) -> List[float]: - """Return the current liquidity prices.""" - return self._get_liquidity_info(self.liquidity_prices) - - @current_liquidity_prices.setter - def current_liquidity_prices(self, value: List[float]) -> None: - """Set the current liquidity prices.""" - self.liquidity_prices[self.mock_question_id] = value - - @property - def current_liquidity_amounts(self) -> List[int]: - """Return the current liquidity amounts.""" - return self._get_liquidity_info(self.liquidity_amounts) - - @current_liquidity_amounts.setter - def current_liquidity_amounts(self, value: List[int]) -> None: - """Set the current liquidity amounts.""" - self.liquidity_amounts[self.mock_question_id] = value - - def _initialize_simulated_now_timestamps( - self, bets: List[Bet], safe_voting_range: int - ) -> None: - """Creates the list of simulated days for the benchmarking mode""" - self.simulated_days_idx = 0 - # Find the maximum timestamp from openingTimestamp field - max_timestamp = max(bet.openingTimestamp for bet in bets) - # adding some time range to allow voting - # in the sampling round the within_safe condition is designed to check - # the openingtimestamp of the market strickly less than the safe voting range - # so we need to create a timestamp that passes this condition for the max openingtimestamp - max_timestamp = max_timestamp - safe_voting_range - 1 - - # Get current timestamp - now_timestamp = int(time.time()) - # Convert timestamps to datetime objects - max_date = datetime.fromtimestamp(max_timestamp) - current_date = datetime.fromtimestamp(now_timestamp) - self.context.logger.info( - f"Simulating timestamps between {current_date} and {max_date}" - ) - # Generate list of timestamps with one day intervals - timestamps = [] - while current_date <= max_date: - timestamps.append(int(current_date.timestamp())) - current_date += timedelta(days=1) - self.context.logger.info(f"Simulated timestamps: {timestamps}") - self.simulated_days = timestamps - - def increase_one_day_simulation(self) -> None: - """Increased the index used for the current simulated day.""" - self.simulated_days_idx += 1 - - def check_benchmarking_finished(self) -> bool: - """Checks if we simulated already all days.""" - return self.simulated_days_idx >= len(self.simulated_days) - - def get_simulated_now_timestamp( - self, bets: List[Bet], safe_voting_range: int - ) -> int: - """Gets the current simulated day timestamp.""" - if len(self.simulated_days) == 0: - self._initialize_simulated_now_timestamps(bets, safe_voting_range) - - return self.simulated_days[self.simulated_days_idx] - - def setup(self) -> None: - """Set up the model.""" - super().setup() - params = self.context.params - self.redeeming_progress.event_filtering_batch_size = ( - params.event_filtering_batch_size - ) - self.strategy_to_filehash = { - value: key - for key, values in params.file_hash_to_strategies.items() - for value in values - } - selected_strategy = params.trading_strategy - strategy_exec = self.strategy_to_filehash.keys() - if selected_strategy not in strategy_exec: - raise ValueError( - f"The selected trading strategy {selected_strategy} " - f"is not in the strategies' executables {strategy_exec}." - ) - - -def extract_keys_from_template(delimiter: str, template: str) -> Set[str]: - """Extract the keys from a string template, given the delimiter.""" - # matches the placeholders of the template's keys - pattern = re.escape(delimiter) + RE_CONTENT_IN_BRACKETS - keys = re.findall(pattern, template) - return set(keys) - - -def check_prompt_template(bet_prompt_template: PromptTemplate) -> None: - """Check if the keys required for a bet are given in the provided prompt's template.""" - delimiter = bet_prompt_template.delimiter - template_keys = extract_keys_from_template(delimiter, bet_prompt_template.template) - if template_keys != REQUIRED_BET_TEMPLATE_KEYS: - example_key = (REQUIRED_BET_TEMPLATE_KEYS - template_keys).pop() - n_found = len(template_keys) - found = "no keys" if n_found == 0 else f"keys {template_keys}" - raise ValueError( - f"The bet's template should contain exclusively the following keys: {REQUIRED_BET_TEMPLATE_KEYS}.\n" - f"Found {found} instead in the given template:\n{bet_prompt_template.template!r}\n" - f"Please make sure that you are using the right delimiter {delimiter!r} for the prompt's template.\n" - f"For example, to parametrize {example_key!r} you may use " - f"'{delimiter}{{{example_key}}}'" - ) - - -def _raise_incorrect_config(key: str, values: Any) -> None: - """Raise a `ValueError` for incorrect configuration of a nested_list workaround.""" - raise ValueError( - f"The given configuration for {key!r} is incorrectly formatted: {values}!" - "The value is expected to be a list of lists that can be represented as a dictionary." - ) - - -def nested_list_todict_workaround( - kwargs: Dict, - key: str, -) -> Dict: - """Get a nested list from the kwargs and convert it to a dictionary.""" - values = list(kwargs.get(key, [])) - if len(values) == 0: - raise ValueError(f"No {key!r} specified in agent's configurations: {kwargs}!") - if any(not issubclass(type(nested_values), Iterable) for nested_values in values): - _raise_incorrect_config(key, values) - if any(len(nested_values) % 2 == 1 for nested_values in values): - _raise_incorrect_config(key, values) - return {value[0]: value[1] for value in values} - - -class DecisionMakerParams(MarketManagerParams, MechInteractParams): - """Decision maker's parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the parameters' object.""" - # the number of days to sample bets from - self.sample_bets_closing_days: int = self._ensure( - "sample_bets_closing_days", kwargs, int - ) - if self.sample_bets_closing_days <= 0: - msg = "The number of days to sample bets from must be positive!" - raise ValueError(msg) - - # the trading strategy to use for placing bets - self.trading_strategy: str = self._ensure("trading_strategy", kwargs, str) - self.use_fallback_strategy: bool = self._ensure( - "use_fallback_strategy", kwargs, bool - ) - self.tools_accuracy_hash: str = self._ensure("tools_accuracy_hash", kwargs, str) - # the threshold amount in WEI starting from which we are willing to place a bet - self.bet_threshold: int = self._ensure("bet_threshold", kwargs, int) - self._prompt_template: str = self._ensure("prompt_template", kwargs, str) - check_prompt_template(self.prompt_template) - self.dust_threshold: int = self._ensure("dust_threshold", kwargs, int) - self.conditional_tokens_address: str = self._ensure( - "conditional_tokens_address", kwargs, str - ) - self.realitio_proxy_address: str = self._ensure( - "realitio_proxy_address", kwargs, str - ) - self.realitio_address: str = self._ensure("realitio_address", kwargs, str) - # this is the maximum batch size that will be used when filtering blocks for events. - # increasing this number allows for faster filtering operations, - # but also increases the chances of getting a timeout error from the RPC - self.event_filtering_batch_size: int = self._ensure( - "event_filtering_batch_size", kwargs, int - ) - self.reduce_factor: float = self._ensure("reduce_factor", kwargs, float) - # the minimum batch size for redeeming operations, this is added to avoid the batch size to be too small - self.minimum_batch_size: int = self._ensure("minimum_batch_size", kwargs, int) - self.max_filtering_retries: int = self._ensure( - "max_filtering_retries", kwargs, int - ) - # this is the max number of redeeming operations that will be batched on a single multisend transaction. - # increasing this number equals fewer fees but more chances for the transaction to fail - self.redeeming_batch_size: int = self._ensure( - "redeeming_batch_size", kwargs, int - ) - self.redeem_round_timeout: float = self._ensure( - "redeem_round_timeout", kwargs, float - ) - # a slippage in the range of [0, 1] to apply to the `minOutcomeTokensToBuy` when buying shares on a fpmm - self._slippage: float = 0.0 - self.slippage: float = self._ensure("slippage", kwargs, float) - self.epsilon: float = self._ensure("policy_epsilon", kwargs, float) - self.agent_registry_address: str = self._ensure( - "agent_registry_address", kwargs, str - ) - self.store_path: Path = self.get_store_path(kwargs) - self.irrelevant_tools: set = set(self._ensure("irrelevant_tools", kwargs, list)) - self.tool_punishment_multiplier: int = self._ensure( - "tool_punishment_multiplier", kwargs, int - ) - self.contract_timeout: float = self._ensure("contract_timeout", kwargs, float) - self.file_hash_to_strategies: Dict[ - str, List[str] - ] = nested_list_todict_workaround( - kwargs, - "file_hash_to_strategies_json", - ) - self.strategies_kwargs: Dict[str, List[Any]] = nested_list_todict_workaround( - kwargs, "strategies_kwargs" - ) - self.use_subgraph_for_redeeming = self._ensure( - "use_subgraph_for_redeeming", - kwargs, - bool, - ) - self.use_nevermined = self._ensure("use_nevermined", kwargs, bool) - self.rpc_sleep_time: int = self._ensure("rpc_sleep_time", kwargs, int) - self.mech_to_subscription_params: Dict[ - str, Any - ] = nested_list_todict_workaround( - kwargs, - "mech_to_subscription_params", - ) - self.service_endpoint = self._ensure("service_endpoint", kwargs, str) - self.safe_voting_range = self._ensure("safe_voting_range", kwargs, int) - self.rebet_chance = self._ensure("rebet_chance", kwargs, float) - self.policy_store_update_offset = self._ensure( - "policy_store_update_offset", kwargs, int - ) - self.expected_mech_response_time = self._ensure( - "expected_mech_response_time", kwargs, int - ) - self.mech_invalid_response: str = self._ensure( - "mech_invalid_response", kwargs, str - ) - self.policy_threshold: int = self._ensure( - "mech_consecutive_failures_threshold", kwargs, int - ) - self.tool_quarantine_duration: int = self._ensure( - "tool_quarantine_duration", kwargs, int - ) - super().__init__(*args, **kwargs) - - @property - def using_kelly(self) -> bool: - """Get the max bet amount if the `bet_amount_per_conf_threshold` strategy is used.""" - return self.trading_strategy == STRATEGY_KELLY_CRITERION - - @property - def prompt_template(self) -> PromptTemplate: - """Get the prompt template as a string `PromptTemplate`.""" - return PromptTemplate(self._prompt_template) - - @property - def slippage(self) -> float: - """Get the slippage.""" - return self._slippage - - @slippage.setter - def slippage(self, slippage: float) -> None: - """Set the slippage.""" - if slippage < 0 or slippage > 1: - raise ValueError( - f"The configured slippage {slippage!r} is not in the range [0, 1]." - ) - self._slippage = slippage - - def get_store_path(self, kwargs: Dict) -> Path: - """Get the path of the store.""" - path = self._ensure("store_path", kwargs, str) - # check if path exists, and we can write to it - if ( - not os.path.isdir(path) - or not os.access(path, os.W_OK) - or not os.access(path, os.R_OK) - ): - raise ValueError( - f"Policy store path {path!r} is not a directory or is not writable." - ) - return Path(path) - - -class BenchmarkingMode(Model, TypeCheckMixin): - """Configuration for the benchmarking mode.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the `BenchmarkingMode` object.""" - self.enabled: bool = self._ensure("enabled", kwargs, bool) - self.native_balance: int = self._ensure("native_balance", kwargs, int) - self.collateral_balance: int = self._ensure("collateral_balance", kwargs, int) - self.mech_cost: int = self._ensure("mech_cost", kwargs, int) - self.pool_fee: int = self._ensure("pool_fee", kwargs, int) - self.sep: str = self._ensure("sep", kwargs, str) - self.dataset_filename: Path = Path( - self._ensure("dataset_filename", kwargs, str) - ) - self.question_field: str = self._ensure("question_field", kwargs, str) - self.question_id_field: str = self._ensure("question_id_field", kwargs, str) - self.answer_field: str = self._ensure("answer_field", kwargs, str) - self.p_yes_field_part: str = self._ensure("p_yes_field_part", kwargs, str) - self.p_no_field_part: str = self._ensure("p_no_field_part", kwargs, str) - self.confidence_field_part: str = self._ensure( - "confidence_field_part", kwargs, str - ) - # this is the mode for the p and confidence parts - # if the flag is `True`, then the field parts are used as prefixes, otherwise as suffixes - self.part_prefix_mode: bool = self._ensure("part_prefix_mode", kwargs, bool) - self.bet_amount_field: str = self._ensure("bet_amount_field", kwargs, str) - self.results_filename: Path = Path( - self._ensure("results_filename", kwargs, str) - ) - self.randomness: str = self._ensure("randomness", kwargs, str) - self.nr_mech_calls: int = self._ensure("nr_mech_calls", kwargs, int) - super().__init__(*args, **kwargs) - - -class AccuracyInfoFields(Model, TypeCheckMixin): - """Configuration which holds the accuracy information file's fieldnames.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the `AccuracyInfoFields` object.""" - self.tool: str = self._ensure("tool", kwargs, str) - self.requests: str = self._ensure("requests", kwargs, str) - self.accuracy: str = self._ensure("accuracy", kwargs, str) - self.sep: str = self._ensure("sep", kwargs, str) - self.max: str = self._ensure("max", kwargs, str) - self.datetime_format: str = self._ensure("datetime_format", kwargs, str) - super().__init__(*args, **kwargs) - - -class AgentToolsSpecs(ApiSpecs): - """A model that wraps ApiSpecs for the Mech agent's tools specifications.""" - - -@dataclass -class MultisendBatch: - """A structure representing a single transaction of a multisend.""" - - to: str - data: HexBytes - value: int = 0 - operation: MultiSendOperation = MultiSendOperation.CALL - - -@dataclass -class BenchmarkingMockData: - """The mock data for a `BenchmarkingMode`.""" - - id: str - question: str - answer: str - p_yes: float - - @property - def is_winning(self) -> bool: - """Whether the current position is winning.""" - return ( - self.answer == YES - and self.p_yes > 0.5 - or self.answer == NO - and self.p_yes < 0.5 - ) - - -class TradesSubgraph(Subgraph): - """A model that wraps ApiSpecs for the OMEN's subgraph specifications for trades.""" - - -class ConditionalTokensSubgraph(Subgraph): - """A model that wraps ApiSpecs for the Conditional Tokens' subgraph specifications.""" - - -class RealitioSubgraph(Subgraph): - """A model that wraps ApiSpecs for the Realitio's subgraph specifications.""" diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/payloads.py b/trader_backup/vendor/valory/skills/decision_maker_abci/payloads.py deleted file mode 100644 index b15c02b01..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/payloads.py +++ /dev/null @@ -1,129 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the transaction payloads for the decision maker.""" - -from dataclasses import dataclass -from typing import Optional - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload - - -@dataclass(frozen=True) -class DecisionReceivePayload(UpdateBetsPayload): - """Represents a transaction payload for the decision-making.""" - - is_profitable: Optional[bool] - vote: Optional[int] - confidence: Optional[float] - bet_amount: Optional[int] - next_mock_data_row: Optional[int] - policy: Optional[str] - decision_received_timestamp: Optional[int] - - -@dataclass(frozen=True) -class SamplingPayload(UpdateBetsPayload): - """Represents a transaction payload for the sampling of a bet.""" - - index: Optional[int] - benchmarking_finished: Optional[bool] - day_increased: Optional[bool] - - -@dataclass(frozen=True) -class MultisigTxPayload(BaseTxPayload): - """Represents a transaction payload for preparing an on-chain transaction to be sent via the agents' multisig.""" - - tx_submitter: Optional[str] = None - tx_hash: Optional[str] = None - mocking_mode: Optional[bool] = None - - -@dataclass(frozen=True) -class RedeemPayload(MultisigTxPayload): - """Represents a transaction payload for preparing an on-chain transaction for redeeming.""" - - mech_tools: str = "[]" - policy: Optional[str] = None - utilized_tools: Optional[str] = None - redeemed_condition_ids: Optional[str] = None - payout_so_far: Optional[int] = None - - -@dataclass(frozen=True) -class DecisionRequestPayload(BaseTxPayload): - """Represents a transaction payload for preparing mech requests.""" - - mech_requests: Optional[str] = None - mocking_mode: Optional[bool] = None - - -@dataclass(frozen=True) -class SubscriptionPayload(MultisigTxPayload): - """Represents a transaction payload for subscribing.""" - - agreement_id: str = "" - wallet_balance: Optional[int] = None - - -@dataclass(frozen=True) -class ClaimPayload(BaseTxPayload): - """Represents a transaction payload for claiming a subscription.""" - - vote: bool - - -@dataclass(frozen=True) -class VotingPayload(BaseTxPayload): - """Represents a transaction payload for voting.""" - - vote: bool - - -@dataclass(frozen=True) -class BlacklistingPayload(UpdateBetsPayload): - """Represents a transaction payload for blacklisting.""" - - policy: str - - -@dataclass(frozen=True) -class ToolSelectionPayload(BaseTxPayload): - """Represents a transaction payload for selecting a mech tool.""" - - mech_tools: Optional[str] - policy: Optional[str] - utilized_tools: Optional[str] - selected_tool: Optional[str] - - -@dataclass(frozen=True) -class BetPlacementPayload(MultisigTxPayload): - """Represents a transaction payload for placing a bet.""" - - wallet_balance: Optional[int] = None - - -@dataclass(frozen=True) -class HandleFailedTxPayload(VotingPayload): - """Represents a transaction payload for placing a bet.""" - - tx_submitter: str diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/policy.py b/trader_backup/vendor/valory/skills/decision_maker_abci/policy.py deleted file mode 100644 index 667526279..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/policy.py +++ /dev/null @@ -1,291 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 an Epsilon Greedy Policy implementation.""" - -import json -import random -from dataclasses import asdict, dataclass, field, is_dataclass -from time import time -from typing import Any, Dict, List, Optional, Tuple, Union - -from packages.valory.skills.decision_maker_abci.utils.scaling import scale_value - - -RandomnessType = Union[int, float, str, bytes, bytearray, None] - -VOLUME_FACTOR_REGULARIZATION = 0.5 -UNSCALED_WEIGHTED_ACCURACY_INTERVAL = (-0.5, 100.5) -SCALED_WEIGHTED_ACCURACY_INTERVAL = (0, 1) - - -class DataclassEncoder(json.JSONEncoder): - """A custom JSON encoder for dataclasses.""" - - def default(self, o: Any) -> Any: - """The default JSON encoder.""" - if is_dataclass(o): - return asdict(o) - return super().default(o) - - -def argmax(li: Union[Tuple, List]) -> int: - """Get the index of the max value within the provided tuple or list.""" - return li.index((max(li))) - - -@dataclass -class AccuracyInfo: - """The accuracy information of a tool.""" - - # the number of requests that this tool has responded to - requests: int = 0 - # the number of pending evaluations, i.e., responses for which we have not redeemed yet - pending: int = 0 - # the accuracy of the tool - accuracy: float = 0.0 - - -@dataclass -class ConsecutiveFailures: - """The consecutive failures of a tool.""" - - n_failures: int = 0 - timestamp: int = 0 - - def increase(self, timestamp: int) -> None: - """Increase the number of consecutive failures.""" - self.n_failures += 1 - self.timestamp = timestamp - - def reset(self, timestamp: int) -> None: - """Reset the number of consecutive failures.""" - self.n_failures = 0 - self.timestamp = timestamp - - def update_status(self, timestamp: int, has_failed: bool) -> None: - """Update the number of consecutive failures.""" - if has_failed: - self.increase(timestamp) - else: - self.reset(timestamp) - - -class EGreedyPolicyDecoder(json.JSONDecoder): - """A custom JSON decoder for the e greedy policy.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the custom JSON decoder.""" - super().__init__(object_hook=self.hook, *args, **kwargs) - - @staticmethod - def hook( - data: Dict[str, Any], - ) -> Union[ - "EGreedyPolicy", - AccuracyInfo, - ConsecutiveFailures, - Dict[str, "EGreedyPolicy"], - Dict[str, ConsecutiveFailures], - ]: - """Perform the custom decoding.""" - for cls_ in (AccuracyInfo, ConsecutiveFailures, EGreedyPolicy): - cls_attributes = cls_.__annotations__.keys() # pylint: disable=no-member - if sorted(cls_attributes) == sorted(data.keys()): - # if the attributes match the ones of the current class, use it to perform the deserialization - return cls_(**data) - - return data - - -@dataclass -class EGreedyPolicy: - """An e-Greedy policy for the tool selection based on tool accuracy.""" - - eps: float - consecutive_failures_threshold: int - quarantine_duration: int - accuracy_store: Dict[str, AccuracyInfo] = field(default_factory=dict) - weighted_accuracy: Dict[str, float] = field(default_factory=dict) - consecutive_failures: Dict[str, ConsecutiveFailures] = field(default_factory=dict) - updated_ts: int = 0 - - def __post_init__(self) -> None: - """Perform post-initialization checks.""" - if not (0 <= self.eps <= 1): - error = f"Cannot initialize the policy with an epsilon value of {self.eps}. Must be between 0 and 1." - raise ValueError(error) - self.update_weighted_accuracy() - - @classmethod - def deserialize(cls, policy: str) -> "EGreedyPolicy": - """Deserialize a string to an `EGreedyPolicy` object.""" - return json.loads(policy, cls=EGreedyPolicyDecoder) - - @property - def tools(self) -> List[str]: - """Get the policy's tools.""" - return list(self.accuracy_store.keys()) - - @property - def n_tools(self) -> int: - """Get the number of the policy's tools.""" - return len(self.accuracy_store) - - @property - def n_requests(self) -> int: - """Get the total number of requests.""" - return sum( - acc_info.requests + acc_info.pending - for acc_info in self.accuracy_store.values() - ) - - @property - def has_updated(self) -> bool: - """Whether the policy has ever been updated since its genesis or not.""" - return self.n_requests > 0 - - @property - def random_tool(self) -> str: - """Get the name of a tool randomly.""" - return random.choice(list(self.accuracy_store.keys())) # nosec - - def is_quarantined(self, tool: str) -> bool: - """Check if the policy is valid.""" - if tool not in self.consecutive_failures: - return False - - failures = self.consecutive_failures[tool] - return ( - failures.n_failures > self.consecutive_failures_threshold - and failures.timestamp + self.quarantine_duration > int(time()) - ) - - @property - def valid_tools(self) -> List[str]: - """Get the policy's tools.""" - return list( - tool for tool in self.accuracy_store.keys() if not self.is_quarantined(tool) - ) - - @property - def valid_weighted_accuracy(self) -> Dict[str, float]: - """Get the valid weighted accuracy.""" - if not self.weighted_accuracy: - # Log or raise an error if no tools are present - raise ValueError( - "Weighted accuracy is empty. Ensure tools are initialized." - ) - return { - tool: acc - for tool, acc in self.weighted_accuracy.items() - if not self.is_quarantined(tool) - } - - @property - def best_tool(self) -> Optional[str]: - """Get the best non-quarantined tool, or fallback gracefully.""" - # Get valid weighted accuracies - valid_weighted_accuracy = self.valid_weighted_accuracy - if valid_weighted_accuracy: - valid_tools, valid_weighted_accuracies = zip( - *valid_weighted_accuracy.items() - ) - else: - # Fallback to all tools if no valid tools are available - valid_tools, valid_weighted_accuracies = zip( - *self.weighted_accuracy.items() - ) - - # Determine the best tool based on weighted accuracies - best_index = argmax(valid_weighted_accuracies) - return valid_tools[best_index] - - def update_weighted_accuracy(self) -> None: - """Update the weighted accuracy for each tool.""" - self.weighted_accuracy = { - tool: scale_value( - ( - acc_info.accuracy - + ((acc_info.requests - acc_info.pending) / self.n_requests) - * VOLUME_FACTOR_REGULARIZATION - ), - UNSCALED_WEIGHTED_ACCURACY_INTERVAL, - SCALED_WEIGHTED_ACCURACY_INTERVAL, - ) - for tool, acc_info in self.accuracy_store.items() - } - - def select_tool(self, randomness: RandomnessType = None) -> Optional[str]: - """Select a Mech tool and return its index.""" - if self.n_tools == 0: - print(f"No tools to select. accuracy store ={self.accuracy_store}") - return None - - if randomness is not None: - random.seed(randomness) - - if not self.has_updated or random.random() < self.eps: # nosec - return self.random_tool - - return self.best_tool - - def tool_used(self, tool: str) -> None: - """Increase the times used for the given tool.""" - self.accuracy_store[tool].pending += 1 - self.update_weighted_accuracy() - - def tool_responded(self, tool: str, timestamp: int, failed: bool = True) -> None: - """Update the policy based on the given tool's response.""" - if tool not in self.consecutive_failures: - self.consecutive_failures[tool] = ConsecutiveFailures() - self.consecutive_failures[tool].update_status(timestamp, failed) - - def update_accuracy_store(self, tool: str, winning: bool) -> None: - """Update the accuracy store for the given tool.""" - acc_info = self.accuracy_store[tool] - total_correct_answers = acc_info.accuracy * acc_info.requests - if winning: - total_correct_answers += 1 - - acc_info.requests += 1 - acc_info.pending -= 1 - acc_info.accuracy = total_correct_answers / acc_info.requests - self.update_weighted_accuracy() - - def serialize(self) -> str: - """Return the accuracy policy serialized.""" - return json.dumps(self, cls=DataclassEncoder, sort_keys=True) - - def stats_report(self) -> str: - """Report policy statistics.""" - if not self.has_updated: - return "No policy statistics available." - - report = "Policy statistics so far (only for resolved markets):\n" - stats = ( - f"\t{tool} tool:\n" - f"\t\tQuarantined: {self.is_quarantined(tool)}\n" - f"\t\tTimes used: {self.accuracy_store[tool].requests}\n" - f"\t\tWeighted Accuracy: {self.weighted_accuracy[tool]}" - for tool in self.tools - ) - report += "\n".join(stats) - report += f"\nBest non-quarantined tool so far is {self.best_tool!r}." - return report diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/redeem_info.py b/trader_backup/vendor/valory/skills/decision_maker_abci/redeem_info.py deleted file mode 100644 index 175103c75..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/redeem_info.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - - -"""Structures for the redeeming.""" - -import dataclasses -from typing import Any, List - -from hexbytes import HexBytes - - -INVALID_MARKET_ANSWER = ( - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -) - - -@dataclasses.dataclass(frozen=True) -class Condition: - """A structure for an OMEN condition.""" - - id: HexBytes - outcomeSlotCount: int - - def __post_init__(self) -> None: - """Post initialization to adjust the values.""" - super().__setattr__("outcomeSlotCount", int(self.outcomeSlotCount)) - - if isinstance(self.id, str): - super().__setattr__("id", HexBytes(self.id)) - - @property - def index_sets(self) -> List[int]: - """Get the index sets.""" - return [i + 1 for i in range(self.outcomeSlotCount)] - - -@dataclasses.dataclass(frozen=True) -class Question: - """A structure for an OMEN question.""" - - id: bytes - data: str - - def __post_init__(self) -> None: - """Post initialization to adjust the values.""" - if isinstance(self.id, str): - super().__setattr__("id", bytes.fromhex(self.id[2:])) - - -@dataclasses.dataclass(frozen=True) -class FPMM: - """A structure for an OMEN FPMM.""" - - answerFinalizedTimestamp: int - collateralToken: str - condition: Condition - creator: str - creationTimestamp: int - currentAnswer: str - question: Question - templateId: int - - def __post_init__(self) -> None: - """Post initialization to adjust the values.""" - super().__setattr__( - "answerFinalizedTimestamp", int(self.answerFinalizedTimestamp) - ) - super().__setattr__("templateId", int(self.templateId)) - super().__setattr__("creationTimestamp", int(self.creationTimestamp)) - - if isinstance(self.condition, dict): - super().__setattr__("condition", Condition(**self.condition)) - - if isinstance(self.question, dict): - super().__setattr__("question", Question(**self.question)) - - @property - def current_answer_index(self) -> int: - """Get the index of the market's current answer.""" - return int(self.currentAnswer, 16) - - -@dataclasses.dataclass(frozen=True) -class Trade: - """A structure for an OMEN trade.""" - - fpmm: FPMM - outcomeIndex: int - outcomeTokenMarginalPrice: float - outcomeTokensTraded: int - transactionHash: str - - def __post_init__(self) -> None: - """Post initialization to adjust the values.""" - super().__setattr__("outcomeIndex", int(self.outcomeIndex)) - super().__setattr__( - "outcomeTokenMarginalPrice", float(self.outcomeTokenMarginalPrice) - ) - super().__setattr__("outcomeTokensTraded", int(self.outcomeTokensTraded)) - - if isinstance(self.fpmm, dict): - super().__setattr__("fpmm", FPMM(**self.fpmm)) - - def __eq__(self, other: Any) -> bool: - """Check equality.""" - return isinstance(other, Trade) and ( - self.fpmm.condition.id == other.fpmm.condition.id - or self.fpmm.question.id == other.fpmm.question.id - ) - - def __hash__(self) -> int: - """Custom hashing operator.""" - return hash(self.fpmm.condition.id) + hash(self.fpmm.question.id) - - @property - def is_winning(self) -> bool: - """Return whether the current position is winning.""" - our_answer = self.outcomeIndex - correct_answer = self.fpmm.current_answer_index - return our_answer == correct_answer or correct_answer == INVALID_MARKET_ANSWER - - @property - def claimable_amount(self) -> int: - """Get the claimable amount of the current market.""" - amount = self.outcomeTokensTraded - if self.is_winning: - return amount - return -amount diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/rounds.py b/trader_backup/vendor/valory/skills/decision_maker_abci/rounds.py deleted file mode 100644 index 2a942e2e4..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/rounds.py +++ /dev/null @@ -1,381 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the rounds for the decision-making.""" - -from typing import Dict, Set - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AppState, - get_name, -) -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) -from packages.valory.skills.decision_maker_abci.states.blacklisting import ( - BlacklistingRound, -) -from packages.valory.skills.decision_maker_abci.states.check_benchmarking import ( - CheckBenchmarkingModeRound, -) -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) -from packages.valory.skills.decision_maker_abci.states.decision_receive import ( - DecisionReceiveRound, -) -from packages.valory.skills.decision_maker_abci.states.decision_request import ( - DecisionRequestRound, -) -from packages.valory.skills.decision_maker_abci.states.final_states import ( - BenchmarkingDoneRound, - BenchmarkingModeDisabledRound, - FinishedDecisionMakerRound, - FinishedDecisionRequestRound, - FinishedSubscriptionRound, - FinishedWithoutDecisionRound, - FinishedWithoutRedeemingRound, - ImpossibleRound, - RefillRequiredRound, -) -from packages.valory.skills.decision_maker_abci.states.handle_failed_tx import ( - HandleFailedTxRound, -) -from packages.valory.skills.decision_maker_abci.states.order_subscription import ( - SubscriptionRound, -) -from packages.valory.skills.decision_maker_abci.states.randomness import ( - BenchmarkingRandomnessRound, - RandomnessRound, -) -from packages.valory.skills.decision_maker_abci.states.redeem import RedeemRound -from packages.valory.skills.decision_maker_abci.states.sampling import SamplingRound -from packages.valory.skills.decision_maker_abci.states.tool_selection import ( - ToolSelectionRound, -) -from packages.valory.skills.market_manager_abci.rounds import ( - Event as MarketManagerEvent, -) - - -class DecisionMakerAbciApp(AbciApp[Event]): - """DecisionMakerAbciApp - - Initial round: CheckBenchmarkingModeRound - - Initial states: {CheckBenchmarkingModeRound, ClaimRound, DecisionReceiveRound, HandleFailedTxRound, RandomnessRound, RedeemRound} - - Transition states: - 0. CheckBenchmarkingModeRound - - benchmarking enabled: 1. - - benchmarking disabled: 14. - - no majority: 0. - - round timeout: 0. - - done: 20. - - subscription error: 20. - 1. BenchmarkingRandomnessRound - - done: 3. - - round timeout: 1. - - no majority: 1. - 2. RandomnessRound - - done: 3. - - round timeout: 2. - - no majority: 2. - 3. SamplingRound - - done: 4. - - none: 16. - - no majority: 3. - - round timeout: 3. - - new simulated resample: 3. - - benchmarking enabled: 6. - - benchmarking finished: 21. - - fetch error: 20. - 4. SubscriptionRound - - done: 18. - - mock tx: 6. - - no subscription: 6. - - none: 4. - - subscription error: 4. - - no majority: 4. - - round timeout: 4. - 5. ClaimRound - - done: 6. - - subscription error: 5. - - no majority: 5. - - round timeout: 5. - 6. ToolSelectionRound - - done: 7. - - none: 6. - - no majority: 6. - - round timeout: 6. - 7. DecisionRequestRound - - done: 15. - - mock mech request: 8. - - slots unsupported error: 9. - - no majority: 7. - - round timeout: 7. - 8. DecisionReceiveRound - - done: 10. - - mech response error: 9. - - no majority: 8. - - tie: 9. - - unprofitable: 9. - - round timeout: 8. - 9. BlacklistingRound - - done: 16. - - mock tx: 16. - - none: 20. - - no majority: 9. - - round timeout: 9. - - fetch error: 20. - 10. BetPlacementRound - - done: 13. - - mock tx: 11. - - insufficient balance: 19. - - no majority: 10. - - round timeout: 10. - - none: 20. - 11. RedeemRound - - done: 13. - - mock tx: 3. - - no redeeming: 17. - - no majority: 11. - - redeem round timeout: 17. - - none: 20. - 12. HandleFailedTxRound - - blacklist: 9. - - no op: 11. - - no majority: 12. - 13. FinishedDecisionMakerRound - 14. BenchmarkingModeDisabledRound - 15. FinishedDecisionRequestRound - 16. FinishedWithoutDecisionRound - 17. FinishedWithoutRedeemingRound - 18. FinishedSubscriptionRound - 19. RefillRequiredRound - 20. ImpossibleRound - 21. BenchmarkingDoneRound - - Final states: {BenchmarkingDoneRound, BenchmarkingModeDisabledRound, FinishedDecisionMakerRound, FinishedDecisionRequestRound, FinishedSubscriptionRound, FinishedWithoutDecisionRound, FinishedWithoutRedeemingRound, ImpossibleRound, RefillRequiredRound} - - Timeouts: - round timeout: 30.0 - redeem round timeout: 3600.0 - """ - - initial_round_cls: AppState = CheckBenchmarkingModeRound - initial_states: Set[AppState] = { - CheckBenchmarkingModeRound, - RandomnessRound, - HandleFailedTxRound, - DecisionReceiveRound, - RedeemRound, - ClaimRound, - } - transition_function: AbciAppTransitionFunction = { - CheckBenchmarkingModeRound: { - Event.BENCHMARKING_ENABLED: BenchmarkingRandomnessRound, - Event.BENCHMARKING_DISABLED: BenchmarkingModeDisabledRound, - Event.NO_MAJORITY: CheckBenchmarkingModeRound, - Event.ROUND_TIMEOUT: CheckBenchmarkingModeRound, - # added because of `autonomy analyse fsm-specs` - # falsely reporting them as missing from the transition - Event.DONE: ImpossibleRound, - Event.SUBSCRIPTION_ERROR: ImpossibleRound, - }, - BenchmarkingRandomnessRound: { - Event.DONE: SamplingRound, - Event.ROUND_TIMEOUT: BenchmarkingRandomnessRound, - Event.NO_MAJORITY: BenchmarkingRandomnessRound, - }, - RandomnessRound: { - Event.DONE: SamplingRound, - Event.ROUND_TIMEOUT: RandomnessRound, - Event.NO_MAJORITY: RandomnessRound, - }, - SamplingRound: { - Event.DONE: SubscriptionRound, - Event.NONE: FinishedWithoutDecisionRound, - Event.NO_MAJORITY: SamplingRound, - Event.ROUND_TIMEOUT: SamplingRound, - Event.NEW_SIMULATED_RESAMPLE: SamplingRound, - Event.BENCHMARKING_ENABLED: ToolSelectionRound, - Event.BENCHMARKING_FINISHED: BenchmarkingDoneRound, - # this is here because of `autonomy analyse fsm-specs` - # falsely reporting it as missing from the transition - MarketManagerEvent.FETCH_ERROR: ImpossibleRound, - }, - SubscriptionRound: { - Event.DONE: FinishedSubscriptionRound, - # skip placing the subscription tx and the claiming round - Event.MOCK_TX: ToolSelectionRound, - Event.NO_SUBSCRIPTION: ToolSelectionRound, - Event.NONE: SubscriptionRound, - Event.SUBSCRIPTION_ERROR: SubscriptionRound, - Event.NO_MAJORITY: SubscriptionRound, - Event.ROUND_TIMEOUT: SubscriptionRound, - }, - ClaimRound: { - Event.DONE: ToolSelectionRound, - Event.SUBSCRIPTION_ERROR: ClaimRound, - Event.NO_MAJORITY: ClaimRound, - Event.ROUND_TIMEOUT: ClaimRound, - }, - ToolSelectionRound: { - Event.DONE: DecisionRequestRound, - Event.NONE: ToolSelectionRound, - Event.NO_MAJORITY: ToolSelectionRound, - Event.ROUND_TIMEOUT: ToolSelectionRound, - }, - DecisionRequestRound: { - Event.DONE: FinishedDecisionRequestRound, - # skip the request to the mech - Event.MOCK_MECH_REQUEST: DecisionReceiveRound, - Event.SLOTS_UNSUPPORTED_ERROR: BlacklistingRound, - Event.NO_MAJORITY: DecisionRequestRound, - Event.ROUND_TIMEOUT: DecisionRequestRound, - }, - DecisionReceiveRound: { - Event.DONE: BetPlacementRound, - Event.MECH_RESPONSE_ERROR: BlacklistingRound, - Event.NO_MAJORITY: DecisionReceiveRound, - Event.TIE: BlacklistingRound, - Event.UNPROFITABLE: BlacklistingRound, - # loop on the same state until Mech deliver is received - Event.ROUND_TIMEOUT: DecisionReceiveRound, - }, - BlacklistingRound: { - Event.DONE: FinishedWithoutDecisionRound, - Event.MOCK_TX: FinishedWithoutDecisionRound, - # degenerate round on purpose, should never have reached here - Event.NONE: ImpossibleRound, - Event.NO_MAJORITY: BlacklistingRound, - Event.ROUND_TIMEOUT: BlacklistingRound, - # this is here because of `autonomy analyse fsm-specs` - # falsely reporting it as missing from the transition - MarketManagerEvent.FETCH_ERROR: ImpossibleRound, - }, - BetPlacementRound: { - Event.DONE: FinishedDecisionMakerRound, - # skip the bet placement tx - Event.MOCK_TX: RedeemRound, - # degenerate round on purpose, owner must refill the safe - Event.INSUFFICIENT_BALANCE: RefillRequiredRound, - Event.NO_MAJORITY: BetPlacementRound, - Event.ROUND_TIMEOUT: BetPlacementRound, - # this is here because of `autonomy analyse fsm-specs` - # falsely reporting it as missing from the transition - Event.NONE: ImpossibleRound, - }, - RedeemRound: { - Event.DONE: FinishedDecisionMakerRound, - Event.MOCK_TX: SamplingRound, - Event.NO_REDEEMING: FinishedWithoutRedeemingRound, - Event.NO_MAJORITY: RedeemRound, - # in case of a round timeout, there likely is something wrong with redeeming - # it could be the RPC, or some other issue. - # We don't want to be stuck trying to redeem. - Event.REDEEM_ROUND_TIMEOUT: FinishedWithoutRedeemingRound, - # this is here because of `autonomy analyse fsm-specs` falsely - # reporting it as missing from the transition - Event.NONE: ImpossibleRound, - }, - HandleFailedTxRound: { - Event.BLACKLIST: BlacklistingRound, - Event.NO_OP: RedeemRound, - Event.NO_MAJORITY: HandleFailedTxRound, - }, - FinishedDecisionMakerRound: {}, - BenchmarkingModeDisabledRound: {}, - FinishedDecisionRequestRound: {}, - FinishedWithoutDecisionRound: {}, - FinishedWithoutRedeemingRound: {}, - FinishedSubscriptionRound: {}, - RefillRequiredRound: {}, - ImpossibleRound: {}, - BenchmarkingDoneRound: {}, - } - cross_period_persisted_keys = frozenset( - { - get_name(SynchronizedData.available_mech_tools), - get_name(SynchronizedData.policy), - get_name(SynchronizedData.utilized_tools), - get_name(SynchronizedData.redeemed_condition_ids), - get_name(SynchronizedData.payout_so_far), - get_name(SynchronizedData.mech_price), - get_name(SynchronizedData.mocking_mode), - get_name(SynchronizedData.next_mock_data_row), - get_name(SynchronizedData.agreement_id), - } - ) - final_states: Set[AppState] = { - FinishedDecisionMakerRound, - BenchmarkingModeDisabledRound, - FinishedDecisionRequestRound, - FinishedSubscriptionRound, - FinishedWithoutDecisionRound, - FinishedWithoutRedeemingRound, - RefillRequiredRound, - ImpossibleRound, - BenchmarkingDoneRound, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - Event.REDEEM_ROUND_TIMEOUT: 3600.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = { - RedeemRound: set(), - ClaimRound: set(), - DecisionReceiveRound: { - get_name(SynchronizedData.final_tx_hash), - }, - HandleFailedTxRound: { - get_name(SynchronizedData.bets_hash), - }, - RandomnessRound: set(), - CheckBenchmarkingModeRound: set(), - } - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedDecisionMakerRound: { - get_name(SynchronizedData.sampled_bet_index), - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - }, - BenchmarkingModeDisabledRound: set(), - FinishedDecisionRequestRound: set(), - FinishedSubscriptionRound: { - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.agreement_id), - }, - FinishedWithoutDecisionRound: {get_name(SynchronizedData.sampled_bet_index)}, - FinishedWithoutRedeemingRound: set(), - RefillRequiredRound: set(), - ImpossibleRound: set(), - BenchmarkingDoneRound: { - get_name(SynchronizedData.mocking_mode), - get_name(SynchronizedData.next_mock_data_row), - }, - } diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/skill.yaml b/trader_backup/vendor/valory/skills/decision_maker_abci/skill.yaml deleted file mode 100644 index a871ea4ca..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/skill.yaml +++ /dev/null @@ -1,446 +0,0 @@ -name: decision_maker_abci -author: valory -version: 0.1.0 -type: skill -description: This skill is responsible for the decision making and placing the bets. - It samples a market based on its liquidity, it sends a request to a mech to decide - what to vote for, it receives the response from the mech, it decides whether voting - is profitable or not, and ultimately, it either bets or blacklists the market. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeia367zzdwndvlhw27rvnwodytjo3ms7gbc3q7mhrrjqjgfasnk47i - __init__.py: bafybeih563ujnigeci2ldzh7hakbau6a222vsed7leg3b7lq32vcn3nm4a - behaviours/__init__.py: bafybeih6ddz2ocvm6x6ytvlbcz6oi4snb5ee5xh5h65nq4w2qf7fd7zfky - behaviours/base.py: bafybeibgmle4ggpuocvpmexoofln6bu6bxtf4csusigr4d7yaobmn452vu - behaviours/bet_placement.py: bafybeig7rdvdk2matibxsllrcxcmsazxaznwrmf5q7va4ads7yzs5xs4pa - behaviours/blacklisting.py: bafybeieuqoup2vrmrtvjfqnr5mzrvkegc7afb2oeujzq2itsbhcsham2se - behaviours/check_benchmarking.py: bafybeiao2lyj7apezkqrpgsyzb3dwvrdgsrgtprf6iuhsmlsufvxfl5bci - behaviours/claim_subscription.py: bafybeigbqkhc6mb73rbwaks32tfiqx6u2xza43uiy6rvbtrnqd6m4fru3e - behaviours/decision_receive.py: bafybeibai2prkijmcuqdofrbuoxrikkkxsadps2ijubcha7a2k6uqi2r2m - behaviours/decision_request.py: bafybeia22omb7tvocyfe3z2ucn5au5mcas7dg37ha42u7znefzrewjpk7y - behaviours/handle_failed_tx.py: bafybeiashwlfp6ty3g6ukgmliaghwu6yiunbqpjmyrzheokw3pbcr2ckaq - behaviours/order_subscription.py: bafybeib3maqohhx35wzryy4otdcjp5thkr4sbp27ksvwidy3pwm444itra - behaviours/randomness.py: bafybeiaoj3awyyg2onhpsdsn3dyczs23gr4smuzqcbw3e5ocljwxswjkce - behaviours/reedem.py: bafybeidjmhh6c6shbg25d7exmc4nnp4heqbqselwuxj7rp2ss665lrytxe - behaviours/round_behaviour.py: bafybeih63hpia2bwwzu563hxs5yd3t5ycvxvkfnhvxbzghbyy3mw3xjl3i - behaviours/sampling.py: bafybeiet37e4o4s5kdf4u4denls7iaqm6b2a2mqa5eu576waiwmuwozhmi - behaviours/sell_outcome_token.py: bafybeicjpqnukexia457s73yp34yvgefpkgaikainmjf3sxgdk5c4kfqba - behaviours/storage_manager.py: bafybeic6wca37fkwonbsrwme55xnklfbqtheknroudayzfxdge4pxdbm7y - behaviours/tool_selection.py: bafybeienlxcgjs3ogyofli3d7q3p5rst3mcxxcnwqf7qolqjeefjtixeke - dialogues.py: bafybeigpwuzku3we7axmxeamg7vn656maww6emuztau5pg3ebsoquyfdqm - fsm_specification.yaml: bafybeidlnqnd7dwg7r2vhsgm2balrqhxm36qdflkmr7csze2kdeu3a7sbu - handlers.py: bafybeibf42562x3d5i66yf5p3vi6a2oolhwwxr32pjqtuxz5w4gmg3r4oa - io_/__init__.py: bafybeifxgmmwjqzezzn3e6keh2bfo4cyo7y5dq2ept3stfmgglbrzfl5rq - io_/loader.py: bafybeih3sdsx5dhe4kzhtoafexjgkutsujwqy3zcdrlrkhtdks45bc7exa - models.py: bafybeidcfp5y7sqqzwhzifq7mch5sqdfazgbynv3n7sgrj4fqcux2btfmu - payloads.py: bafybeieygushjlrzwzpnhagjgpbs3goot3pnfheh6yawuwctrk3uoeesfm - policy.py: bafybeidofgwvk6sudz75tvuduskuphtn3amtib2irzw5hr3qcfn5pdwuc4 - redeem_info.py: bafybeifiiix4gihfo4avraxt34sfw35v6dqq45do2drrssei2shbps63mm - rounds.py: bafybeidjve7efycfkkbignqky4x6awvrobn4w32grxiubxxiiparr7xd2i - states/__init__.py: bafybeid23llnyp6j257dluxmrnztugo5llsrog7kua53hllyktz4dqhqoy - states/base.py: bafybeiducubeh7oanfufy5xe2dx5njjeyqr3akw2cjjg7wl445slafqw6u - states/bet_placement.py: bafybeih5eopyxubczys5u5t3bdxbxpc7mmfdyqrpqsbm2uha5jc2phza4i - states/blacklisting.py: bafybeiapelgjhbjjn4uq4z5gspyirqzwzgccg5anktrp5kxdwamfnfw5mi - states/check_benchmarking.py: bafybeifvto757zbfzy7mpehblyjd7zqboarxesjfiobtnbxew4nkltfkim - states/claim_subscription.py: bafybeidlubctpk5djsredvvwdhubs34rztud3lw7pwp5kj6ggzah6dvyly - states/decision_receive.py: bafybeidxz4mfzjrjbhghh47erwyo2bucvjenpwcpckpc7ywfra7iyaw2mu - states/decision_request.py: bafybeiarv3r5j7cfvxmudki2llbdl2pvf24p5mvsva6bdgrylnwdyag5xy - states/final_states.py: bafybeicjrrojo3gmfaxzicwloyorlnqgzl6a2avevo4nvhoh424zwzmbti - states/handle_failed_tx.py: bafybeiha5wkl4u4jlj7txpmhuzfnibnu3ix5zw4vmufjunoyuq6s6ubhnu - states/order_subscription.py: bafybeihl3pwrbccaitiukbigygd5u3weyih34pvzql3c6n5k7gjj47f2be - states/randomness.py: bafybeiceoo4nx3t4dofpwczw3v5mclramwmzpwjs6hv7l56arodrjx4l5u - states/redeem.py: bafybeica6cn4xg7shea2wjhbqnddgxe5zao2hkmceltze7qknxdhtsoaxe - states/sampling.py: bafybeif2yuwl5swelp7oh5nfuupdf3vg2ijjzapk2xqht7e6i6ggcsl2zy - states/sell_outcome_token.py: bafybeievk4w3zbi4buicml7nivhpepsoed6dsayauqhyk2bkkyqxdil2xm - states/tool_selection.py: bafybeiak5ihuie4nxh3sguiea6pcdgyxr4k4xyzvq6o2uj5xpf7urocawy - tests/__init__.py: bafybeiakpi3k3kc7wrjj7hrluvjcj36lu2gezpmrctwiz5yg2fe7ggnf3i - tests/behaviours/__init__.py: bafybeic7icz7lfhfepdkqkase7y7zn3a6pwdw6fx4ah2hajmgejawpolc4 - tests/behaviours/data/.gitkeep: bafybeiekl43sjsyqfgl6y27ve5ydo4svcngrptgtffblokmspfezroxvvi - tests/behaviours/dummy_strategy/__init__.py: bafybeiep5w5yckjzy724v63qd5cmzfn3uxytmnizynomxggfobbysfcttq - tests/behaviours/dummy_strategy/dummy_strategy.py: bafybeig5e3xfr7gxsakfj4stbxqcwdiljl7klvgahkuwe3obzxgkg3qt2e - tests/behaviours/test_base.py: bafybeif6pglmr7pvojylatfzaxtlk65igx6a2omyrbxfihnnft6o7p75p4 - tests/conftest.py: bafybeidy5hw56kw5mxudnfbhvogofn6k4rqb4ux2bd45baedrrhmgyrude - tests/states/test_base.py: bafybeieqy7wz5677jathwnolsgrt7zdifauammly3aeoq6dk4hdsqo5fte - tests/states/test_bet_placement.py: bafybeibvc37n2cluep4tasvgmvwxwne2deais6ptirducpogk67v4gj4ga - tests/states/test_blacklising.py: bafybeihm2ex6l7fhorgi3mjj2epztu2r7bqbg56unpgpzfzymghshchqzy - tests/states/test_check_benchmarking.py: bafybeiaauepn46l5z5kx2ifzsqcuravg3zvddecuhdgp4eaeous6vaqyoq - tests/states/test_claim_subscription.py: bafybeiclkxjhceb3ehgmg6klt4uywew5drk5b3w6no7mwxetpubxqrejfy - tests/states/test_decision_receive.py: bafybeibkxalkfxuyokb6y5hkyu4pdlg4yfusbpgtkfr66cprygu7cgyd2y - tests/states/test_decision_request.py: bafybeigqbakm2olkwvcngertjplhnmu6on6tp6hxn7lxygi2gf5a5eurbe - tests/states/test_final_states.py: bafybeiftfd3ovaqpfe7t5ry7maiziavk74wl66d6zo6ikhgodznormd2nm - tests/states/test_handle_failed_tx.py: bafybeiebqgfhncmdexgq7khgkmcsym35547x3j6tr3mmybuyhocv6h5zpq - tests/states/test_order_subscription.py: bafybeidx2tzivsxhpr5xx5e5h2xmpjyewfogt2mujv4sq3hbaeksmcbvhy - tests/states/test_randomness.py: bafybeib3eqjv6mhlprzda7d4viddn5alrfqteq6juyg3ccejseoywcsbey - tests/states/test_redeem.py: bafybeiezdnfrxukb2xpwffrr357g2anmdkwy7wo3nphvlggipq5xrdzr7a - tests/states/test_sampling.py: bafybeifvbzikke6wtex2p5j7fsnpdbj4qqxl5vh2lm2m2apgvuqdonoyzm - tests/states/test_tool_selection.py: bafybeib7js3dj7647t33o5ybfqftwytxktwrvhbri5yuyymg6znj6y7xxa - tests/test_dialogues.py: bafybeibulo64tgfrq4e5qbcqnmifrlehkqciwuavublints353zaj2mlpa - tests/test_handlers.py: bafybeihpkgtjjm3uegpup6zkznpoaxqpu6kmp3ujiggrzbe73p5fzlq7im - tests/test_payloads.py: bafybeiggbcppj4j54r23qvg423elsnd7dcxl3sfo534ek5sd3g65ua57nq - tests/test_rounds.py: bafybeigifftusd4ew42tyvyrr55o2uehhcik2gdq3atkpjwwlqdeskedty - utils/__init__.py: bafybeiazrfg3kwfdl5q45azwz6b6mobqxngxpf4hazmrnkhinpk4qhbbf4 - utils/nevermined.py: bafybeigallaqxhqopznhjhefr6bukh4ojkz5vdtqyzod5dksshrf24fjgi - utils/scaling.py: bafybeialr3z4zogp4k3l2bzcjfi4igvxzjexmlpgze2bai2ufc3plaow4y -fingerprint_ignore_patterns: [] -connections: -- valory/http_server:0.22.0:bafybeihpgu56ovmq4npazdbh6y6ru5i7zuv6wvdglpxavsckyih56smu7m -contracts: -- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge -- valory/market_maker:0.1.0:bafybeibevdc5trbi2qgt2tvwbsr2h5xvonfhcjwfmozftzvef575fdvbjq -- valory/erc20:0.1.0:bafybeid2p2jyvjjlcsqugnawksdzsca6ljghpqbp2kfi3cxuxoy2233dbi -- valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y -- valory/mech:0.1.0:bafybeiejfjfoxqggghcme43sx53q5gruefrws3k2jam2opkxl5uzffoarm -- valory/conditional_tokens:0.1.0:bafybeibnzmqmeph4cj5vfh3s622mo2o5627vjjwc6bptrhj4dk65mzgvhe -- valory/realitio:0.1.0:bafybeietgux6kkhdquspy35qera7gjwwqwrremmoeatjzwwokjb2lzsata -- valory/realitio_proxy:0.1.0:bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4 -- valory/agent_registry:0.1.0:bafybeiblc4i5xjxbywnfccwtv3unhaghrgqls7panfbuqbpstbc34h42xq -- valory/transfer_nft_condition:0.1.0:bafybeid6z2tf7nc4rhwggktxk5f62bowxdczykrxc3y76sbt2ttlw5hmtq -protocols: -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -- valory/ipfs:0.1.0:bafybeiftxi2qhreewgsc5wevogi7yc5g6hbcbo4uiuaibauhv3nhfcdtvm -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/market_manager_abci:0.1.0:bafybeibo63iiziwvqn6fmx36ungyg35z3chfv432kf6spuiszm6na22vdy -- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae -- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm -- valory/staking_abci:0.1.0:bafybeicupccurmrg7qesivonlyt3nryarsmk5qf5yh6auno64wn45bybvq -behaviours: - main: - args: {} - class_name: AgentDecisionMakerRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - multisend_batch_size: 1 - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 350.0 - service_id: decision_maker - service_registry_address: null - agent_registry_address: '0x0000000000000000000000000000000000000000' - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - sleep_time: 1 - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - tx_timeout: 10.0 - use_termination: false - mech_contract_address: '0x77af31de935740567cf4ff1986d04b2c964a786a' - mech_request_price: null - mech_chain_id: gnosis - mech_wrapped_native_token_address: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d' - mech_interaction_sleep_time: 10 - creator_per_subgraph: - omen_subgraph: [] - slot_count: 2 - opening_margin: 300 - languages: - - en_US - average_block_time: 5 - abt_error_mult: 5 - the_graph_error_message_key: message - the_graph_payment_required_error: payment required for subsequent requests for - this API key - sample_bets_closing_days: 10 - trading_strategy: strategy_name - use_fallback_strategy: true - bet_threshold: 100000000000000000 - ipfs_address: https://gateway.autonolas.tech/ipfs/ - tools_accuracy_hash: QmR8etyW3TPFadNtNrW54vfnFqmh8vBrMARWV76EmxCZyk - prompt_template: With the given question "@{question}" and the `yes` option - represented by `@{yes}` and the `no` option represented by `@{no}`, what are - the respective probabilities of `p_yes` and `p_no` occurring? - dust_threshold: 10000000000000 - conditional_tokens_address: '0xCeAfDD6bc0bEF976fdCd1112955828E00543c0Ce' - realitio_proxy_address: '0xAB16D643bA051C11962DA645f74632d3130c81E2' - realitio_address: '0x79e32aE03fb27B07C89c0c568F80287C01ca2E57' - redeem_round_timeout: 3600.0 - event_filtering_batch_size: 5000 - reduce_factor: 0.25 - max_filtering_retries: 6 - minimum_batch_size: 500 - redeeming_batch_size: 5 - store_path: data - slippage: 0.01 - policy_epsilon: 0.1 - use_subgraph_for_redeeming: true - use_nevermined: true - policy_store_update_offset: 259200 - mech_to_subscription_params: - - - base_url - - https://marketplace-api.gnosis.nevermined.app/api/v1/metadata/assets/ddo - - - did - - did:nv:0ea01d5de3b34e3792db825f2a5f5595c393c68b19fd5efdacd00fcc63a53483 - - - escrow_payment_condition_address - - '0x9dDC4F1Ea5b94C138A23b60EC48c0d01d172629a' - - - lock_payment_condition_address - - '0xDE85A368Ee6f374d236500d176814365370778dA' - - - transfer_nft_condition_address - - '0xbBa4A25262745a55f020D0a3E9a82c25bb6F4979' - - - token_address - - '0xa30DE8C6aC39B825192e5F1FADe0770332D279A8' - - - order_address - - '0xc7751eff5396a846e7bc83ac31d3cb7d37cb49e4' - - - nft_amount - - '100' - - - payment_token - - '0x0000000000000000000000000000000000000000' - - - order_address - - '0xc7751eff5396a846e7bc83ac31d3cb7d37cb49e4' - - - price - - '1000000000000000000' - irrelevant_tools: - - openai-text-davinci-002 - - openai-text-davinci-003 - - openai-gpt-3.5-turbo - - openai-gpt-4 - - stabilityai-stable-diffusion-v1-5 - - stabilityai-stable-diffusion-xl-beta-v2-2-2 - - stabilityai-stable-diffusion-512-v2-1 - - stabilityai-stable-diffusion-768-v2-1 - tool_punishment_multiplier: 1 - contract_timeout: 300.0 - file_hash_to_strategies_json: - - - hash - - - strategy_name - strategies_kwargs: - - - bet_kelly_fraction - - 1.0 - - - floor_balance - - 500000000000000000 - - - bet_amount_per_threshold - - 0.0: 0 - 0.1: 0 - 0.2: 0 - 0.3: 0 - 0.4: 0 - 0.5: 0 - 0.6: 0 - 0.7: 0 - 0.8: 0 - 0.9: 0 - 1.0: 0 - service_endpoint: trader.staging.autonolas.tech/ - rpc_sleep_time: 10 - safe_voting_range: 600 - rebet_chance: 0.6 - use_mech_marketplace: false - mech_marketplace_config: - mech_marketplace_address: '0x0000000000000000000000000000000000000000' - priority_mech_address: '0x0000000000000000000000000000000000000000' - priority_mech_staking_instance_address: '0x0000000000000000000000000000000000000000' - priority_mech_service_id: 0 - requester_staking_instance_address: '0x0000000000000000000000000000000000000000' - response_timeout: 300 - agent_balance_threshold: 10000000000000000 - expected_mech_response_time: 300 - mech_invalid_response: Invalid Response - mech_consecutive_failures_threshold: 2 - tool_quarantine_duration: 18000 - class_name: DecisionMakerParams - benchmarking_mode: - args: - enabled: false - native_balance: 10000000000000000000 - collateral_balance: 10000000000000000000 - mech_cost: 10000000000000000 - pool_fee: 20000000000000000 - outcome_token_amounts: - - 11000000000000000000 - - 9000000000000000000 - outcome_token_marginal_prices: - - 0.4 - - 0.6 - sep: ',' - dataset_filename: benchmark_data.csv - question_field: question - question_id_field: question_id - answer_field: answer - p_yes_field_part: p_yes_ - p_no_field_part: p_no_ - confidence_field_part: confidence_ - part_prefix_mode: true - bet_amount_field: collateral_amount - results_filename: benchmarking_results.csv - randomness: benchmarking_randomness - nr_mech_calls: 60 - class_name: BenchmarkingMode - acc_info_fields: - args: - tool: tool - requests: total_requests - accuracy: tool_accuracy - sep: ',' - max: max - datetime_format: '%Y-%m-%d %H:%M:%S' - class_name: AccuracyInfoFields - trades_subgraph: - args: - api_id: trades - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:fpmmTrades - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/protofire/omen-xdai - class_name: TradesSubgraph - conditional_tokens_subgraph: - args: - api_id: conditional_tokens - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:user:userPositions - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/gnosis/conditional-tokens-gc - class_name: ConditionalTokensSubgraph - realitio_subgraph: - args: - api_id: realitio - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:answers - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/realityeth/realityeth-gnosis - class_name: RealitioSubgraph - agent_tools: - args: - api_id: agent_tools - headers: - Content-Type: application/json - method: GET - parameters: {} - response_key: tools - response_type: list - retries: 5 - url: '' - class_name: AgentToolsSpecs - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: - hexbytes: - version: ==0.3.1 - hypothesis: - version: ==6.21.6 - py-multibase: - version: ==1.0.3 - py-multicodec: - version: ==0.2.1 - web3: - version: <7,>=6.0.0 - eth-abi: - version: ==4.0.0 - pyyaml: - version: <=6.0.1,>=3.10 -is_abstract: true diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/__init__.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/__init__.py deleted file mode 100644 index bddac5611..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 package contains the rounds for the 'decision_maker_abci' skill.""" diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/base.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/base.py deleted file mode 100644 index 3acc844a7..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/base.py +++ /dev/null @@ -1,318 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the base functionality for the rounds of the decision-making abci app.""" - -import json -from enum import Enum -from typing import Dict, List, Optional, Set, Tuple, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - CollectSameUntilThresholdRound, - DeserializedCollection, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import MultisigTxPayload -from packages.valory.skills.decision_maker_abci.policy import EGreedyPolicy -from packages.valory.skills.market_manager_abci.rounds import ( - SynchronizedData as MarketManagerSyncedData, -) -from packages.valory.skills.mech_interact_abci.states.base import ( - MechInteractionResponse, - MechMetadata, -) -from packages.valory.skills.staking_abci.rounds import StakingState -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TxSettlementSyncedData, -) - - -class Event(Enum): - """Event enumeration for the price estimation demo.""" - - DONE = "done" - NONE = "none" - BENCHMARKING_ENABLED = "benchmarking_enabled" - BENCHMARKING_DISABLED = "benchmarking_disabled" - BENCHMARKING_FINISHED = "benchmarking_finished" - MOCK_MECH_REQUEST = "mock_mech_request" - MOCK_TX = "mock_tx" - MECH_RESPONSE_ERROR = "mech_response_error" - SLOTS_UNSUPPORTED_ERROR = "slots_unsupported_error" - TIE = "tie" - UNPROFITABLE = "unprofitable" - INSUFFICIENT_BALANCE = "insufficient_balance" - NO_REDEEMING = "no_redeeming" - BLACKLIST = "blacklist" - NO_OP = "no_op" - SUBSCRIPTION_ERROR = "subscription_error" - NO_SUBSCRIPTION = "no_subscription" - ROUND_TIMEOUT = "round_timeout" - REDEEM_ROUND_TIMEOUT = "redeem_round_timeout" - NO_MAJORITY = "no_majority" - NEW_SIMULATED_RESAMPLE = "new_simulated_resample" - - -class SynchronizedData(MarketManagerSyncedData, TxSettlementSyncedData): - """Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - @property - def sampled_bet_index(self) -> int: - """Get the sampled bet.""" - return int(self.db.get_strict("sampled_bet_index")) - - @property - def benchmarking_finished(self) -> bool: - """Get the flag of benchmarking finished.""" - return bool(self.db.get_strict("benchmarking_finished")) - - @property - def simulated_day(self) -> bool: - """Get the flag of simulated_day.""" - return bool(self.db.get_strict("simulated_day")) - - @property - def is_mech_price_set(self) -> bool: - """Get whether mech's price is known.""" - return bool(self.db.get("mech_price", False)) - - @property - def available_mech_tools(self) -> List[str]: - """Get all the available mech tools.""" - tools = self.db.get_strict("available_mech_tools") - return json.loads(tools) - - @property - def is_policy_set(self) -> bool: - """Get whether the policy is set.""" - return bool(self.db.get("policy", False)) - - @property - def policy(self) -> EGreedyPolicy: - """Get the policy.""" - policy = self.db.get_strict("policy") - return EGreedyPolicy.deserialize(policy) - - @property - def has_tool_selection_run(self) -> bool: - """Get whether the tool selection has run.""" - mech_tool = self.db.get("mech_tool", None) - return mech_tool is not None - - @property - def mech_tool(self) -> str: - """Get the selected mech tool.""" - return str(self.db.get_strict("mech_tool")) - - @property - def utilized_tools(self) -> Dict[str, str]: - """Get a mapping of the utilized tools' indexes for each transaction.""" - tools = str(self.db.get_strict("utilized_tools")) - return json.loads(tools) - - @property - def redeemed_condition_ids(self) -> Set[str]: - """Get the condition ids of all the redeemed positions.""" - ids = self.db.get("redeemed_condition_ids", None) - if ids is None: - return set() - return set(json.loads(ids)) - - @property - def payout_so_far(self) -> int: - """Get the payout of all the redeemed positions so far.""" - payout = self.db.get("payout_so_far", None) - if payout is None: - return 0 - return int(payout) - - @property - def vote(self) -> Optional[int]: - """Get the bet's vote index.""" - vote = self.db.get_strict("vote") - return int(vote) if vote is not None else None - - @property - def previous_vote(self) -> Optional[int]: - """Get the bet's previous vote index.""" - previous_vote = self.db.get_strict("previous_vote") - return int(previous_vote) if previous_vote is not None else None - - @property - def confidence(self) -> float: - """Get the vote's confidence.""" - return float(self.db.get_strict("confidence")) - - @property - def bet_amount(self) -> int: - """Get the calculated bet amount.""" - return int(self.db.get_strict("bet_amount")) - - @property - def weighted_accuracy(self) -> float: - """Get the weighted accuracy of the selected tool.""" - tool_name = self.mech_tool - store_tools = set(self.policy.weighted_accuracy.keys()) - if tool_name not in store_tools: - raise ValueError( - f"The tool {tool_name} was selected but it is not available in the policy!" - ) - return self.policy.weighted_accuracy[tool_name] - - @property - def is_profitable(self) -> bool: - """Get whether the current vote is profitable or not.""" - return bool(self.db.get_strict("is_profitable")) - - @property - def did_transact(self) -> bool: - """Get whether the service performed any transactions in the current period.""" - return bool(self.db.get("tx_submitter", None)) - - @property - def tx_submitter(self) -> str: - """Get the round that submitted a tx to transaction_settlement_abci.""" - return str(self.db.get_strict("tx_submitter")) - - @property - def participant_to_decision(self) -> DeserializedCollection: - """Get the participants to decision-making.""" - return self._get_deserialized("participant_to_decision") - - @property - def participant_to_tx_prep(self) -> DeserializedCollection: - """Get the participants to bet-placement.""" - return self._get_deserialized("participant_to_tx_prep") - - @property - def participant_to_handle_failed_tx(self) -> DeserializedCollection: - """Get the participants to `HandleFailedTxRound`.""" - return self._get_deserialized("participant_to_handle_failed_tx") - - @property - def agreement_id(self) -> str: - """Get the agreement id.""" - return str(self.db.get_strict("agreement_id")) - - @property - def claim(self) -> bool: - """Get the claim.""" - return bool(self.db.get_strict("claim")) - - @property - def mech_price(self) -> int: - """Get the mech's request price.""" - return int(self.db.get_strict("mech_price")) - - @property - def mech_requests(self) -> List[MechMetadata]: - """Get the mech requests.""" - serialized = self.db.get("mech_requests", "[]") - if serialized is None: - serialized = "[]" - requests = json.loads(serialized) - return [MechMetadata(**metadata_item) for metadata_item in requests] - - @property - def mocking_mode(self) -> Optional[bool]: - """Get whether the mocking mode should be enabled.""" - mode = self.db.get_strict("mocking_mode") - if mode is None: - return None - return bool(mode) - - @property - def next_mock_data_row(self) -> int: - """Get the next_mock_data_row.""" - next_mock_data_row = self.db.get("next_mock_data_row", 1) - if next_mock_data_row is None: - return 1 - return int(next_mock_data_row) - - @property - def mech_responses(self) -> List[MechInteractionResponse]: - """Get the mech responses.""" - serialized = self.db.get("mech_responses", "[]") - if serialized is None: - serialized = "[]" - responses = json.loads(serialized) - return [MechInteractionResponse(**response_item) for response_item in responses] - - @property - def wallet_balance(self) -> int: - """Get the balance of the wallet.""" - wallet_balance = self.db.get("wallet_balance", 0) - if wallet_balance is None: - return 0 - return int(wallet_balance) - - @property - def decision_receive_timestamp(self) -> int: - """Get the timestamp of the mech decision.""" - decision_receive_timestamp = self.db.get("decision_receive_timestamp", 0) - if decision_receive_timestamp is None: - return 0 - return int(decision_receive_timestamp) - - @property - def is_staking_kpi_met(self) -> bool: - """Get the status of the staking kpi.""" - return bool(self.db.get("is_staking_kpi_met", False)) - - @property - def service_staking_state(self) -> StakingState: - """Get the service's staking state.""" - return StakingState(self.db.get("service_staking_state", 0)) - - @property - def after_bet_attempt(self) -> bool: - """Get the service's staking state.""" - return bool(self.db.get("after_bet_attempt", False)) - - -class TxPreparationRound(CollectSameUntilThresholdRound): - """A round for preparing a transaction.""" - - payload_class = MultisigTxPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - none_event = Event.NONE - no_majority_event = Event.NO_MAJORITY - selection_key: Tuple[str, ...] = ( - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.mocking_mode), - ) - collection_key = get_name(SynchronizedData.participant_to_tx_prep) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - if event == Event.DONE and synced_data.mocking_mode: - return synced_data, Event.MOCK_TX - - return res diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/bet_placement.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/bet_placement.py deleted file mode 100644 index 35e7c63f1..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/bet_placement.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the sampling state of the decision-making abci app.""" -from enum import Enum -from typing import Optional, Tuple, Type - -from packages.valory.skills.abstract_round_abci.base import BaseSynchronizedData -from packages.valory.skills.decision_maker_abci.payloads import ( - BetPlacementPayload, - MultisigTxPayload, -) -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - TxPreparationRound, -) - - -class BetPlacementRound(TxPreparationRound): - """A round for placing a bet.""" - - payload_class: Type[MultisigTxPayload] = BetPlacementPayload - - none_event = Event.INSUFFICIENT_BALANCE - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - update = super().end_block() - if update is None: - return None - - sync_data, event = update - wallet_balance = self.most_voted_payload_values[-1] - sync_data = sync_data.update(wallet_balance=wallet_balance) - return sync_data, event diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/blacklisting.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/blacklisting.py deleted file mode 100644 index d2a714583..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/blacklisting.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the blacklisting state of the decision-making abci app.""" - -from enum import Enum -from typing import Any, Optional, Tuple, Type, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import BlacklistingPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload -from packages.valory.skills.market_manager_abci.rounds import UpdateBetsRound - - -class BlacklistingRound(UpdateBetsRound): - """A round for updating the bets after blacklisting the sampled one.""" - - payload_class: Type[UpdateBetsPayload] = BlacklistingPayload - done_event = Event.DONE - none_event = Event.NONE - no_majority_event = Event.NO_MAJORITY - selection_key: Any = ( - UpdateBetsRound.selection_key, - get_name(SynchronizedData.policy), - ) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - if event == Event.DONE and self.context.benchmarking_mode.enabled: - return synced_data, Event.MOCK_TX - return res diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/check_benchmarking.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/check_benchmarking.py deleted file mode 100644 index e50d6478b..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/check_benchmarking.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 state of the decision-making abci app which checks if the benchmarking mode is enabled.""" - -from packages.valory.skills.decision_maker_abci.payloads import VotingPayload -from packages.valory.skills.decision_maker_abci.states.base import Event -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) - - -class CheckBenchmarkingModeRound(ClaimRound): - """A round for checking whether the benchmarking mode is enabled.""" - - payload_class = VotingPayload - done_event = Event.BENCHMARKING_ENABLED - negative_event = Event.BENCHMARKING_DISABLED diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/claim_subscription.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/claim_subscription.py deleted file mode 100644 index 40331ef3c..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/claim_subscription.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the decision receiving state of the decision-making abci app.""" - -from typing import Type - -from packages.valory.skills.abstract_round_abci.base import ( - BaseTxPayload, - VotingRound, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import ClaimPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) - - -class ClaimRound(VotingRound): - """A round for preparing a transaction.""" - - payload_class: Type[BaseTxPayload] = ClaimPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - negative_event = Event.SUBSCRIPTION_ERROR - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_votes) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/decision_receive.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/decision_receive.py deleted file mode 100644 index 37ac2c3cb..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/decision_receive.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the decision receiving state of the decision-making abci app.""" - -from enum import Enum -from typing import Any, Optional, Tuple, cast - -from packages.valory.skills.abstract_round_abci.base import ( - CollectSameUntilThresholdRound, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import DecisionReceivePayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.market_manager_abci.rounds import UpdateBetsRound - - -class DecisionReceiveRound(CollectSameUntilThresholdRound): - """A round in which the agents decide on the bet's answer.""" - - payload_class = DecisionReceivePayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - none_event = Event.MECH_RESPONSE_ERROR - no_majority_event = Event.NO_MAJORITY - selection_key: Any = ( - UpdateBetsRound.selection_key, - get_name(SynchronizedData.is_profitable), - get_name(SynchronizedData.vote), - get_name(SynchronizedData.confidence), - get_name(SynchronizedData.bet_amount), - get_name(SynchronizedData.next_mock_data_row), - get_name(SynchronizedData.policy), - ) - collection_key = get_name(SynchronizedData.participant_to_decision) - - def end_block(self) -> Optional[Tuple[SynchronizedData, Enum]]: - """Process the end of the block.""" - - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - - if event == Event.DONE: - decision_receive_timestamp = self.most_voted_payload_values[-1] - - synced_data = cast( - SynchronizedData, - synced_data.update( - decision_receive_timestamp=decision_receive_timestamp - ), - ) - - if event == Event.DONE and synced_data.vote is None: - return synced_data, Event.TIE - - if event == Event.DONE and not synced_data.is_profitable: - return synced_data, Event.UNPROFITABLE - - return synced_data, event diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/decision_request.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/decision_request.py deleted file mode 100644 index 5c4df3e9b..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/decision_request.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the decision requesting state of the decision-making abci app.""" - -from enum import Enum -from typing import Optional, Tuple, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - CollectSameUntilThresholdRound, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import DecisionRequestPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) - - -class DecisionRequestRound(CollectSameUntilThresholdRound): - """A round in which the agents prepare a tx to initiate a request to a mech to determine the answer to a bet.""" - - payload_class = DecisionRequestPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_selection) - selection_key = ( - get_name(SynchronizedData.mech_requests), - get_name(SynchronizedData.mocking_mode), - ) - none_event = Event.SLOTS_UNSUPPORTED_ERROR - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - if event == Event.DONE and synced_data.mocking_mode: - return synced_data, Event.MOCK_MECH_REQUEST - - return res diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/final_states.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/final_states.py deleted file mode 100644 index 6c1294748..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/final_states.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the final states of the decision-making abci app.""" - -import sys -from enum import Enum -from typing import Optional, Tuple - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - DegenerateRound, -) - - -class BenchmarkingModeDisabledRound(DegenerateRound): - """A round representing that the benchmarking mode is disabled.""" - - -class FinishedDecisionMakerRound(DegenerateRound): - """A round representing that decision-making has finished.""" - - -class FinishedDecisionRequestRound(DegenerateRound): - """A round representing that decision request has finished.""" - - -class FinishedSubscriptionRound(DegenerateRound): - """A round representing that subscription has finished.""" - - -class FinishedWithoutRedeemingRound(DegenerateRound): - """A round representing that decision-making has finished without redeeming.""" - - -class FinishedWithoutDecisionRound(DegenerateRound): - """A round representing that decision-making has finished without deciding on a bet.""" - - -class RefillRequiredRound(DegenerateRound): - """A round representing that a refill is required for placing a bet.""" - - -class BenchmarkingDoneRound(DegenerateRound): - """A round representing that the benchmarking has finished.""" - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Gracefully stop the service.""" - sys.exit(0) - - -class ImpossibleRound(DegenerateRound): - """A round representing that decision-making is impossible with the given parametrization.""" diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/handle_failed_tx.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/handle_failed_tx.py deleted file mode 100644 index 0f4c8412d..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/handle_failed_tx.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the blacklisting state of the decision-making abci app.""" - -from enum import Enum -from typing import Optional, Tuple, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - CollectSameUntilThresholdRound, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import HandleFailedTxPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) - - -class HandleFailedTxRound(CollectSameUntilThresholdRound): - """A round for updating the bets after blacklisting the sampled one.""" - - payload_class = HandleFailedTxPayload - synchronized_data_class = SynchronizedData - done_event = Event.BLACKLIST - no_op_event = Event.NO_OP - none_event = Event.NO_OP - no_majority_event = Event.NO_MAJORITY - selection_key = ( - get_name(SynchronizedData.after_bet_attempt), - get_name(SynchronizedData.tx_submitter), - ) - collection_key = get_name(SynchronizedData.participant_to_handle_failed_tx) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - - if event != self.done_event: - return res - - if synced_data.after_bet_attempt: - return synced_data, self.done_event - - return synced_data, self.no_op_event diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/order_subscription.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/order_subscription.py deleted file mode 100644 index 5c5831bd7..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/order_subscription.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the decision receiving state of the decision-making abci app.""" - -from enum import Enum -from typing import Optional, Tuple, Type - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import ( - MultisigTxPayload, - SubscriptionPayload, -) -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, - TxPreparationRound, -) - - -class SubscriptionRound(TxPreparationRound): - """A round in which the agents prepare a tx to initiate a request to a mech to determine the answer to a bet.""" - - payload_class: Type[MultisigTxPayload] = SubscriptionPayload - selection_key = TxPreparationRound.selection_key + ( - get_name(SynchronizedData.agreement_id), - ) - none_event = Event.NO_SUBSCRIPTION - - NO_TX_PAYLOAD = "no_tx" - ERROR_PAYLOAD = "error" - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.threshold_reached: - tx_hash = self.most_voted_payload_values[1] - if tx_hash == self.ERROR_PAYLOAD: - return self.synchronized_data, Event.SUBSCRIPTION_ERROR - - if tx_hash == self.NO_TX_PAYLOAD: - return self.synchronized_data, Event.NO_SUBSCRIPTION - - if self.context.benchmarking_mode.enabled: - return self.synchronized_data, Event.MOCK_TX - - update = super().end_block() - if update is None: - return None - - sync_data, event = update - agreement_id = self.most_voted_payload_values[3] - wallet_balance = self.most_voted_payload_values[4] - sync_data = sync_data.update( - agreement_id=agreement_id, wallet_balance=wallet_balance - ) - return sync_data, event diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/randomness.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/randomness.py deleted file mode 100644 index 9000e153f..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/randomness.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the randomness state of the decision-making abci app.""" - -from typing import Any - -from packages.valory.skills.decision_maker_abci.states.base import Event -from packages.valory.skills.transaction_settlement_abci.rounds import ( - RandomnessTransactionSubmissionRound, -) - - -class RandomnessRound(RandomnessTransactionSubmissionRound): - """A round for gathering randomness.""" - - done_event: Any = Event.DONE - no_majority_event: Any = Event.NO_MAJORITY - - -class BenchmarkingRandomnessRound(RandomnessRound): - """A round for gathering randomness in benchmarking mode.""" diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/redeem.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/redeem.py deleted file mode 100644 index f40ade4c5..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/redeem.py +++ /dev/null @@ -1,107 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the redeem state of the decision-making abci app.""" - -from enum import Enum -from typing import Any, Optional, Tuple, Type, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import ( - MultisigTxPayload, - RedeemPayload, -) -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, - TxPreparationRound, -) - - -IGNORED = "ignored" -MECH_TOOLS_FIELD = "mech_tools" - - -class RedeemRound(TxPreparationRound): - """A round in which the agents prepare a tx to redeem the winnings.""" - - payload_class: Type[MultisigTxPayload] = RedeemPayload - mech_tools_name = get_name(SynchronizedData.available_mech_tools) - selection_key = TxPreparationRound.selection_key + ( - mech_tools_name, - get_name(SynchronizedData.policy), - get_name(SynchronizedData.utilized_tools), - get_name(SynchronizedData.redeemed_condition_ids), - get_name(SynchronizedData.payout_so_far), - ) - none_event = Event.NO_REDEEMING - - @property - def most_voted_payload_values( - self, - ) -> Tuple[Any, ...]: - """Get the most voted payload values in such a way to create a custom none event that ignores the mech tools.""" - most_voted_payload_values = super().most_voted_payload_values - # sender does not matter for the init as the `data` property used below to obtain the dictionary ignores it - most_voted_payload = RedeemPayload(IGNORED, *most_voted_payload_values) - most_voted_payload_dict = most_voted_payload.data - mech_tools = most_voted_payload_dict.pop(MECH_TOOLS_FIELD, None) - if mech_tools is None: - raise ValueError(f"`{MECH_TOOLS_FIELD}` must not be `None`") - if all(val is None for val in most_voted_payload_dict.values()): - return (None,) * len(self.selection_key) - return most_voted_payload_values - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if ( - res is None - and self.block_confirmations == self.synchronized_data.period_count == 0 - ): - # necessary for always setting the persisted keys and not raise an exception when the first period ends - # this also protects us in case a round timeout is raised - update = { - db_key: self.synchronized_data.db.get(db_key, None) - for db_key in RedeemRound.selection_key - } - self.synchronized_data.db.update(**update) - self.block_confirmations = 1 - - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - - # also update the mech tools if there is a majority, because the overridden property does not include it - if event != self.no_majority_event: - most_voted_payload_values = self.payload_values_count.most_common()[0][0] - # sender does not matter for the init as the `data` property used below to obtain the dictionary ignores it - most_voted_payload = RedeemPayload(IGNORED, *most_voted_payload_values) - mech_tools_update = most_voted_payload.mech_tools - updated_data = synced_data.update( - self.synchronized_data_class, - **{self.mech_tools_name: mech_tools_update}, - ) - return updated_data, event - - return res diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/sampling.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/sampling.py deleted file mode 100644 index dbbf08461..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/sampling.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the sampling state of the decision-making abci app.""" - -from enum import Enum -from typing import Any, Optional, Tuple, Type, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import SamplingPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload -from packages.valory.skills.market_manager_abci.rounds import UpdateBetsRound - - -class SamplingRound(UpdateBetsRound): - """A round for sampling a bet.""" - - payload_class: Type[UpdateBetsPayload] = SamplingPayload - done_event = Event.DONE - none_event = Event.NONE - no_majority_event = Event.NO_MAJORITY - selection_key: Any = ( - UpdateBetsRound.selection_key, - get_name(SynchronizedData.sampled_bet_index), - get_name(SynchronizedData.benchmarking_finished), - get_name(SynchronizedData.simulated_day), - ) - synchronized_data_class = SynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - - if event != Event.DONE: - return res - - if synced_data.benchmarking_finished: - return synced_data, Event.BENCHMARKING_FINISHED - - if synced_data.simulated_day: - return synced_data, Event.NEW_SIMULATED_RESAMPLE - - if self.context.benchmarking_mode.enabled: - return synced_data, Event.BENCHMARKING_ENABLED - - return res diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/sell_outcome_token.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/sell_outcome_token.py deleted file mode 100644 index 3fdeb628c..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/sell_outcome_token.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the sell outcome token state of the decision-making abci app.""" - -from packages.valory.skills.decision_maker_abci.states.base import TxPreparationRound - - -class SellOutcomeTokenRound(TxPreparationRound): - """A round for selling a token.""" diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/states/tool_selection.py b/trader_backup/vendor/valory/skills/decision_maker_abci/states/tool_selection.py deleted file mode 100644 index 9b6ce6316..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/states/tool_selection.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the tool selection state of the decision-making abci app.""" - -from packages.valory.skills.abstract_round_abci.base import ( - CollectSameUntilThresholdRound, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import ToolSelectionPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) - - -class ToolSelectionRound(CollectSameUntilThresholdRound): - """A round for selecting a Mech tool.""" - - payload_class = ToolSelectionPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - none_event = Event.NONE - no_majority_event = Event.NO_MAJORITY - selection_key = ( - get_name(SynchronizedData.available_mech_tools), - get_name(SynchronizedData.policy), - get_name(SynchronizedData.utilized_tools), - get_name(SynchronizedData.mech_tool), - ) - collection_key = get_name(SynchronizedData.participant_to_selection) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/__init__.py deleted file mode 100644 index da96e5260..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the tests for valory/decision_maker_abci.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/decision_maker_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/__init__.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/__init__.py deleted file mode 100644 index ce9c4fc94..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the tests for valory/decision_maker_abci's behaviours.""" diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/data/.gitkeep b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/data/.gitkeep deleted file mode 100644 index 12461b81d..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/data/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep this folder here for testing purposes diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/__init__.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/__init__.py deleted file mode 100644 index 2f1c30eae..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 dummy strategy for testing purposes.""" diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/dummy_strategy.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/dummy_strategy.py deleted file mode 100644 index 69a942008..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/dummy_strategy.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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. -# -# ------------------------------------------------------------------------------ - - -"""Implements a dummy strategy for testing purposes.""" - - -from typing import Any - - -def dummy(*args: Any, **kwargs: Any) -> str: - """The dummy function.""" - return "dummy" diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/test_base.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/test_base.py deleted file mode 100644 index 5f48f32e3..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/behaviours/test_base.py +++ /dev/null @@ -1,275 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the tests for valory/decision_maker_abci's base behaviour.""" - -import re -from pathlib import Path -from typing import Any, Dict, Optional, Tuple, cast -from unittest import mock - -import pytest -from hypothesis import given, settings -from hypothesis import strategies as st - -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - BET_AMOUNT_FIELD, - DecisionMakerBaseBehaviour, - WXDAI, - remove_fraction_wei, -) -from packages.valory.skills.decision_maker_abci.behaviours.blacklisting import ( - BlacklistingBehaviour, -) -from packages.valory.skills.decision_maker_abci.states.base import SynchronizedData -from packages.valory.skills.decision_maker_abci.tests.conftest import profile_name - - -settings.load_profile(profile_name) -FRACTION_REMOVAL_PRECISION = 2 -CURRENT_FILE_PATH = Path(__file__).resolve() -PACKAGE_DIR = CURRENT_FILE_PATH.parents[2] - - -@st.composite -def remove_fraction_args(draw: st.DrawFn) -> Tuple[int, float, int]: - """A strategy for building the values of the `test_remove_fraction_wei` with the desired constraints.""" - amount = draw(st.integers()) - fraction = draw(st.floats(min_value=0, max_value=1)) - keep_percentage = 1 - fraction - assert 0 <= keep_percentage <= 1 - expected = int(amount * keep_percentage) - return amount, fraction, expected - - -@given(remove_fraction_args()) -def test_remove_fraction_wei(strategy: Tuple[int, float, int]) -> None: - """Test the `remove_fraction_wei` function.""" - amount, fraction, expected = strategy - assert remove_fraction_wei(amount, fraction) == expected - - -@given( - amount=st.integers(), - fraction=st.floats().filter(lambda x: x < 0 or x > 1), -) -def test_remove_fraction_wei_incorrect_fraction(amount: int, fraction: float) -> None: - """Test the `remove_fraction_wei` function.""" - with pytest.raises( - ValueError, - match=re.escape(f"The given fraction {fraction!r} is not in the range [0, 1]."), - ): - remove_fraction_wei(amount, fraction) - - -@st.composite -def strategy_executables( - draw: st.DrawFn, -) -> Tuple[str, Dict[str, Tuple[str, str]], Optional[Tuple[str, str]]]: - """A strategy for building valid availability window data.""" - strategy_name = draw(st.text()) - expected_result = draw(st.tuples(st.text(), st.text())) - negative_case = draw(st.booleans()) - - if negative_case: - return strategy_name, {}, None - - return strategy_name, {strategy_name: expected_result}, expected_result - - -class TestDecisionMakerBaseBehaviour(FSMBehaviourBaseCase): - """Test `DecisionMakerBaseBehaviour`.""" - - path_to_skill = PACKAGE_DIR - - def ffw( - self, - behaviour_cls: Any, - db_items: Optional[Dict] = None, - ) -> None: - """Fast-forward to the given behaviour.""" - if db_items is None: - db_items = {} - - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=behaviour_cls.auto_behaviour_id(), - synchronized_data=SynchronizedData( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists(db_items), - ) - ), - ) - - @given(strategy_executables()) - def test_strategy_exec( - self, - strategy: Tuple[str, Dict[str, Tuple[str, str]], Optional[str]], - ) -> None: - """Test the `strategy_exec` method.""" - strategy_name, strategies_executables, expected_result = strategy - # use `BlacklistingBehaviour` because it overrides the `DecisionMakerBaseBehaviour`. - self.ffw(BlacklistingBehaviour) - behaviour = cast(BlacklistingBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == BlacklistingBehaviour.auto_behaviour_id() - behaviour.shared_state.strategies_executables = strategies_executables - res = behaviour.strategy_exec(strategy_name) - assert res == expected_result - - @pytest.mark.parametrize( - "strategy_path", (Path("dummy_strategy/dummy_strategy.py"),) - ) - @pytest.mark.parametrize( - "args, kwargs, method_name, expected_result", - ( - ((), {}, "", {BET_AMOUNT_FIELD: 0}), - ((), {"unexpected_field": "test"}, "", {BET_AMOUNT_FIELD: 0}), - ((), {"trading_strategy": None}, "", {BET_AMOUNT_FIELD: 0}), - ( - (), - {"trading_strategy": "non_existing_strategy"}, - "", - {BET_AMOUNT_FIELD: 0}, - ), - ( - (), - {"trading_strategy": "test"}, - "non_existing_method", - {BET_AMOUNT_FIELD: 0}, - ), - ((), {"trading_strategy": "test"}, "dummy", "dummy"), - ), - ) - def test_execute_strategy( - self, - strategy_path: str, - args: tuple, - kwargs: dict, - method_name: str, - expected_result: int, - ) -> None: - """Test the `execute_strategy` method.""" - # use `BlacklistingBehaviour` because it overrides the `DecisionMakerBaseBehaviour`. - self.ffw(BlacklistingBehaviour) - behaviour = cast(BlacklistingBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == BlacklistingBehaviour.auto_behaviour_id() - current_dir = CURRENT_FILE_PATH.parent - with open(current_dir / strategy_path) as dummy_strategy: - behaviour.shared_state.strategies_executables["test"] = ( - dummy_strategy.read(), - method_name, - ) - - res = behaviour.execute_strategy(*args, **kwargs) - assert res == expected_result - - @given(st.integers()) - def test_wei_to_native(self, wei: int) -> None: - """Test the `wei_to_native` method.""" - result = DecisionMakerBaseBehaviour.wei_to_native(wei) - assert isinstance(result, float) - assert result == wei / 10**18 - - @given(st.integers(), st.booleans(), st.booleans()) - def test_collateral_amount_info( - self, amount: int, benchmarking_mode_enabled: bool, is_wxdai: bool - ) -> None: - """Test the `collateral_amount_info` method.""" - # use `BlacklistingBehaviour` because it overrides the `DecisionMakerBaseBehaviour`. - self.ffw(BlacklistingBehaviour, {"sampled_bet_index": 0}) - behaviour = cast(BlacklistingBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == BlacklistingBehaviour.auto_behaviour_id() - - behaviour.benchmarking_mode.enabled = benchmarking_mode_enabled - with mock.patch.object(behaviour, "read_bets"): - collateral_token = WXDAI if is_wxdai else "unknown" - behaviour.bets = [(mock.MagicMock(collateralToken=collateral_token))] - result = behaviour._collateral_amount_info(amount) - - if benchmarking_mode_enabled or is_wxdai: - assert result == f"{behaviour.wei_to_native(amount)} wxDAI" - else: - assert ( - result - == f"{amount} WEI of the collateral token with address {collateral_token}" - ) - - @given(st.integers(), st.integers()) - def test_mock_balance_check( - self, collateral_balance: int, native_balance: int - ) -> None: - """Test the `_mock_balance_check` method.""" - # use `BlacklistingBehaviour` because it overrides the `DecisionMakerBaseBehaviour`. - self.ffw(BlacklistingBehaviour) - behaviour = cast(BlacklistingBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == BlacklistingBehaviour.auto_behaviour_id() - - behaviour.benchmarking_mode.collateral_balance = collateral_balance - behaviour.benchmarking_mode.native_balance = native_balance - with mock.patch.object(behaviour, "_report_balance") as mock_report_balance: - behaviour._mock_balance_check() - mock_report_balance.assert_called_once() - assert behaviour.token_balance == collateral_balance - assert behaviour.wallet_balance == native_balance - - @pytest.mark.parametrize( - "mocked_result, expected_result", - ( - ({}, 0), - ({"not the correct field": 80}, 0), - ({BET_AMOUNT_FIELD: 0}, 0), - ({BET_AMOUNT_FIELD: -10}, -10), - ({BET_AMOUNT_FIELD: 10}, 10), - ({BET_AMOUNT_FIELD: 23456}, 23456), - ), - ) - def test_get_bet_amount( - self, - mocked_result: int, - expected_result: int, - ) -> None: - """Test the `get_bet_amount` method.""" - # use `BlacklistingBehaviour` because it overrides the `DecisionMakerBaseBehaviour`. - self.ffw(BlacklistingBehaviour) - behaviour = cast(BlacklistingBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == BlacklistingBehaviour.auto_behaviour_id() - behaviour.download_strategies = lambda: (yield) # type: ignore - behaviour.wait_for_condition_with_sleep = lambda _: (yield) # type: ignore - behaviour.execute_strategy = lambda *_, **__: mocked_result # type: ignore - gen = behaviour.get_bet_amount( - 0, - 0, - 0, - 0, - 0, - 0, - ) - for _ in range(2): - # `download_strategies` and `wait_for_condition_with_sleep` mock calls - next(gen) - try: - next(gen) - except StopIteration as e: - assert e.value == expected_result - else: - raise AssertionError("Expected `StopIteration` exception!") diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/conftest.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/conftest.py deleted file mode 100644 index d690940ab..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/conftest.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Conftest module for decision maker tests.""" - -import os -from pathlib import Path - -from hypothesis import settings - - -# pylint: skip-file - - -CI = "CI" -PACKAGE_DIR = Path(__file__).parent.parent -settings.register_profile(CI, deadline=5000) -profile_name = ("default", "CI")[bool(os.getenv("CI"))] diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_base.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_base.py deleted file mode 100644 index ad41e0e8c..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_base.py +++ /dev/null @@ -1,257 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -import json -from unittest.mock import MagicMock, patch - -import pytest - -from packages.valory.skills.decision_maker_abci.policy import ( - AccuracyInfo, - EGreedyPolicy, -) -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, - TxPreparationRound, -) - - -class MechMetadata: - """The class for test of Mech Data""" - - def __init__(self, request_id: str, data: str) -> None: - """Initialize MechMetadata with request ID and data.""" - self.request_id = request_id - self.data = data - - -@pytest.fixture -def mocked_db() -> MagicMock: - """Fixture to mock the database.""" - return MagicMock() - - -@pytest.fixture -def sync_data(mocked_db: MagicMock) -> SynchronizedData: - """Fixture for SynchronizedData.""" - return SynchronizedData(db=mocked_db) - - -def test_sampled_bet_index(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the sampled_bet_index property.""" - mocked_db.get_strict.return_value = "5" - assert sync_data.sampled_bet_index == 5 - mocked_db.get_strict.assert_called_once_with("sampled_bet_index") - - -def test_is_mech_price_set(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the is_mech_price_set property.""" - mocked_db.get.return_value = True - assert sync_data.is_mech_price_set is True - mocked_db.get.assert_called_once_with("mech_price", False) - - -def test_available_mech_tools( - sync_data: SynchronizedData, mocked_db: MagicMock -) -> None: - """Test the available_mech_tools property.""" - mocked_db.get_strict.return_value = '["tool1", "tool2"]' - assert sync_data.available_mech_tools == ["tool1", "tool2"] - mocked_db.get_strict.assert_called_once_with("available_mech_tools") - - -def test_is_policy_set(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the is_policy_set property.""" - mocked_db.get.return_value = True - assert sync_data.is_policy_set is True - mocked_db.get.assert_called_once_with("policy", False) - - -def test_has_tool_selection_run( - sync_data: SynchronizedData, mocked_db: MagicMock -) -> None: - """Test the has_tool_selection_run property.""" - mocked_db.get.return_value = "tool1" - assert sync_data.has_tool_selection_run is True - mocked_db.get.assert_called_once_with("mech_tool", None) - - -def test_mech_tool(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the mech_tool property.""" - mocked_db.get_strict.return_value = "tool1" - assert sync_data.mech_tool == "tool1" - mocked_db.get_strict.assert_called_once_with("mech_tool") - - -def test_utilized_tools(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the utilized_tools property.""" - mocked_db.get_strict.return_value = '{"tx1": "tool1"}' - assert sync_data.utilized_tools == {"tx1": "tool1"} - mocked_db.get_strict.assert_called_once_with("utilized_tools") - - -def test_redeemed_condition_ids( - sync_data: SynchronizedData, mocked_db: MagicMock -) -> None: - """Test the redeemed_condition_ids property.""" - mocked_db.get.return_value = '["cond1", "cond2"]' - assert sync_data.redeemed_condition_ids == {"cond1", "cond2"} - mocked_db.get.assert_called_once_with("redeemed_condition_ids", None) - - -def test_payout_so_far(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the payout_so_far property.""" - mocked_db.get.return_value = "100" - assert sync_data.payout_so_far == 100 - mocked_db.get.assert_called_once_with("payout_so_far", None) - - -def test_vote(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the vote property.""" - mocked_db.get_strict.return_value = "1" - assert sync_data.vote == 1 - mocked_db.get_strict.assert_called_once_with("vote") - - -def test_confidence(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the confidence property.""" - mocked_db.get_strict.return_value = "0.9" - assert sync_data.confidence == 0.9 - mocked_db.get_strict.assert_called_once_with("confidence") - - -def test_bet_amount(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the bet_amount property.""" - mocked_db.get_strict.return_value = "50" - assert sync_data.bet_amount == 50 - mocked_db.get_strict.assert_called_once_with("bet_amount") - - -def test_is_profitable(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the is_profitable property.""" - mocked_db.get_strict.return_value = True - assert sync_data.is_profitable is True - mocked_db.get_strict.assert_called_once_with("is_profitable") - - -def test_tx_submitter(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the tx_submitter property.""" - mocked_db.get_strict.return_value = "submitter1" - assert sync_data.tx_submitter == "submitter1" - mocked_db.get_strict.assert_called_once_with("tx_submitter") - - -@patch("packages.valory.skills.decision_maker_abci.policy.EGreedyPolicy.deserialize") -def test_policy_property( - mock_deserialize: MagicMock, sync_data: SynchronizedData, mocked_db: MagicMock -) -> None: - """Test for policy property""" - mock_policy_serialized = "serialized_policy_string" - mocked_db.get_strict.return_value = mock_policy_serialized - - expected_policy = EGreedyPolicy( - eps=0.1, consecutive_failures_threshold=1, quarantine_duration=0 - ) - mock_deserialize.return_value = expected_policy - - result = sync_data.policy - - mocked_db.get_strict.assert_called_once_with("policy") - mock_deserialize.assert_called_once_with(mock_policy_serialized) - assert result == expected_policy - - -def test_mech_requests(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the mech_requests property.""" - mocked_db.get.return_value = '[{"request_id": "1", "data": "request_data"}]' - requests = json.loads(mocked_db.get.return_value) - - mech_requests = [ - MechMetadata(request_id=item["request_id"], data=item["data"]) - for item in requests - ] - - assert len(mech_requests) == 1 - assert isinstance(mech_requests[0], MechMetadata) - assert mech_requests[0].request_id == "1" - - -def test_weighted_accuracy(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the weighted_accuracy property.""" - selected_mech_tool = "tool1" - policy_db_name = "policy" - policy_mock = EGreedyPolicy( - eps=0.1, - consecutive_failures_threshold=1, - quarantine_duration=0, - accuracy_store={selected_mech_tool: AccuracyInfo(requests=1)}, - ).serialize() - mocked_db.get_strict = lambda name: ( - policy_mock if name == policy_db_name else selected_mech_tool - ) - policy = EGreedyPolicy.deserialize(policy_mock) - assert selected_mech_tool in policy.weighted_accuracy - assert sync_data.weighted_accuracy == policy.weighted_accuracy[selected_mech_tool] - - -def test_mech_responses(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the mech_responses property.""" - - # Mock the response with empty dictionaries to avoid field mismatches - mocked_db.get.return_value = "[{}, {}]" - - # Access the mech_responses property - responses = sync_data.mech_responses - - # Validate the responses length - assert len(responses) == 2 - - # Test when db.get() returns None - mocked_db.get.return_value = None - responses = sync_data.mech_responses - assert responses == [] - - # Test when db.get() returns an empty list - mocked_db.get.return_value = "[]" - responses = sync_data.mech_responses - assert responses == [] - - -def test_end_block(mocked_db: MagicMock) -> None: - """Test the end_block logic in TxPreparationRound.""" - mocked_sync_data = MagicMock(spec=SynchronizedData) - mock_context = MagicMock() - round_instance = TxPreparationRound( - synchronized_data=mocked_sync_data, context=mock_context - ) - - with patch.object( - TxPreparationRound, "end_block", return_value=(mocked_sync_data, Event.DONE) - ): - result = round_instance.end_block() - assert result == (mocked_sync_data, Event.DONE) - - with patch.object( - TxPreparationRound, "end_block", return_value=(mocked_sync_data, Event.NONE) - ): - result = round_instance.end_block() - assert result == (mocked_sync_data, Event.NONE) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_bet_placement.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_bet_placement.py deleted file mode 100644 index 36128e3fb..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_bet_placement.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -from typing import Any, Dict - -import pytest - -from packages.valory.skills.decision_maker_abci.states.base import Event -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) - - -@pytest.fixture -def bet_placement_round() -> BetPlacementRound: - """Fixture to set up a BetPlacementRound instance for testing.""" - synchronized_data: Dict[str, Any] = {} # Added type annotation - context: Dict[str, Any] = {} # Added type annotation - return BetPlacementRound(synchronized_data, context) - - -def test_initial_event(bet_placement_round: BetPlacementRound) -> None: - """Test that the initial event is set correctly.""" - assert bet_placement_round.none_event == Event.INSUFFICIENT_BALANCE diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_blacklising.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_blacklising.py deleted file mode 100644 index 02b7dba0f..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_blacklising.py +++ /dev/null @@ -1,121 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" -from unittest.mock import MagicMock, patch - -import pytest - -from packages.valory.skills.decision_maker_abci.payloads import BlacklistingPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.blacklisting import ( - BlacklistingRound, -) -from packages.valory.skills.market_manager_abci.rounds import UpdateBetsRound - - -@pytest.fixture -def mocked_context() -> MagicMock: - """Fixture to mock the context.""" - context = MagicMock() - context.benchmarking_mode.enabled = False # Default for the test - return context - - -@pytest.fixture -def mocked_synchronized_data() -> MagicMock: - """Fixture to mock the synchronized data.""" - return MagicMock(spec=SynchronizedData) - - -@pytest.fixture -def blacklisting_round( - mocked_context: MagicMock, mocked_synchronized_data: MagicMock -) -> BlacklistingRound: - """Fixture to create an instance of BlacklistingRound.""" - return BlacklistingRound( - context=mocked_context, synchronized_data=mocked_synchronized_data - ) - - -def test_blacklisting_round_initialization( - blacklisting_round: BlacklistingRound, -) -> None: - """Test the initialization of the BlacklistingRound.""" - assert blacklisting_round.done_event == Event.DONE - assert blacklisting_round.none_event == Event.NONE - assert blacklisting_round.no_majority_event == Event.NO_MAJORITY - assert blacklisting_round.payload_class == BlacklistingPayload - assert isinstance(blacklisting_round.selection_key, tuple) - assert len(blacklisting_round.selection_key) == 2 - - -def test_blacklisting_round_end_block_done_event_no_benchmarking( - blacklisting_round: BlacklistingRound, mocked_context: MagicMock -) -> None: - """Test end_block when event is DONE and benchmarking is disabled.""" - # Mock the superclass end_block to return DONE event - synced_data = MagicMock(spec=SynchronizedData) - with patch.object( - UpdateBetsRound, "end_block", return_value=(synced_data, Event.DONE) - ) as mock_super_end_block: - result = blacklisting_round.end_block() - - mock_super_end_block.assert_called_once() - assert result == (synced_data, Event.DONE) - assert not mocked_context.benchmarking_mode.enabled # Benchmarking disabled - - -def test_blacklisting_round_end_block_done_event_with_benchmarking( - blacklisting_round: BlacklistingRound, mocked_context: MagicMock -) -> None: - """Test end_block when event is DONE and benchmarking is enabled.""" - # Set benchmarking mode to enabled - mocked_context.benchmarking_mode.enabled = True - - # Mock the superclass end_block to return DONE event - synced_data = MagicMock(spec=SynchronizedData) - with patch.object( - UpdateBetsRound, "end_block", return_value=(synced_data, Event.DONE) - ) as mock_super_end_block: - result = blacklisting_round.end_block() - - mock_super_end_block.assert_called_once() - assert result == ( - synced_data, - Event.MOCK_TX, - ) # Should return MOCK_TX since benchmarking is enabled - assert mocked_context.benchmarking_mode.enabled # Benchmarking enabled - - -def test_blacklisting_round_end_block_none_event( - blacklisting_round: BlacklistingRound, -) -> None: - """Test end_block when the superclass returns None.""" - # Mock the superclass end_block to return None - with patch.object( - UpdateBetsRound, "end_block", return_value=None - ) as mock_super_end_block: - result = blacklisting_round.end_block() - - mock_super_end_block.assert_called_once() - assert result is None # Should return None when the superclass returns None diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_check_benchmarking.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_check_benchmarking.py deleted file mode 100644 index ebc2b3c06..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_check_benchmarking.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -from unittest.mock import MagicMock - -from packages.valory.skills.decision_maker_abci.rounds import CheckBenchmarkingModeRound -from packages.valory.skills.decision_maker_abci.states.base import Event -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) - - -def test_check_benchmarking_mode_round_initialization() -> None: - """Test the initialization of CheckBenchmarkingModeRound.""" - round_instance = CheckBenchmarkingModeRound(MagicMock(), MagicMock()) - - # Test that the round is properly initialized with the correct event types - assert round_instance.done_event == Event.BENCHMARKING_ENABLED - assert round_instance.negative_event == Event.BENCHMARKING_DISABLED - - # Check that it inherits from ClaimRound - assert isinstance(round_instance, ClaimRound) - - -def test_check_benchmarking_mode_round_events() -> None: - """Test that the correct events are used in the CheckBenchmarkingModeRound.""" - round_instance = CheckBenchmarkingModeRound(MagicMock(), MagicMock()) - - # Assert that the done_event is BENCHMARKING_ENABLED - assert round_instance.done_event == Event.BENCHMARKING_ENABLED - - # Assert that the negative_event is BENCHMARKING_DISABLED - assert round_instance.negative_event == Event.BENCHMARKING_DISABLED diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_claim_subscription.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_claim_subscription.py deleted file mode 100644 index 48d945d43..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_claim_subscription.py +++ /dev/null @@ -1,227 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -import json -from dataclasses import dataclass, field -from typing import ( - Any, - Callable, - Dict, - FrozenSet, - Hashable, - List, - Mapping, - Optional, - Type, -) -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - CollectionRound, - VotingRound, - get_name, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseVotingRoundTest, -) -from packages.valory.skills.decision_maker_abci.payloads import ClaimPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) - - -# Dummy payload data -DUMMY_PAYLOAD_DATA = {"vote": True} - - -# Data class for test cases -@dataclass -class RoundTestCase: - """Data class to hold round test case details.""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, ClaimPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -# Maximum participants -MAX_PARTICIPANTS: int = 4 - - -# Helper functions for payloads and participants -def get_participants() -> FrozenSet[str]: - """Get participants for the test.""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -def get_participant_to_votes( - participants: FrozenSet[str], vote: bool -) -> Dict[str, ClaimPayload]: - """Map participants to votes.""" - return { - participant: ClaimPayload(sender=participant, vote=vote) - for participant in participants - } - - -def get_participant_to_votes_serialized( - participants: FrozenSet[str], vote: bool -) -> Dict[str, Dict[str, Any]]: - """Get serialized votes from participants.""" - return CollectionRound.serialize_collection( - get_participant_to_votes(participants, vote) - ) - - -def get_payloads( - payload_cls: Type[ClaimPayload], data: Optional[str] -) -> Mapping[str, ClaimPayload]: - """Generate payloads for the test.""" - return { - participant: payload_cls(participant, data is not None) - for participant in get_participants() - } - - -def get_dummy_claim_payload_serialized() -> str: - """Get serialized dummy payload.""" - return json.dumps(DUMMY_PAYLOAD_DATA, sort_keys=True) - - -# Base test class for ClaimRound -class BaseClaimRoundTest(BaseVotingRoundTest): - """Base Test Class for ClaimRound""" - - test_class: Type[VotingRound] - test_payload: Type[ClaimPayload] - - def _test_voting_round( - self, vote: bool, expected_event: Any, threshold_check: Callable - ) -> None: - """Helper method to test voting rounds with positive or negative votes.""" - - test_round = self.test_class( - synchronized_data=self.synchronized_data, context=MagicMock() - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_votes(self.participants, vote=vote), - synchronized_data_update_fn=lambda synchronized_data, test_round: synchronized_data.update( - participant_to_votes=get_participant_to_votes_serialized( - self.participants, vote=vote - ) - ), - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.participant_to_votes.keys() - ] - if vote - else [], - exit_event=expected_event, - threshold_check=threshold_check, - ) - ) - - def test_positive_votes(self) -> None: - """Test ClaimRound with positive votes.""" - self._test_voting_round( - vote=True, - expected_event=self._event_class.DONE, - threshold_check=lambda x: x.positive_vote_threshold_reached, - ) - - def test_negative_votes(self) -> None: - """Test ClaimRound with negative votes.""" - self._test_voting_round( - vote=False, - expected_event=self._event_class.SUBSCRIPTION_ERROR, - threshold_check=lambda x: x.negative_vote_threshold_reached, - ) - - -# Test class for ClaimRound -class TestClaimRound(BaseClaimRoundTest): - """Tests for ClaimRound.""" - - test_class = ClaimRound - _event_class = Event - _synchronized_data_class = SynchronizedData - - @pytest.mark.parametrize( - "test_case", - ( - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_payloads( - ClaimPayload, get_dummy_claim_payload_serialized() - ), - final_data={}, - event=Event.DONE, - most_voted_payload=get_dummy_claim_payload_serialized(), - synchronized_data_attr_checks=[ - lambda sync_data: sync_data.db.get( - get_name(SynchronizedData.participant_to_votes) - ) - == CollectionRound.deserialize_collection( - json.loads(get_dummy_claim_payload_serialized()) - ) - ], - ), - RoundTestCase( - name="No majority", - initial_data={}, - payloads=get_payloads( - ClaimPayload, get_dummy_claim_payload_serialized() - ), - final_data={}, - event=Event.NO_MAJORITY, - most_voted_payload=get_dummy_claim_payload_serialized(), - synchronized_data_attr_checks=[], - ), - ), - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run the parameterized tests.""" - if test_case.event == Event.DONE: - self.test_positive_votes() - elif test_case.event == Event.NO_MAJORITY: - self.test_negative_votes() - - -# Test for SynchronizedData initialization -def test_synchronized_data_initialization() -> None: - """Test SynchronizedData initialization.""" - data = SynchronizedData(db=AbciAppDB(setup_data={"test": ["test"]})) - assert data.db._data == {0: {"test": ["test"]}} diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_receive.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_receive.py deleted file mode 100644 index bcf00f1b1..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_receive.py +++ /dev/null @@ -1,224 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" -import datetime -import json -from dataclasses import dataclass, field -from typing import Any, Callable, Dict, FrozenSet, Hashable, List, Mapping, Optional -from unittest import mock - -import pytest - -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.decision_maker_abci.payloads import DecisionReceivePayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.decision_receive import ( - DecisionReceiveRound, -) -from packages.valory.skills.market_manager_abci.rounds import UpdateBetsPayload - - -DUMMY_DECISION_HASH = "dummy_decision_hash" -DUMMY_PARTICIPANT_TO_DECISION_HASH = json.dumps( - { - "agent_0": "decision_1", - "agent_1": "decision_2", - "agent_2": "decision_3", - } -) -DUMMY_BETS_HASH = "dummy_bets_hash" # Added a dummy bets hash - - -def get_participants() -> FrozenSet[str]: - """Participants.""" - return frozenset([f"agent_{i}" for i in range(4)]) - - -def get_payloads( - vote: Optional[int], - confidence: Optional[float], - bet_amount: Optional[int], - next_mock_data_row: Optional[int], - is_profitable: Optional[bool], - bets_hash: str, - policy: str, -) -> Mapping[str, UpdateBetsPayload]: - """Get payloads.""" - return { - participant: DecisionReceivePayload( - sender=participant, - vote=vote, - confidence=confidence, - bet_amount=bet_amount, - next_mock_data_row=next_mock_data_row, - is_profitable=is_profitable, - bets_hash=bets_hash, - policy=policy, - decision_received_timestamp=int(datetime.datetime.utcnow().timestamp()), - ) - for participant in get_participants() - } - - -@dataclass -class RoundTestCase: - """RoundTestCase for DecisionReceiveRound.""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, UpdateBetsPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -class TestDecisionReceiveRound(BaseCollectSameUntilThresholdRoundTest): - """Tests for DecisionReceiveRound.""" - - _synchronized_data_class = SynchronizedData - - @pytest.mark.parametrize( - "test_case", - ( - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_payloads( - vote=1, - confidence=80.0, - bet_amount=100, - next_mock_data_row=1, - is_profitable=True, - policy="", - bets_hash=DUMMY_BETS_HASH, # Added bets_hash - ), - final_data={ - "decision_hash": DUMMY_DECISION_HASH, - "participant_to_decision_hash": DUMMY_PARTICIPANT_TO_DECISION_HASH, - }, - event=Event.DONE, - most_voted_payload=DUMMY_DECISION_HASH, - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.decision_hash, - ], - ), - RoundTestCase( - name="Unprofitable decision", - initial_data={"is_profitable": False}, - payloads=get_payloads( - vote=0, - confidence=50.0, - bet_amount=50, - next_mock_data_row=2, - is_profitable=False, - policy="", - bets_hash=DUMMY_BETS_HASH, # Added bets_hash - ), - final_data={ - "decision_hash": DUMMY_DECISION_HASH, - "participant_to_decision_hash": DUMMY_PARTICIPANT_TO_DECISION_HASH, - }, - event=Event.UNPROFITABLE, - most_voted_payload=DUMMY_DECISION_HASH, - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.decision_hash, - ], - ), - RoundTestCase( - name="No majority", - initial_data={}, - payloads=get_payloads( - vote=None, - confidence=None, - bet_amount=None, - next_mock_data_row=None, - is_profitable=True, - policy="", - bets_hash=DUMMY_BETS_HASH, # Added bets_hash - ), - final_data={}, - event=Event.NO_MAJORITY, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - RoundTestCase( - name="Tie event", - initial_data={}, - payloads=get_payloads( - vote=None, - confidence=None, - bet_amount=None, - next_mock_data_row=None, - is_profitable=True, - policy="", - bets_hash=DUMMY_BETS_HASH, # Added bets_hash - ), - final_data={}, - event=Event.TIE, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - RoundTestCase( - name="Mechanism response error", - initial_data={"mocking_mode": True}, - payloads=get_payloads( - vote=None, - confidence=None, - bet_amount=None, - next_mock_data_row=None, - is_profitable=True, - policy="", - bets_hash=DUMMY_BETS_HASH, # Added bets_hash - ), - final_data={}, - event=Event.MECH_RESPONSE_ERROR, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - ), - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run tests.""" - self.run_test(test_case) - - def run_test(self, test_case: RoundTestCase) -> None: - """Run the test.""" - self.synchronized_data.update(SynchronizedData, **test_case.initial_data) - - test_round = DecisionReceiveRound( - synchronized_data=self.synchronized_data, context=mock.MagicMock() - ) - - self._test_round( - test_round=test_round, - round_payloads=test_case.payloads, - synchronized_data_update_fn=lambda sync_data, _: sync_data.update( - **test_case.final_data - ), - synchronized_data_attr_checks=test_case.synchronized_data_attr_checks, - most_voted_payload=test_case.most_voted_payload, - exit_event=test_case.event, - ) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_request.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_request.py deleted file mode 100644 index e1a9003a3..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_request.py +++ /dev/null @@ -1,157 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -import json -from dataclasses import dataclass, field -from typing import Any, Callable, Dict, FrozenSet, Hashable, List, Mapping, Optional -from unittest import mock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.decision_maker_abci.payloads import DecisionRequestPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.decision_request import ( - DecisionRequestRound, -) - - -DUMMY_REQUEST_HASH = "dummy_request_hash" -DUMMY_PARTICIPANT_TO_SELECTION_HASH = json.dumps( - { - "agent_0": "selection_1", - "agent_1": "selection_2", - "agent_2": "selection_3", - } -) - - -def get_participants() -> FrozenSet[str]: - """Participants.""" - return frozenset([f"agent_{i}" for i in range(4)]) - - -def get_payloads(data: Optional[str]) -> Mapping[str, BaseTxPayload]: - """Get payloads.""" - return { - participant: DecisionRequestPayload(participant, data) - for participant in get_participants() - } - - -@dataclass -class RoundTestCase: - """RoundTestCase for DecisionRequestRound.""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, BaseTxPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -class TestDecisionRequestRound(BaseCollectSameUntilThresholdRoundTest): - """Tests for DecisionRequestRound.""" - - _synchronized_data_class = SynchronizedData # Define the missing attribute - - @pytest.mark.parametrize( - "test_case", - ( - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_payloads(data=DUMMY_REQUEST_HASH), - final_data={ - "request_hash": DUMMY_REQUEST_HASH, - "participant_to_selection_hash": DUMMY_PARTICIPANT_TO_SELECTION_HASH, - }, - event=Event.DONE, - most_voted_payload=DUMMY_REQUEST_HASH, - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.request_hash, - ], - ), - RoundTestCase( - name="Mocking mode", - initial_data={"mocking_mode": True}, - payloads=get_payloads(data=DUMMY_REQUEST_HASH), - final_data={ - "request_hash": DUMMY_REQUEST_HASH, - "participant_to_selection_hash": DUMMY_PARTICIPANT_TO_SELECTION_HASH, - }, - event=Event.MOCK_MECH_REQUEST, - most_voted_payload=DUMMY_REQUEST_HASH, - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.request_hash, - ], - ), - RoundTestCase( - name="No majority", - initial_data={}, - payloads=get_payloads(data=None), # Simulating insufficient votes - final_data={}, - event=Event.NO_MAJORITY, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - RoundTestCase( - name="None event", - initial_data={}, - payloads=get_payloads(data=None), # Simulating unsupported slots - final_data={}, - event=Event.SLOTS_UNSUPPORTED_ERROR, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - ), - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run tests.""" - self.run_test(test_case) - - def run_test(self, test_case: RoundTestCase) -> None: - """Run the test.""" - self.synchronized_data.update(SynchronizedData, **test_case.initial_data) - - test_round = DecisionRequestRound( - synchronized_data=self.synchronized_data, context=mock.MagicMock() - ) - - self._test_round( - test_round=test_round, - round_payloads=test_case.payloads, - synchronized_data_update_fn=lambda sync_data, _: sync_data.update( - **test_case.final_data - ), - synchronized_data_attr_checks=test_case.synchronized_data_attr_checks, - most_voted_payload=test_case.most_voted_payload, - exit_event=test_case.event, - ) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_final_states.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_final_states.py deleted file mode 100644 index 60e26a15b..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_final_states.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -from typing import Any, Dict, List, Tuple - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - BaseSynchronizedData, - DegenerateRound, -) -from packages.valory.skills.decision_maker_abci.states.final_states import ( - BenchmarkingDoneRound, - BenchmarkingModeDisabledRound, - FinishedDecisionMakerRound, - FinishedDecisionRequestRound, - FinishedSubscriptionRound, - FinishedWithoutDecisionRound, - FinishedWithoutRedeemingRound, - ImpossibleRound, - RefillRequiredRound, -) - - -class MockSynchronizedData(BaseSynchronizedData): - """A mock class for SynchronizedData.""" - - def __init__(self, db: AbciAppDB) -> None: - """Mock function""" - super().__init__(db) # Pass db to the parent class - - -class MockContext: - """A mock class for context used in the rounds.""" - - def __init__(self) -> None: - """Mock function""" - self.some_attribute = "mock_value" # Add any necessary attributes here - - -class TestFinalStates: - """The class for test of Final States""" - - @pytest.fixture - def setup_round(self) -> Tuple[MockSynchronizedData, MockContext]: - """Fixture to set up a round instance.""" - setup_data: Dict[str, List[Any]] = {} - mock_db = AbciAppDB(setup_data) - synchronized_data = MockSynchronizedData(db=mock_db) # Provide a mock db value - context = MockContext() - return synchronized_data, context - - def test_benchmarking_mode_disabled_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of BenchmarkingModeDisabledRound.""" - synchronized_data, context = setup_round - round_instance = BenchmarkingModeDisabledRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, BenchmarkingModeDisabledRound) - assert isinstance(round_instance, DegenerateRound) - - def test_finished_decision_maker_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of FinishedDecisionMakerRound.""" - synchronized_data, context = setup_round - round_instance = FinishedDecisionMakerRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, FinishedDecisionMakerRound) - assert isinstance(round_instance, DegenerateRound) - - def test_finished_decision_request_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of FinishedDecisionRequestRound.""" - synchronized_data, context = setup_round - round_instance = FinishedDecisionRequestRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, FinishedDecisionRequestRound) - assert isinstance(round_instance, DegenerateRound) - - def test_finished_subscription_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of FinishedSubscriptionRound.""" - synchronized_data, context = setup_round - round_instance = FinishedSubscriptionRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, FinishedSubscriptionRound) - assert isinstance(round_instance, DegenerateRound) - - def test_finished_without_redeeming_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of FinishedWithoutRedeemingRound.""" - synchronized_data, context = setup_round - round_instance = FinishedWithoutRedeemingRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, FinishedWithoutRedeemingRound) - assert isinstance(round_instance, DegenerateRound) - - def test_finished_without_decision_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of FinishedWithoutDecisionRound.""" - synchronized_data, context = setup_round - round_instance = FinishedWithoutDecisionRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, FinishedWithoutDecisionRound) - assert isinstance(round_instance, DegenerateRound) - - def test_refill_required_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of RefillRequiredRound.""" - synchronized_data, context = setup_round - round_instance = RefillRequiredRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, RefillRequiredRound) - assert isinstance(round_instance, DegenerateRound) - - def test_benchmarking_done_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of BenchmarkingDoneRound and its end_block method.""" - synchronized_data, context = setup_round - round_instance = BenchmarkingDoneRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, BenchmarkingDoneRound) - assert isinstance(round_instance, DegenerateRound) - - # Test the end_block method - with pytest.raises(SystemExit): - round_instance.end_block() # Should exit the program - - def test_impossible_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of ImpossibleRound.""" - synchronized_data, context = setup_round - round_instance = ImpossibleRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, ImpossibleRound) - assert isinstance(round_instance, DegenerateRound) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_handle_failed_tx.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_handle_failed_tx.py deleted file mode 100644 index 53fe7db7d..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_handle_failed_tx.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -from typing import Dict, Optional -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import CollectionRound -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.decision_maker_abci.payloads import HandleFailedTxPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.handle_failed_tx import ( - HandleFailedTxRound, -) - - -class TestEstimateConsensusRound(BaseCollectSameUntilThresholdRoundTest): - """Test EstimateConsensusRound.""" - - _synchronized_data_class = SynchronizedData - _event_class = Event - - def get_participant_to_handle( - self, vote: Optional[bool] - ) -> Dict[str, HandleFailedTxPayload]: - """Map participants to votes.""" - return { - participant: HandleFailedTxPayload( - sender=participant, vote=vote, tx_submitter="tx_submitter" # type: ignore - ) - for participant in self.participants - } - - @pytest.mark.parametrize( - "vote, expected_event", - ( - (None, HandleFailedTxRound.none_event), - (True, HandleFailedTxRound.done_event), - (False, HandleFailedTxRound.no_op_event), - ), - ) - def test_run( - self, - vote: Optional[bool], - expected_event: Event, - ) -> None: - """Runs test.""" - - test_round = HandleFailedTxRound( - synchronized_data=self.synchronized_data, context=MagicMock() - ) - participant_to_handle = self.get_participant_to_handle(vote) - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=participant_to_handle, - synchronized_data_update_fn=lambda _synchronized_data, _test_round: _synchronized_data.update( - participant_to_handle_failed_tx=CollectionRound.serialize_collection( - participant_to_handle - ), - most_voted_estimate=_test_round.most_voted_payload, - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.participant_to_handle_failed_tx.keys() - ], - most_voted_payload=vote, - exit_event=expected_event, - ) - ) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_order_subscription.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_order_subscription.py deleted file mode 100644 index 82c026e62..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_order_subscription.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -from typing import Any, Optional, Type -from unittest.mock import MagicMock, patch - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - BaseSynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.base import Event -from packages.valory.skills.decision_maker_abci.states.order_subscription import ( - SubscriptionRound, -) - - -# Dummy values for testing -class MockSynchronizedData(BaseSynchronizedData): - """The class for testing""" - - def __init__(self, db: AbciAppDB) -> None: - """Mock""" - super().__init__(db=db) - self.agreement_id: Optional[str] = "dummy_agreement_id" - - def update( - self, synchronized_data_class: Optional[Type[Any]] = None, **kwargs: Any - ) -> "MockSynchronizedData": - """Mock the update method to simulate updating agreement_id.""" - updated_data = self.__class__( - self.db - ) # Use self.db directly as AbciAppDB might not have a 'copy' method - updated_data.__dict__.update(kwargs) - return updated_data - - -@pytest.fixture -def setup_subscription_round() -> SubscriptionRound: - """Fixture to set up a basic SubscriptionRound instance.""" - mock_synchronized_data = MockSynchronizedData( - db=AbciAppDB(setup_data={}) - ) # Ensure setup_data is passed - round_instance = SubscriptionRound( - synchronized_data=mock_synchronized_data, context=MagicMock() - ) - return round_instance - - -def test_threshold_reached_with_error( - setup_subscription_round: SubscriptionRound, -) -> None: - """Test when the threshold is reached and the transaction is an error.""" - round_instance = setup_subscription_round - with patch.object( - SubscriptionRound, - "threshold_reached", - new_callable=MagicMock(return_value=True), - ): - with patch.object( - SubscriptionRound, - "most_voted_payload_values", - new_callable=MagicMock(return_value=[None, round_instance.ERROR_PAYLOAD]), - ): - result = round_instance.end_block() - - assert result == ( - round_instance.synchronized_data, - Event.SUBSCRIPTION_ERROR, - ) - - -def test_threshold_reached_with_no_tx( - setup_subscription_round: SubscriptionRound, -) -> None: - """Test when the threshold is reached and there's no transaction.""" - round_instance = setup_subscription_round - with patch.object( - SubscriptionRound, - "threshold_reached", - new_callable=MagicMock(return_value=True), - ): - with patch.object( - SubscriptionRound, - "most_voted_payload_values", - new_callable=MagicMock(return_value=[None, round_instance.NO_TX_PAYLOAD]), - ): - result = round_instance.end_block() - - assert result == (round_instance.synchronized_data, Event.NO_SUBSCRIPTION) - - -def test_threshold_reached_with_mock_tx( - setup_subscription_round: SubscriptionRound, -) -> None: - """Test when the threshold is reached and benchmarking mode is enabled.""" - round_instance = setup_subscription_round - round_instance.context.benchmarking_mode.enabled = True - with patch.object( - SubscriptionRound, - "threshold_reached", - new_callable=MagicMock(return_value=True), - ): - with patch.object( - SubscriptionRound, - "most_voted_payload_values", - new_callable=MagicMock(return_value=[None, "mock_tx_hash"]), - ): - result = round_instance.end_block() - - assert result == (round_instance.synchronized_data, Event.MOCK_TX) - - -def test_end_block_updates_sync_data( - setup_subscription_round: SubscriptionRound, -) -> None: - """Test if the agreement_id is correctly updated in synchronized data.""" - round_instance = setup_subscription_round - # Patch the `most_voted_payload_values` to return a list with the new agreement ID - with patch.object( - SubscriptionRound, - "most_voted_payload_values", - new_callable=MagicMock( - return_value=[None, None, None, "new_agreement_id", 10000] - ), - ): - # Call the `end_block` method to trigger the update - result = round_instance.end_block() - # Check the updated synchronized_data object returned by end_block - if result is not None: - sync_data, event = result - # Assert that the agreement_id was updated to the new_agreement_id - assert getattr(sync_data, "agreement_id", None) == "new_agreement_id" - assert getattr(sync_data, "wallet_balance", None) == 10000 - assert event is not None - - -def test_no_update_when_threshold_not_reached( - setup_subscription_round: SubscriptionRound, -) -> None: - """Test when the threshold is not reached, there should be no changes.""" - round_instance = setup_subscription_round - with patch.object( - SubscriptionRound, - "threshold_reached", - new_callable=MagicMock(return_value=False), - ): - with patch( - "packages.valory.skills.decision_maker_abci.states.order_subscription.SubscriptionRound.end_block", - return_value=None, - ) as mock_super: - result = round_instance.end_block() - - assert result is None - mock_super.assert_called_once() diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_randomness.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_randomness.py deleted file mode 100644 index 4dd8e6256..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_randomness.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 test cases for the RandomnessRound class.""" - -import pytest - -from packages.valory.skills.decision_maker_abci.rounds import RandomnessRound -from packages.valory.skills.decision_maker_abci.states.base import Event -from packages.valory.skills.transaction_settlement_abci.rounds import ( - RandomnessTransactionSubmissionRound, -) - - -class MockSynchronizedData: - """A mock class for SynchronizedData to provide necessary attributes.""" - - pass - - -class MockContext: - """A mock class for context used in RandomnessTransactionSubmissionRound.""" - - def __init__(self) -> None: - """Initialize the MockContext with necessary attributes.""" - self.sender = "mock_sender" - - -class TestRandomnessRound: - """Test suite for the RandomnessRound class.""" - - @pytest.fixture - def setup_randomness_round(self) -> RandomnessRound: - """Fixture to set up a RandomnessRound instance.""" - context = MockContext() - synchronized_data = MockSynchronizedData() - return RandomnessRound(context=context, synchronized_data=synchronized_data) - - def test_randomness_round_properties( - self, setup_randomness_round: RandomnessRound - ) -> None: - """Test the properties of the RandomnessRound class.""" - randomness_round = setup_randomness_round - - assert randomness_round.done_event == Event.DONE - assert randomness_round.no_majority_event == Event.NO_MAJORITY - - def test_randomness_round_inherits_randomness_transaction_submission_round( - self, - ) -> None: - """Test that RandomnessRound inherits from RandomnessTransactionSubmissionRound.""" - assert issubclass(RandomnessRound, RandomnessTransactionSubmissionRound) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_redeem.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_redeem.py deleted file mode 100644 index a35c9c084..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_redeem.py +++ /dev/null @@ -1,170 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test for Redeem round""" - -from typing import Any, Dict, Optional -from unittest.mock import PropertyMock, patch - -import pytest - -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.redeem import RedeemRound - - -class MockDB(AbciAppDB): - """Mock database for testing.""" - - def __init__(self) -> None: - """Initialize the mock database.""" - setup_data: Dict[str, Any] = {} - super().__init__(setup_data=setup_data) - self.data: Dict[str, Optional[int]] = {} - - def get(self, key: str, default: Optional[int] = None) -> Optional[int]: - """Get value from mock db.""" - return self.data.get(key, default) - - def update(self, **kwargs: Any) -> None: - """Update mock db.""" - self.data.update(kwargs) - - -class MockSynchronizedData(SynchronizedData): - """Mock synchronized data for testing.""" - - def __init__(self) -> None: - """Initialize mock synchronized data.""" - db = MockDB() - super().__init__(db) - self._period_count = 0 - - @property - def period_count(self) -> int: - """Get period count.""" - return self._period_count - - @period_count.setter - def period_count(self, value: int) -> None: - """Set period count.""" - self._period_count = value - - -class MockContext: - """Mock context for testing.""" - - def __init__(self) -> None: - """Initialize mock context.""" - self.params: Dict[str, Optional[int]] = {} - - -class TestRedeemRound: - """Tests for the RedeemRound class.""" - - @pytest.fixture - def setup_redeem_round(self) -> RedeemRound: - """Set up a RedeemRound instance.""" - mock_synchronized_data = MockSynchronizedData() - mock_context = MockContext() - redeem_round = RedeemRound( - context=mock_context, synchronized_data=mock_synchronized_data - ) - return redeem_round - - def test_initial_attributes(self, setup_redeem_round: RedeemRound) -> None: - """Test initial attributes.""" - redeem_round = setup_redeem_round - assert redeem_round.payload_class is not None - assert redeem_round.payload_class.__name__ == "RedeemPayload" - assert redeem_round.none_event == Event.NO_REDEEMING - - def test_selection_key(self, setup_redeem_round: RedeemRound) -> None: - """Test selection key generation.""" - redeem_round = setup_redeem_round - assert isinstance(redeem_round.selection_key, tuple) - assert all(isinstance(key, str) for key in redeem_round.selection_key) - - def test_selection_key_contains_mech_tools_name( - self, setup_redeem_round: RedeemRound - ) -> None: - """Test that mech_tools_name is part of the selection key.""" - redeem_round = setup_redeem_round - assert RedeemRound.mech_tools_name in redeem_round.selection_key - - @pytest.mark.parametrize( - "period_count, expected_confirmations, expected_event", - [ - (0, 1, Event.NO_MAJORITY), # Test without update - (1, 0, Event.NO_MAJORITY), # Test with update - ], - ) - def test_end_block_update_behavior( - self, - setup_redeem_round: RedeemRound, - period_count: int, - expected_confirmations: int, - expected_event: Event, - ) -> None: - """Test end_block behavior based on period_count.""" - redeem_round = setup_redeem_round - - with patch.object( - MockSynchronizedData, "period_count", new_callable=PropertyMock - ) as mock_period_count: - mock_period_count.return_value = period_count - - result = redeem_round.end_block() - - if result is None: - # Case where no update occurs - assert redeem_round.block_confirmations == expected_confirmations - else: - # Case where update occurs - synchronized_data, event = result - assert isinstance(synchronized_data, MockSynchronizedData) - assert event == expected_event - - def test_most_voted_payload_values(self, setup_redeem_round: RedeemRound) -> None: - """Test most_voted_payload_values property.""" - redeem_round = setup_redeem_round - # Mock `most_voted_payload_values` to return the expected result - with patch.object( - RedeemRound, "most_voted_payload_values", new_callable=PropertyMock - ) as mock_values: - mock_values.return_value = (None,) - values = redeem_round.most_voted_payload_values - assert values == (None,) - - def test_most_voted_payload_dict_processing( - self, setup_redeem_round: RedeemRound - ) -> None: - """Test processing of most_voted_payload_dict in most_voted_payload_values.""" - redeem_round = setup_redeem_round - # Mock `most_voted_payload_values` to simulate dictionary processing in the property - with patch.object( - RedeemRound, "most_voted_payload_values", new_callable=PropertyMock - ) as mock_values: - mock_values.return_value = ("tool_data",) - - values = redeem_round.most_voted_payload_values - assert values is not None # Ensure it executes without error diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_sampling.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_sampling.py deleted file mode 100644 index 50594d9bd..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_sampling.py +++ /dev/null @@ -1,118 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -import pytest - -from packages.valory.skills.abstract_round_abci.base import AbciAppDB, get_name -from packages.valory.skills.decision_maker_abci.payloads import SamplingPayload -from packages.valory.skills.decision_maker_abci.rounds import SamplingRound -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.market_manager_abci.rounds import UpdateBetsRound - - -# Mock classes to simulate required attributes -class MockSynchronizedData(SynchronizedData): - """A mock class for SynchronizedData to provide necessary attributes.""" - - sampled_bet_index = 0 # Default value for sampled_bet_index - benchmarking_finished = False - simulated_day = False - - def __init__(self, db: AbciAppDB): - """Initialize MockSynchronizedData with the given db.""" - super().__init__(db) - - -class MockContext: - """A mock class for context used in AbstractRound.""" - - def __init__(self) -> None: - """Mock function""" - self.sender = "mock_sender" - self.bets_hash = "mock_bets_hash" - - -class TestSamplingRound: - """The class for testing Sampling Round""" - - @pytest.fixture - def setup_sampling_round(self) -> SamplingRound: - """Fixture to set up a SamplingRound instance.""" - context = MockContext() - synchronized_data = MockSynchronizedData( - db=AbciAppDB({}) - ) # Passing a mock AbciAppDB instance - return SamplingRound(context=context, synchronized_data=synchronized_data) - - def test_sampling_round_properties( - self, setup_sampling_round: SamplingRound - ) -> None: - """Test the properties of the SamplingRound class.""" - sampling_round = setup_sampling_round - assert sampling_round.payload_class == SamplingPayload - assert sampling_round.done_event == Event.DONE - assert sampling_round.none_event == Event.NONE - assert sampling_round.no_majority_event == Event.NO_MAJORITY - assert sampling_round.selection_key is not None - - def test_sampling_payload_initialization(self) -> None: - """Test the initialization of the SamplingPayload.""" - payload = SamplingPayload( - sender="mock_sender", - bets_hash="mock_bets_hash", - index=0, - benchmarking_finished=False, - day_increased=False, - ) # Added index - assert payload is not None - assert payload.sender == "mock_sender" - assert payload.bets_hash == "mock_bets_hash" - assert payload.index == 0 # Check that the index is correctly initialized - - def test_sampling_round_inherits_update_bets_round(self) -> None: - """Test that SamplingRound inherits from UpdateBetsRound.""" - assert issubclass(SamplingRound, UpdateBetsRound) - - def test_sampling_round_selection_key( - self, setup_sampling_round: SamplingRound - ) -> None: - """Test the selection key property of SamplingRound.""" - sampling_round = setup_sampling_round - expected_selection_key = ( - UpdateBetsRound.selection_key, - get_name(SynchronizedData.sampled_bet_index), - get_name(SynchronizedData.benchmarking_finished), - get_name(SynchronizedData.simulated_day), - # Pass the property, not the value - ) - assert sampling_round.selection_key == expected_selection_key - - def test_sampling_round_event_handling( - self, setup_sampling_round: SamplingRound - ) -> None: - """Test event handling in SamplingRound.""" - sampling_round = setup_sampling_round - # Simulate event handling through method calls or appropriate property checks - assert sampling_round.done_event == Event.DONE - assert sampling_round.no_majority_event == Event.NO_MAJORITY diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_tool_selection.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_tool_selection.py deleted file mode 100644 index 583b774e0..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/states/test_tool_selection.py +++ /dev/null @@ -1,149 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - - -from dataclasses import dataclass, field -from typing import Any, Callable, Dict, Hashable, List, Mapping, Optional -from unittest import mock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.decision_maker_abci.payloads import ToolSelectionPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.tool_selection import ( - ToolSelectionRound, -) - - -DUMMY_TOOL_SELECTION_HASH = "dummy_tool_selection_hash" -DUMMY_POLICY = "dummy_policy" -DUMMY_UTILIZED_TOOLS = "dummy_utilized_tools" -DUMMY_MECH_TOOLS = "dummy_mech_tools" -DUMMY_SELECTED_TOOL = "dummy_selected_tool" -DUMMY_PARTICIPANT_TO_SELECTION_HASH = ( - '{"agent_0": "tool_1", "agent_1": "tool_2", "agent_2": "tool_3"}' -) - - -def get_participants() -> List[str]: - """Returns a list of participants.""" - return [f"agent_{i}" for i in range(4)] - - -def get_payloads(data: Optional[str]) -> Mapping[str, BaseTxPayload]: - """Returns payloads for the test.""" - return { - participant: ToolSelectionPayload( - participant, - policy=DUMMY_POLICY, - utilized_tools=DUMMY_UTILIZED_TOOLS, - selected_tool=data, - mech_tools=DUMMY_MECH_TOOLS, # Add the missing mech_tools argument - ) - for participant in get_participants() - } - - -@dataclass -class RoundTestCase: - """Test case structure for ToolSelectionRound.""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, BaseTxPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -class TestToolSelectionRound(BaseCollectSameUntilThresholdRoundTest): - """Tests for ToolSelectionRound.""" - - _synchronized_data_class = SynchronizedData - - @pytest.mark.parametrize( - "test_case", - [ - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_payloads(data=DUMMY_TOOL_SELECTION_HASH), - final_data={ - "mech_tool": DUMMY_TOOL_SELECTION_HASH, - "participant_to_selection_hash": DUMMY_PARTICIPANT_TO_SELECTION_HASH, - }, - event=Event.DONE, - most_voted_payload=DUMMY_TOOL_SELECTION_HASH, - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.mech_tool, - ], - ), - RoundTestCase( - name="No majority", - initial_data={}, - payloads=get_payloads(data=None), # Simulating no majority - final_data={}, - event=Event.NO_MAJORITY, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - RoundTestCase( - name="None event", - initial_data={}, - payloads=get_payloads(data=None), # Simulating unsupported selection - final_data={}, - event=Event.NONE, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - ], - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run each test case.""" - self.run_test(test_case) - - def run_test(self, test_case: RoundTestCase) -> None: - """Run a single test case.""" - self.synchronized_data.update(SynchronizedData, **test_case.initial_data) - - test_round = ToolSelectionRound( - synchronized_data=self.synchronized_data, context=mock.MagicMock() - ) - - self._test_round( - test_round=test_round, - round_payloads=test_case.payloads, - synchronized_data_update_fn=lambda sync_data, _: sync_data.update( - **test_case.final_data - ), - synchronized_data_attr_checks=test_case.synchronized_data_attr_checks, - most_voted_payload=test_case.most_voted_payload, - exit_event=test_case.event, - ) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_dialogues.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_dialogues.py deleted file mode 100644 index f2be77cd6..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.decision_maker_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_handlers.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_handlers.py deleted file mode 100644 index f934bbbe4..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_handlers.py +++ /dev/null @@ -1,381 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the tests for the handlers for the decision maker abci.""" -import json -from dataclasses import dataclass -from typing import Any, Dict, Union -from unittest import mock -from unittest.mock import MagicMock, patch - -import pytest -from aea.configurations.data_types import PublicId -from aea.skills.base import Handler - -from packages.valory.connections.http_server.connection import ( - PUBLIC_ID as HTTP_SERVER_PUBLIC_ID, -) -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.decision_maker_abci.handlers import ( - ABCIHandler, - ContractApiHandler, - HttpHandler, - HttpMethod, - IpfsHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, -) - - -@dataclass -class GetHandlerTestCase: - """Get Handler test case.""" - - name: str - url: str - method: str - expected_handler: Union[str, None] - - -@dataclass -class HandleTestCase: - """Handle test case.""" - - name: str - message_performative: str - message_sender: str - get_handler_return_value: tuple - message_url: Union[str, None] = None - message_method: Union[str, None] = None - update_return_value: Union[MagicMock, None] = None - expected_logger_call: Union[str, None] = None - expected_handler_call: bool = False - - -@pytest.mark.parametrize( - "handler, base_handler", - [ - (ABCIHandler, BaseABCIRoundHandler), - (SigningHandler, BaseSigningHandler), - (LedgerApiHandler, BaseLedgerApiHandler), - (ContractApiHandler, BaseContractApiHandler), - (TendermintHandler, BaseTendermintHandler), - ], -) -def test_handler(handler: Handler, base_handler: Handler) -> None: - """Test that the 'handlers.py' of the DecisionMakerAbci can be imported.""" - handler = handler( - name="dummy_handler", - skill_context=MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")), - ) - - assert isinstance(handler, base_handler) - - -class TestIpfsHandler: - """Class for testing the IPFS Handler.""" - - def setup(self) -> None: - """Set up the tests.""" - self.context = MagicMock() - self.handler = IpfsHandler(name="", skill_context=self.context) - - def test_handle(self) -> None: - """Test the 'handle' method.""" - callback = MagicMock() - request_reference = "reference" - self.handler.shared_state.req_to_callback = {} - self.handler.shared_state.req_to_callback[request_reference] = callback - - mock_dialogue = MagicMock() - mock_dialogue.dialogue_label.dialogue_reference = [request_reference] - - with mock.patch.object( - self.handler.context.ipfs_dialogues, "update", return_value=mock_dialogue - ): - mock_message = MagicMock(performative=IpfsMessage.Performative.FILES) - self.handler.handle(mock_message) - - callback.assert_called_once_with(mock_message, mock_dialogue) - - def test_handle_negative_performative_not_allowed(self) -> None: - """Test the 'handle' method, negative case (performative not allowed).""" - self.handler.handle(MagicMock()) - - -class TestHttpHandler: - """Class for testing the Http Handler.""" - - def setup(self) -> None: - """Set up the tests.""" - self.context = MagicMock() - self.context.logger = MagicMock() - self.handler = HttpHandler(name="", skill_context=self.context) - self.handler.context.params.service_endpoint = "http://localhost:8080/some/path" - self.handler.setup() - - def test_setup(self) -> None: - """Test the setup method of HttpHandler.""" - - config_uri_base_hostname = "localhost" - propel_uri_base_hostname = ( - r"https?:\/\/[a-zA-Z0-9]{16}.agent\.propel\.(staging\.)?autonolas\.tech" - ) - local_ip_regex = r"192\.168(\.\d{1,3}){2}" - hostname_regex = rf".*({config_uri_base_hostname}|{propel_uri_base_hostname}|{local_ip_regex}|localhost|127.0.0.1|0.0.0.0)(:\d+)?" - health_url_regex = rf"{hostname_regex}\/healthcheck" - assert self.handler.handler_url_regex == rf"{hostname_regex}\/.*" - assert self.handler.routes == { - (HttpMethod.GET.value, HttpMethod.HEAD.value): [ - (health_url_regex, self.handler._handle_get_health), - ], - } - assert self.handler.json_content_header == "Content-Type: application/json\n" - - @pytest.mark.parametrize( - "test_case", - [ - GetHandlerTestCase( - name="Happy Path", - url="http://localhost:8080/healthcheck", - method=HttpMethod.GET.value, - expected_handler="_handle_get_health", - ), - GetHandlerTestCase( - name="No url match", - url="http://invalid.url/not/matching", - method=HttpMethod.GET.value, - expected_handler=None, - ), - GetHandlerTestCase( - name="No method match", - url="http://localhost:8080/some/path", - method=HttpMethod.POST.value, - expected_handler="_handle_bad_request", - ), - ], - ) - def test_get_handler(self, test_case: GetHandlerTestCase) -> None: - """Test _get_handler.""" - url = test_case.url - method = test_case.method - - if test_case.expected_handler is not None: - expected_handler = getattr(self.handler, test_case.expected_handler) - else: - expected_handler = test_case.expected_handler - expected_captures: Dict[Any, Any] = {} - - handler, captures = self.handler._get_handler(url, method) - - assert handler == expected_handler - assert captures == expected_captures - - @pytest.mark.parametrize( - "test_case", - [ - HandleTestCase( - name="Test Handle", - message_performative=HttpMessage.Performative.RESPONSE, - message_sender="incorrect sender", - get_handler_return_value=(None, {}), - ), - HandleTestCase( - name="Test Handle No Handler", - message_performative=HttpMessage.Performative.REQUEST, - message_sender=str(HTTP_SERVER_PUBLIC_ID.without_hash()), - message_url="http://localhost/test", - message_method="GET", - get_handler_return_value=(None, {}), - ), - HandleTestCase( - name="Test Handle Invalid Dialogue", - message_performative=HttpMessage.Performative.REQUEST, - message_sender=str(HTTP_SERVER_PUBLIC_ID.without_hash()), - message_url="http://localhost/test", - message_method="GET", - get_handler_return_value=(lambda x, y: None, {}), - update_return_value=None, - expected_logger_call="Received invalid http message={}, unidentified dialogue.", - ), - HandleTestCase( - name="Test Handle Valid Message", - message_performative=HttpMessage.Performative.REQUEST, - message_sender=str(HTTP_SERVER_PUBLIC_ID.without_hash()), - message_url="http://localhost/test", - message_method="GET", - get_handler_return_value=(MagicMock(), {"key": "value"}), - update_return_value=MagicMock(), - expected_handler_call=True, - expected_logger_call="Received http request with method={}, url={} and body={!r}", - ), - ], - ) - def test_handle(self, test_case: HandleTestCase) -> None: - """Parameterized test for 'handle' method.""" - - self.message = MagicMock(performative=test_case.message_performative) - self.message.sender = test_case.message_sender - self.message.url = test_case.message_url - self.message.method = test_case.message_method - - with patch.object( - self.handler, - "_get_handler", - return_value=test_case.get_handler_return_value, - ), patch.object( - BaseHttpHandler, "handle", return_value=None - ) as mock_super_handle: - if not test_case.expected_logger_call: - self.handler.handle(self.message) - mock_super_handle.assert_called_once_with(self.message) - else: - http_dialogues_mock = MagicMock() - self.context.http_dialogues = http_dialogues_mock - http_dialogues_mock.update.return_value = test_case.update_return_value - self.handler.handle(self.message) - - if not test_case.expected_handler_call: - self.context.logger.info.assert_called_with( - test_case.expected_logger_call.format(self.message) - ) - else: - test_case.get_handler_return_value[0].assert_called_with( - self.message, - http_dialogues_mock.update.return_value, - key="value", - ) - self.context.logger.info.assert_called_with( - test_case.expected_logger_call.format( - self.message.method, self.message.url, self.message.body - ) - ) - - def test_handle_bad_request(self) -> None: - """Test handle with a bad request.""" - http_msg = MagicMock() - http_dialogue = MagicMock() - - # Configure the mocks - http_msg.version = "1.1" - http_msg.headers = {"Content-Type": "application/json"} - http_dialogue.reply.return_value = MagicMock() - - # Call the method - self.handler._handle_bad_request(http_msg, http_dialogue) - - # Verify that the reply method was called with the correct arguments - http_dialogue.reply.assert_called_once_with( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_msg, - version=http_msg.version, - status_code=400, - status_text="Bad request", - headers=http_msg.headers, - body=b"", - ) - - # Verify that the logger was called with the expected message - http_response = http_dialogue.reply.return_value - self.handler.context.logger.info.assert_called_once_with( - "Responding with: {}".format(http_response) - ) - - # Verify that the message was put into the outbox - self.handler.context.outbox.put_message.assert_called_once_with( - message=http_response - ) - - def test_send_ok_response(self) -> None: - """Test send_ok_response function.""" - http_msg = MagicMock() - http_dialogue = MagicMock() - data = {"key": "value"} - - mock_response = MagicMock() - http_dialogue.reply.return_value = mock_response - - # Call the method - self.handler._send_ok_response(http_msg, http_dialogue, data) - - # Verify that the reply method was called with the correct arguments - http_dialogue.reply.assert_called_once_with( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_msg, - version=http_msg.version, - status_code=200, - status_text="Success", - headers=f"{self.handler.json_content_header}{http_msg.headers}", - body=json.dumps(data).encode("utf-8"), - ) - - self.handler.context.logger.info.assert_called_once_with( - "Responding with: {}".format(mock_response) - ) - self.handler.context.outbox.put_message.assert_called_once_with( - message=mock_response - ) - - def test_send_not_found_response(self) -> None: - """Test _send_not_found_response.""" - - http_msg = MagicMock() - http_dialogue = MagicMock() - - # Create a mock response - mock_response = MagicMock() - http_dialogue.reply.return_value = mock_response - - self.handler._send_not_found_response(http_msg, http_dialogue) - - http_dialogue.reply.assert_called_once_with( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_msg, - version=http_msg.version, - status_code=404, - status_text="Not found", - headers=http_msg.headers, - body=b"", - ) - - self.handler.context.logger.info.assert_called_once_with( - "Responding with: {}".format(mock_response) - ) - self.handler.context.outbox.put_message.assert_called_once_with( - message=mock_response - ) diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_payloads.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_payloads.py deleted file mode 100644 index f406adc7e..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_payloads.py +++ /dev/null @@ -1,136 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the transaction payloads for the decision maker abci.""" - -from datetime import datetime -from typing import Dict, Type - -import pytest - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.decision_maker_abci.payloads import ( - BlacklistingPayload, - ClaimPayload, - DecisionReceivePayload, - DecisionRequestPayload, - MultisigTxPayload, - RedeemPayload, - SamplingPayload, - SubscriptionPayload, - ToolSelectionPayload, - VotingPayload, -) - - -@pytest.mark.parametrize( - "payload_class, payload_kwargs", - [ - ( - DecisionReceivePayload, - { - "bets_hash": "dummy bets hash", - "is_profitable": True, - "vote": True, - "confidence": 0.90, - "bet_amount": 1, - "next_mock_data_row": 1, - "policy": "dummy policy", - "decision_received_timestamp": int(datetime.utcnow().timestamp()), - }, - ), - ( - SamplingPayload, - { - "index": 1, - "bets_hash": "dummy_bets_hash", - "benchmarking_finished": False, - "day_increased": False, - }, - ), - ( - MultisigTxPayload, - { - "tx_submitter": "dummy tx submitter", - "tx_hash": "dummy tx hash", - "mocking_mode": True, - }, - ), - ( - RedeemPayload, - { - "tx_submitter": "dummy tx submitter", - "tx_hash": "dummy tx hash", - "mocking_mode": True, - "mech_tools": "dummy mech tools", - "policy": "dummy policy", - "utilized_tools": "dummy utilized tools", - "redeemed_condition_ids": "dummy redeemed condition ids", - "payout_so_far": 1, - }, - ), - ( - DecisionRequestPayload, - { - "mech_requests": "dummy mech requests", - "mocking_mode": True, - }, - ), - ( - SubscriptionPayload, - { - "agreement_id": "", - "tx_submitter": "dummy tx submitter", - "tx_hash": "dummy tx hash", - "mocking_mode": True, - "wallet_balance": 10000, - }, - ), - ( - ClaimPayload, - {"vote": True}, - ), - ( - VotingPayload, - {"vote": True}, - ), - ( - BlacklistingPayload, - {"policy": "dummy policy", "bets_hash": "dummy bets hash"}, - ), - ( - ToolSelectionPayload, - { - "mech_tools": "dummy mech tools", - "policy": "dummy policy", - "utilized_tools": "dummy utilized tools", - "selected_tool": "dummy selected tool", - }, - ), - ], -) -def test_payload(payload_class: Type[BaseTxPayload], payload_kwargs: Dict) -> None: - """Test payloads.""" - payload = payload_class(sender="sender", **payload_kwargs) - - for key, value in payload_kwargs.items(): - assert getattr(payload, key) == value - - assert payload.sender == "sender" - assert payload.data == payload_kwargs - assert payload_class.from_json(payload.json) == payload diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_rounds.py b/trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_rounds.py deleted file mode 100644 index 9cbf81d60..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/tests/test_rounds.py +++ /dev/null @@ -1,212 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the test for rounds of decision maker""" -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.decision_maker_abci.rounds import DecisionMakerAbciApp -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) -from packages.valory.skills.decision_maker_abci.states.blacklisting import ( - BlacklistingRound, -) -from packages.valory.skills.decision_maker_abci.states.check_benchmarking import ( - CheckBenchmarkingModeRound, -) -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) -from packages.valory.skills.decision_maker_abci.states.decision_receive import ( - DecisionReceiveRound, -) -from packages.valory.skills.decision_maker_abci.states.decision_request import ( - DecisionRequestRound, -) -from packages.valory.skills.decision_maker_abci.states.final_states import ( - BenchmarkingModeDisabledRound, - FinishedDecisionMakerRound, - FinishedDecisionRequestRound, - FinishedSubscriptionRound, - FinishedWithoutDecisionRound, -) -from packages.valory.skills.decision_maker_abci.states.order_subscription import ( - SubscriptionRound, -) -from packages.valory.skills.decision_maker_abci.states.randomness import ( - BenchmarkingRandomnessRound, - RandomnessRound, -) -from packages.valory.skills.decision_maker_abci.states.redeem import RedeemRound -from packages.valory.skills.decision_maker_abci.states.sampling import SamplingRound -from packages.valory.skills.decision_maker_abci.states.tool_selection import ( - ToolSelectionRound, -) - - -@pytest.fixture -def setup_app() -> DecisionMakerAbciApp: - """Set up the initial app instance for testing.""" - # Create mock objects for the required arguments - synchronized_data = MagicMock(spec=SynchronizedData) - logger = MagicMock() # Mock logger - context = MagicMock() # Mock context - - # Initialize the app with the mocked dependencies - return DecisionMakerAbciApp(synchronized_data, logger, context) - - -def test_initial_state(setup_app: DecisionMakerAbciApp) -> None: - """Test the initial round of the application.""" - app = setup_app - assert app.initial_round_cls == CheckBenchmarkingModeRound - assert CheckBenchmarkingModeRound in app.initial_states - - -def test_check_benchmarking_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from CheckBenchmarkingModeRound.""" - app = setup_app - transition_function = app.transition_function[CheckBenchmarkingModeRound] - - # Transition on benchmarking enabled - assert ( - transition_function[Event.BENCHMARKING_ENABLED] == BenchmarkingRandomnessRound - ) - - # Transition on benchmarking disabled - assert ( - transition_function[Event.BENCHMARKING_DISABLED] - == BenchmarkingModeDisabledRound - ) - - # Test no majority - assert transition_function[Event.NO_MAJORITY] == CheckBenchmarkingModeRound - - -def test_sampling_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from SamplingRound.""" - app = setup_app - transition_function = app.transition_function[SamplingRound] - - # Transition on done - assert transition_function[Event.DONE] == SubscriptionRound - - # Test none and no majority - assert transition_function[Event.NONE] == FinishedWithoutDecisionRound - assert transition_function[Event.NO_MAJORITY] == SamplingRound - - -def test_subscription_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from SubscriptionRound.""" - app = setup_app - transition_function = app.transition_function[SubscriptionRound] - - # Transition on done - assert transition_function[Event.DONE] == FinishedSubscriptionRound - - # Mock transaction cases - assert transition_function[Event.MOCK_TX] == ToolSelectionRound - assert transition_function[Event.NO_SUBSCRIPTION] == ToolSelectionRound - - -def test_claim_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from ClaimRound.""" - app = setup_app - transition_function = app.transition_function[ClaimRound] - - # Test transition on done - assert transition_function[Event.DONE] == ToolSelectionRound - - -def test_randomness_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from RandomnessRound.""" - app = setup_app - transition_function = app.transition_function[RandomnessRound] - - # Transition on done - assert transition_function[Event.DONE] == SamplingRound - - -def test_tool_selection_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from ToolSelectionRound.""" - app = setup_app - transition_function = app.transition_function[ToolSelectionRound] - - # Test transition on done - assert transition_function[Event.DONE] == DecisionRequestRound - - -def test_decision_request_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from DecisionRequestRound.""" - app = setup_app - transition_function = app.transition_function[DecisionRequestRound] - - # Test transition on done - assert transition_function[Event.DONE] == FinishedDecisionRequestRound - assert transition_function[Event.MOCK_MECH_REQUEST] == DecisionReceiveRound - - -def test_decision_receive_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from DecisionReceiveRound.""" - app = setup_app - transition_function = app.transition_function[DecisionReceiveRound] - - # Test transition on done - assert transition_function[Event.DONE] == BetPlacementRound - - -def test_blacklisting_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from BlacklistingRound.""" - app = setup_app - transition_function = app.transition_function[BlacklistingRound] - - # Test transition on done - assert transition_function[Event.DONE] == FinishedWithoutDecisionRound - - -def test_bet_placement_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from BetPlacementRound.""" - app = setup_app - transition_function = app.transition_function[BetPlacementRound] - - # Test transition on done - assert transition_function[Event.DONE] == FinishedDecisionMakerRound - - -def test_redeem_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from RedeemRound.""" - app = setup_app - transition_function = app.transition_function[RedeemRound] - - # Test transition on done - assert transition_function[Event.DONE] == FinishedDecisionMakerRound - - -def test_final_states(setup_app: DecisionMakerAbciApp) -> None: - """Test the final states of the application.""" - app = setup_app - assert FinishedDecisionMakerRound in app.final_states - assert BenchmarkingModeDisabledRound in app.final_states - assert FinishedWithoutDecisionRound in app.final_states diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/utils/__init__.py b/trader_backup/vendor/valory/skills/decision_maker_abci/utils/__init__.py deleted file mode 100644 index fc72e841a..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/utils/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 package contains helpers.""" diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/utils/nevermined.py b/trader_backup/vendor/valory/skills/decision_maker_abci/utils/nevermined.py deleted file mode 100644 index e7f808254..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/utils/nevermined.py +++ /dev/null @@ -1,373 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the behaviour for the decision-making of the skill.""" - -import re -import uuid -from typing import Any, Dict, List, Tuple - -from eth_abi import encode -from web3 import Web3 - - -def zero_x_transformer(input_str: str, zero_output: bool = True) -> str: - """Transform a string to a hex string.""" - match = re.match(r"^(?:0x)*([a-f0-9]+)$", input_str, re.IGNORECASE) - valid = match is not None - output = match.group(1) if valid else "" # type: ignore - - return ("0x" if zero_output and valid else "") + output - - -def generate_id(length: int = 64) -> str: - """Generate a random ID.""" - generated_id = "" - while len(generated_id) < length: - generated_id += str(uuid.uuid4()).replace("-", "") - - return generated_id[:length] - - -def find_service_by_type(did_doc: Dict[str, Any], type: str) -> Dict[str, Any]: - """Find a service by name.""" - services = did_doc.get("service", []) - for service in services: - if service.get("type") == type: - return service - - raise Exception(f"No service found with type {type}") - - -def find_service_condition_by_name( - service: Dict[str, Any], name: str -) -> Dict[str, Any]: - """Find a condition by name.""" - conditions = ( - service.get("attributes", {}) - .get("serviceAgreementTemplate", {}) - .get("conditions", []) - ) - - condition = next((c for c in conditions if c["name"] == name), None) - - if condition is None: - raise Exception(f"Condition '{name!r}' not found.") - - return condition - - -def get_asset_price_from_service(service: Dict[str, Any]) -> Dict[str, int]: - """Get the price of a DID.""" - escrow_payment_condition = find_service_condition_by_name(service, "escrowPayment") - - if not escrow_payment_condition: - raise Exception("escrowPayment not found in service") - - amounts: List = next( - ( - p["value"] - for p in escrow_payment_condition.get("parameters", []) - if p["name"] == "_amounts" - ), - [], - ) - receivers: List = next( - ( - p["value"] - for p in escrow_payment_condition.get("parameters", []) - if p["name"] == "_receivers" - ), - [], - ) - - rewards_map = dict(zip(receivers, map(int, amounts))) - - return rewards_map - - -def get_price(did_doc: Dict[str, Any], type: str = "nft-sales") -> Dict[str, int]: - """Get the price of a DID.""" - service = find_service_by_type(did_doc, type) - return get_asset_price_from_service(service) - - -def get_nft_address(did_doc: Dict[str, Any], type: str = "nft-sales") -> str: - """Get the NFT address of a DID.""" - service = find_service_by_type(did_doc, type) - transfer_condition = find_service_condition_by_name(service, "transferNFT") - contract_param = next( - ( - p["value"] - for p in transfer_condition.get("parameters", []) - if p["name"] == "_contractAddress" or p["name"] == "_contract" - ), - None, - ) - - return contract_param if contract_param is not None else "" - - -def get_nft_holder(did_doc: Dict[str, Any], type: str = "nft-sales") -> str: - """Get the NFT holder of a DID.""" - service = find_service_by_type(did_doc, type) - transfer_condition = find_service_condition_by_name(service, "transferNFT") - contract_param = next( - ( - p["value"] - for p in transfer_condition.get("parameters", []) - if p["name"] == "_nftHolder" - ), - None, - ) - - return contract_param if contract_param is not None else "" - - -def get_nft_transfer(did_doc: Dict[str, Any], type: str = "nft-sales") -> str: - """Get the NFT holder of a DID.""" - service = find_service_by_type(did_doc, type) - transfer_condition = find_service_condition_by_name(service, "transferNFT") - contract_param = next( - ( - p["value"] - for p in transfer_condition.get("parameters", []) - if p["name"] == "_nftTransfer" - ), - None, - ) - - return contract_param if contract_param is not None else "" - - -def no_did_prefixed(input_string: str) -> str: - """Remove the DID prefix from a string.""" - return did_transformer(input_string, False) - - -def did_transformer(input_string: str, prefix_output: bool = False) -> str: - """Transform a string to a DID.""" - pattern = re.compile(r"^(?:0x|did:nv:)*([a-f0-9]{64})$", re.IGNORECASE) - match_result = input_match(input_string, pattern) - - valid, output = match_result["valid"], match_result["output"] - - return ("did:nv:" if prefix_output and valid else "") + output - - -def input_match(input_string: str, pattern: re.Pattern) -> Dict[str, Any]: - """Match an input string with a pattern.""" - match_result = re.match(pattern, input_string) - if match_result: - return {"valid": True, "output": match_result.group(1)} - else: - return {"valid": False, "output": ""} - - -def hash_data( - types: List[str], - values: List[Any], -) -> str: - """Hash data.""" - encoded_data = encode(types, values) - return Web3.keccak(encoded_data).hex() - - -def short_id(did: str) -> str: - """Get the short ID of a DID.""" - return did.replace("did:nv:", "") - - -def get_agreement_id(seed: str, creator: str) -> str: - """Get the agreement ID.""" - seed_0x = zero_x_transformer(seed) - creator_0x = Web3.to_checksum_address(creator) - return hash_data(["bytes32", "address"], [bytes.fromhex(seed_0x[2:]), creator_0x]) - - -def get_lock_payment_seed( - agreement_id: str, - did_doc: Dict[str, Any], - lock_payment_condition_address: str, - escrow_payment_condition_address: str, - token_address: str, - amounts: List[int], - receivers: List[str], -) -> Tuple[str, str]: - """Get the lock payment seed.""" - short_id_ = zero_x_transformer(short_id(did_doc["id"])) - escrow_payment_condition_address_0x = zero_x_transformer( - escrow_payment_condition_address - ) - token_address = Web3.to_checksum_address(token_address) - receivers = [Web3.to_checksum_address(receiver) for receiver in receivers] - - hash_values = hash_data( - ["bytes32", "address", "address", "uint256[]", "address[]"], - [ - bytes.fromhex(short_id_[2:]), - escrow_payment_condition_address_0x, - token_address, - amounts, - receivers, - ], - ) - return hash_values, hash_data( - ["bytes32", "address", "bytes32"], - [ - bytes.fromhex(agreement_id[2:]), - lock_payment_condition_address, - bytes.fromhex(hash_values[2:]), - ], - ) - - -def get_transfer_nft_condition_seed( - agreement_id: str, - did_doc: Dict[str, Any], - buyer_address: str, - nft_amount: int, - transfer_nft_condition_address: str, - lock_condition_id: str, - nft_contract_address: str, - expiration: int = 0, -) -> Tuple[str, str]: - """Get the lock payment seed.""" - short_id_ = zero_x_transformer(short_id(did_doc["id"])) - nft_holder = Web3.to_checksum_address(get_nft_holder(did_doc)) - will_transfer = get_nft_transfer(did_doc) == "true" - - hash_values = hash_data( - ["bytes32", "address", "address", "uint256", "bytes32", "address", "bool"], - [ - bytes.fromhex(short_id_[2:]), - nft_holder, - Web3.to_checksum_address(buyer_address), - nft_amount, - bytes.fromhex(lock_condition_id[2:]), - Web3.to_checksum_address(nft_contract_address), - will_transfer, - ], - ) - - return hash_values, hash_data( - ["bytes32", "address", "bytes32"], - [ - bytes.fromhex(agreement_id[2:]), - transfer_nft_condition_address, - bytes.fromhex(hash_values[2:]), - ], - ) - - -def get_escrow_payment_seed( - agreement_id: str, - did_doc: Dict[str, Any], - amounts: List[int], - receivers: List[str], - buyer_address: str, - escrow_payment_condition_address: str, - token_address: str, - lock_seed: str, - access_seed: str, -) -> Tuple[str, str]: - """Get the escrow payment seed.""" - short_id_ = zero_x_transformer(short_id(did_doc["id"])) - escrow_payment_condition_address = Web3.to_checksum_address( - escrow_payment_condition_address - ) - receivers = [Web3.to_checksum_address(receiver) for receiver in receivers] - buyer_address = Web3.to_checksum_address(buyer_address) - token_address = Web3.to_checksum_address(token_address) - - values_hash = hash_data( - [ - "bytes32", - "uint256[]", - "address[]", - "address", - "address", - "address", - "bytes32", - "bytes32[]", - ], - [ - bytes.fromhex(short_id_[2:]), - amounts, - receivers, - buyer_address, - escrow_payment_condition_address, - token_address, - bytes.fromhex(lock_seed[2:]), - [bytes.fromhex(access_seed[2:])], - ], - ) - - return values_hash, hash_data( - ["bytes32", "address", "bytes32"], - [ - bytes.fromhex(agreement_id[2:]), - escrow_payment_condition_address, - bytes.fromhex(values_hash[2:]), - ], - ) - - -def get_timeouts_and_timelocks(did_doc: Dict[str, Any]) -> Tuple[List[int], List[int]]: - """Get timeouts and timelocks""" - type = "nft-sales" - service = find_service_by_type(did_doc, type) - conditions = ( - service.get("attributes", {}) - .get("serviceAgreementTemplate", {}) - .get("conditions", []) - ) - timeouts, timelocks = [], [] - for condition in conditions: - timeouts.append(condition.get("timeout", 0)) - timelocks.append(condition.get("timelock", 0)) - - return timeouts, timelocks - - -def get_reward_address(did_doc: Dict[str, Any], type: str = "nft-sales") -> str: - """Get the reward address of a DID.""" - service = find_service_by_type(did_doc, type) - transfer_condition = find_service_condition_by_name(service, "lockPayment") - contract_param = next( - ( - p["value"] - for p in transfer_condition.get("parameters", []) - if p["name"] == "_rewardAddress" - ), - None, - ) - - return contract_param if contract_param is not None else "" - - -def get_creator(did_doc: Dict[str, Any]) -> str: - """Get the creator of a DID.""" - return did_doc["proof"]["creator"] - - -def get_claim_endpoint(did_doc: Dict[str, Any]) -> str: - """Get the claim endpoint of a DID.""" - service = find_service_by_type(did_doc, "nft-sales") - return service["serviceEndpoint"] diff --git a/trader_backup/vendor/valory/skills/decision_maker_abci/utils/scaling.py b/trader_backup/vendor/valory/skills/decision_maker_abci/utils/scaling.py deleted file mode 100644 index 147aaa7a6..000000000 --- a/trader_backup/vendor/valory/skills/decision_maker_abci/utils/scaling.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 package contains helpers for scaling operations.""" - - -from typing import List, Tuple - - -def min_max(li: List[float]) -> Tuple[float, float]: - """Get the min and max of a list.""" - if not li: - raise ValueError("The list is empty.") - - min_ = max_ = li[0] - - for num in li[1:]: - if num < min_: - min_ = num - elif num > max_: - max_ = num - - return min_, max_ - - -def scale_value( - value: float, - min_max_bounds: Tuple[float, float], - scale_bounds: Tuple[float, float] = (0, 1), -) -> float: - """Perform min-max scaling on a value.""" - min_, max_ = min_max_bounds - current_range = max_ - min_ - # normalize between 0-1 - std = (value - min_) / current_range - # scale between min_bound and max_bound - min_bound, max_bound = scale_bounds - target_range = max_bound - min_bound - return std * target_range + min_bound - - -def min_max_scale( - li: List[float], - scale_bounds: Tuple[float, float] = (0, 1), -) -> List[float]: - """Perform min-max scaling on a list of values.""" - min_max_ = min_max(li) - return [scale_value(value, min_max_, scale_bounds) for value in li] diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/README.md b/trader_backup/vendor/valory/skills/market_manager_abci/README.md deleted file mode 100644 index 6171b3b17..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Market manager abci - -## Description - -This module contains the MarketManager skill for an AEA. diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/__init__.py b/trader_backup/vendor/valory/skills/market_manager_abci/__init__.py deleted file mode 100644 index 4a6394a5b..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- 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 the MarketManager skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/market_manager_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/behaviours.py b/trader_backup/vendor/valory/skills/market_manager_abci/behaviours.py deleted file mode 100644 index 999523130..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/behaviours.py +++ /dev/null @@ -1,236 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviours for the MarketManager skill.""" - -import json -import os.path -from abc import ABC -from json import JSONDecodeError -from typing import Any, Dict, Generator, List, Optional, Set, Type - -from aea.helpers.ipfs.base import IPFSHashOnly - -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.behaviours import AbstractRoundBehaviour -from packages.valory.skills.market_manager_abci.bets import ( - Bet, - BetsDecoder, - serialize_bets, -) -from packages.valory.skills.market_manager_abci.graph_tooling.requests import ( - FetchStatus, - MAX_LOG_SIZE, - QueryingBehaviour, -) -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload -from packages.valory.skills.market_manager_abci.rounds import ( - MarketManagerAbciApp, - UpdateBetsRound, -) - - -BETS_FILENAME = "bets.json" -MULTI_BETS_FILENAME = "multi_bets.json" -READ_MODE = "r" -WRITE_MODE = "w" - - -class BetsManagerBehaviour(BaseBehaviour, ABC): - """Abstract behaviour responsible for bets management, such as storing, hashing, reading.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize `BetsManagerBehaviour`.""" - super().__init__(**kwargs) - self.bets: List[Bet] = [] - self.multi_bets_filepath: str = self.params.store_path / MULTI_BETS_FILENAME - self.bets_filepath: str = self.params.store_path / BETS_FILENAME - - def store_bets(self) -> None: - """Store the bets to the agent's data dir as JSON.""" - serialized = serialize_bets(self.bets) - if serialized is None: - self.context.logger.warning("No bets to store.") - return - - try: - with open(self.multi_bets_filepath, WRITE_MODE) as bets_file: - try: - bets_file.write(serialized) - return - except (IOError, OSError): - err = f"Error writing to file {self.multi_bets_filepath!r}!" - except (FileNotFoundError, PermissionError, OSError): - err = f"Error opening file {self.multi_bets_filepath!r} in write mode!" - - self.context.logger.error(err) - - def read_bets(self) -> None: - """Read the bets from the agent's data dir as JSON.""" - self.bets = [] - _read_path = self.multi_bets_filepath - - if not os.path.isfile(_read_path): - self.context.logger.warning( - f"No stored bets file was detected in {_read_path}. Assuming trader is being run for the first time in multi-bets mode." - ) - _read_path = self.bets_filepath - elif not os.path.isfile(_read_path): - self.context.logger.warning( - f"No stored bets file was detected in {_read_path}. Assuming bets are empty" - ) - return - - try: - with open(_read_path, READ_MODE) as bets_file: - try: - self.bets = json.load(bets_file, cls=BetsDecoder) - return - except (JSONDecodeError, TypeError): - err = f"Error decoding file {_read_path!r} to a list of bets!" - except (FileNotFoundError, PermissionError, OSError): - err = f"Error opening file {_read_path!r} in read mode!" - - self.context.logger.error(err) - - def hash_stored_bets(self) -> str: - """Get the hash of the stored bets' file.""" - return IPFSHashOnly.hash_file(self.multi_bets_filepath) - - -class UpdateBetsBehaviour(BetsManagerBehaviour, QueryingBehaviour): - """Behaviour that fetches and updates the bets.""" - - matching_round = UpdateBetsRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize `UpdateBetsBehaviour`.""" - super().__init__(**kwargs) - - def _requeue_all_bets(self) -> None: - """Requeue all bets.""" - for bet in self.bets: - bet.queue_status = bet.queue_status.move_to_fresh() - - def _blacklist_expired_bets(self) -> None: - """Blacklist bets that are older than the opening margin.""" - for bet in self.bets: - if self.synced_time >= bet.openingTimestamp - self.params.opening_margin: - bet.blacklist_forever() - - def setup(self) -> None: - """Set up the behaviour.""" - - # Read the bets from the agent's data dir as JSON, if they exist - self.read_bets() - - # fetch checkpoint status and if reached requeue all bets - if self.synchronized_data.is_checkpoint_reached: - self._requeue_all_bets() - - # blacklist bets that are older than the opening margin - # if trader ran after a long time - # helps in resetting the queue number to 0 - if self.bets: - self._blacklist_expired_bets() - - def get_bet_idx(self, bet_id: str) -> Optional[int]: - """Get the index of the bet with the given id, if it exists, otherwise `None`.""" - return next((i for i, bet in enumerate(self.bets) if bet.id == bet_id), None) - - def _process_chunk(self, chunk: Optional[List[Dict[str, Any]]]) -> None: - """Process a chunk of bets.""" - if chunk is None: - return - - for raw_bet in chunk: - bet = Bet(**raw_bet, market=self._current_market) - index = self.get_bet_idx(bet.id) - if index is None: - self.bets.append(bet) - else: - self.bets[index].update_market_info(bet) - - def _update_bets( - self, - ) -> Generator: - """Fetch the questions from all the prediction markets and update the local copy of the bets.""" - - # Fetching bets from the prediction markets - while True: - can_proceed = self._prepare_fetching() - if not can_proceed: - break - - bets_market_chunk = yield from self._fetch_bets() - self._process_chunk(bets_market_chunk) - - if self._fetch_status != FetchStatus.SUCCESS: - # this won't wipe the bets as the `store_bets` of the `BetsManagerBehaviour` takes this into consideration - self.bets = [] - - # truncate the bets, otherwise logs get too big - bets_str = str(self.bets)[:MAX_LOG_SIZE] - self.context.logger.info(f"Updated bets: {bets_str}") - - def _bet_freshness_check_and_update(self) -> None: - """Check the freshness of the bets.""" - all_bets_fresh = all( - bet.queue_status.is_fresh() - for bet in self.bets - if not bet.queue_status.is_expired() - ) - - if all_bets_fresh: - for bet in self.bets: - bet.queue_status = bet.queue_status.move_to_process() - - return - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - # Update the bets list with new bets or update existing ones - yield from self._update_bets() - - # if trader is run after a long time, there is a possibility that - # all bets are fresh and this should be updated to DAY_0_FRESH - if self.bets: - self._bet_freshness_check_and_update() - - # Store the bets to the agent's data dir as JSON - self.store_bets() - - bets_hash = self.hash_stored_bets() if self.bets else None - payload = UpdateBetsPayload(self.context.agent_address, bets_hash) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - self.set_done() - - -class MarketManagerRoundBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the MarketManager behaviour.""" - - initial_behaviour_cls = UpdateBetsBehaviour - abci_app_cls = MarketManagerAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - UpdateBetsBehaviour, # type: ignore - } diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/bets.py b/trader_backup/vendor/valory/skills/market_manager_abci/bets.py deleted file mode 100644 index 021ac544d..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/bets.py +++ /dev/null @@ -1,388 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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. -# -# ------------------------------------------------------------------------------ - - -"""Structures for the bets.""" - -import builtins -import dataclasses -import json -import sys -from enum import Enum -from typing import Any, Dict, List, Optional, Union - - -YES = "yes" -NO = "no" -P_YES_FIELD = "p_yes" -P_NO_FIELD = "p_no" -CONFIDENCE_FIELD = "confidence" -INFO_UTILITY_FIELD = "info_utility" -BINARY_N_SLOTS = 2 - - -class QueueStatus(Enum): - """The status of a bet in the queue.""" - - # Common statuses - EXPIRED = -1 # Bets that have expired, i.e., the market is not live anymore - FRESH = 0 # Fresh bets that have just been added - TO_PROCESS = 1 # Bets that are ready to be processed - PROCESSED = 2 # Bets that have been processed - REPROCESSED = 3 # Bets that have been reprocessed - BENCHMARKING_DONE = 4 - - def is_fresh(self) -> bool: - """Check if the bet is fresh.""" - return self == QueueStatus.FRESH - - def is_expired(self) -> bool: - """Check if the bet is expired.""" - return self == QueueStatus.EXPIRED - - def move_to_process(self) -> "QueueStatus": - """Move the bet to the process status.""" - if self == QueueStatus.FRESH: - return QueueStatus.TO_PROCESS - return self - - def move_to_fresh(self) -> "QueueStatus": - """Move the bet to the fresh status.""" - if self not in [QueueStatus.EXPIRED, QueueStatus.BENCHMARKING_DONE]: - return QueueStatus.FRESH - return self - - def mark_benchmarking_done(self) -> "QueueStatus": - return QueueStatus.BENCHMARKING_DONE - - def next_status(self) -> "QueueStatus": - """Get the next status in the queue.""" - if self == QueueStatus.TO_PROCESS: - return QueueStatus.PROCESSED - elif self == QueueStatus.PROCESSED: - return QueueStatus.REPROCESSED - elif self != QueueStatus.REPROCESSED: - return QueueStatus.FRESH - return self - - return self - - -@dataclasses.dataclass(init=False) -class PredictionResponse: - """A response of a prediction.""" - - p_yes: float - p_no: float - confidence: float - info_utility: float - - def __init__(self, **kwargs: Any) -> None: - """Initialize the mech's prediction ignoring extra keys.""" - self.p_yes = float(kwargs.pop(P_YES_FIELD)) - self.p_no = float(kwargs.pop(P_NO_FIELD)) - self.confidence = float(kwargs.pop(CONFIDENCE_FIELD)) - self.info_utility = float(kwargs.pop(INFO_UTILITY_FIELD)) - - # all the fields are probabilities; run checks on whether the current prediction response is valid or not. - probabilities = (getattr(self, field_) for field_ in self.__annotations__) - if ( - any(not (0 <= prob <= 1) for prob in probabilities) - or self.p_yes + self.p_no != 1 - ): - raise ValueError("Invalid prediction response initialization.") - - @property - def vote(self) -> Optional[int]: - """Return the vote. `0` represents "yes" and `1` represents "no".""" - if self.p_no != self.p_yes: - return int(self.p_no > self.p_yes) - return None - - @property - def win_probability(self) -> float: - """Return the probability estimation for winning with vote.""" - return max(self.p_no, self.p_yes) - - -def get_default_prediction_response() -> PredictionResponse: - """Get the default prediction response.""" - return PredictionResponse(p_yes=0.5, p_no=0.5, confidence=0.5, info_utility=0.5) - - -@dataclasses.dataclass -class Bet: - """A bet's structure.""" - - id: str - market: str - title: str - collateralToken: str - creator: str - fee: int - openingTimestamp: int - outcomeSlotCount: int - outcomeTokenAmounts: List[int] - outcomeTokenMarginalPrices: List[float] - outcomes: Optional[List[str]] - scaledLiquidityMeasure: float - prediction_response: PredictionResponse = dataclasses.field( - default_factory=get_default_prediction_response - ) - position_liquidity: int = 0 - potential_net_profit: int = 0 - processed_timestamp: int = 0 - queue_status: QueueStatus = QueueStatus.FRESH - # a mapping from vote to investment amounts - investments: Dict[str, List[int]] = dataclasses.field(default_factory=dict) - - @property - def yes_investments(self) -> List[int]: - """Get the yes investments.""" - return self.investments[self.yes] - - @property - def no_investments(self) -> List[int]: - """Get the no investments.""" - return self.investments[self.no] - - @property - def n_yes_bets(self) -> int: - """Get the number of yes bets.""" - return len(self.yes_investments) - - @property - def n_no_bets(self) -> int: - """Get the number of no bets.""" - return len(self.no_investments) - - @property - def n_bets(self) -> int: - """Get the number of bets.""" - return self.n_yes_bets + self.n_no_bets - - @property - def invested_amount_yes(self) -> int: - """Get the amount invested in yes bets.""" - return sum(self.yes_investments) - - @property - def invested_amount_no(self) -> int: - """Get the amount invested in no bets.""" - return sum(self.no_investments) - - @property - def invested_amount(self) -> int: - """Get the amount invested in bets.""" - return self.invested_amount_yes + self.invested_amount_no - - def __post_init__(self) -> None: - """Post initialization to adjust the values.""" - self._validate() - self._cast() - self._check_usefulness() - self.investments = {self.yes: [], self.no: []} - - def __lt__(self, other: "Bet") -> bool: - """Implements less than operator.""" - return self.scaledLiquidityMeasure < other.scaledLiquidityMeasure - - def blacklist_forever(self) -> None: - """Blacklist a bet forever. Should only be used in cases where it is impossible to bet.""" - self.outcomes = None - self.processed_timestamp = sys.maxsize - self.queue_status = QueueStatus.EXPIRED - - def _validate(self) -> None: - """Validate the values of the instance.""" - necessary_values = ( - self.id, - self.market, - self.title, - self.collateralToken, - self.creator, - self.fee, - self.openingTimestamp, - self.outcomeSlotCount, - self.outcomes, - self.scaledLiquidityMeasure, - self.outcomeTokenAmounts, - self.outcomeTokenMarginalPrices, - ) - nulls_exist = any(val is None or val == "null" for val in necessary_values) - - outcomes_lists = ( - self.outcomes, - self.outcomeTokenAmounts, - self.outcomeTokenMarginalPrices, - ) - mismatching_outcomes = any( - self.outcomeSlotCount != len(outcomes) - for outcomes in outcomes_lists - if outcomes is not None - ) - - if nulls_exist or mismatching_outcomes: - self.blacklist_forever() - - def _cast(self) -> None: - """Cast the values of the instance.""" - types_to_cast = ("int", "float", "str") - str_to_type = {getattr(builtins, type_): type_ for type_ in types_to_cast} - for field, hinted_type in self.__annotations__.items(): - uncasted = getattr(self, field) - if uncasted is None: - continue - - for type_to_cast, type_name in str_to_type.items(): - if hinted_type == type_to_cast: - setattr(self, field, hinted_type(uncasted)) - if f"{str(List)}[{type_name}]" == str(hinted_type): - setattr(self, field, list(type_to_cast(val) for val in uncasted)) - - def _check_usefulness(self) -> None: - """If the bet is deemed unhelpful, then blacklist it.""" - if self.scaledLiquidityMeasure == 0: - self.blacklist_forever() - - def get_outcome(self, index: int) -> str: - """Get an outcome given its index.""" - if self.outcomes is None: - raise ValueError(f"Bet {self} has an incorrect outcomes list of `None`.") - try: - return self.outcomes[index] - except KeyError as exc: - error = f"Cannot get outcome with index {index} from {self.outcomes}" - raise ValueError(error) from exc - - def _get_binary_outcome(self, no: bool) -> str: - """Get an outcome only if it is binary.""" - if self.outcomeSlotCount == BINARY_N_SLOTS: - return self.get_outcome(int(no)) - requested_outcome = NO if no else YES - error = ( - f"A {requested_outcome!r} outcome is only available for binary questions." - ) - raise ValueError(error) - - @property - def yes(self) -> str: - """Return the "yes" outcome.""" - return self._get_binary_outcome(False) - - @property - def no(self) -> str: - """Return the "no" outcome.""" - return self._get_binary_outcome(True) - - def update_investments(self, amount: int) -> bool: - """Get the investments for the current vote type.""" - vote = self.prediction_response.vote - if vote is None: - return False - - vote_name = self.get_outcome(vote) - to_update = self.investments[vote_name] - to_update.append(amount) - return True - - def update_market_info(self, bet: "Bet") -> None: - """Update the bet's market information.""" - if ( - self.processed_timestamp == sys.maxsize - or bet.processed_timestamp == sys.maxsize - ): - # do not update the bet if it has been blacklisted forever - return - - self.outcomeTokenAmounts = bet.outcomeTokenAmounts.copy() - self.outcomeTokenMarginalPrices = bet.outcomeTokenMarginalPrices.copy() - self.scaledLiquidityMeasure = bet.scaledLiquidityMeasure - - def rebet_allowed( - self, - prediction_response: PredictionResponse, - liquidity: int, - potential_net_profit: int, - ) -> bool: - """Check if a rebet is allowed based on the previous bet's information.""" - if self.n_bets == 0: - # it's the first time betting, always allow it - return True - - more_confident = ( - self.prediction_response.win_probability - >= prediction_response.win_probability - ) - if self.prediction_response.vote == prediction_response.vote: - higher_liquidity = self.position_liquidity >= liquidity - return more_confident and higher_liquidity - else: - profit_increases = self.potential_net_profit >= potential_net_profit - return more_confident and profit_increases - - -class BetsEncoder(json.JSONEncoder): - """JSON encoder for bets.""" - - def default(self, o: Any) -> Any: - """The default encoder.""" - if dataclasses.is_dataclass(o) and not isinstance(o, type): - return dataclasses.asdict(o) - if isinstance(o, QueueStatus): - return o.value - return super().default(o) - - -class BetsDecoder(json.JSONDecoder): - """JSON decoder for bets.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the Bets JSON decoder.""" - super().__init__(object_hook=self.hook, *args, **kwargs) - - @staticmethod - def hook(data: Dict[str, Any]) -> Union[Bet, PredictionResponse, Dict[str, Bet]]: - """Perform the custom decoding.""" - # if this is a `PredictionResponse` - prediction_attributes = sorted(PredictionResponse.__annotations__.keys()) - data_attributes = sorted(data.keys()) - if prediction_attributes == data_attributes: - return PredictionResponse(**data) - - # if this is a `Bet` - bet_annotations = sorted(Bet.__annotations__.keys()) - if bet_annotations == data_attributes: - data["queue_status"] = QueueStatus(data["queue_status"]) - return Bet(**data) - elif "id" in data_attributes: - common_attributes = set(bet_annotations) & set(data_attributes) - data = {key: data[key] for key in common_attributes} - if "queue_status" in data: - data["queue_status"] = QueueStatus(data["queue_status"]) - return Bet(**data) - - return data - - -def serialize_bets(bets: List[Bet]) -> Optional[str]: - """Get the bets serialized.""" - if len(bets) == 0: - return None - return json.dumps(bets, cls=BetsEncoder) diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/dialogues.py b/trader_backup/vendor/valory/skills/market_manager_abci/dialogues.py deleted file mode 100644 index 153b6ce50..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/dialogues.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- 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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/fsm_specification.yaml b/trader_backup/vendor/valory/skills/market_manager_abci/fsm_specification.yaml deleted file mode 100644 index 665d8c38f..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/fsm_specification.yaml +++ /dev/null @@ -1,21 +0,0 @@ -alphabet_in: -- DONE -- FETCH_ERROR -- NO_MAJORITY -- ROUND_TIMEOUT -default_start_state: UpdateBetsRound -final_states: -- FailedMarketManagerRound -- FinishedMarketManagerRound -label: MarketManagerAbciApp -start_states: -- UpdateBetsRound -states: -- FailedMarketManagerRound -- FinishedMarketManagerRound -- UpdateBetsRound -transition_func: - (UpdateBetsRound, DONE): FinishedMarketManagerRound - (UpdateBetsRound, FETCH_ERROR): FailedMarketManagerRound - (UpdateBetsRound, NO_MAJORITY): UpdateBetsRound - (UpdateBetsRound, ROUND_TIMEOUT): UpdateBetsRound diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/__init__.py b/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/__init__.py deleted file mode 100644 index f83960aa0..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 functionality for interacting with a GraphQL API.""" diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/__init__.py b/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/__init__.py deleted file mode 100644 index 80ec84132..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""GraphQL queries.""" diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/conditional_tokens.py b/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/conditional_tokens.py deleted file mode 100644 index c64fbacf8..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/conditional_tokens.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Omen queries.""" - -from string import Template - - -user_positions = Template( - """ - { - user(id: "${id}") { - userPositions( - first: ${first} - where: { - id_gt: "${userPositions_id_gt}" - } - orderBy: id - ) { - balance - id - position { - id - conditionIds - lifetimeValue - } - totalBalance - wrappedBalance - } - } - } - """ -) diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/network.py b/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/network.py deleted file mode 100644 index d5f4b5900..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/network.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Network queries.""" - -from string import Template - - -block_number = Template( - """ - { - blocks ( - first: 1, - orderBy: timestamp, - orderDirection: asc, - where: { - timestamp_gte: "${timestamp_from}", - timestamp_lte:"${timestamp_to}" - } - ){ - id - } - } - """ -) diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/omen.py b/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/omen.py deleted file mode 100644 index c82d99899..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/omen.py +++ /dev/null @@ -1,96 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Omen queries.""" - -from string import Template - - -questions = Template( - """ - { - fixedProductMarketMakers( - where: { - creator_in: ${creators}, - outcomeSlotCount: ${slot_count}, - openingTimestamp_gt: ${opening_threshold}, - language_in: ${languages}, - isPendingArbitration: false - }, - orderBy: creationTimestamp - orderDirection: desc - first: 1000 - ){ - id - title - collateralToken - creator - fee - openingTimestamp - outcomeSlotCount - outcomeTokenAmounts - outcomeTokenMarginalPrices - outcomes - scaledLiquidityMeasure - } - } - """ -) - -trades = Template( - """ - { - fpmmTrades ( - where: { - type: Buy, - creator: "${creator}", - fpmm_: { - creationTimestamp_gt: "${creationTimestamp_gt}", - answerFinalizedTimestamp_not: null, - isPendingArbitration: false - } - } - orderBy: fpmm__creationTimestamp - orderDirection: asc - first: ${first} - ){ - fpmm { - answerFinalizedTimestamp - collateralToken - condition { - id - outcomeSlotCount - } - creator - creationTimestamp - currentAnswer - question { - id - data - } - templateId - } - outcomeIndex - outcomeTokenMarginalPrice - outcomeTokensTraded - transactionHash - } - } - """ -) diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/realitio.py b/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/realitio.py deleted file mode 100644 index f6bb67f48..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/realitio.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Omen queries.""" - -from string import Template - - -answers = Template( - """ - { - answers(where: {question_: {questionId: "${question_id}"}}) { - answer - question { - historyHash - id - user - updatedTimestamp - questionId - } - bondAggregate - lastBond - timestamp - } - } - """ -) diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/trades.py b/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/trades.py deleted file mode 100644 index 6d2054c74..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/queries/trades.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Trades queries.""" - -from string import Template - - -trades = Template( - """ - { - fpmmTrades( - where: { - type: Buy, - creator: "${creator}", - fpmm_: { - creationTimestamp_gte: "${creationTimestamp_gte}", - creationTimestamp_lt: "${creationTimestamp_lte}" - }, - creationTimestamp_gte: "${creationTimestamp_gte}", - creationTimestamp_lte: "${creationTimestamp_lte}" - creationTimestamp_gt: "${creationTimestamp_gt}" - } - first: ${first} - orderBy: creationTimestamp - orderDirection: asc - ) { - id - title - collateralToken - outcomeTokenMarginalPrice - oldOutcomeTokenMarginalPrice - type - creator { - id - } - creationTimestamp - collateralAmount - collateralAmountUSD - feeAmount - outcomeIndex - outcomeTokensTraded - transactionHash - fpmm { - id - outcomes - title - answerFinalizedTimestamp - currentAnswer - isPendingArbitration - arbitrationOccurred - openingTimestamp - condition { - id - } - } - } - } - """ -) diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/requests.py b/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/requests.py deleted file mode 100644 index 627be35e8..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/requests.py +++ /dev/null @@ -1,414 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Tooling to perform subgraph requests from a behaviour.""" - -import json -from abc import ABC -from enum import Enum, auto -from typing import Any, Dict, Generator, Iterator, List, Optional, Tuple, cast - -from web3 import Web3 - -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.models import ApiSpecs -from packages.valory.skills.market_manager_abci.graph_tooling.queries.conditional_tokens import ( - user_positions as user_positions_query, -) -from packages.valory.skills.market_manager_abci.graph_tooling.queries.network import ( - block_number, -) -from packages.valory.skills.market_manager_abci.graph_tooling.queries.omen import ( - questions, - trades, -) -from packages.valory.skills.market_manager_abci.graph_tooling.queries.realitio import ( - answers as answers_query, -) -from packages.valory.skills.market_manager_abci.graph_tooling.queries.trades import ( - trades as trades_query, -) -from packages.valory.skills.market_manager_abci.models import ( - MarketManagerParams, - SharedState, -) -from packages.valory.skills.market_manager_abci.rounds import SynchronizedData - - -QUERY_BATCH_SIZE = 1000 -MAX_LOG_SIZE = 1000 - - -def to_content(query: str) -> bytes: - """Convert the given query string to payload content, i.e., add it under a `queries` key and convert it to bytes.""" - finalized_query = {"query": query} - encoded_query = json.dumps(finalized_query, sort_keys=True).encode("utf-8") - - return encoded_query - - -def to_graphql_list(li: list) -> str: - """Convert the given list to a string representing a list for a GraphQL query.""" - return repr(li).replace("'", '"') - - -class FetchStatus(Enum): - """The status of a fetch operation.""" - - SUCCESS = auto() - IN_PROGRESS = auto() - FAIL = auto() - NONE = auto() - - -class QueryingBehaviour(BaseBehaviour, ABC): - """Abstract behaviour that implements subgraph querying functionality.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize a querying behaviour.""" - super().__init__(**kwargs) - self._call_failed: bool = False - self._fetch_status: FetchStatus = FetchStatus.NONE - self._creators_iterator: Iterator[ - Tuple[str, List[str]] - ] = self.params.creators_iterator - self._current_market: str = "" - self._current_creators: List[str] = [] - - @property - def params(self) -> MarketManagerParams: - """Get the params.""" - return cast(MarketManagerParams, self.context.params) - - @property - def shared_state(self) -> SharedState: - """Get the shared state.""" - return cast(SharedState, self.context.state) - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return cast(SynchronizedData, super().synchronized_data) - - @property - def synced_time(self) -> int: - """Get the synchronized time among agents.""" - synced_time = self.shared_state.round_sequence.last_round_transition_timestamp - return int(synced_time.timestamp()) - - @property - def current_subgraph(self) -> ApiSpecs: - """Get a subgraph by prediction market's name.""" - return getattr(self.context, self._current_market) - - def _prepare_fetching(self) -> bool: - """Prepare for fetching a bet.""" - if self._fetch_status in (FetchStatus.SUCCESS, FetchStatus.NONE): - res = next(self._creators_iterator, None) - if res is None: - return False - self._current_market, self._current_creators = res - - if self._fetch_status == FetchStatus.FAIL: - return False - - self._fetch_status = FetchStatus.IN_PROGRESS - return True - - def _handle_response( - self, - subgraph: ApiSpecs, - res: Optional[Dict], - res_context: str, - sleep_on_fail: bool = True, - ) -> Generator[None, None, Optional[Any]]: - """Handle a response from a subgraph. - - :param subgraph: the subgraph to handle the response for. - :param res: the response to handle. - :param res_context: the context of the current response. - :param sleep_on_fail: whether we want to sleep if we fail to get the response's result. - :return: the response's result, using the given keys. `None` if response is `None` (has failed). - :yield: None - """ - if res is None: - self.context.logger.error( - f"Could not get {res_context} from {subgraph.api_id}" - ) - self._call_failed = True - subgraph.increment_retries() - - if subgraph.is_retries_exceeded(): - self._fetch_status = FetchStatus.FAIL - - if sleep_on_fail: - sleep_time = subgraph.retries_info.suggested_sleep_time - yield from self.sleep(sleep_time) - return None - - # truncate the response, otherwise logs get too big - res_str = str(res)[:MAX_LOG_SIZE] - self.context.logger.info(f"Retrieved {res_context}: {res_str}.") - self._call_failed = False - subgraph.reset_retries() - self._fetch_status = FetchStatus.SUCCESS - return res - - def _fetch_bets(self) -> Generator[None, None, Optional[list]]: - """Fetch questions from the current subgraph, for the current creators.""" - self._fetch_status = FetchStatus.IN_PROGRESS - - query = questions.substitute( - creators=to_graphql_list(self._current_creators), - slot_count=self.params.slot_count, - opening_threshold=self.synced_time + self.params.opening_margin, - languages=to_graphql_list(self.params.languages), - ) - - res_raw = yield from self.get_http_response( - content=to_content(query), - **self.current_subgraph.get_spec(), - ) - res = self.current_subgraph.process_response(res_raw) - - bets = yield from self._handle_response( - self.current_subgraph, - res, - res_context="questions", - ) - - return bets - - def _fetch_redeem_info(self) -> Generator[None, None, Optional[list]]: - """Fetch redeeming information from the current subgraph.""" - self._fetch_status = FetchStatus.IN_PROGRESS - - current_subgraph = self.context.trades_subgraph - safe = self.synchronized_data.safe_contract_address - creation_timestamp_gt = ( - 0 # used to allow for batching based on creation timestamp - ) - all_trades: List[Dict[str, Any]] = [] - # fetch trades in batches of `QUERY_BATCH_SIZE` - while True: - query = trades.substitute( - creator=safe.lower(), - first=QUERY_BATCH_SIZE, - creationTimestamp_gt=creation_timestamp_gt, - ) - - res_raw = yield from self.get_http_response( - content=to_content(query), - **current_subgraph.get_spec(), - ) - res = current_subgraph.process_response(res_raw) - trades_chunk = yield from self._handle_response( - current_subgraph, - res, - res_context="trades", - ) - if res is None: - # something went wrong - self.context.logger.error("Failed to process all trades.") - return all_trades - - trades_chunk = cast(List[Dict[str, Any]], trades_chunk) - if len(trades_chunk) == 0: - # no more trades to fetch - return all_trades - - # this is the last trade's creation timestamp - # they are sorted by creation timestamp in ascending order - # so we can use this to fetch the next batch - creation_timestamp_gt = trades_chunk[-1]["fpmm"]["creationTimestamp"] - all_trades.extend(trades_chunk) - - def _fetch_block_number( - self, timestamp: int - ) -> Generator[None, None, Dict[str, str]]: - """Get a block number by its timestamp.""" - self._fetch_status = FetchStatus.IN_PROGRESS - - margin = self.params.average_block_time * self.params.abt_error_mult - query = block_number.substitute( - timestamp_from=timestamp, timestamp_to=timestamp + margin - ) - - current_subgraph = self.context.network_subgraph - res_raw = yield from self.get_http_response( - content=to_content(query), - **current_subgraph.get_spec(), - ) - res = current_subgraph.process_response(res_raw) - - block = yield from self._handle_response( - current_subgraph, - res, - res_context="block number", - ) - - return {} if block is None else block - - def fetch_claim_params( - self, question_id: str - ) -> Generator[None, None, Optional[List[Dict[str, Any]]]]: - """Fetch claim parameters from the subgraph.""" - self._fetch_status = FetchStatus.IN_PROGRESS - current_subgraph = self.context.realitio_subgraph - query = answers_query.substitute( - question_id=question_id, - ) - res_raw = yield from self.get_http_response( - content=to_content(query), - **current_subgraph.get_spec(), - ) - res = current_subgraph.process_response(res_raw) - raw_answers = yield from self._handle_response( - current_subgraph, - res, - res_context="answers", - ) - if raw_answers is None: - # we failed to get the answers - self.context.logger.error( - f"Failing to get answers for question {question_id} from {current_subgraph.api_id}" - ) - return None - answers = [ - { - "args": { - "answer": bytes.fromhex(answer["answer"][2:]), - "question_id": bytes.fromhex(answer["question"]["questionId"][2:]), - "history_hash": bytes.fromhex( - answer["question"]["historyHash"][2:] - ), - "user": Web3.to_checksum_address(answer["question"]["user"]), - "bond": int(answer["bondAggregate"]), - "timestamp": int(answer["timestamp"]), - "is_commitment": False, - } - } - for answer in raw_answers - ] - return answers - - def fetch_trades( - self, - creator: str, - from_timestamp: float, - to_timestamp: float, - ) -> Generator[None, None, Optional[List[Dict[str, Any]]]]: - """Fetch trades from the subgraph.""" - self._fetch_status = FetchStatus.IN_PROGRESS - current_subgraph = self.context.trades_subgraph - - all_trades: List[Dict[str, Any]] = [] - creation_timestamp_gt = ( - 0 # used to allow for batching based on creation timestamp - ) - # fetch trades in batches of `QUERY_BATCH_SIZE` - while True: - query = trades_query.substitute( - creator=creator.lower(), - creationTimestamp_lte=int(to_timestamp), - creationTimestamp_gte=int(from_timestamp), - first=QUERY_BATCH_SIZE, - creationTimestamp_gt=creation_timestamp_gt, - ) - - res_raw = yield from self.get_http_response( - content=to_content(query), - **current_subgraph.get_spec(), - ) - res = current_subgraph.process_response(res_raw) - trades_chunk = yield from self._handle_response( - current_subgraph, - res, - res_context="trades", - ) - if res is None: - # something went wrong - self.context.logger.error("Failed to process all trades.") - return all_trades - - trades_chunk = cast(List[Dict[str, Any]], trades_chunk) - if len(trades_chunk) == 0: - # no more trades to fetch - return all_trades - - # this is the last trade's creation timestamp - # they are sorted by creation timestamp in ascending order - # so we can use this to fetch the next batch - creation_timestamp_gt = trades_chunk[-1]["creationTimestamp"] - all_trades.extend(trades_chunk) - - def fetch_user_positions( - self, user: str - ) -> Generator[None, None, Optional[List[Dict[str, Any]]]]: - """Fetch positions for a user from the subgraph.""" - self._fetch_status = FetchStatus.IN_PROGRESS - current_subgraph = self.context.conditional_tokens_subgraph - - user_positions_id_gt = ( - 0 # used to allow for batching based on user positions id - ) - all_positions: List[Dict[str, Any]] = [] - while True: - query = user_positions_query.substitute( - id=user.lower(), - first=QUERY_BATCH_SIZE, - userPositions_id_gt=user_positions_id_gt, - ) - res_raw = yield from self.get_http_response( - content=to_content(query), - **current_subgraph.get_spec(), - ) - res = current_subgraph.process_response(res_raw) - - positions = yield from self._handle_response( - current_subgraph, - res, - res_context="positions", - ) - if res is None: - # something went wrong - self.context.logger.error("Failed to process all positions.") - return all_positions - - positions = cast(List[Dict[str, Any]], positions) - if len(positions) == 0: - # no more positions to fetch - return all_positions - - all_positions.extend(positions) - user_positions_id_gt = positions[-1]["id"] - - def clean_up(self) -> None: - """Clean up the resources.""" - markets_subgraphs = tuple(market for market, _ in self.params.creators_iterator) - other_subgraphs = ( - "conditional_tokens_subgraph", - "network_subgraph", - "realitio_subgraph", - "trades_subgraph", - ) - for subgraph in markets_subgraphs + other_subgraphs: - subgraph_specs = getattr(self.context, subgraph) - subgraph_specs.reset_retries() diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/utils.py b/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/utils.py deleted file mode 100644 index 21ec569bf..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/graph_tooling/utils.py +++ /dev/null @@ -1,130 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Utils for graph interactions.""" -import time -from enum import Enum -from typing import Any, Dict, List, Tuple - - -INVALID_MARKET_ANSWER = ( - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -) - - -class MarketState(Enum): - """Market state""" - - OPEN = 1 - PENDING = 2 - FINALIZING = 3 - ARBITRATING = 4 - CLOSED = 5 - - def __str__(self) -> str: - """Prints the market status.""" - return self.name.capitalize() - - -def get_position_balance( - user_positions: List[Dict[str, Any]], - condition_id: str, -) -> int: - """Get the balance of a position.""" - for position in user_positions: - position_condition_ids = position["position"]["conditionIds"] - balance = int(position["balance"]) - if condition_id.lower() in position_condition_ids: - return balance - - return 0 - - -def get_position_lifetime_value( - user_positions: List[Dict[str, Any]], - condition_id: str, -) -> int: - """Get the balance of a position.""" - for position in user_positions: - position_condition_ids = position["position"]["conditionIds"] - balance = int(position["position"]["lifetimeValue"]) - if condition_id.lower() in position_condition_ids: - return balance - - return 0 - - -def get_condition_id_to_balances( - creator_trades: List[Dict[str, Any]], - user_positions: List[Dict[str, Any]], -) -> Tuple[Dict[str, int], Dict[str, int]]: - """Get the condition id to balances.""" - condition_id_to_payout = {} - condition_id_to_balance = {} - for fpmm_trade in creator_trades: - outcome_index = int(fpmm_trade["outcomeIndex"]) - fpmm = fpmm_trade["fpmm"] - answer_finalized_timestamp = fpmm["answerFinalizedTimestamp"] - is_pending_arbitration = fpmm["isPendingArbitration"] - opening_timestamp = fpmm["openingTimestamp"] - market_status = MarketState.CLOSED - if ( - fpmm["currentAnswer"] is None - and opening_timestamp is not None - and time.time() >= float(opening_timestamp) - ): - market_status = MarketState.PENDING - elif fpmm["currentAnswer"] is None: - market_status = MarketState.OPEN - elif is_pending_arbitration: - market_status = MarketState.ARBITRATING - elif time.time() < float(answer_finalized_timestamp): - market_status = MarketState.FINALIZING - - if market_status == MarketState.CLOSED: - current_answer = int(fpmm["currentAnswer"], 16) # type: ignore - # we have the correct answer, or the market was invalid - if ( - outcome_index == current_answer - or current_answer == INVALID_MARKET_ANSWER - ): - condition_id = fpmm_trade["fpmm"]["condition"]["id"] - balance = get_position_balance(user_positions, condition_id) - condition_id_to_balance[condition_id] = balance - # get the payout for this condition - payout = get_position_lifetime_value(user_positions, condition_id) - if payout > 0 and balance == 0: - condition_id_to_payout[condition_id] = payout - - return condition_id_to_payout, condition_id_to_balance - - -def filter_claimed_conditions( - payouts: Dict[str, int], claimed_condition_ids: List[str] -) -> Dict[str, int]: - """Filter out the claimed payouts.""" - claimed_condition_ids = [ - condition_id.lower() for condition_id in claimed_condition_ids - ] - # filter out the claimed payouts, in a case-insensitive way - return { - condition_id: payout - for condition_id, payout in payouts.items() - if condition_id.lower() not in claimed_condition_ids - } diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/handlers.py b/trader_backup/vendor/valory/skills/market_manager_abci/handlers.py deleted file mode 100644 index b1913b693..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/handlers.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- 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 the handlers for the 'market_manager_abci' skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIMarketManagerHandler = ABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/models.py b/trader_backup/vendor/valory/skills/market_manager_abci/models.py deleted file mode 100644 index c39c3fc94..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/models.py +++ /dev/null @@ -1,108 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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. -# -# ------------------------------------------------------------------------------ - - -"""Custom objects for the MarketManager ABCI application.""" - -import builtins -from typing import Any, Dict, Iterator, List, Tuple - -from packages.valory.protocols.http import HttpMessage -from packages.valory.skills.abstract_round_abci.models import ApiSpecs, BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.market_manager_abci.bets import BINARY_N_SLOTS -from packages.valory.skills.market_manager_abci.rounds import MarketManagerAbciApp - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = MarketManagerAbciApp - - -class Subgraph(ApiSpecs): - """Specifies `ApiSpecs` with common functionality for subgraphs.""" - - def process_response(self, response: HttpMessage) -> Any: - """Process the response.""" - res = super().process_response(response) - if res is not None: - return res - - error_data = self.response_info.error_data - expected_error_type = getattr(builtins, self.response_info.error_type) - if isinstance(error_data, expected_error_type): - error_message_key = self.context.params.the_graph_error_message_key - error_message = error_data.get(error_message_key, None) - if self.context.params.the_graph_payment_required_error in error_message: - err = "Payment required for subsequent requests for the current 'The Graph' API key!" - self.context.logger.error(err) - return None - - -class OmenSubgraph(Subgraph): - """A model that wraps ApiSpecs for the OMEN's subgraph specifications.""" - - -class NetworkSubgraph(Subgraph): - """A model that wraps ApiSpecs for the network's subgraph specifications.""" - - -class MarketManagerParams(BaseParams): - """Market manager's parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the parameters' object.""" - # this is a mapping from a prediction market spec's attribute to the creators we want to take into account - self.creator_per_market: Dict[str, List[str]] = self._ensure( - "creator_per_subgraph", kwargs, Dict[str, List[str]] - ) - self.slot_count: int = self._ensure("slot_count", kwargs, int) - - if self.slot_count != BINARY_N_SLOTS: - raise ValueError( - f"Only a slot_count `2` is currently supported. `{self.slot_count}` was found in the configuration." - ) - - self.opening_margin: int = self._ensure("opening_margin", kwargs, int) - self.languages: List[str] = self._ensure("languages", kwargs, List[str]) - self.average_block_time: int = self._ensure("average_block_time", kwargs, int) - self.abt_error_mult: int = self._ensure("abt_error_mult", kwargs, int) - self.the_graph_error_message_key: str = self._ensure( - "the_graph_error_message_key", kwargs, str - ) - self.the_graph_payment_required_error: str = self._ensure( - "the_graph_payment_required_error", kwargs, str - ) - super().__init__(*args, **kwargs) - - @property - def creators_iterator(self) -> Iterator[Tuple[str, List[str]]]: - """Return an iterator of market per creators.""" - return iter(self.creator_per_market.items()) diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/payloads.py b/trader_backup/vendor/valory/skills/market_manager_abci/payloads.py deleted file mode 100644 index d7247c415..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/payloads.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the transaction payloads for the MarketManager.""" - -from dataclasses import dataclass -from typing import Optional - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class UpdateBetsPayload(BaseTxPayload): - """A transaction payload for the updated bets.""" - - bets_hash: Optional[str] diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/rounds.py b/trader_backup/vendor/valory/skills/market_manager_abci/rounds.py deleted file mode 100644 index 1ac5dc8be..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/rounds.py +++ /dev/null @@ -1,156 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the rounds for the MarketManager ABCI application.""" - -from abc import ABC -from enum import Enum -from typing import Dict, Set, Tuple, Type, cast - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AbstractRound, - AppState, - BaseSynchronizedData, - CollectSameUntilThresholdRound, - CollectionRound, - DegenerateRound, - DeserializedCollection, - get_name, -) -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload - - -class Event(Enum): - """Event enumeration for the MarketManager demo.""" - - DONE = "done" - NO_MAJORITY = "no_majority" - ROUND_TIMEOUT = "round_timeout" - FETCH_ERROR = "fetch_error" - - -class SynchronizedData(BaseSynchronizedData): - """Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - def _get_deserialized(self, key: str) -> DeserializedCollection: - """Strictly get a collection and return it deserialized.""" - serialized = self.db.get_strict(key) - return CollectionRound.deserialize_collection(serialized) - - @property - def bets_hash(self) -> str: - """Get the most voted bets' hash.""" - return str(self.db.get_strict("bets_hash")) - - @property - def participant_to_bets_hash(self) -> DeserializedCollection: - """Get the participants to bets' hash.""" - return self._get_deserialized("participant_to_bets_hash") - - @property - def is_checkpoint_reached(self) -> bool: - """Check if the checkpoint is reached.""" - return bool(self.db.get("is_checkpoint_reached", False)) - - -class MarketManagerAbstractRound(AbstractRound[Event], ABC): - """Abstract round for the MarketManager skill.""" - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return cast(SynchronizedData, super().synchronized_data) - - def _return_no_majority_event(self) -> Tuple[SynchronizedData, Event]: - """ - Trigger the `NO_MAJORITY` event. - - :return: the new synchronized data and a `NO_MAJORITY` event - """ - return self.synchronized_data, Event.NO_MAJORITY - - -class UpdateBetsRound(CollectSameUntilThresholdRound, MarketManagerAbstractRound): - """A round for the bets fetching & updating.""" - - payload_class = UpdateBetsPayload - done_event: Enum = Event.DONE - none_event: Enum = Event.FETCH_ERROR - no_majority_event: Enum = Event.NO_MAJORITY - selection_key = get_name(SynchronizedData.bets_hash) - collection_key = get_name(SynchronizedData.participant_to_bets_hash) - synchronized_data_class = SynchronizedData - - -class FinishedMarketManagerRound(DegenerateRound, ABC): - """A round that represents MarketManager has finished""" - - -class FailedMarketManagerRound(DegenerateRound, ABC): - """A round that represents that the period failed""" - - -class MarketManagerAbciApp(AbciApp[Event]): # pylint: disable=too-few-public-methods - """MarketManagerAbciApp - - Initial round: UpdateBetsRound - - Initial states: {UpdateBetsRound} - - Transition states: - 0. UpdateBetsRound - - done: 1. - - fetch error: 2. - - round timeout: 0. - - no majority: 0. - 1. FinishedMarketManagerRound - 2. FailedMarketManagerRound - - Final states: {FailedMarketManagerRound, FinishedMarketManagerRound} - - Timeouts: - round timeout: 30.0 - """ - - initial_round_cls: Type[AbstractRound] = UpdateBetsRound - transition_function: AbciAppTransitionFunction = { - UpdateBetsRound: { - Event.DONE: FinishedMarketManagerRound, - Event.FETCH_ERROR: FailedMarketManagerRound, - Event.ROUND_TIMEOUT: UpdateBetsRound, - Event.NO_MAJORITY: UpdateBetsRound, - }, - FinishedMarketManagerRound: {}, - FailedMarketManagerRound: {}, - } - cross_period_persisted_keys = frozenset({get_name(SynchronizedData.bets_hash)}) - final_states: Set[AppState] = {FinishedMarketManagerRound, FailedMarketManagerRound} - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = {UpdateBetsRound: set()} - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedMarketManagerRound: {get_name(SynchronizedData.bets_hash)}, - FailedMarketManagerRound: set(), - } diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/skill.yaml b/trader_backup/vendor/valory/skills/market_manager_abci/skill.yaml deleted file mode 100644 index 7d1de7b60..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/skill.yaml +++ /dev/null @@ -1,197 +0,0 @@ -name: market_manager_abci -author: valory -version: 0.1.0 -type: skill -description: This skill implements the MarketManager for an AEA. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeie6miwn67uin3bphukmf7qgiifh4xtm42i5v3nuyqxzxtehxsqvcq - __init__.py: bafybeigrtedqzlq5mtql2ssjsdriw76ml3666m4e2c3fay6vmyzofl6v6e - behaviours.py: bafybeicfoszavcyrzahe6qaydlaf27mpbwui7a6wgdbstydbzxmdisxhju - bets.py: bafybeia7anwfr5ibesvumzyalcuwcozovkndgjbxadcrgzr5sq23gj3ldi - dialogues.py: bafybeiebofyykseqp3fmif36cqmmyf3k7d2zbocpl6t6wnlpv4szghrxbm - fsm_specification.yaml: bafybeic5cvwfbiu5pywyp3h5s2elvu7jqdrcwayay7o3v3ow47vu2jw53q - graph_tooling/__init__.py: bafybeigzo7nhbzafyq3fuhrlewksjvmzttiuk4vonrggtjtph4rw4ncpk4 - graph_tooling/queries/__init__.py: bafybeihbybnl53i7k57ql5ujt5ru5n2eg324jfndh4lcnm4fk52mwbkjda - graph_tooling/queries/conditional_tokens.py: bafybeic6ohkdp4rvkcfglieksv6gbzm4qocpgdjaz4sroutl37sxijthji - graph_tooling/queries/network.py: bafybeigeq72ys2nrjqspj2uacaudrgljrne5a3o5jvzsktldxdq6m2xmeu - graph_tooling/queries/omen.py: bafybeiesgavgoio6zeovdyvzeezz5qoosdgioktoen5ckrgyxpr4u3m3nu - graph_tooling/queries/realitio.py: bafybeiftewjwk5fi6uqrhmalweun47voau2qkxi7hg3faxcmyy3va44zma - graph_tooling/queries/trades.py: bafybeigu6c25kf3mrlvmwjeskgagswdjnnxsygpriygmip44us4xvuf7ji - graph_tooling/requests.py: bafybeibjyb6av33aswnptttekj6t7k7xysgphh2bigoorcgkc54y2j3xkm - graph_tooling/utils.py: bafybeig5hxhnqgyfn5ym3poc5nziqwpeozqbd6wa4s6c2hjn6iyedg3t3y - handlers.py: bafybeihot2i2yvfkz2gcowvt66wdu6tkjbmv7hsmc4jzt4reqeaiuphbtu - models.py: bafybeibjttnga54y4auz6f33ecfrngyw53b2xzpompm72drjsr4xoytmiy - payloads.py: bafybeicfymvvtdpkcgmkvthfzmb7dqakepkzslqrz6rcs7nxkz7qq3mrzy - rounds.py: bafybeibqqq3vjotaasc67olhlqthka6e6refodguntkmpksgdbqlzme73a - tests/__init__.py: bafybeigaewntxawezvygss345kytjijo56bfwddjtfm6egzxfajsgojam4 - tests/test_dialogues.py: bafybeiet646su5nsjmvruahuwg6un4uvwzyj2lnn2jvkye6cxooz22f3ja - tests/test_handlers.py: bafybeiaz3idwevvlplcyieaqo5oeikuthlte6e2gi4ajw452ylvimwgiki - tests/test_payloads.py: bafybeidvld43p5c4wpwi7m6rfzontkheqqgxdchjnme5b54wmldojc5dmm - tests/test_rounds.py: bafybeidahkavof43y3o4omnihh6yxdx7gqofio7kzukdydymxbebylempu -fingerprint_ignore_patterns: [] -connections: [] -contracts: [] -protocols: -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -behaviours: - main: - args: {} - class_name: MarketManagerRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIMarketManagerHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 350.0 - service_id: market_manager - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - sleep_time: 5 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - termination_sleep: 900 - tx_timeout: 10.0 - use_termination: false - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - creator_per_subgraph: - omen_subgraph: [] - slot_count: 2 - opening_margin: 300 - languages: - - en_US - average_block_time: 5 - abt_error_mult: 5 - the_graph_error_message_key: message - the_graph_payment_required_error: payment required for subsequent requests for - this API key - class_name: MarketManagerParams - network_subgraph: - args: - api_id: network - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:blocks - response_index: 0 - response_type: dict - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/stakewise/ethereum-gnosis - class_name: NetworkSubgraph - omen_subgraph: - args: - api_id: omen - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:fixedProductMarketMakers - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/protofire/omen-xdai - class_name: OmenSubgraph - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState -dependencies: - web3: - version: <7,>=6.0.0 -is_abstract: true diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/market_manager_abci/tests/__init__.py deleted file mode 100644 index 574eff5a1..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/market_manager skill.""" diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/tests/test_dialogues.py b/trader_backup/vendor/valory/skills/market_manager_abci/tests/test_dialogues.py deleted file mode 100644 index cdcfd1185..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.market_manager_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/tests/test_handlers.py b/trader_backup/vendor/valory/skills/market_manager_abci/tests/test_handlers.py deleted file mode 100644 index 16f555389..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/tests/test_handlers.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the tests for the handlers for the 'market_manager_abci' skill.""" -from unittest.mock import MagicMock - -import pytest -from aea.configurations.data_types import PublicId -from aea.skills.base import Handler - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.market_manager_abci.handlers import ( - ABCIMarketManagerHandler, - ContractApiHandler, - HttpHandler, - IpfsHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, -) - - -@pytest.mark.parametrize( - "handler, base_handler", - [ - (ABCIMarketManagerHandler, ABCIRoundHandler), - (HttpHandler, BaseHttpHandler), - (SigningHandler, BaseSigningHandler), - (LedgerApiHandler, BaseLedgerApiHandler), - (ContractApiHandler, BaseContractApiHandler), - (TendermintHandler, BaseTendermintHandler), - (IpfsHandler, BaseIpfsHandler), - ], -) -def test_handler(handler: Handler, base_handler: Handler) -> None: - """Test that the 'handlers.py' of the TraderAbci can be imported.""" - handler = handler( - name="dummy_handler", - skill_context=MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")), - ) - - assert isinstance(handler, base_handler) diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/tests/test_payloads.py b/trader_backup/vendor/valory/skills/market_manager_abci/tests/test_payloads.py deleted file mode 100644 index 898c80b48..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/tests/test_payloads.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the transaction payloads for the market manager abci.""" - -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload - - -def test_update_bets_payload() -> None: - """Test `UpdateBetsPayload`.""" - - payload = UpdateBetsPayload(sender="sender", bets_hash="dummy bets hash") - - assert payload.bets_hash == "dummy bets hash" - assert UpdateBetsPayload.from_json(payload.json) == payload diff --git a/trader_backup/vendor/valory/skills/market_manager_abci/tests/test_rounds.py b/trader_backup/vendor/valory/skills/market_manager_abci/tests/test_rounds.py deleted file mode 100644 index 33b184c69..000000000 --- a/trader_backup/vendor/valory/skills/market_manager_abci/tests/test_rounds.py +++ /dev/null @@ -1,324 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the test for rounds for the MarketManager ABCI application.""" - -import json -from dataclasses import dataclass, field -from typing import ( - Any, - Callable, - Dict, - FrozenSet, - Hashable, - List, - Mapping, - Optional, - Union, -) -from unittest import mock -from unittest.mock import MagicMock, patch - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - BaseTxPayload, - get_name, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload -from packages.valory.skills.market_manager_abci.rounds import ( - Event, - FailedMarketManagerRound, - FinishedMarketManagerRound, - MarketManagerAbciApp, - SynchronizedData, - UpdateBetsRound, -) - - -@pytest.fixture -def abci_app() -> MarketManagerAbciApp: - """Fixture for MarketManagerAbciApp.""" - # Create mocks for the required parameters - synchronized_data = MagicMock() - logger = MagicMock() - context = MagicMock() - - # Instantiate MarketManagerAbciApp with the required arguments - return MarketManagerAbciApp( - synchronized_data=synchronized_data, logger=logger, context=context - ) - - -DUMMY_BETS_HASH = "dummy_bets_hash" -DUMMY_PARTICIPANT_TO_BETS_HASH = json.dumps( - { - "agent_0": "bet_1", - "agent_1": "bet_2", - "agent_2": "bet_3", - } -) - - -def get_participants() -> FrozenSet[str]: - """Participants""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -def get_payloads( - data: Optional[str], -) -> Mapping[str, BaseTxPayload]: - """Get payloads.""" - return { - participant: UpdateBetsPayload(participant, data) - for participant in get_participants() - } - - -@dataclass -class RoundTestCase: - """RoundTestCase""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, BaseTxPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -MAX_PARTICIPANTS: int = 4 - - -class BaseMarketManagerRoundTestClass(BaseCollectSameUntilThresholdRoundTest): - """Base test class for MarketManager rounds.""" - - synchronized_data: SynchronizedData - _synchronized_data_class = SynchronizedData - _event_class = Event - round_class = UpdateBetsRound - - def run_test(self, test_case: RoundTestCase) -> None: - """Run the test""" - - # Set initial data - self.synchronized_data.update( - self._synchronized_data_class, **test_case.initial_data - ) - - test_round = self.round_class( - synchronized_data=self.synchronized_data, context=mock.MagicMock() - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=test_case.payloads, - synchronized_data_update_fn=lambda sync_data, _: sync_data.update( - **test_case.final_data - ), - synchronized_data_attr_checks=test_case.synchronized_data_attr_checks, - most_voted_payload=test_case.most_voted_payload, - exit_event=test_case.event, - ) - ) - - -class TestUpdateBetsRound(BaseMarketManagerRoundTestClass): - """Tests for UpdateBetsRound.""" - - round_class = UpdateBetsRound - synchronized_data: SynchronizedData - _synchronized_data_class = SynchronizedData - _event_class = Event - - @pytest.mark.parametrize( - "test_case", - ( - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_payloads( - data=DUMMY_BETS_HASH, - ), - final_data={ - "bets_hash": DUMMY_BETS_HASH, - "participant_to_bets_hash": DUMMY_PARTICIPANT_TO_BETS_HASH, - }, - event=Event.DONE, - most_voted_payload=DUMMY_BETS_HASH, - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.bets_hash, - ], - ), - RoundTestCase( - name="Fetch error", - initial_data={}, - payloads=get_payloads( - data=None, - ), - final_data={}, - event=Event.FETCH_ERROR, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - ), - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run tests.""" - - self.run_test(test_case) - - def test_return_no_majority_event(self) -> None: - """Test the _return_no_majority_event method.""" - # Mock synchronized data and create an instance of the round - synchronized_data = MagicMock(spec=SynchronizedData) - update_bets_round = UpdateBetsRound( - synchronized_data=synchronized_data, context=MagicMock() - ) - - # Call the method and check the results - result = update_bets_round._return_no_majority_event() - assert result == (synchronized_data, Event.NO_MAJORITY) - - -class TestFinishedMarketManagerRound: - """Tests for FinishedMarketManagerRound.""" - - def test_finished_market_manager_round_initialization(self) -> None: - """Test the initialization of FinishedMarketManagerRound.""" - round_ = FinishedMarketManagerRound( - synchronized_data=MagicMock(), context=MagicMock() - ) - assert isinstance(round_, FinishedMarketManagerRound) - - -class TestFailedMarketManagerRound: - """Tests for FailedMarketManagerRound.""" - - def test_failed_market_manager_round_initialization(self) -> None: - """Test the initialization of FailedMarketManagerRound.""" - round_ = FailedMarketManagerRound( - synchronized_data=MagicMock(), context=MagicMock() - ) - assert isinstance(round_, FailedMarketManagerRound) - - -def test_market_manager_abci_app_initialization(abci_app: MarketManagerAbciApp) -> None: - """Test the initialization of MarketManagerAbciApp.""" - assert abci_app.initial_round_cls is UpdateBetsRound - assert abci_app.final_states == { - FinishedMarketManagerRound, - FailedMarketManagerRound, - } - assert abci_app.transition_function == { - UpdateBetsRound: { - Event.DONE: FinishedMarketManagerRound, - Event.FETCH_ERROR: FailedMarketManagerRound, - Event.ROUND_TIMEOUT: UpdateBetsRound, - Event.NO_MAJORITY: UpdateBetsRound, - }, - FinishedMarketManagerRound: {}, - FailedMarketManagerRound: {}, - } - assert abci_app.event_to_timeout == {Event.ROUND_TIMEOUT: 30.0} - assert abci_app.db_pre_conditions == {UpdateBetsRound: set()} - assert abci_app.db_post_conditions == { - FinishedMarketManagerRound: {get_name(SynchronizedData.bets_hash)}, - FailedMarketManagerRound: set(), - } - - -# Mock serialized collections for different keys -DUMMY_PARTICIPANT_TO_BETS_HASH = json.dumps( - { - "agent_0": {"sender": "agent_0", "data": "bet_1"}, - "agent_1": {"sender": "agent_1", "data": "bet_2"}, - } -) -DUMMY_BETS_HASH = json.dumps({"bets_hash": "dummy_bets_hash"}) - -DUMMY_SERIALIZED_PARTICIPANT_TO_BETS_HASH = json.dumps(DUMMY_PARTICIPANT_TO_BETS_HASH) -DUMMY_SERIALIZED_BETS_HASH = json.dumps(DUMMY_BETS_HASH) - - -@pytest.mark.parametrize( - "key,serialized_data,expected_result,property_to_check", - [ - ( - "participant_to_bets_hash", - DUMMY_SERIALIZED_PARTICIPANT_TO_BETS_HASH, - json.loads(DUMMY_PARTICIPANT_TO_BETS_HASH), - "participant_to_bets_hash", - ), - ( - "bets_hash", - DUMMY_SERIALIZED_BETS_HASH, - json.loads(DUMMY_BETS_HASH), - "bets_hash", - ), - ], -) -@patch( - "packages.valory.skills.market_manager_abci.rounds.CollectionRound.deserialize_collection" -) -def test_synchronized_data_get_deserialized( - mock_deserialize_collection: MagicMock, - key: str, - serialized_data: str, - expected_result: Mapping[str, Any], - property_to_check: str, -) -> None: - """Test the _get_deserialized method and properties in SynchronizedData.""" - # Mock the db.get_strict to return the serialized data - mock_db = mock.MagicMock() - mock_db.get_strict.return_value = serialized_data - - # Initialize SynchronizedData with the mocked db - synchronized_data = SynchronizedData(db=mock_db) - - # Mock the deserialize_collection function to return the expected deserialized result - mock_deserialize_collection.return_value = expected_result - - deserialized_data: Union[str, Mapping[str, BaseTxPayload]] - if property_to_check == "participant_to_bets_hash": - deserialized_data = synchronized_data.participant_to_bets_hash - else: - deserialized_data = synchronized_data.bets_hash - - # Ensure that get_strict is called with the correct key - mock_db.get_strict.assert_called_once_with(key) - - # Ensure that deserialize_collection is called with the correct serialized data only for collection fields - if property_to_check == "participant_to_bets_hash": - mock_deserialize_collection.assert_called_once_with(serialized_data) - assert deserialized_data == expected_result - - -def test_synchronized_data_initialization() -> None: - """Test the initialization and attributes of SynchronizedData.""" - setup_data = {"test": ["test"]} - synchronized_data = SynchronizedData(db=AbciAppDB(setup_data=setup_data)) - - assert synchronized_data.db._data == {0: {"test": ["test"]}} diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/__init__.py b/trader_backup/vendor/valory/skills/mech_interact_abci/__init__.py deleted file mode 100644 index 3a0f255cf..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- 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 the implementation of the mech interact skill.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/mech_interact_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/__init__.py b/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/__init__.py deleted file mode 100644 index eecc0b1c1..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 package contains the behaviours for the mech interact skill.""" diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/base.py b/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/base.py deleted file mode 100644 index 45444cb8f..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/base.py +++ /dev/null @@ -1,221 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the base behaviour for the mech interact abci skill.""" - -import json -from abc import ABC -from dataclasses import asdict, is_dataclass -from datetime import datetime, timedelta -from typing import Any, Callable, Generator, List, Optional, cast - -from aea.configurations.data_types import PublicId - -from packages.valory.contracts.mech.contract import Mech -from packages.valory.contracts.mech_marketplace.contract import MechMarketplace -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - BaseBehaviour, - TimeoutException, -) -from packages.valory.skills.mech_interact_abci.models import ( - MechMarketplaceConfig, - MechParams, - MultisendBatch, -) -from packages.valory.skills.mech_interact_abci.states.base import SynchronizedData - - -WaitableConditionType = Generator[None, None, bool] - - -class MechInteractBaseBehaviour(BaseBehaviour, ABC): - """Represents the base class for the mech interaction FSM behaviour.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize the bet placement behaviour.""" - super().__init__(**kwargs) - self.multisend_batches: List[MultisendBatch] = [] - self.multisend_data = b"" - self._safe_tx_hash = "" - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return cast(SynchronizedData, super().synchronized_data) - - @property - def params(self) -> MechParams: - """Return the params.""" - return cast(MechParams, self.context.params) - - @property - def mech_marketplace_config(self) -> MechMarketplaceConfig: - """Return the mech marketplace config.""" - return cast(MechMarketplaceConfig, self.context.params.mech_marketplace_config) - - def default_error( - self, contract_id: str, contract_callable: str, response_msg: ContractApiMessage - ) -> None: - """Return a default contract interaction error message.""" - self.context.logger.error( - f"Could not successfully interact with the {contract_id} contract " - f"using {contract_callable!r}: {response_msg}" - ) - - def contract_interaction_error( - self, contract_id: str, contract_callable: str, response_msg: ContractApiMessage - ) -> None: - """Return a contract interaction error message.""" - # contracts can only return one message, i.e., multiple levels cannot exist. - for level in ("info", "warning", "error"): - msg = response_msg.raw_transaction.body.get(level, None) - logger = getattr(self.context.logger, level) - if msg is not None: - logger(msg) - return - - self.default_error(contract_id, contract_callable, response_msg) - - def contract_interact( - self, - performative: ContractApiMessage.Performative, - contract_address: str, - contract_public_id: PublicId, - contract_callable: str, - data_key: str, - placeholder: str, - **kwargs: Any, - ) -> WaitableConditionType: - """Interact with a contract.""" - contract_id = str(contract_public_id) - - self.context.logger.info( - f"Interacting with contract {contract_id} at address {contract_address}\n" - f"Calling method {contract_callable} with parameters: {kwargs}" - ) - - response_msg = yield from self.get_contract_api_response( - performative, - contract_address, - contract_id, - contract_callable, - **kwargs, - ) - - self.context.logger.info(f"Contract response: {response_msg}") - - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.default_error(contract_id, contract_callable, response_msg) - return False - - data = response_msg.raw_transaction.body.get(data_key, None) - if data is None: - self.contract_interaction_error( - contract_id, contract_callable, response_msg - ) - return False - - setattr(self, placeholder, data) - return True - - def _mech_contract_interact( - self, contract_callable: str, data_key: str, placeholder: str, **kwargs: Any - ) -> WaitableConditionType: - """Interact with the mech contract.""" - status = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.mech_contract_address, - contract_public_id=Mech.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def _mech_marketplace_contract_interact( - self, - contract_callable: str, - data_key: str, - placeholder: str, - **kwargs: Any, - ) -> WaitableConditionType: - """Interact with the mech marketplace contract.""" - status = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.mech_marketplace_config.mech_marketplace_address, - contract_public_id=MechMarketplace.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def wait_for_condition_with_sleep( - self, - condition_gen: Callable[[], WaitableConditionType], - timeout: Optional[float] = None, - ) -> Generator: - """Wait for a condition to happen and sleep in-between checks. - - This is a modified version of the base `wait_for_condition` method which: - 1. accepts a generator that creates the condition instead of a callable - 2. sleeps in-between checks - - :param condition_gen: a generator of the condition to wait for - :param timeout: the maximum amount of time to wait - :yield: None - """ - - deadline = ( - datetime.now() + timedelta(0, timeout) - if timeout is not None - else datetime.max - ) - - while True: - condition_satisfied = yield from condition_gen() - if condition_satisfied: - break - if timeout is not None and datetime.now() > deadline: - raise TimeoutException() - msg = f"Retrying in {self.params.mech_interaction_sleep_time} seconds." - self.context.logger.info(msg) - yield from self.sleep(self.params.mech_interaction_sleep_time) - - def finish_behaviour(self, payload: BaseTxPayload) -> Generator: - """Finish the behaviour.""" - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class DataclassEncoder(json.JSONEncoder): - """A custom JSON encoder for dataclasses.""" - - def default(self, o: Any) -> Any: - """The default JSON encoder.""" - if is_dataclass(o): - return asdict(o) - return super().default(o) diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/request.py b/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/request.py deleted file mode 100644 index 51410893f..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/request.py +++ /dev/null @@ -1,499 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the request state of the mech interaction abci app.""" - -import json -from dataclasses import asdict -from pathlib import Path -from tempfile import mkdtemp -from typing import Any, Generator, List, Optional, cast - -import multibase -import multicodec -from aea.exceptions import AEAEnforceError -from aea.helpers.cid import to_v1 -from hexbytes import HexBytes - -from packages.valory.contracts.erc20.contract import ERC20 -from packages.valory.contracts.gnosis_safe.contract import ( - GnosisSafeContract, - SafeOperation, -) -from packages.valory.contracts.multisend.contract import MultiSendContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.abstract_round_abci.io_.store import SupportedFiletype -from packages.valory.skills.mech_interact_abci.behaviours.base import ( - DataclassEncoder, - MechInteractBaseBehaviour, - WaitableConditionType, -) -from packages.valory.skills.mech_interact_abci.models import MultisendBatch -from packages.valory.skills.mech_interact_abci.payloads import MechRequestPayload -from packages.valory.skills.mech_interact_abci.states.base import ( - MechInteractionResponse, - MechMetadata, -) -from packages.valory.skills.mech_interact_abci.states.request import MechRequestRound -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - hash_payload_to_hex, -) -from packages.valory.skills.transaction_settlement_abci.rounds import TX_HASH_LENGTH - - -METADATA_FILENAME = "metadata.json" -V1_HEX_PREFIX = "f01" -Ox = "0x" - -# setting the safe gas to 0 means that all available gas will be used -# which is what we want in most cases -# more info here: https://safe-docs.dev.gnosisdev.com/safe/docs/contracts_tx_execution/ -SAFE_GAS = 0 - - -class MechRequestBehaviour(MechInteractBaseBehaviour): - """A behaviour in which the agents prepare a tx to initiate a request to a mech.""" - - matching_round = MechRequestRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize Behaviour.""" - super().__init__(**kwargs) - self._v1_hex_truncated: str = "" - self._request_data: bytes = b"" - self._price: int = 0 - self._mech_requests: List[MechMetadata] = [] - self._pending_responses: List[MechInteractionResponse] = [] - - @property - def metadata_filepath(self) -> str: - """Get the filepath to the metadata.""" - return str(Path(mkdtemp()) / METADATA_FILENAME) - - @property - def request_data(self) -> bytes: - """Get the request data.""" - return self._request_data - - @request_data.setter - def request_data(self, data: bytes) -> None: - """Set the request data.""" - self._request_data = data - - @property - def price(self) -> int: - """Get the price.""" - return self._price - - @price.setter - def price(self, price: int) -> None: - """Set the price.""" - self._price = price - - @property - def safe_tx_hash(self) -> str: - """Get the safe_tx_hash.""" - return self._safe_tx_hash - - @safe_tx_hash.setter - def safe_tx_hash(self, safe_hash: str) -> None: - """Set the safe_tx_hash.""" - length = len(safe_hash) - if length != TX_HASH_LENGTH: - raise ValueError( - f"Incorrect length {length} != {TX_HASH_LENGTH} detected " - f"when trying to assign a safe transaction hash: {safe_hash}" - ) - self._safe_tx_hash = safe_hash[2:] - - @property - def multi_send_txs(self) -> List[dict]: - """Get the multisend transactions as a list of dictionaries.""" - return [asdict(batch) for batch in self.multisend_batches] - - @property - def txs_value(self) -> int: - """Get the total value of the transactions.""" - return sum(batch.value for batch in self.multisend_batches) - - @property - def tx_hex(self) -> Optional[str]: - """Serialize the safe tx to a hex string.""" - if self.safe_tx_hash == "": - raise ValueError( - "Cannot prepare a multisend transaction without a safe transaction hash." - ) - return hash_payload_to_hex( - self.safe_tx_hash, - self.txs_value, - SAFE_GAS, - self.params.multisend_address, - self.multisend_data, - SafeOperation.DELEGATE_CALL.value, - ) - - @staticmethod - def wei_to_unit(wei: int) -> float: - """Convert WEI to unit token.""" - return wei / 10**18 - - def _get_native_balance(self, account: str) -> Generator[None, None, Optional[int]]: - """Get native balance for account.""" - ledger_api_response = yield from self.get_ledger_api_response( - performative=LedgerApiMessage.Performative.GET_STATE, # type: ignore - ledger_callable="get_balance", - block_identifier="latest", - account=account, - chain_id=self.params.mech_chain_id, - ) - - try: - balance = int(ledger_api_response.state.body["get_balance_result"]) - except (AEAEnforceError, KeyError, ValueError, TypeError): - balance = None - - if balance is None: - log_msg = f"Failed to get the native balance for account {account}." - self.context.logger.error(f"{log_msg}: {ledger_api_response}") - return None - - self.context.logger.info( - f"Account {account} has {self.wei_to_unit(balance)} native tokens." - ) - return balance - - def _get_wrapped_native_balance( - self, account: str - ) -> Generator[None, None, Optional[int]]: - """Get wrapped native balance for account.""" - - error_message = f"Failed to get the wrapped native balance for account {account} (mech_wrapped_native_token_address={self.params.mech_wrapped_native_token_address})." - config_message = "Please configure 'mech_wrapped_native_token_address' appropriately if you want to use wrapped native tokens for mech requests." - if not self.params.mech_wrapped_native_token_address: - self.context.logger.info( - f"Wrapped native token address has not been configured. Assumed wrapped native token = 0. {config_message}" - ) - return 0 - - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.mech_wrapped_native_token_address, - contract_id=str(ERC20.contract_id), - contract_callable="check_balance", - account=account, - ) - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.context.logger.error( - f"{error_message} {config_message} {response_msg}" - ) - return None - - token = response_msg.raw_transaction.body.get("token", None) - wallet = response_msg.raw_transaction.body.get("wallet", None) - if token is None or wallet is None: - self.context.logger.error( - f"{error_message} {config_message} {response_msg}" - ) - return None - - self.context.logger.info( - f"Account {account} has {self.wei_to_unit(token)} wrapped native tokens." - ) - return token - - def update_safe_balances(self) -> WaitableConditionType: - """Check the safe's balance.""" - account = self.synchronized_data.safe_contract_address - wallet = yield from self._get_native_balance(account) - if wallet is None: - return False - - token = yield from self._get_wrapped_native_balance(account) - if token is None: - return False - - self.token_balance = int(token) - self.wallet_balance = int(wallet) - return True - - def _build_unwrap_tokens_tx(self) -> WaitableConditionType: - """Exchange wrapped native tokens to native tokens.""" - - if not self.params.mech_wrapped_native_token_address: - return True - - # A total of price - wallet_balance wrapped native tokens are required - amount = self.price - self.wallet_balance - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.params.mech_wrapped_native_token_address, - contract_id=str(ERC20.contract_id), - contract_callable="build_withdraw_tx", - amount=amount, - ) - - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.info(f"Could not build withdraw tx: {response_msg}") - return False - - withdraw_data = response_msg.state.body.get("data") - if withdraw_data is None: - self.context.logger.info(f"Could not build withdraw tx: {response_msg}") - return False - - batch = MultisendBatch( - to=self.params.mech_wrapped_native_token_address, - data=HexBytes(withdraw_data), - ) - self.multisend_batches.append(batch) - self.context.logger.info(f"Built transaction to unwrap {amount} tokens.") - return True - - def _ensure_available_balance(self) -> WaitableConditionType: - """Ensures available payment for the mech request and unwraps tokens if needed.""" - yield from self.wait_for_condition_with_sleep(self.update_safe_balances) - - # There is enough balance using native tokens - if self.price <= self.wallet_balance: - return True - - # There is enough balance using native and wrapped tokens - if self.price <= self.wallet_balance + self.token_balance: - yield from self.wait_for_condition_with_sleep(self._build_unwrap_tokens_tx) - return True - - shortage = self.price - self.wallet_balance - self.token_balance - balance_info = "The balance is not enough to pay for the mech's price." - refill_info = f"Please refill the safe with at least {self.wei_to_unit(shortage)} native tokens." - if self.params.mech_wrapped_native_token_address: - refill_info = f"Please refill the safe with at least {self.wei_to_unit(shortage)} native tokens or wrapped native tokens." - - self.context.logger.warning(balance_info + " " + refill_info) - self.sleep(self.params.sleep_time) - return False - - def _build_multisend_data( - self, - ) -> WaitableConditionType: - """Get the multisend tx.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.multisend_address, - contract_id=str(MultiSendContract.contract_id), - contract_callable="get_tx_data", - multi_send_txs=self.multi_send_txs, - chain_id=self.params.mech_chain_id, - ) - expected_performative = ContractApiMessage.Performative.RAW_TRANSACTION - if response_msg.performative != expected_performative: - self.context.logger.error( - f"Couldn't compile the multisend tx. " - f"Expected response performative {expected_performative.value}, " # type: ignore - f"received {response_msg.performative.value}: {response_msg}" - ) - return False - - multisend_data_str = response_msg.raw_transaction.body.get("data", None) - if multisend_data_str is None: - self.context.logger.error( - f"Something went wrong while trying to prepare the multisend data: {response_msg}" - ) - return False - - # strip "0x" from the response - multisend_data_str = str(response_msg.raw_transaction.body["data"])[2:] - self.multisend_data = bytes.fromhex(multisend_data_str) - return True - - def _build_multisend_safe_tx_hash(self) -> WaitableConditionType: - """Prepares and returns the safe tx hash for a multisend tx.""" - self.context.logger.info( - f"Building multisend safe tx hash: safe={self.synchronized_data.safe_contract_address}" - ) - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_raw_safe_transaction_hash", - to_address=self.params.multisend_address, - value=self.txs_value, - data=self.multisend_data, - safe_tx_gas=SAFE_GAS, - operation=SafeOperation.DELEGATE_CALL.value, - chain_id=self.params.mech_chain_id, - ) - - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - "Couldn't get safe tx hash. Expected response performative " - f"{ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response_msg.performative.value}: {response_msg}." - ) - return False - - tx_hash = response_msg.state.body.get("tx_hash", None) - if tx_hash is None or len(tx_hash) != TX_HASH_LENGTH: - self.context.logger.error( - "Something went wrong while trying to get the buy transaction's hash. " - f"Invalid hash {tx_hash!r} was returned." - ) - return False - - self.safe_tx_hash = tx_hash - return True - - def setup(self) -> None: - """Set up the `MechRequest` behaviour.""" - self._mech_requests = self.synchronized_data.mech_requests - self.context.logger.info(f"Processing mech requests: {self._mech_requests}") - - def _send_metadata_to_ipfs( - self, - ) -> WaitableConditionType: - """Send Mech metadata to IPFS.""" - metadata = self._mech_requests.pop() - metadata_hash = yield from self.send_to_ipfs( - self.metadata_filepath, asdict(metadata), filetype=SupportedFiletype.JSON - ) - if metadata_hash is None: - return False - - v1_file_hash = to_v1(metadata_hash) - cid_bytes = cast(bytes, multibase.decode(v1_file_hash)) - multihash_bytes = multicodec.remove_prefix(cid_bytes) - v1_file_hash_hex = V1_HEX_PREFIX + multihash_bytes.hex() - ipfs_link = self.params.ipfs_address + v1_file_hash_hex - self.context.logger.info(f"Prompt uploaded: {ipfs_link}") - mech_request_data = v1_file_hash_hex[9:] - pending_response = MechInteractionResponse( - nonce=metadata.nonce, data=mech_request_data - ) - self._v1_hex_truncated = Ox + mech_request_data - self._pending_responses.append(pending_response) - return True - - def _build_request_data(self) -> WaitableConditionType: - """Get the request tx data encoded.""" - if self.params.use_mech_marketplace: - status = yield from self._mech_marketplace_contract_interact( - "get_request_data", - "data", - get_name(MechRequestBehaviour.request_data), - request_data=self._v1_hex_truncated, - priority_mech=self.mech_marketplace_config.priority_mech_address, - priority_mech_staking_instance=self.mech_marketplace_config.priority_mech_staking_instance_address, - priority_mech_service_id=self.mech_marketplace_config.priority_mech_service_id, - requester_staking_instance=self.mech_marketplace_config.requester_staking_instance_address, - requester_service_id=self.params.on_chain_service_id, - response_timeout=self.mech_marketplace_config.response_timeout, - chain_id=self.params.mech_chain_id, - ) - else: - status = yield from self._mech_contract_interact( - "get_request_data", - "data", - get_name(MechRequestBehaviour.request_data), - request_data=self._v1_hex_truncated, - chain_id=self.params.mech_chain_id, - ) - - if status: - to = ( - self.mech_marketplace_config.mech_marketplace_address - if self.params.use_mech_marketplace - else self.params.mech_contract_address - ) - batch = MultisendBatch( - to=to, - data=HexBytes(self.request_data), - value=self.price, - ) - self.multisend_batches.append(batch) - - return status - - def _get_price(self) -> WaitableConditionType: - """Get the price of the mech request.""" - # If the optional parameter 'mech_request_price' is set, then - # use that price (wei). Otherwise, determine the request price - # by calling the contract. - # This parameter is useful to set 'mech_request_price=0' when the - # agent is using a Nevermined subscription. - price = self.params.mech_request_price - - if price is not None: - self.price = price - return True - - result = yield from self._mech_contract_interact( - "get_price", - "price", - get_name(MechRequestBehaviour.price), - chain_id=self.params.mech_chain_id, - ) - return result - - def _prepare_safe_tx(self) -> Generator: - """Prepare a multisend safe tx for sending requests to a mech and return the hex for the tx settlement skill.""" - n_iters = min(self.params.multisend_batch_size, len(self._mech_requests)) - steps = (self._get_price,) - steps += (self._ensure_available_balance,) - steps += (self._send_metadata_to_ipfs, self._build_request_data) * n_iters - steps += (self._build_multisend_data, self._build_multisend_safe_tx_hash) - - for step in steps: - yield from self.wait_for_condition_with_sleep(step) - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - if not self._mech_requests: - payload = MechRequestPayload( - self.context.agent_address, - self.matching_round.auto_round_id(), - None, - None, - self.params.mech_chain_id, - None, - None, - ) - else: - self.context.logger.info( - f"Preparing mech requests: {self._mech_requests}" - ) - yield from self._prepare_safe_tx() - serialized_data = ( - json.dumps(data, cls=DataclassEncoder) - for data in (self._mech_requests, self._pending_responses) - ) - self.context.logger.info( - f"Preparing mech request:\ntx_hex: {self.tx_hex}\nprice: {self.price}\nserialized_data: {serialized_data}\n" - ) - payload = MechRequestPayload( - self.context.agent_address, - self.matching_round.auto_round_id(), - self.tx_hex, - self.price, - self.params.mech_chain_id, - *serialized_data, - ) - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/response.py b/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/response.py deleted file mode 100644 index 61a2ba60f..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/response.py +++ /dev/null @@ -1,270 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the response state of the mech interaction abci app.""" - -import json -from typing import Any, Callable, Dict, Generator, List, Optional - -from web3.constants import ADDRESS_ZERO - -from packages.valory.contracts.mech.contract import Mech -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.mech_interact_abci.behaviours.base import ( - DataclassEncoder, - MechInteractBaseBehaviour, - WaitableConditionType, -) -from packages.valory.skills.mech_interact_abci.behaviours.request import V1_HEX_PREFIX -from packages.valory.skills.mech_interact_abci.models import MechResponseSpecs -from packages.valory.skills.mech_interact_abci.payloads import MechResponsePayload -from packages.valory.skills.mech_interact_abci.states.base import ( - MechInteractionResponse, - MechRequest, -) -from packages.valory.skills.mech_interact_abci.states.response import MechResponseRound - - -IPFS_HASH_PREFIX = f"{V1_HEX_PREFIX}701220" - - -class MechResponseBehaviour(MechInteractBaseBehaviour): - """A behaviour in which the agents receive the Mech's responses.""" - - matching_round = MechResponseRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize Behaviour.""" - super().__init__(**kwargs) - self._from_block: int = 0 - self._requests: List[MechRequest] = [] - self._response_hex: str = "" - self._mech_responses: List[ - MechInteractionResponse - ] = self.synchronized_data.mech_responses - self._current_mech_response: MechInteractionResponse = MechInteractionResponse( - error="The mech's response has not been set!" - ) - - @property - def from_block(self) -> int: - """Get the block number in which the request to the mech was settled.""" - return self._from_block - - @from_block.setter - def from_block(self, from_block: int) -> None: - """Set the block number in which the request to the mech was settled.""" - self._from_block = from_block - - @property - def requests(self) -> List[MechRequest]: - """Get the requests.""" - return self._requests - - @requests.setter - def requests(self, requests: List[Dict[str, str]]) -> None: - """Set the requests.""" - self._requests = [MechRequest(**request) for request in requests] - - @property - def response_hex(self) -> str: - """Get the hash of the response data.""" - return self._response_hex - - @response_hex.setter - def response_hex(self, response_hash: bytes) -> None: - """Set the hash of the response data.""" - try: - self._response_hex = response_hash.hex() - except AttributeError: - msg = f"Response hash {response_hash!r} is not valid hex bytes!" - self.context.logger.error(msg) - - @property - def mech_response_api(self) -> MechResponseSpecs: - """Get the mech response api specs.""" - return self.context.mech_response - - @property - def serialized_responses(self) -> str: - """Get the Mech's responses serialized.""" - return json.dumps(self._mech_responses, cls=DataclassEncoder) - - def setup(self) -> None: - """Set up the `MechResponse` behaviour.""" - self._mech_responses = self.synchronized_data.mech_responses - - def set_mech_response_specs(self, request_id: int) -> None: - """Set the mech's response specs.""" - full_ipfs_hash = IPFS_HASH_PREFIX + self.response_hex - ipfs_link = self.params.ipfs_address + full_ipfs_hash + f"/{request_id}" - # The url must be dynamically generated as it depends on the ipfs hash - self.mech_response_api.__dict__["_frozen"] = False - self.mech_response_api.url = ipfs_link - self.mech_response_api.__dict__["_frozen"] = True - - def _get_block_number(self) -> WaitableConditionType: - """Get the block number in which the request to the mech was settled.""" - result = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - # we do not need the address to get the block number, but the base method does - contract_address=ADDRESS_ZERO, - contract_public_id=Mech.contract_id, - contract_callable="get_block_number", - data_key="number", - placeholder=get_name(MechResponseBehaviour.from_block), - tx_hash=self.synchronized_data.final_tx_hash, - chain_id=self.params.mech_chain_id, - ) - - return result - - @property - def mech_contract_interact(self) -> Callable[..., WaitableConditionType]: - """Interact with the mech contract.""" - if self.params.use_mech_marketplace: - return self._mech_marketplace_contract_interact - - return self._mech_contract_interact - - def _process_request_event(self) -> WaitableConditionType: - """Process the request event.""" - result = yield from self.mech_contract_interact( - contract_callable="process_request_event", - data_key="results", - placeholder=get_name(MechResponseBehaviour.requests), - tx_hash=self.synchronized_data.final_tx_hash, - expected_logs=len(self._mech_responses), - chain_id=self.params.mech_chain_id, - ) - return result - - def _get_response_hash(self) -> WaitableConditionType: - """Get the hash of the response data.""" - request_id = self._current_mech_response.requestId - self.context.logger.info( - f"Filtering the mech's events from block {self.from_block} " - f"for a response to our request with id {request_id!r}." - ) - result = yield from self.mech_contract_interact( - contract_callable="get_response", - data_key="data", - placeholder=get_name(MechResponseBehaviour.response_hex), - request_id=request_id, - from_block=self.from_block, - chain_id=self.params.mech_chain_id, - ) - - if result: - self.set_mech_response_specs(request_id) - - return result - - def _handle_response( - self, - res: Optional[str], - ) -> Optional[Any]: - """Handle the response from the IPFS. - - :param res: the response to handle. - :return: the response's result, using the given keys. `None` if response is `None` (has failed). - """ - if res is None: - msg = f"Could not get the mech's response from {self.mech_response_api.api_id}" - self.context.logger.error(msg) - self.mech_response_api.increment_retries() - return None - - self.context.logger.info(f"Retrieved the mech's response: {res}.") - self.mech_response_api.reset_retries() - return res - - def _get_response(self) -> WaitableConditionType: - """Get the response data from IPFS.""" - specs = self.mech_response_api.get_spec() - res_raw = yield from self.get_http_response(**specs) - res = self.mech_response_api.process_response(res_raw) - res = self._handle_response(res) - - if self.mech_response_api.is_retries_exceeded(): - self._current_mech_response.retries_exceeded() - return True - - if res is None: - return False - - try: - self._current_mech_response.result = res - except (ValueError, TypeError): - self._current_mech_response.incorrect_format(res) - - return True - - def _set_current_response(self, request: MechRequest) -> None: - """Set the current Mech response.""" - for pending_response in self._mech_responses: - if ( - pending_response.data == request.data.hex() - ): # TODO: why is request.data bytes now? - pending_response.requestId = request.requestId - self._current_mech_response = pending_response - break - - def _process_responses( - self, - ) -> Generator: - """Get the response.""" - for step in ( - self._get_block_number, - self._process_request_event, - ): - yield from self.wait_for_condition_with_sleep(step) - - for request in self.requests: - self._set_current_response(request) - - for step in (self._get_response_hash, self._get_response): - yield from self.wait_for_condition_with_sleep(step) - - self.context.logger.info( - f"Response has been received:\n{self._current_mech_response}" - ) - if self._current_mech_response.result is None: - self.context.logger.error( - f"There was an error in the mech's response: {self._current_mech_response.error}" - ) - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - if self.synchronized_data.final_tx_hash: - yield from self._process_responses() - - self.context.logger.info( - f"Received mech responses: {self.serialized_responses}" - ) - - payload = MechResponsePayload( - self.context.agent_address, - self.serialized_responses, - ) - - yield from self.finish_behaviour(payload) diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/round_behaviour.py b/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/round_behaviour.py deleted file mode 100644 index c5c40d819..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/behaviours/round_behaviour.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- 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 package contains the round behaviour of MechInteractAbciApp.""" - -from typing import Set, Type - -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.behaviours import AbstractRoundBehaviour -from packages.valory.skills.mech_interact_abci.behaviours.request import ( - MechRequestBehaviour, -) -from packages.valory.skills.mech_interact_abci.behaviours.response import ( - MechResponseBehaviour, -) -from packages.valory.skills.mech_interact_abci.rounds import MechInteractAbciApp - - -class MechInteractRoundBehaviour(AbstractRoundBehaviour): - """MechInteractRoundBehaviour""" - - initial_behaviour_cls = MechRequestBehaviour - abci_app_cls = MechInteractAbciApp # type: ignore - behaviours: Set[Type[BaseBehaviour]] = {MechRequestBehaviour, MechResponseBehaviour} diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/dialogues.py b/trader_backup/vendor/valory/skills/mech_interact_abci/dialogues.py deleted file mode 100644 index a6963e0a5..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/dialogues.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- 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 the dialogues of the MechInteractAbciApp.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/fsm_specification.yaml b/trader_backup/vendor/valory/skills/mech_interact_abci/fsm_specification.yaml deleted file mode 100644 index 60923b53e..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/fsm_specification.yaml +++ /dev/null @@ -1,30 +0,0 @@ -alphabet_in: -- DONE -- NO_MAJORITY -- ROUND_TIMEOUT -- SKIP_REQUEST -default_start_state: MechRequestRound -final_states: -- FinishedMechRequestRound -- FinishedMechRequestSkipRound -- FinishedMechResponseRound -- FinishedMechResponseTimeoutRound -label: MechInteractAbciApp -start_states: -- MechRequestRound -- MechResponseRound -states: -- FinishedMechRequestRound -- FinishedMechRequestSkipRound -- FinishedMechResponseRound -- FinishedMechResponseTimeoutRound -- MechRequestRound -- MechResponseRound -transition_func: - (MechRequestRound, DONE): FinishedMechRequestRound - (MechRequestRound, NO_MAJORITY): MechRequestRound - (MechRequestRound, ROUND_TIMEOUT): MechRequestRound - (MechRequestRound, SKIP_REQUEST): FinishedMechRequestSkipRound - (MechResponseRound, DONE): FinishedMechResponseRound - (MechResponseRound, NO_MAJORITY): MechResponseRound - (MechResponseRound, ROUND_TIMEOUT): FinishedMechResponseTimeoutRound diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/handlers.py b/trader_backup/vendor/valory/skills/mech_interact_abci/handlers.py deleted file mode 100644 index e664d676d..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/handlers.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- 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 the handlers for the skill of MechInteractAbciApp.""" - -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIHandler = BaseABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/models.py b/trader_backup/vendor/valory/skills/mech_interact_abci/models.py deleted file mode 100644 index 96fc52cce..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/models.py +++ /dev/null @@ -1,135 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the models for the abci skill of MechInteractAbciApp.""" - -from dataclasses import dataclass -from typing import Any, Dict, Optional - -from aea.exceptions import enforce -from hexbytes import HexBytes - -from packages.valory.contracts.multisend.contract import MultiSendOperation -from packages.valory.skills.abstract_round_abci.models import ApiSpecs, BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.mech_interact_abci.rounds import MechInteractAbciApp - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -class MechResponseSpecs(ApiSpecs): - """A model that wraps ApiSpecs for the Mech's response specifications.""" - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = MechInteractAbciApp - - -@dataclass(frozen=True) -class MechMarketplaceConfig: - """The configuration for the Mech marketplace.""" - - mech_marketplace_address: str - priority_mech_address: str - priority_mech_staking_instance_address: str - priority_mech_service_id: int - requester_staking_instance_address: str - response_timeout: int - - @classmethod - def from_dict(cls, data: Dict[str, Any]) -> "MechMarketplaceConfig": - """Create an instance from a dictionary.""" - return cls( - mech_marketplace_address=data["mech_marketplace_address"], - priority_mech_address=data["priority_mech_address"], - priority_mech_staking_instance_address=data[ - "priority_mech_staking_instance_address" - ], - priority_mech_service_id=data["priority_mech_service_id"], - requester_staking_instance_address=data[ - "requester_staking_instance_address" - ], - response_timeout=data["response_timeout"], - ) - - -class MechParams(BaseParams): - """The mech interact abci skill's parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Set up the mech-interaction parameters.""" - multisend_address = kwargs.get("multisend_address", None) - enforce(multisend_address is not None, "Multisend address not specified!") - self.multisend_address: str = multisend_address - self.multisend_batch_size: int = self._ensure( - "multisend_batch_size", kwargs, int - ) - self.mech_contract_address: str = self._ensure( - "mech_contract_address", kwargs, str - ) - self.mech_request_price: Optional[int] = kwargs.get("mech_request_price", None) - self._ipfs_address: str = self._ensure("ipfs_address", kwargs, str) - self.mech_chain_id: Optional[str] = kwargs.get("mech_chain_id", "gnosis") - self.mech_wrapped_native_token_address: Optional[str] = kwargs.get( - "mech_wrapped_native_token_address", None - ) - self.mech_interaction_sleep_time: int = self._ensure( - "mech_interaction_sleep_time", kwargs, int - ) - self.use_mech_marketplace = self._ensure("use_mech_marketplace", kwargs, bool) - self.mech_marketplace_config: MechMarketplaceConfig = ( - MechMarketplaceConfig.from_dict(kwargs["mech_marketplace_config"]) - ) - enforce( - not self.use_mech_marketplace - or self.mech_contract_address - == self.mech_marketplace_config.priority_mech_address, - "The mech contract address must be the same as the priority mech address when using the marketplace.", - ) - super().__init__(*args, **kwargs) - - @property - def ipfs_address(self) -> str: - """Get the IPFS address.""" - if self._ipfs_address.endswith("/"): - return self._ipfs_address - return f"{self._ipfs_address}/" - - -Params = MechParams - - -@dataclass -class MultisendBatch: - """A structure representing a single transaction of a multisend.""" - - to: str - data: HexBytes - value: int = 0 - operation: MultiSendOperation = MultiSendOperation.CALL diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/payloads.py b/trader_backup/vendor/valory/skills/mech_interact_abci/payloads.py deleted file mode 100644 index 250843c28..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/payloads.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the transaction payloads of the MechInteractAbciApp.""" - -from dataclasses import dataclass -from typing import Optional - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class MechRequestPayload(BaseTxPayload): - """Represent a transaction payload for the MechRequestRound.""" - - tx_submitter: Optional[str] - tx_hash: Optional[str] - price: Optional[int] - chain_id: Optional[str] - mech_requests: Optional[str] - mech_responses: Optional[str] - - -@dataclass(frozen=True) -class MechResponsePayload(BaseTxPayload): - """Represent a transaction payload for the MechResponseRound.""" - - mech_responses: str diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/rounds.py b/trader_backup/vendor/valory/skills/mech_interact_abci/rounds.py deleted file mode 100644 index 0195b03e6..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/rounds.py +++ /dev/null @@ -1,119 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the rounds of MechInteractAbciApp.""" - -from typing import Dict, Set - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AppState, - EventToTimeout, - get_name, -) -from packages.valory.skills.mech_interact_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.mech_interact_abci.states.final_states import ( - FinishedMechRequestRound, - FinishedMechRequestSkipRound, - FinishedMechResponseRound, - FinishedMechResponseTimeoutRound, -) -from packages.valory.skills.mech_interact_abci.states.request import MechRequestRound -from packages.valory.skills.mech_interact_abci.states.response import MechResponseRound - - -class MechInteractAbciApp(AbciApp[Event]): - """MechInteractAbciApp - - Initial round: MechRequestRound - - Initial states: {MechRequestRound, MechResponseRound} - - Transition states: - 0. MechRequestRound - - done: 2. - - skip request: 5. - - no majority: 0. - - round timeout: 0. - 1. MechResponseRound - - done: 3. - - no majority: 1. - - round timeout: 4. - 2. FinishedMechRequestRound - 3. FinishedMechResponseRound - 4. FinishedMechResponseTimeoutRound - 5. FinishedMechRequestSkipRound - - Final states: {FinishedMechRequestRound, FinishedMechRequestSkipRound, FinishedMechResponseRound, FinishedMechResponseTimeoutRound} - - Timeouts: - round timeout: 30.0 - """ - - initial_round_cls: AppState = MechRequestRound - initial_states: Set[AppState] = {MechRequestRound, MechResponseRound} - transition_function: AbciAppTransitionFunction = { - MechRequestRound: { - Event.DONE: FinishedMechRequestRound, - Event.SKIP_REQUEST: FinishedMechRequestSkipRound, - Event.NO_MAJORITY: MechRequestRound, - Event.ROUND_TIMEOUT: MechRequestRound, - }, - MechResponseRound: { - Event.DONE: FinishedMechResponseRound, - Event.NO_MAJORITY: MechResponseRound, - Event.ROUND_TIMEOUT: FinishedMechResponseTimeoutRound, - }, - FinishedMechRequestRound: {}, - FinishedMechResponseRound: {}, - FinishedMechResponseTimeoutRound: {}, - FinishedMechRequestSkipRound: {}, - } - final_states: Set[AppState] = { - FinishedMechRequestRound, - FinishedMechResponseRound, - FinishedMechResponseTimeoutRound, - FinishedMechRequestSkipRound, - } - event_to_timeout: EventToTimeout = { - Event.ROUND_TIMEOUT: 30.0, - } - cross_period_persisted_keys: Set[str] = {get_name(SynchronizedData.mech_responses)} - db_pre_conditions: Dict[AppState, Set[str]] = { - # using `set(get_name(SynchronizedData.mech_requests))` - # makes the checks complain that "db pre and post conditions intersect" - MechRequestRound: set(), - # we should be able to include `SynchronizedData.final_tx_hash` in the set below, - # however, we can't, because the checks incorrectly report that "db pre and post conditions intersect" - MechResponseRound: set(), - } - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedMechRequestRound: { - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.mech_price), - }, - FinishedMechRequestSkipRound: set(), - FinishedMechResponseRound: set(get_name(SynchronizedData.mech_responses)), - FinishedMechResponseTimeoutRound: set(), - } diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/skill.yaml b/trader_backup/vendor/valory/skills/mech_interact_abci/skill.yaml deleted file mode 100644 index 0bd20797b..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/skill.yaml +++ /dev/null @@ -1,200 +0,0 @@ -name: mech_interact_abci -author: valory -version: 0.1.0 -type: skill -description: The mech interact skill can be used to send requests to a mech and receive - the responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeidf3nlv5fpvfy4libtscayhirdw64shgmhfmvjiftjmjkmhu7auxq - behaviours/__init__.py: bafybeie3zsi6p3yanz5mqwpkdrcgywaqvkit3hdintsb4awnvalgxpxa4i - behaviours/base.py: bafybeif4dvt4p5wfh6q3ybqwnzy62lbr3vqy322sr3wm6pkcrha2ggin6q - behaviours/request.py: bafybeihaevbnfn66atdutf7rt7v3lw3vbw3tr4bugfdssebtmydgnuvjyq - behaviours/response.py: bafybeibigqdtdxxzufx7cclzjrafszg2lb6y5ommp3jzbyoit735wtm7tq - behaviours/round_behaviour.py: bafybeib33inrpyzzlx7k7i3okkslsx4p46dgdaww2m5k7rno57o5nndage - dialogues.py: bafybeigjmyzd2bx6mgqiet2c223k6wkc5jk7kdkstbhpaxlqxatey26tlm - fsm_specification.yaml: bafybeiapzwz6zcneelc2b2wrcb7cae7x6vbthmf6a57cm4mv6hucp67lz4 - handlers.py: bafybeiduy2nwkqdynainuimkjulcv7u2qq6iglkuut3gfurkckydapitg4 - models.py: bafybeidfes4ovzsyntxvqtx55qi2tznmllhzznf5qmozi52zrukiyrtbni - payloads.py: bafybeihhnbwsnaqxcltqxp4camiw3tz7gcymrdvxhmqlk4nww24tujiy7q - rounds.py: bafybeif7taciv6pqupb7xuewurqssziplbjeobbv4d7ea3vbngz3kpjnee - states/__init__.py: bafybeie34wx5znr2hxwh3gs2fchmbeuzjcfnraymdvtzjaxaq5zsiw233q - states/base.py: bafybeidnyaofckmpq6dts5a7rkfbljmxkazjz4shsv5vyh3cbxamt2dmci - states/final_states.py: bafybeihjntrbc666blxj4viz74y4p2hfc5e4vijs3bqng2k4vqbwkud7sq - states/request.py: bafybeifdkqn4o2tx57yflnxfhy6eoy42z7bdpadcevre64aw7l2hh2kpjy - states/response.py: bafybeibaxnp2oxwjptoq7qzm6o7ww2qrdj2vnxzg2qt523vz2ftqzx5hyi - tests/__init__.py: bafybeifojfnffwlsv6aiku25nwyjwm7h4m45yci3fgmaawpeoyoogzonum - tests/test_behaviours.py: bafybeidj7git7zaego7k75eejtxlr3usj6wnnqisu7urqwvalpwh5w7nyq - tests/test_dialogues.py: bafybeig6uzk7fklieyxapemiobdvv5tyx7hgdkdpl4vnacohgw2ecphdpq - tests/test_handlers.py: bafybeidwrmekr5tydmehvkolyksw37sah5js7buy3ca5fxkpgkppmgb3wi - tests/test_models.py: bafybeid3cvcttdxlklwvr6tqmiurb2qywvmgr5bnsn62pb5gl5p552eagy - tests/test_payloads.py: bafybeiakqhgochfu4ra4hp65hi7jvxtjd7fdub5wqmhlccrc4va26hb7da - tests/test_rounds.py: bafybeiauu5adaoxu7yvtrfa6uwdw4sxr5gn2pj7qjh6vowd556iji6vtca -fingerprint_ignore_patterns: [] -connections: [] -contracts: -- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge -- valory/mech:0.1.0:bafybeiejfjfoxqggghcme43sx53q5gruefrws3k2jam2opkxl5uzffoarm -- valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y -- valory/erc20:0.1.0:bafybeid2p2jyvjjlcsqugnawksdzsca6ljghpqbp2kfi3cxuxoy2233dbi -- valory/mech_marketplace:0.1.0:bafybeiba7kh3wygwtpyf7oo3sili6givzo2gyadhbb66rvwsokswsywvuu -protocols: -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae -behaviours: - main: - args: {} - class_name: MechInteractRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - finalize_timeout: 60.0 - genesis_config: - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_duration: '172800000000000' - max_age_num_blocks: '100000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - genesis_time: '2022-05-20T16:00:21.735122717Z' - voting_power: '10' - history_check_timeout: 1205 - ipfs_domain_name: null - keeper_allowed_retries: 3 - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 30.0 - service_id: mech_interact - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - consensus_threshold: null - safe_contract_address: '0x0000000000000000000000000000000000000000' - share_tm_config_on_startup: false - sleep_time: 1 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - tx_timeout: 10.0 - validate_timeout: 1205 - multisend_batch_size: 50 - mech_contract_address: '0x77af31De935740567Cf4fF1986D04B2c964A786a' - mech_request_price: null - mech_chain_id: gnosis - mech_wrapped_native_token_address: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d' - ipfs_address: https://gateway.autonolas.tech/ipfs/ - use_termination: false - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - mech_interaction_sleep_time: 10 - use_mech_marketplace: false - mech_marketplace_config: - mech_marketplace_address: '0x0000000000000000000000000000000000000000' - priority_mech_address: '0x0000000000000000000000000000000000000000' - priority_mech_staking_instance_address: '0x0000000000000000000000000000000000000000' - priority_mech_service_id: 0 - requester_staking_instance_address: '0x0000000000000000000000000000000000000000' - response_timeout: 300 - class_name: Params - mech_response: - args: - api_id: mech_response - headers: - Content-Type: application/json - method: GET - parameters: {} - response_key: result - response_type: str - retries: 5 - url: '' - class_name: MechResponseSpecs - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: - web3: - version: <7,>=6.0.0 - hexbytes: {} - py-multicodec: {} - py-multibase: {} -is_abstract: true diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/states/__init__.py b/trader_backup/vendor/valory/skills/mech_interact_abci/states/__init__.py deleted file mode 100644 index c126495fd..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/states/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 package contains the rounds for the mech interact abci skill.""" diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/states/base.py b/trader_backup/vendor/valory/skills/mech_interact_abci/states/base.py deleted file mode 100644 index 4f4fb6c08..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/states/base.py +++ /dev/null @@ -1,148 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the base functionality for the rounds of the mech interact abci app.""" - -import json -from dataclasses import dataclass -from enum import Enum -from typing import Any, List, Mapping, Optional, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseTxPayload, - CollectSameUntilThresholdRound, - CollectionRound, -) -from packages.valory.skills.mech_interact_abci.payloads import ( - MechRequestPayload, - MechResponsePayload, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TxSynchronizedData, -) - - -class Event(Enum): - """MechInteractAbciApp Events""" - - DONE = "done" - NO_MAJORITY = "no_majority" - ROUND_TIMEOUT = "round_timeout" - SKIP_REQUEST = "skip_request" - - -@dataclass -class MechMetadata: - """A Mech's metadata.""" - - prompt: str - tool: str - nonce: str - - -@dataclass -class MechRequest: - """A Mech's request.""" - - data: str = "" - requestId: int = 0 - - -@dataclass -class MechInteractionResponse(MechRequest): - """A structure for the response of a mech interaction task.""" - - nonce: str = "" - result: Optional[str] = None - error: str = "Unknown" - - def retries_exceeded(self) -> None: - """Set an incorrect format response.""" - self.error = "Retries were exceeded while trying to get the mech's response." - - def incorrect_format(self, res: Any) -> None: - """Set an incorrect format response.""" - self.error = f"The response's format was unexpected: {res}" - - -class SynchronizedData(TxSynchronizedData): - """ - Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - @property - def mech_price(self) -> int: - """Get the mech's request price.""" - return int(self.db.get_strict("mech_price")) - - @property - def mech_requests(self) -> List[MechMetadata]: - """Get the mech requests.""" - requests = self.db.get("mech_requests", "[]") - if isinstance(requests, str): - requests = json.loads(requests) - return [MechMetadata(**metadata_item) for metadata_item in requests] - - @property - def mech_responses(self) -> List[MechInteractionResponse]: - """Get the mech responses.""" - responses = self.db.get("mech_responses", "[]") - if isinstance(responses, str): - responses = json.loads(responses) - return [MechInteractionResponse(**response_item) for response_item in responses] - - @property - def participant_to_requests(self) -> Mapping[str, MechRequestPayload]: - """Get the `participant_to_requests`.""" - serialized = self.db.get_strict("participant_to_requests") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(Mapping[str, MechRequestPayload], deserialized) - - @property - def participant_to_responses(self) -> Mapping[str, MechResponsePayload]: - """Get the `participant_to_responses`.""" - serialized = self.db.get_strict("participant_to_responses") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(Mapping[str, MechResponsePayload], deserialized) - - @property - def final_tx_hash(self) -> Optional[str]: - """Get the verified tx hash.""" - return cast(str, self.db.get("final_tx_hash", None)) - - @property - def chain_id(self) -> Optional[str]: - """Get the chain name where to send the transactions.""" - return cast(str, self.db.get("chain_id", None)) - - @property - def tx_submitter(self) -> str: - """Get the round that submitted a tx to transaction_settlement_abci.""" - return str(self.db.get_strict("tx_submitter")) - - -class MechInteractionRound(CollectSameUntilThresholdRound): - """A base round for the mech interactions.""" - - payload_class = BaseTxPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - no_majority_event = Event.NO_MAJORITY diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/states/final_states.py b/trader_backup/vendor/valory/skills/mech_interact_abci/states/final_states.py deleted file mode 100644 index c2ad59cbb..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/states/final_states.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the final states of the mech interact abci app.""" - -from packages.valory.skills.abstract_round_abci.base import DegenerateRound - - -class FinishedMechRequestRound(DegenerateRound): - """FinishedMechRequestRound""" - - -class FinishedMechRequestSkipRound(DegenerateRound): - """FinishedMechRequestSkipRound""" - - -class FinishedMechResponseRound(DegenerateRound): - """FinishedMechResponseRound""" - - -class FinishedMechResponseTimeoutRound(DegenerateRound): - """FinishedMechResponseTimeoutRound""" diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/states/request.py b/trader_backup/vendor/valory/skills/mech_interact_abci/states/request.py deleted file mode 100644 index 2e0d7765e..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/states/request.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the request state of the mech interaction abci app.""" - -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.mech_interact_abci.payloads import MechRequestPayload -from packages.valory.skills.mech_interact_abci.states.base import ( - Event, - MechInteractionRound, - SynchronizedData, -) - - -class MechRequestRound(MechInteractionRound): - """A round for performing requests to a Mech.""" - - payload_class = MechRequestPayload - - selection_key = ( - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.mech_price), - get_name(SynchronizedData.chain_id), - get_name(SynchronizedData.mech_requests), - get_name(SynchronizedData.mech_responses), - ) - collection_key = get_name(SynchronizedData.participant_to_requests) - none_event = Event.SKIP_REQUEST diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/states/response.py b/trader_backup/vendor/valory/skills/mech_interact_abci/states/response.py deleted file mode 100644 index 6b700f2fb..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/states/response.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- 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 the response state of the mech interaction abci app.""" - -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.mech_interact_abci.payloads import MechResponsePayload -from packages.valory.skills.mech_interact_abci.states.base import ( - MechInteractionRound, - SynchronizedData, -) - - -class MechResponseRound(MechInteractionRound): - """A round for collecting the responses from a Mech.""" - - payload_class = MechResponsePayload - selection_key = get_name(SynchronizedData.mech_responses) - collection_key = get_name(SynchronizedData.participant_to_responses) diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/mech_interact_abci/tests/__init__.py deleted file mode 100644 index 6ea42d4cc..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for the mech interact abci skill.""" diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_behaviours.py b/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_behaviours.py deleted file mode 100644 index 2905d0b7b..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_behaviours.py +++ /dev/null @@ -1,132 +0,0 @@ -# -*- 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 package contains round behaviours of MechInteractAbciApp.""" - -from dataclasses import dataclass, field -from pathlib import Path -from typing import Any, Dict, Hashable, Optional, Type - -import pytest - -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.behaviours import BaseBehaviour -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.mech_interact_abci.behaviours.base import ( - MechInteractBaseBehaviour, -) -from packages.valory.skills.mech_interact_abci.behaviours.request import ( - MechRequestBehaviour, -) -from packages.valory.skills.mech_interact_abci.behaviours.response import ( - MechResponseBehaviour, -) -from packages.valory.skills.mech_interact_abci.behaviours.round_behaviour import ( - MechInteractRoundBehaviour, -) -from packages.valory.skills.mech_interact_abci.states.base import ( - Event, - SynchronizedData, -) - - -@dataclass -class BehaviourTestCase: - """BehaviourTestCase""" - - name: str - initial_data: Dict[str, Hashable] - event: Event - kwargs: Dict[str, Any] = field(default_factory=dict) - - -class BaseMechInteractTest(FSMBehaviourBaseCase): - """Base test case.""" - - path_to_skill = Path(__file__).parent.parent - - behaviour: MechInteractRoundBehaviour - behaviour_class: Type[MechInteractBaseBehaviour] - next_behaviour_class: Type[MechInteractBaseBehaviour] - synchronized_data: SynchronizedData - done_event = Event.DONE - - @property - def current_behaviour_id(self) -> str: - """Current RoundBehaviour's behaviour id""" - - return self.behaviour.current_behaviour.behaviour_id - - def fast_forward(self, data: Optional[Dict[str, Any]] = None) -> None: - """Fast-forward on initialization""" - - data = data if data is not None else {} - self.fast_forward_to_behaviour( - self.behaviour, - self.behaviour_class.behaviour_id, - SynchronizedData(AbciAppDB(setup_data=AbciAppDB.data_to_lists(data))), - ) - assert self.current_behaviour_id == self.behaviour_class.behaviour_id - - def complete(self, event: Event) -> None: - """Complete test""" - - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(done_event=event) - assert self.current_behaviour_id == self.next_behaviour_class.behaviour_id - - -class TestMechRequestBehaviour(BaseMechInteractTest): - """Tests MechRequestBehaviour""" - - # TODO: set next_behaviour_class - behaviour_class: Type[BaseBehaviour] = MechRequestBehaviour - next_behaviour_class: Type[BaseBehaviour] = ... - - # TODO: provide test cases - @pytest.mark.parametrize("test_case", []) - def test_run(self, test_case: BehaviourTestCase) -> None: - """Run tests.""" - - self.fast_forward(test_case.initial_data) - # TODO: mock the necessary calls - # self.mock_ ... - self.complete(test_case.event) - - -class TestMechResponseBehaviour(BaseMechInteractTest): - """Tests MechResponseBehaviour""" - - # TODO: set next_behaviour_class - behaviour_class: Type[BaseBehaviour] = MechResponseBehaviour - next_behaviour_class: Type[BaseBehaviour] = ... - - # TODO: provide test cases - @pytest.mark.parametrize("test_case", []) - def test_run(self, test_case: BehaviourTestCase) -> None: - """Run tests.""" - - self.fast_forward(test_case.initial_data) - # TODO: mock the necessary calls - # self.mock_ ... - self.complete(test_case.event) diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_dialogues.py b/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_dialogues.py deleted file mode 100644 index 7913ae0db..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_dialogues.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the MechInteract.""" - -import packages.valory.skills.mech_interact_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' of the MechInteract can be imported.""" diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_handlers.py b/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_handlers.py deleted file mode 100644 index 8a7c03aa0..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_handlers.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Test the handlers.py module of the MechInteract.""" - -import packages.valory.skills.mech_interact_abci.handlers # noqa - - -def test_import() -> None: - """Test that the 'handlers.py' of the MechInteract can be imported.""" diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_models.py b/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_models.py deleted file mode 100644 index 1b18facea..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_models.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Test the models.py module of the MechInteract.""" - -from packages.valory.skills.abstract_round_abci.test_tools.base import DummyContext -from packages.valory.skills.mech_interact_abci.models import SharedState - - -class TestSharedState: - """Test SharedState of MechInteract.""" - - def test_initialization(self) -> None: - """Test initialization.""" - SharedState(name="", skill_context=DummyContext()) diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_payloads.py b/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_payloads.py deleted file mode 100644 index 40c5d022a..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_payloads.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- 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 package contains payload tests for the MechInteractAbciApp.""" - -from dataclasses import dataclass -from typing import Hashable, Type - -import pytest - -from packages.valory.skills.mech_interact_abci.payloads import BaseTxPayload - - -@dataclass -class PayloadTestCase: - """PayloadTestCase""" - - name: str - payload_cls: Type[BaseTxPayload] - content: Hashable - - -# TODO: provide test cases -@pytest.mark.parametrize("test_case", []) -def test_payloads(test_case: PayloadTestCase) -> None: - """Tests for MechInteractAbciApp payloads""" - - payload = test_case.payload_cls(sender="sender", content=test_case.content) - assert payload.sender == "sender" - assert payload.from_json(payload.json) == payload diff --git a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_rounds.py b/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_rounds.py deleted file mode 100644 index bd5914e95..000000000 --- a/trader_backup/vendor/valory/skills/mech_interact_abci/tests/test_rounds.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- 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 package contains the tests for rounds of MechInteract.""" - -from dataclasses import dataclass, field -from typing import Any, Callable, Dict, Hashable, List, Mapping, Type - -import pytest - -from packages.valory.skills.abstract_round_abci.base import AbstractRound, BaseTxPayload -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseRoundTestClass, -) -from packages.valory.skills.mech_interact_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.mech_interact_abci.states.request import MechRequestRound -from packages.valory.skills.mech_interact_abci.states.response import MechResponseRound - - -@dataclass -class RoundTestCase: - """RoundTestCase""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, BaseTxPayload] - final_data: Dict[str, Hashable] - event: Event - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - kwargs: Dict[str, Any] = field(default_factory=dict) - - -MAX_PARTICIPANTS: int = 4 - - -class BaseMechInteractRoundTest(BaseRoundTestClass): - """Base test class for MechInteract rounds.""" - - round_cls: Type[AbstractRound] - synchronized_data: SynchronizedData - _synchronized_data_class = SynchronizedData - _event_class = Event - - def run_test(self, test_case: RoundTestCase) -> None: - """Run the test""" - - self.synchronized_data.update(**test_case.initial_data) - - test_round = self.round_cls( - synchronized_data=self.synchronized_data, - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=test_case.payloads, - synchronized_data_update_fn=lambda sync_data, _: sync_data.update( - **test_case.final_data - ), - synchronized_data_attr_checks=test_case.synchronized_data_attr_checks, - exit_event=test_case.event, - **test_case.kwargs, # varies per BaseRoundTestClass child - ) - ) - - -class TestMechRequestRound(BaseMechInteractRoundTest): - """Tests for MechRequestRound.""" - - round_class = MechRequestRound - - # TODO: provide test cases - @pytest.mark.parametrize("test_case", []) - def test_run(self, test_case: RoundTestCase) -> None: - """Run tests.""" - - self.run_test(test_case) - - -class TestMechResponseRound(BaseMechInteractRoundTest): - """Tests for MechResponseRound.""" - - round_class = MechResponseRound - - # TODO: provide test cases - @pytest.mark.parametrize("test_case", []) - def test_run(self, test_case: RoundTestCase) -> None: - """Run tests.""" - - self.run_test(test_case) diff --git a/trader_backup/vendor/valory/skills/registration_abci/README.md b/trader_backup/vendor/valory/skills/registration_abci/README.md deleted file mode 100644 index a8eeb2265..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Registration abci - -## Description - -This module contains the ABCI registration skill for an AEA. - -## Behaviours - -* `RegistrationBaseBehaviour` - - Register to the next periods. - -* `RegistrationBehaviour` - - Register to the next periods. - -* `RegistrationStartupBehaviour` - - Register to the next periods. - - -## Handlers - -No Handlers (the skill is purely behavioural). - diff --git a/trader_backup/vendor/valory/skills/registration_abci/__init__.py b/trader_backup/vendor/valory/skills/registration_abci/__init__.py deleted file mode 100644 index e69b708ed..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the ABCI registration skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/registration_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/registration_abci/behaviours.py b/trader_backup/vendor/valory/skills/registration_abci/behaviours.py deleted file mode 100644 index 4a617b4d1..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/behaviours.py +++ /dev/null @@ -1,492 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the behaviours for the 'registration_abci' skill.""" - -import datetime -import json -from abc import ABC -from enum import Enum -from typing import Any, Dict, Generator, Optional, Set, Type, cast - -from aea.mail.base import EnvelopeContext - -from packages.valory.connections.p2p_libp2p_client.connection import ( - PUBLIC_ID as P2P_LIBP2P_CLIENT_PUBLIC_ID, -) -from packages.valory.contracts.service_registry.contract import ServiceRegistryContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.tendermint import TendermintMessage -from packages.valory.skills.abstract_round_abci.base import ABCIAppInternalError -from packages.valory.skills.abstract_round_abci.behaviour_utils import TimeoutException -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.abstract_round_abci.utils import parse_tendermint_p2p_url -from packages.valory.skills.registration_abci.dialogues import TendermintDialogues -from packages.valory.skills.registration_abci.models import SharedState -from packages.valory.skills.registration_abci.payloads import RegistrationPayload -from packages.valory.skills.registration_abci.rounds import ( - AgentRegistrationAbciApp, - RegistrationRound, - RegistrationStartupRound, -) - - -NODE = "node_{address}" -WAIT_FOR_BLOCK_TIMEOUT = 60.0 # 1 minute - - -class RegistrationBaseBehaviour(BaseBehaviour, ABC): - """Agent registration to the FSM App.""" - - def async_act(self) -> Generator: - """ - Do the action. - - Steps: - - Build a registration transaction. - - Send the transaction and wait for it to be mined. - - Wait until ABCI application transitions to the next round. - - Go to the next behaviour (set done event). - """ - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - serialized_db = self.synchronized_data.db.serialize() - payload = RegistrationPayload( - self.context.agent_address, initialisation=serialized_db - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class RegistrationStartupBehaviour(RegistrationBaseBehaviour): - """Agent registration to the FSM App.""" - - ENCODING: str = "utf-8" - matching_round = RegistrationStartupRound - local_tendermint_params: Dict[str, Any] = {} - updated_genesis_data: Dict[str, Any] = {} - collection_complete: bool = False - - @property - def initial_tm_configs(self) -> Dict[str, Dict[str, Any]]: - """A mapping of the other agents' addresses to their initial Tendermint configuration.""" - return self.context.state.initial_tm_configs - - @initial_tm_configs.setter - def initial_tm_configs(self, configs: Dict[str, Dict[str, Any]]) -> None: - """A mapping of the other agents' addresses to their initial Tendermint configuration.""" - self.context.state.initial_tm_configs = configs - - class LogMessages(Enum): - """Log messages used in RegistrationStartupBehaviour""" - - config_sharing = "Sharing Tendermint config on start-up?" - # request personal tendermint configuration - request_personal = "Request validator config from personal Tendermint node" - response_personal = "Response validator config from personal Tendermint node" - failed_personal = "Failed validator config from personal Tendermint node" - # verify deployment on-chain contract - request_verification = "Request service registry contract verification" - response_verification = "Response service registry contract verification" - failed_verification = "Failed service registry contract verification" - # request service info from on-chain contract - request_service_info = "Request on-chain service info" - response_service_info = "Response on-chain service info" - failed_service_info = "Failed on-chain service info" - # request tendermint configuration other agents - request_others = "Request Tendermint config info from other agents" - collection_complete = "Completed collecting Tendermint configuration responses" - # update personal tendermint node config - request_update = "Request update Tendermint node configuration" - response_update = "Response update Tendermint node configuration" - failed_update = "Failed update Tendermint node configuration" - # exceptions - no_contract_address = "Service registry contract address not provided" - no_on_chain_service_id = "On-chain service id not provided" - contract_incorrect = "Service registry contract not correctly deployed" - no_agents_registered = "No agents registered on-chain" - self_not_registered = "This agent is not registered on-chain" - - def __str__(self) -> str: - """For ease of use in formatted string literals""" - return self.value - - @property - def tendermint_parameter_url(self) -> str: - """Tendermint URL for obtaining and updating parameters""" - return f"{self.params.tendermint_com_url}/params" - - def _decode_result( - self, message: HttpMessage, error_log: LogMessages - ) -> Optional[Dict[str, Any]]: - """Decode a http message's body. - - :param message: the http message. - :param error_log: a log to prefix potential errors with. - :return: the message's body, as a dictionary - """ - try: - response = json.loads(message.body.decode()) - except json.JSONDecodeError as error: - self.context.logger.error(f"{error_log}: {error}") - return None - - if not response["status"]: # pragma: no cover - self.context.logger.error(f"{error_log}: {response['error']}") - return None - - return response - - def is_correct_contract( - self, service_registry_address: str - ) -> Generator[None, None, bool]: - """Contract deployment verification.""" - - self.context.logger.info(self.LogMessages.request_verification) - - performative = ContractApiMessage.Performative.GET_STATE - kwargs = dict( - performative=performative, - contract_address=service_registry_address, - contract_id=str(ServiceRegistryContract.contract_id), - contract_callable="verify_contract", - chain_id=self.params.default_chain_id, - ) - contract_api_response = yield from self.get_contract_api_response(**kwargs) # type: ignore - if ( - contract_api_response.performative - is not ContractApiMessage.Performative.STATE - ): - verified = False - log_method = self.context.logger.error - log_message = f"{self.LogMessages.failed_verification} ({kwargs}): {contract_api_response}" - else: - verified = cast(bool, contract_api_response.state.body["verified"]) - log_method = self.context.logger.info - log_message = f"{self.LogMessages.response_verification}: {verified}" - - log_method(log_message) - return verified - - def get_agent_instances( - self, service_registry_address: str, on_chain_service_id: int - ) -> Generator[None, None, Dict[str, Any]]: - """Get service info available on-chain""" - - log_message = self.LogMessages.request_service_info - self.context.logger.info(f"{log_message}") - - performative = ContractApiMessage.Performative.GET_STATE - kwargs = dict( - performative=performative, - contract_address=service_registry_address, - contract_id=str(ServiceRegistryContract.contract_id), - contract_callable="get_agent_instances", - service_id=on_chain_service_id, - chain_id=self.params.default_chain_id, - ) - contract_api_response = yield from self.get_contract_api_response(**kwargs) # type: ignore - if contract_api_response.performative != ContractApiMessage.Performative.STATE: - log_message = self.LogMessages.failed_service_info - self.context.logger.error( - f"{log_message} ({kwargs}): {contract_api_response}" - ) - return {} - - log_message = self.LogMessages.response_service_info - self.context.logger.info(f"{log_message}: {contract_api_response}") - return cast(dict, contract_api_response.state.body) - - def get_addresses(self) -> Generator: # pylint: disable=too-many-return-statements - """Get addresses of agents registered for the service""" - - service_registry_address = self.params.service_registry_address - if service_registry_address is None: - log_message = self.LogMessages.no_contract_address.value - self.context.logger.error(log_message) - return False - - correctly_deployed = yield from self.is_correct_contract( - service_registry_address - ) - if not correctly_deployed: - return False - - on_chain_service_id = self.params.on_chain_service_id - if on_chain_service_id is None: - log_message = self.LogMessages.no_on_chain_service_id.value - self.context.logger.error(log_message) - return False - - service_info = yield from self.get_agent_instances( - service_registry_address, on_chain_service_id - ) - if not service_info: - return False - - registered_addresses = set(service_info["agentInstances"]) - if not registered_addresses: - log_message = self.LogMessages.no_agents_registered.value - self.context.logger.error(f"{log_message}: {service_info}") - return False - - my_address = self.context.agent_address - if my_address not in registered_addresses: - log_message = f"{self.LogMessages.self_not_registered} ({my_address})" - self.context.logger.error(f"{log_message}: {registered_addresses}") - return False - - # put service info in the shared state for p2p message handler - info: Dict[str, Dict[str, str]] = {i: {} for i in registered_addresses} - tm_host, tm_port = parse_tendermint_p2p_url(url=self.params.tendermint_p2p_url) - validator_config = dict( - hostname=tm_host, - p2p_port=tm_port, - address=self.local_tendermint_params["address"], - pub_key=self.local_tendermint_params["pub_key"], - peer_id=self.local_tendermint_params["peer_id"], - ) - info[self.context.agent_address] = validator_config - self.initial_tm_configs = info - log_message = self.LogMessages.response_service_info.value - self.context.logger.info(f"{log_message}: {info}") - return True - - def get_tendermint_configuration(self) -> Generator[None, None, bool]: - """Make HTTP GET request to obtain agent's local Tendermint node parameters""" - - url = self.tendermint_parameter_url - log_message = self.LogMessages.request_personal - self.context.logger.info(f"{log_message}: {url}") - - result = yield from self.get_http_response(method="GET", url=url) - response = self._decode_result(result, self.LogMessages.failed_personal) - if response is None: - return False - - self.local_tendermint_params = response["params"] - log_message = self.LogMessages.response_personal - self.context.logger.info(f"{log_message}: {response}") - return True - - def request_tendermint_info(self) -> Generator[None, None, bool]: - """Request Tendermint info from other agents""" - - still_missing = {k for k, v in self.initial_tm_configs.items() if not v} - { - self.context.agent_address - } - log_message = self.LogMessages.request_others - self.context.logger.info(f"{log_message}: {still_missing}") - - for address in still_missing: - dialogues = cast(TendermintDialogues, self.context.tendermint_dialogues) - performative = TendermintMessage.Performative.GET_GENESIS_INFO - message, _ = dialogues.create( - counterparty=address, performative=performative - ) - message = cast(TendermintMessage, message) - context = EnvelopeContext(connection_id=P2P_LIBP2P_CLIENT_PUBLIC_ID) - self.context.outbox.put_message(message=message, context=context) - # we wait for the messages that were put in the outbox. - yield from self.sleep(self.params.sleep_time) - - if all(self.initial_tm_configs.values()): - log_message = self.LogMessages.collection_complete - self.context.logger.info(f"{log_message}: {self.initial_tm_configs}") - validator_to_agent = { - config["address"]: agent - for agent, config in self.initial_tm_configs.items() - } - self.context.state.setup_slashing(validator_to_agent) - self.collection_complete = True - return self.collection_complete - - def format_genesis_data( - self, - collected_agent_info: Dict[str, Any], - ) -> Dict[str, Any]: - """Format collected agent info for genesis update""" - - validators = [] - for address, validator_config in collected_agent_info.items(): - validator = dict( - hostname=validator_config["hostname"], - p2p_port=validator_config["p2p_port"], - address=validator_config["address"], - pub_key=validator_config["pub_key"], - peer_id=validator_config["peer_id"], - power=self.params.genesis_config.voting_power, - name=NODE.format(address=address[2:]), # skip 0x part - ) - validators.append(validator) - - genesis_data = dict( - validators=validators, - genesis_config=self.params.genesis_config.to_json(), - external_address=self.params.tendermint_p2p_url, - ) - return genesis_data - - def request_update(self) -> Generator[None, None, bool]: - """Make HTTP POST request to update agent's local Tendermint node""" - - url = self.tendermint_parameter_url - genesis_data = self.format_genesis_data(self.initial_tm_configs) - log_message = self.LogMessages.request_update - self.context.logger.info(f"{log_message}: {genesis_data}") - - content = json.dumps(genesis_data).encode(self.ENCODING) - result = yield from self.get_http_response( - method="POST", url=url, content=content - ) - response = self._decode_result(result, self.LogMessages.failed_update) - if response is None: - return False - - log_message = self.LogMessages.response_update - self.context.logger.info(f"{log_message}: {response}") - self.updated_genesis_data.update(genesis_data) - return True - - def wait_for_block(self, timeout: float) -> Generator[None, None, bool]: - """Wait for a block to be received in the specified timeout.""" - # every agent will finish with the reset at a different time - # hence the following will be different for all agents - start_time = datetime.datetime.now() - - def received_block() -> bool: - """Check whether we have received a block after "start_time".""" - try: - shared_state = cast(SharedState, self.context.state) - last_timestamp = shared_state.round_sequence.last_timestamp - if last_timestamp > start_time: - return True - return False - except ABCIAppInternalError: - # this can happen if we haven't received a block yet - return False - - try: - yield from self.wait_for_condition( - condition=received_block, timeout=timeout - ) - # if the `wait_for_condition` finish without an exception, - # it means that the condition has been satisfied on time - return True - except TimeoutException: - # the agent wasn't able to receive blocks in the given amount of time (timeout) - return False - - def async_act(self) -> Generator: # pylint: disable=too-many-return-statements - """ - Do the action. - - Steps: - 1. Collect personal Tendermint configuration - 2. Make Service Registry contract call to retrieve addresses - of the other agents registered on-chain for the service. - 3. Request Tendermint configuration from registered agents. - This is done over the Agent Communication Network using - the p2p_libp2p_client connection. - 4. Update Tendermint configuration via genesis.json with the - information of the other validators (agents). - 5. Restart Tendermint to establish the validator network. - """ - - exchange_config = self.params.share_tm_config_on_startup - log_message = self.LogMessages.config_sharing.value - self.context.logger.info(f"{log_message}: {exchange_config}") - - if not exchange_config: - yield from super().async_act() - return - - self.context.logger.info(f"My address: {self.context.agent_address}") - - # collect personal Tendermint configuration - if not self.local_tendermint_params: - successful = yield from self.get_tendermint_configuration() - if not successful: - yield from self.sleep(self.params.sleep_time) - return - - # if the agent doesn't have it's tm config info set, then make service registry contract call - # to get the rest of the agents, so we can get their tm config info later - info = self.initial_tm_configs.get(self.context.agent_address, None) - if info is None: - successful = yield from self.get_addresses() - if not successful: - yield from self.sleep(self.params.sleep_time) - return - - # collect Tendermint config information from other agents - if not self.collection_complete: - successful = yield from self.request_tendermint_info() - if not successful: - yield from self.sleep(self.params.sleep_time) - return - - # update Tendermint configuration - if not self.updated_genesis_data: - successful = yield from self.request_update() - if not successful: - yield from self.sleep(self.params.sleep_time) - return - - # restart Tendermint with updated configuration - successful = yield from self.reset_tendermint_with_wait(on_startup=True) - if not successful: - yield from self.sleep(self.params.sleep_time) - return - - # the reset has gone through, and at this point tendermint should start - # sending blocks to the agent. However, that might take a while, since - # we rely on 2/3 of the voting power to be active in order for block production - # to begin. In other words, we wait for >=2/3 of the agents to become active. - successful = yield from self.wait_for_block(timeout=WAIT_FOR_BLOCK_TIMEOUT) - if not successful: - yield from self.sleep(self.params.sleep_time) - return - - yield from super().async_act() - - -class RegistrationBehaviour(RegistrationBaseBehaviour): - """Agent registration to the FSM App.""" - - matching_round = RegistrationRound - - -class AgentRegistrationRoundBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the registration.""" - - initial_behaviour_cls = RegistrationStartupBehaviour - abci_app_cls = AgentRegistrationAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - RegistrationBehaviour, # type: ignore - RegistrationStartupBehaviour, # type: ignore - } diff --git a/trader_backup/vendor/valory/skills/registration_abci/dialogues.py b/trader_backup/vendor/valory/skills/registration_abci/dialogues.py deleted file mode 100644 index fcc14acb6..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/dialogues.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the classes required for dialogue management.""" -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_backup/vendor/valory/skills/registration_abci/fsm_specification.yaml b/trader_backup/vendor/valory/skills/registration_abci/fsm_specification.yaml deleted file mode 100644 index 478f352c3..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/fsm_specification.yaml +++ /dev/null @@ -1,18 +0,0 @@ -alphabet_in: -- DONE -- NO_MAJORITY -default_start_state: RegistrationStartupRound -final_states: -- FinishedRegistrationRound -label: AgentRegistrationAbciApp -start_states: -- RegistrationRound -- RegistrationStartupRound -states: -- FinishedRegistrationRound -- RegistrationRound -- RegistrationStartupRound -transition_func: - (RegistrationRound, DONE): FinishedRegistrationRound - (RegistrationRound, NO_MAJORITY): RegistrationRound - (RegistrationStartupRound, DONE): FinishedRegistrationRound diff --git a/trader_backup/vendor/valory/skills/registration_abci/handlers.py b/trader_backup/vendor/valory/skills/registration_abci/handlers.py deleted file mode 100644 index 36053488f..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/handlers.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the handler for the 'registration_abci' skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIHandler = BaseABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_backup/vendor/valory/skills/registration_abci/models.py b/trader_backup/vendor/valory/skills/registration_abci/models.py deleted file mode 100644 index 98c7e53e1..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/models.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the shared state for the registration abci skill.""" - -from packages.valory.skills.abstract_round_abci.models import BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.registration_abci.rounds import AgentRegistrationAbciApp - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = AgentRegistrationAbciApp - - -Params = BaseParams -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool diff --git a/trader_backup/vendor/valory/skills/registration_abci/payloads.py b/trader_backup/vendor/valory/skills/registration_abci/payloads.py deleted file mode 100644 index bea2fc50a..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/payloads.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the transaction payloads for common apps.""" - -from dataclasses import dataclass - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class RegistrationPayload(BaseTxPayload): - """Represent a transaction payload of type 'registration'.""" - - initialisation: str diff --git a/trader_backup/vendor/valory/skills/registration_abci/rounds.py b/trader_backup/vendor/valory/skills/registration_abci/rounds.py deleted file mode 100644 index a191ddd02..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/rounds.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the data classes for common apps ABCI application.""" - -from enum import Enum -from typing import Dict, Optional, Set, Tuple - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AppState, - BaseSynchronizedData, - CollectSameUntilAllRound, - CollectSameUntilThresholdRound, - DegenerateRound, - SlashingNotConfiguredError, - get_name, -) -from packages.valory.skills.abstract_round_abci.models import BaseParams -from packages.valory.skills.registration_abci.payloads import RegistrationPayload - - -class Event(Enum): - """Event enumeration for the price estimation demo.""" - - DONE = "done" - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - - -class FinishedRegistrationRound(DegenerateRound): - """A round representing that agent registration has finished""" - - -class RegistrationStartupRound(CollectSameUntilAllRound): - """ - A round in which the agents get registered. - - This round waits until all agents have registered. - """ - - payload_class = RegistrationPayload - synchronized_data_class = BaseSynchronizedData - - @property - def params(self) -> BaseParams: - """Return the params.""" - return self.context.params - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - if not self.collection_threshold_reached: - return None - - try: - _ = self.context.state.round_sequence.offence_status - # only use slashing if it is configured and the `use_slashing` is set to True - if self.params.use_slashing: - self.context.state.round_sequence.enable_slashing() - except SlashingNotConfiguredError: - self.context.logger.warning("Slashing has not been enabled!") - - self.context.state.round_sequence.sync_db_and_slashing(self.common_payload) - - synchronized_data = self.synchronized_data.update( - participants=tuple(sorted(self.collection)), - synchronized_data_class=self.synchronized_data_class, - ) - - return synchronized_data, Event.DONE - - -class RegistrationRound(CollectSameUntilThresholdRound): - """ - A round in which the agents get registered. - - This rounds waits until the threshold of agents has been reached - and then a further x block confirmations. - """ - - payload_class = RegistrationPayload - required_block_confirmations = 10 - done_event = Event.DONE - synchronized_data_class = BaseSynchronizedData - - # this allows rejoining agents to send payloads - _allow_rejoin_payloads = True - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - if self.threshold_reached: - self.block_confirmations += 1 - if ( - self.threshold_reached - and self.block_confirmations - > self.required_block_confirmations # we also wait here as it gives more (available) agents time to join - ): - self.synchronized_data.db.sync(self.most_voted_payload) - synchronized_data = self.synchronized_data.update( - participants=tuple(sorted(self.collection)), - synchronized_data_class=self.synchronized_data_class, - ) - return synchronized_data, Event.DONE - if ( - not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ) - and self.block_confirmations > self.required_block_confirmations - ): - return self.synchronized_data, Event.NO_MAJORITY - return None - - -class AgentRegistrationAbciApp(AbciApp[Event]): - """AgentRegistrationAbciApp - - Initial round: RegistrationStartupRound - - Initial states: {RegistrationRound, RegistrationStartupRound} - - Transition states: - 0. RegistrationStartupRound - - done: 2. - 1. RegistrationRound - - done: 2. - - no majority: 1. - 2. FinishedRegistrationRound - - Final states: {FinishedRegistrationRound} - - Timeouts: - round timeout: 30.0 - """ - - initial_round_cls: AppState = RegistrationStartupRound - initial_states: Set[AppState] = {RegistrationStartupRound, RegistrationRound} - transition_function: AbciAppTransitionFunction = { - RegistrationStartupRound: { - Event.DONE: FinishedRegistrationRound, - }, - RegistrationRound: { - Event.DONE: FinishedRegistrationRound, - Event.NO_MAJORITY: RegistrationRound, - }, - FinishedRegistrationRound: {}, - } - final_states: Set[AppState] = { - FinishedRegistrationRound, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = { - RegistrationStartupRound: set(), - RegistrationRound: set(), - } - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedRegistrationRound: { - get_name(BaseSynchronizedData.participants), - }, - } diff --git a/trader_backup/vendor/valory/skills/registration_abci/skill.yaml b/trader_backup/vendor/valory/skills/registration_abci/skill.yaml deleted file mode 100644 index 9a6fe5674..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/skill.yaml +++ /dev/null @@ -1,151 +0,0 @@ -name: registration_abci -author: valory -version: 0.1.0 -type: skill -description: ABCI application for common apps. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeieztbubb6yn5umyt5ulknvb2xxppz5ecxaosxqsaejnrcrrwfu2ji - __init__.py: bafybeigqj2uodavhrygpqn6iah3ljp53z54c5fxyh5ykgkxuhh5lof6pda - behaviours.py: bafybeihal7ku3mvwfbcdm3twzuktnet2io3inshsrpnoee5d5o6mbavg5q - dialogues.py: bafybeicm4bqedlyytfo4icqqbyolo36j2hk7pqh32d3zc5yqg75bt4demm - fsm_specification.yaml: bafybeicx5eutgr4lin7mhwr73xhanuzwdmps7pfoy5f2k7gfxmuec4qbyu - handlers.py: bafybeifby6yecei2d7jvxbqrc3tpyemb7xdb4ood2kny5dqja26qnxrf24 - models.py: bafybeifkfjsfkjy2x32cbuoewxujfgpcl3wk3fji6kq27ofr2zcfe7l5oe - payloads.py: bafybeiacrixfazch2a5ydj7jfk2pnvlxwkygqlwzkfmdeldrj4fqgwyyzm - rounds.py: bafybeifch5qouoop77ef6ghsdflzuy7bcgn4upxjuusxalqzbk53vrxj4q - tests/__init__.py: bafybeiab2s4vkmbz5bc4wggcclapdbp65bosv4en5zaazk5dwmldojpqja - tests/test_behaviours.py: bafybeicwlo3y44sf7gzkyzfuzhwqkax4hln3oforbcvy4uitlgleft3cge - tests/test_dialogues.py: bafybeibeqnpzuzgcfb6yz76htslwsbbpenihswbp7j3qdyq42yswjq25l4 - tests/test_handlers.py: bafybeifpnwaktxckbvclklo6flkm5zqs7apmb33ffs4jrmunoykjbl5lni - tests/test_models.py: bafybeiewxl7nio5av2aukql2u7hlhodzdvjjneleba32abr42xeirrycb4 - tests/test_payloads.py: bafybeifik6ek75ughyd4y6t2lchlmjadkzbrz4hsb332k6ul4pwhlo2oga - tests/test_rounds.py: bafybeidk4d3w5csj6ka7mcq3ikjmv2yccbpwxhp27ujvd7huag3zl5vu2m -fingerprint_ignore_patterns: [] -connections: -- valory/p2p_libp2p_client:0.1.0:bafybeid3xg5k2ol5adflqloy75ibgljmol6xsvzvezebsg7oudxeeolz7e -contracts: -- valory/service_registry:0.1.0:bafybeiaop64kwdoetxtedoehabmsalojmms7ihuoqcdwxtwb2hk5i6bzye -protocols: -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -- valory/tendermint:0.1.0:bafybeig4mi3vmlv5zpbjbfuzcgida6j5f2nhrpedxicmrrfjweqc5r7cra -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -behaviours: - main: - args: {} - class_name: AgentRegistrationRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - light_slash_unit_amount: 5000000000000000 - max_attempts: 10 - max_healthcheck: 120 - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 30.0 - serious_slash_unit_amount: 8000000000000000 - service_id: registration - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - sleep_time: 1 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - tx_timeout: 10.0 - use_slashing: false - use_termination: false - class_name: Params - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: {} -is_abstract: true -customs: [] diff --git a/trader_backup/vendor/valory/skills/registration_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/registration_abci/tests/__init__.py deleted file mode 100644 index e4fb2e5eb..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/registration_abci skill.""" diff --git a/trader_backup/vendor/valory/skills/registration_abci/tests/test_behaviours.py b/trader_backup/vendor/valory/skills/registration_abci/tests/test_behaviours.py deleted file mode 100644 index 1c19c139e..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/tests/test_behaviours.py +++ /dev/null @@ -1,644 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/registration_abci skill's behaviours.""" - -# pylint: skip-file - -import collections -import datetime -import json -import logging -import time -from contextlib import ExitStack, contextmanager -from copy import deepcopy -from pathlib import Path -from typing import Any, Callable, Dict, Generator, Iterable, List, Optional, cast -from unittest import mock -from unittest.mock import MagicMock -from urllib.parse import urlparse - -import pytest -from _pytest.logging import LogCaptureFixture - -from packages.valory.contracts.service_registry.contract import ServiceRegistryContract -from packages.valory.protocols.contract_api.message import ContractApiMessage -from packages.valory.protocols.tendermint.message import TendermintMessage -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - BaseBehaviour, - TimeoutException, - make_degenerate_behaviour, -) -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.registration_abci import PUBLIC_ID -from packages.valory.skills.registration_abci.behaviours import ( - RegistrationBaseBehaviour, - RegistrationBehaviour, - RegistrationStartupBehaviour, -) -from packages.valory.skills.registration_abci.models import SharedState -from packages.valory.skills.registration_abci.rounds import ( - BaseSynchronizedData as RegistrationSynchronizedData, -) -from packages.valory.skills.registration_abci.rounds import ( - Event, - FinishedRegistrationRound, -) - - -PACKAGE_DIR = Path(__file__).parent.parent - - -SERVICE_REGISTRY_ADDRESS = "0xa51c1fc2f0d1a1b8494ed1fe312d7c3a78ed91c0" -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" -CONTRACT_ID = str(ServiceRegistryContract.contract_id) -ON_CHAIN_SERVICE_ID = 42 -DUMMY_ADDRESS = "localhost" -DUMMY_VALIDATOR_CONFIG = { - "hostname": DUMMY_ADDRESS, - "address": "address", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "7y7ycBMMABj5Onf74ITYtUS3uZ6SsCQKZML87mIX", - }, - "peer_id": "peer_id", - "p2p_port": 80, -} - - -def test_skill_public_id() -> None: - """Test skill module public ID""" - - assert PUBLIC_ID.name == Path(__file__).parents[1].name - assert PUBLIC_ID.author == Path(__file__).parents[3].name - - -def consume(iterator: Iterable) -> None: - """Consume the iterator""" - collections.deque(iterator, maxlen=0) - - -@contextmanager -def as_context(*contexts: Any) -> Generator[None, None, None]: - """Set contexts""" - with ExitStack() as stack: - consume(map(stack.enter_context, contexts)) - yield - - -class RegistrationAbciBaseCase(FSMBehaviourBaseCase): - """Base case for testing RegistrationAbci FSMBehaviour.""" - - path_to_skill = PACKAGE_DIR - - -class BaseRegistrationTestBehaviour(RegistrationAbciBaseCase): - """Base test case to test RegistrationBehaviour.""" - - behaviour_class = RegistrationBaseBehaviour - next_behaviour_class = BaseBehaviour - - @pytest.mark.parametrize( - "setup_data, expected_initialisation", - ( - ({}, '{"db_data": {"0": {}}, "slashing_config": ""}'), - ({"test": []}, '{"db_data": {"0": {}}, "slashing_config": ""}'), - ( - {"test": [], "valid": [1, 2]}, - '{"db_data": {"0": {"valid": [1, 2]}}, "slashing_config": ""}', - ), - ), - ) - def test_registration( - self, setup_data: Dict, expected_initialisation: Optional[str] - ) -> None: - """Test registration.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.behaviour_class.auto_behaviour_id(), - RegistrationSynchronizedData(AbciAppDB(setup_data=setup_data)), - ) - assert isinstance(self.behaviour.current_behaviour, BaseBehaviour) - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - with mock.patch.object( - self.behaviour.current_behaviour, - "send_a2a_transaction", - side_effect=self.behaviour.current_behaviour.send_a2a_transaction, - ): - self.behaviour.act_wrapper() - assert isinstance( - self.behaviour.current_behaviour.send_a2a_transaction, MagicMock - ) - assert ( - self.behaviour.current_behaviour.send_a2a_transaction.call_args[0][ - 0 - ].initialisation - == expected_initialisation - ) - self.mock_a2a_transaction() - - self._test_done_flag_set() - self.end_round(Event.DONE) - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.next_behaviour_class.auto_behaviour_id() - ) - - -class TestRegistrationStartupBehaviour(RegistrationAbciBaseCase): - """Test case to test RegistrationStartupBehaviour.""" - - behaviour_class = RegistrationStartupBehaviour - next_behaviour_class = make_degenerate_behaviour(FinishedRegistrationRound) - - other_agents: List[str] = ["0xAlice", "0xBob", "0xCharlie"] - _time_in_future = datetime.datetime.now() + datetime.timedelta(hours=10) - _time_in_past = datetime.datetime.now() - datetime.timedelta(hours=10) - - def setup(self, **kwargs: Any) -> None: - """Setup""" - super().setup(**kwargs) - self.state.params.__dict__["sleep_time"] = 0.01 - self.state.params.__dict__["share_tm_config_on_startup"] = True - - def teardown(self, **kwargs: Any) -> None: - """Teardown.""" - super().teardown(**kwargs) - self.state.initial_tm_configs = {} - - @property - def agent_instances(self) -> List[str]: - """Agent instance addresses""" - return [*self.other_agents, self.state.context.agent_address] - - @property - def state(self) -> RegistrationStartupBehaviour: - """Current behavioural state""" - return cast(RegistrationStartupBehaviour, self.behaviour.current_behaviour) - - @property - def logger(self) -> str: - """Logger""" - return "aea.test_agent_name.packages.valory.skills.registration_abci" - - # mock patches - @property - def mocked_service_registry_address(self) -> mock._patch_dict: - """Mocked service registry address""" - return mock.patch.dict( - self.state.params.__dict__, - {"service_registry_address": SERVICE_REGISTRY_ADDRESS}, - ) - - @property - def mocked_on_chain_service_id(self) -> mock._patch_dict: - """Mocked on chain service id""" - return mock.patch.dict( - self.state.params.__dict__, {"on_chain_service_id": ON_CHAIN_SERVICE_ID} - ) - - def mocked_wait_for_condition(self, should_timeout: bool) -> mock._patch: - """Mock BaseBehaviour.wait_for_condition""" - - def dummy_wait_for_condition( - condition: Callable[[], bool], timeout: Optional[float] = None - ) -> Generator[None, None, None]: - """A mock implementation of BaseBehaviour.wait_for_condition""" - # call the condition - condition() - if should_timeout: - # raise in case required - raise TimeoutException() - return - yield - - return mock.patch.object( - self.behaviour.current_behaviour, - "wait_for_condition", - side_effect=dummy_wait_for_condition, - ) - - @property - def mocked_yield_from_sleep(self) -> mock._patch: - """Mock yield from sleep""" - return mock.patch.object(self.behaviour.current_behaviour, "sleep") - - # mock contract calls - def mock_is_correct_contract(self, error_response: bool = False) -> None: - """Mock service registry contract call to for contract verification""" - request_kwargs = dict(performative=ContractApiMessage.Performative.GET_STATE) - state = ContractApiMessage.State(ledger_id="ethereum", body={"verified": True}) - performative = ContractApiMessage.Performative.STATE - if error_response: - performative = ContractApiMessage.Performative.ERROR - response_kwargs = dict( - performative=performative, - callable="verify_contract", - state=state, - ) - self.mock_contract_api_request( - contract_id=CONTRACT_ID, - request_kwargs=request_kwargs, - response_kwargs=response_kwargs, - ) - - def mock_get_agent_instances( - self, *agent_instances: str, error_response: bool = False - ) -> None: - """Mock get agent instances""" - request_kwargs = dict(performative=ContractApiMessage.Performative.GET_STATE) - performative = ContractApiMessage.Performative.STATE - if error_response: - performative = ContractApiMessage.Performative.ERROR - body = {"agentInstances": list(agent_instances)} - state = ContractApiMessage.State(ledger_id="ethereum", body=body) - response_kwargs = dict( - performative=performative, - callable="get_agent_instances", - state=state, - ) - self.mock_contract_api_request( - contract_id=CONTRACT_ID, - request_kwargs=request_kwargs, - response_kwargs=response_kwargs, - ) - - # mock Tendermint config request - def mock_tendermint_request( - self, request_kwargs: Dict, response_kwargs: Dict - ) -> None: - """Mock Tendermint request.""" - - actual_tendermint_message = self.get_message_from_outbox() - assert actual_tendermint_message is not None, "No message in outbox." - has_attributes, error_str = self.message_has_attributes( - actual_message=actual_tendermint_message, - message_type=TendermintMessage, - performative=TendermintMessage.Performative.GET_GENESIS_INFO, - sender=self.state.context.agent_address, - to=actual_tendermint_message.to, - **request_kwargs, - ) - assert has_attributes, error_str - incoming_message = self.build_incoming_message( - message_type=TendermintMessage, - dialogue_reference=( - actual_tendermint_message.dialogue_reference[0], - "stub", - ), - performative=TendermintMessage.Performative.GENESIS_INFO, - target=actual_tendermint_message.message_id, - message_id=-1, - to=self.state.context.agent_address, - sender=actual_tendermint_message.to, - **response_kwargs, - ) - self.tendermint_handler.handle(cast(TendermintMessage, incoming_message)) - - def mock_get_tendermint_info(self, *addresses: str) -> None: - """Mock get Tendermint info""" - for i in addresses: - request_kwargs: Dict = dict() - config = deepcopy(DUMMY_VALIDATOR_CONFIG) - config["address"] = str(config["address"]) + i - info = json.dumps(config) - response_kwargs = dict(info=info) - self.mock_tendermint_request(request_kwargs, response_kwargs) - # give room to the behaviour to finish sleeping - # using the same sleep time here and in the behaviour - # can lead to problems when the sleep here is finished - # before the one in the behaviour - time.sleep(self.state.params.sleep_time * 2) - self.behaviour.act_wrapper() - - # mock HTTP requests - def mock_get_local_tendermint_params(self, valid_response: bool = True) -> None: - """Mock Tendermint get local params""" - url = self.state.tendermint_parameter_url - request_kwargs = dict(method="GET", url=url) - body = b"" - if valid_response: - params = dict(params=DUMMY_VALIDATOR_CONFIG, status=True, error=None) - body = json.dumps(params).encode(self.state.ENCODING) - response_kwargs = dict(status_code=200, body=body) - self.mock_http_request(request_kwargs, response_kwargs) - - def mock_tendermint_update(self, valid_response: bool = True) -> None: - """Mock Tendermint update""" - - validator_configs = self.state.format_genesis_data( - self.state.initial_tm_configs - ) - body = json.dumps(validator_configs).encode(self.state.ENCODING) - url = self.state.tendermint_parameter_url - request_kwargs = dict(method="POST", url=url, body=body) - body = ( - json.dumps({"status": True, "error": None}).encode(self.state.ENCODING) - if valid_response - else b"" - ) - response_kwargs = dict(status_code=200, body=body) - self.mock_http_request(request_kwargs, response_kwargs) - - def set_last_timestamp(self, last_timestamp: Optional[datetime.datetime]) -> None: - """Set last timestamp""" - if last_timestamp is not None: - state = cast(SharedState, self._skill.skill_context.state) - state.round_sequence.blockchain._blocks.append( - MagicMock(timestamp=last_timestamp) - ) - - @staticmethod - def dummy_reset_tendermint_with_wait_wrapper( - valid_response: bool, - ) -> Callable[[], Generator[None, None, Optional[bool]]]: - """Wrapper for a Dummy `reset_tendermint_with_wait` method.""" - - def dummy_reset_tendermint_with_wait( - **_: bool, - ) -> Generator[None, None, Optional[bool]]: - """Dummy `reset_tendermint_with_wait` method.""" - yield - return valid_response - - return dummy_reset_tendermint_with_wait - - # tests - def test_init(self) -> None: - """Empty init""" - assert self.state.initial_tm_configs == {} - assert self.state.local_tendermint_params == {} - assert self.state.updated_genesis_data == {} - - def test_no_contract_address(self, caplog: LogCaptureFixture) -> None: - """Test service registry contract address not provided""" - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_yield_from_sleep, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - log_message = self.state.LogMessages.no_contract_address - assert log_message.value in caplog.text - - @pytest.mark.parametrize("valid_response", [True, False]) - def test_request_personal( - self, valid_response: bool, caplog: LogCaptureFixture - ) -> None: - """Test get tendermint configuration""" - - failed_message = self.state.LogMessages.failed_personal - response_message = self.state.LogMessages.response_personal - log_message = [failed_message, response_message][valid_response] - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_yield_from_sleep, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params(valid_response=valid_response) - assert log_message.value in caplog.text - - def test_failed_verification(self, caplog: LogCaptureFixture) -> None: - """Test service registry contract not correctly deployed""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract(error_response=True) - log_message = self.state.LogMessages.failed_verification - assert log_message.value in caplog.text - - def test_on_chain_service_id_not_set(self, caplog: LogCaptureFixture) -> None: - """Test `get_addresses` when `on_chain_service_id` is `None`.""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - log_message = self.state.LogMessages.no_on_chain_service_id - assert log_message.value in caplog.text - - def test_failed_service_info(self, caplog: LogCaptureFixture) -> None: - """Test get service info failure""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances(error_response=True) - log_message = self.state.LogMessages.failed_service_info - assert log_message.value in caplog.text - - def test_no_agents_registered(self, caplog: LogCaptureFixture) -> None: - """Test no agent instances registered""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances() - log_message = self.state.LogMessages.no_agents_registered - assert log_message.value in caplog.text - - def test_self_not_registered(self, caplog: LogCaptureFixture) -> None: - """Test node operator agent not registered""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances(*self.other_agents) - log_message = self.state.LogMessages.self_not_registered - assert log_message.value in caplog.text - - def test_response_service_info(self, caplog: LogCaptureFixture) -> None: - """Test registered addresses retrieved""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances(*self.agent_instances) - - assert set(self.state.initial_tm_configs) == set(self.agent_instances) - my_info = self.state.initial_tm_configs[self.state.context.agent_address] - assert ( - my_info["hostname"] - == urlparse(self.state.context.params.tendermint_url).hostname - ) - assert not any(map(self.state.initial_tm_configs.get, self.other_agents)) - log_message = self.state.LogMessages.response_service_info - assert log_message.value in caplog.text - - def test_collection_complete(self, caplog: LogCaptureFixture) -> None: - """Test registered addresses retrieved""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - mock.patch.object( - self._skill.skill_context.state, - "acn_container", - side_effect=lambda: self.agent_instances, - ), - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances(*self.agent_instances) - self.mock_get_tendermint_info(*self.other_agents) - - initial_tm_configs = self.state.initial_tm_configs - validator_to_agent = ( - self.state.context.state.round_sequence.validator_to_agent - ) - - assert all(map(initial_tm_configs.get, self.other_agents)) - assert tuple(validator_to_agent.keys()) == tuple( - config["address"] for config in initial_tm_configs.values() - ) - assert tuple(validator_to_agent.values()) == tuple( - initial_tm_configs.keys() - ) - log_message = self.state.LogMessages.collection_complete - assert log_message.value in caplog.text - - @pytest.mark.parametrize("valid_response", [True, False]) - @mock.patch.object(BaseBehaviour, "reset_tendermint_with_wait") - def test_request_update( - self, _: mock.Mock, valid_response: bool, caplog: LogCaptureFixture - ) -> None: - """Test Tendermint config update""" - - self.state.updated_genesis_data = {} - failed_message = self.state.LogMessages.failed_update - response_message = self.state.LogMessages.response_update - log_message = [failed_message, response_message][valid_response] - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - self.mocked_yield_from_sleep, - mock.patch.object( - self._skill.skill_context.state, - "acn_container", - side_effect=lambda: self.agent_instances, - ), - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances(*self.agent_instances) - self.mock_get_tendermint_info(*self.other_agents) - self.mock_tendermint_update(valid_response) - assert log_message.value in caplog.text - - @pytest.mark.parametrize( - "valid_response, last_timestamp, timeout", - [ - (True, _time_in_past, False), - (False, _time_in_past, False), - (True, _time_in_future, False), - (False, _time_in_future, False), - (True, None, False), - (False, None, False), - (True, None, True), - (False, None, True), - ], - ) - def test_request_restart( - self, - valid_response: bool, - last_timestamp: Optional[datetime.datetime], - timeout: bool, - caplog: LogCaptureFixture, - ) -> None: - """Test Tendermint start""" - self.state.updated_genesis_data = {} - self.set_last_timestamp(last_timestamp) - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - self.mocked_wait_for_condition(timeout), - self.mocked_yield_from_sleep, - mock.patch.object( - self.behaviour.current_behaviour, - "reset_tendermint_with_wait", - side_effect=self.dummy_reset_tendermint_with_wait_wrapper( - valid_response - ), - ), - mock.patch.object( - self._skill.skill_context.state, - "acn_container", - side_effect=lambda: self.agent_instances, - ), - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances(*self.agent_instances) - self.mock_get_tendermint_info(*self.other_agents) - self.mock_tendermint_update() - self.behaviour.act_wrapper() - - -class TestRegistrationStartupBehaviourNoConfigShare(BaseRegistrationTestBehaviour): - """Test case to test RegistrationBehaviour.""" - - behaviour_class = RegistrationStartupBehaviour - next_behaviour_class = make_degenerate_behaviour(FinishedRegistrationRound) - - -class TestRegistrationBehaviour(BaseRegistrationTestBehaviour): - """Test case to test RegistrationBehaviour.""" - - behaviour_class = RegistrationBehaviour - next_behaviour_class = make_degenerate_behaviour(FinishedRegistrationRound) diff --git a/trader_backup/vendor/valory/skills/registration_abci/tests/test_dialogues.py b/trader_backup/vendor/valory/skills/registration_abci/tests/test_dialogues.py deleted file mode 100644 index 55d61a50b..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.registration_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_backup/vendor/valory/skills/registration_abci/tests/test_handlers.py b/trader_backup/vendor/valory/skills/registration_abci/tests/test_handlers.py deleted file mode 100644 index aae35f091..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/tests/test_handlers.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.registration_abci.handlers # noqa - - -def test_import() -> None: - """Test that the 'handlers.py' Python module can be imported.""" diff --git a/trader_backup/vendor/valory/skills/registration_abci/tests/test_models.py b/trader_backup/vendor/valory/skills/registration_abci/tests/test_models.py deleted file mode 100644 index eb6d4d72f..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/tests/test_models.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the models.py module of the skill.""" - -# pylint: skip-file - -from packages.valory.skills.abstract_round_abci.test_tools.base import DummyContext -from packages.valory.skills.registration_abci.models import SharedState - - -class TestSharedState: - """Test SharedState(Model) class.""" - - def test_initialization( - self, - ) -> None: - """Test initialization.""" - SharedState(name="", skill_context=DummyContext()) diff --git a/trader_backup/vendor/valory/skills/registration_abci/tests/test_payloads.py b/trader_backup/vendor/valory/skills/registration_abci/tests/test_payloads.py deleted file mode 100644 index b9b0a4093..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/tests/test_payloads.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the payloads.py module of the skill.""" - -# pylint: skip-file - -import pytest - -from packages.valory.skills.abstract_round_abci.base import Transaction -from packages.valory.skills.registration_abci.payloads import RegistrationPayload - - -def test_registration_abci_payload() -> None: - """Test `RegistrationPayload`.""" - - payload = RegistrationPayload(sender="sender", initialisation="dummy") - - assert payload.initialisation == "dummy" - assert payload.data == {"initialisation": "dummy"} - assert RegistrationPayload.from_json(payload.json) == payload - - -def test_registration_abci_payload_raises() -> None: - """Test `RegistrationPayload`.""" - payload = RegistrationPayload(sender="sender", initialisation="0" * 10**7) - signature = "signature" - tx = Transaction(payload, signature) - with pytest.raises(ValueError, match="Transaction must be smaller"): - tx.encode() diff --git a/trader_backup/vendor/valory/skills/registration_abci/tests/test_rounds.py b/trader_backup/vendor/valory/skills/registration_abci/tests/test_rounds.py deleted file mode 100644 index d4428005a..000000000 --- a/trader_backup/vendor/valory/skills/registration_abci/tests/test_rounds.py +++ /dev/null @@ -1,371 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the rounds.py module of the skill.""" - -import json -from typing import Any, Dict, Optional, cast -from unittest import mock -from unittest.mock import MagicMock, PropertyMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData as SynchronizedData, -) -from packages.valory.skills.abstract_round_abci.base import ( - CollectSameUntilAllRound, - SlashingNotConfiguredError, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilAllRoundTest, - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.registration_abci.payloads import RegistrationPayload -from packages.valory.skills.registration_abci.rounds import Event as RegistrationEvent -from packages.valory.skills.registration_abci.rounds import ( - RegistrationRound, - RegistrationStartupRound, -) - - -# pylint: skip-file - - -class TestRegistrationStartupRound(BaseCollectSameUntilAllRoundTest): - """Test RegistrationStartupRound.""" - - _synchronized_data_class = SynchronizedData - _event_class = RegistrationEvent - - @pytest.mark.parametrize("slashing_config", ("", json.dumps({"valid": "config"}))) - def test_run_default( - self, - slashing_config: str, - ) -> None: - """Run test.""" - - self.synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - safe_contract_address="stub_safe_contract_address", - oracle_contract_address="stub_oracle_contract_address", - ), - ) - - test_round = RegistrationStartupRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self.synchronized_data.slashing_config = slashing_config - - if not slashing_config: - seq = test_round.context.state.round_sequence - type(seq).offence_status = PropertyMock( - side_effect=SlashingNotConfiguredError - ) - - most_voted_payload = self.synchronized_data.db.serialize() - round_payloads = { - participant: RegistrationPayload( - sender=participant, - initialisation=most_voted_payload, - ) - for participant in self.participants - } - - self._run_with_round( - test_round, - round_payloads, - most_voted_payload, - RegistrationEvent.DONE, - ) - - assert all( - ( - self.synchronized_data.all_participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.safe_contract_address - == "stub_safe_contract_address", - self.synchronized_data.db.get("oracle_contract_address") - == "stub_oracle_contract_address", - ) - ) - - test_round.context.state.round_sequence.sync_db_and_slashing.assert_called_once_with( - most_voted_payload - ) - - if slashing_config: - test_round.context.state.round_sequence.enable_slashing.assert_called_once() - else: - test_round.context.state.round_sequence.enable_slashing.assert_not_called() - - def test_run_default_not_finished( - self, - ) -> None: - """Run test.""" - - self.synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - safe_contract_address="stub_safe_contract_address", - oracle_contract_address="stub_oracle_contract_address", - ), - ) - test_round = RegistrationStartupRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - with mock.patch.object( - CollectSameUntilAllRound, - "collection_threshold_reached", - new_callable=mock.PropertyMock, - ) as threshold_mock: - threshold_mock.return_value = False - self._run_with_round( - test_round, - finished=False, - most_voted_payload="none", - ) - - assert all( - ( - self.synchronized_data.all_participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.safe_contract_address - == "stub_safe_contract_address", - self.synchronized_data.db.get("oracle_contract_address") - == "stub_oracle_contract_address", - ) - ) - - def _run_with_round( - self, - test_round: RegistrationStartupRound, - round_payloads: Optional[Dict[str, RegistrationPayload]] = None, - most_voted_payload: Optional[Any] = None, - expected_event: Optional[RegistrationEvent] = None, - finished: bool = True, - ) -> None: - """Run with given round.""" - - round_payloads = round_payloads or { - p: RegistrationPayload(sender=p, initialisation="none") - for p in self.participants - } - - test_runner = self._test_round( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=( - lambda *x: SynchronizedData( - AbciAppDB( - setup_data=dict(participants=[tuple(self.participants)]), - ) - ) - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.participants - ], - most_voted_payload=most_voted_payload, - exit_event=expected_event, - finished=finished, - ) - - next(test_runner) - next(test_runner) - next(test_runner) - if finished: - next(test_runner) - - -class TestRegistrationRound(BaseCollectSameUntilThresholdRoundTest): - """Test RegistrationRound.""" - - _synchronized_data_class = SynchronizedData - _event_class = RegistrationEvent - - def test_run_default( - self, - ) -> None: - """Run test.""" - self.synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - safe_contract_address="stub_safe_contract_address", - oracle_contract_address="stub_oracle_contract_address", - ), - ) - test_round = RegistrationRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - payload_data = self.synchronized_data.db.serialize() - - round_payloads = { - participant: RegistrationPayload( - sender=participant, - initialisation=payload_data, - ) - for participant in self.participants - } - - self._run_with_round( - test_round=test_round, - expected_event=RegistrationEvent.DONE, - confirmations=11, - most_voted_payload=payload_data, - round_payloads=round_payloads, - ) - - assert all( - ( - self.synchronized_data.all_participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.safe_contract_address - == "stub_safe_contract_address", - self.synchronized_data.db.get("oracle_contract_address") - == "stub_oracle_contract_address", - ) - ) - - def test_run_default_not_finished( - self, - ) -> None: - """Run test.""" - self.synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - safe_contract_address="stub_safe_contract_address", - oracle_contract_address="stub_oracle_contract_address", - ), - ) - test_round = RegistrationRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - self._run_with_round( - test_round, - confirmations=None, - ) - - assert all( - ( - self.synchronized_data.all_participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.safe_contract_address - == "stub_safe_contract_address", - self.synchronized_data.db.get("oracle_contract_address") - == "stub_oracle_contract_address", - ) - ) - - def _run_with_round( - self, - test_round: RegistrationRound, - round_payloads: Optional[Dict[str, RegistrationPayload]] = None, - most_voted_payload: Optional[Any] = None, - expected_event: Optional[RegistrationEvent] = None, - confirmations: Optional[int] = None, - finished: bool = True, - ) -> None: - """Run with given round.""" - - round_payloads = round_payloads or { - p: RegistrationPayload(sender=p, initialisation="none") - for p in self.participants - } - - test_runner = self._test_round( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=( - lambda *x: SynchronizedData( - AbciAppDB( - setup_data=dict(participants=[tuple(self.participants)]), - ) - ) - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.participants - ], - most_voted_payload=most_voted_payload, - exit_event=expected_event, - ) - - next(test_runner) - if confirmations is None: - assert ( - test_round.block_confirmations - <= test_round.required_block_confirmations - ) - - else: - test_round.block_confirmations = confirmations - test_round = next(test_runner) - prior_confirmations = test_round.block_confirmations - next(test_runner) - assert test_round.block_confirmations == prior_confirmations + 1 - if finished: - next(test_runner) - - def test_no_majority(self) -> None: - """Test the NO_MAJORITY event.""" - self.synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - safe_contract_address="stub_safe_contract_address", - oracle_contract_address="stub_oracle_contract_address", - ), - ) - - test_round = RegistrationRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - with mock.patch.object(test_round, "is_majority_possible", return_value=False): - with mock.patch.object(test_round, "block_confirmations", 11): - self._test_no_majority_event(test_round) - - assert all( - ( - self.synchronized_data.all_participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.safe_contract_address - == "stub_safe_contract_address", - self.synchronized_data.db.get("oracle_contract_address") - == "stub_oracle_contract_address", - ) - ) diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/README.md b/trader_backup/vendor/valory/skills/reset_pause_abci/README.md deleted file mode 100644 index 99ca7988c..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Reset and pause abci - -## Description - -This module contains the ABCI reset and pause skill for an AEA. It implements an ABCI -application. - -## Behaviours - -* `ResetAndPauseBehaviour` - - Reset state. - -* `ResetPauseABCIConsensusBehaviour` - - This behaviour manages the consensus stages for the reset and pause abci app. - -## Handlers - -* `ResetPauseABCIHandler` -* `HttpHandler` -* `SigningHandler` - diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/__init__.py b/trader_backup/vendor/valory/skills/reset_pause_abci/__init__.py deleted file mode 100644 index 850ef3947..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the Reset & Pause skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/reset_pause_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/behaviours.py b/trader_backup/vendor/valory/skills/reset_pause_abci/behaviours.py deleted file mode 100644 index 9ee30a1e9..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/behaviours.py +++ /dev/null @@ -1,99 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the behaviours for the 'reset_pause_abci' skill.""" - -from abc import ABC -from typing import Generator, Set, Type, cast - -from packages.valory.skills.abstract_round_abci.base import BaseSynchronizedData -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.reset_pause_abci.models import Params, SharedState -from packages.valory.skills.reset_pause_abci.payloads import ResetPausePayload -from packages.valory.skills.reset_pause_abci.rounds import ( - ResetAndPauseRound, - ResetPauseAbciApp, -) - - -class ResetAndPauseBaseBehaviour(BaseBehaviour, ABC): - """Reset behaviour.""" - - @property - def synchronized_data(self) -> BaseSynchronizedData: - """Return the synchronized data.""" - return cast( - BaseSynchronizedData, - cast(SharedState, self.context.state).synchronized_data, - ) - - @property - def params(self) -> Params: - """Return the params.""" - return cast(Params, self.context.params) - - -class ResetAndPauseBehaviour(ResetAndPauseBaseBehaviour): - """Reset and pause behaviour.""" - - matching_round = ResetAndPauseRound - - def async_act(self) -> Generator: - """ - Do the action. - - Steps: - - Trivially log the behaviour. - - Sleep for configured interval. - - Build a registration transaction. - - Send the transaction and wait for it to be mined. - - Wait until ABCI application transitions to the next round. - - Go to the next behaviour (set done event). - """ - # + 1 because `period_count` starts from 0 - n_periods_done = self.synchronized_data.period_count + 1 - reset_tm_nodes = n_periods_done % self.params.reset_tendermint_after == 0 - if reset_tm_nodes: - tendermint_reset = yield from self.reset_tendermint_with_wait() - if not tendermint_reset: - return - else: - yield from self.wait_from_last_timestamp(self.params.reset_pause_duration) - self.context.logger.info("Period end.") - self.context.benchmark_tool.save(self.synchronized_data.period_count) - - payload = ResetPausePayload( - self.context.agent_address, self.synchronized_data.period_count - ) - yield from self.send_a2a_transaction(payload, reset_tm_nodes) - yield from self.wait_until_round_end() - self.set_done() - - -class ResetPauseABCIConsensusBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the reset_pause_abci app.""" - - initial_behaviour_cls = ResetAndPauseBehaviour - abci_app_cls = ResetPauseAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - ResetAndPauseBehaviour, # type: ignore - } diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/dialogues.py b/trader_backup/vendor/valory/skills/reset_pause_abci/dialogues.py deleted file mode 100644 index e244bde0b..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/dialogues.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/fsm_specification.yaml b/trader_backup/vendor/valory/skills/reset_pause_abci/fsm_specification.yaml deleted file mode 100644 index b4882ef0a..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/fsm_specification.yaml +++ /dev/null @@ -1,19 +0,0 @@ -alphabet_in: -- DONE -- NO_MAJORITY -- RESET_AND_PAUSE_TIMEOUT -default_start_state: ResetAndPauseRound -final_states: -- FinishedResetAndPauseErrorRound -- FinishedResetAndPauseRound -label: ResetPauseAbciApp -start_states: -- ResetAndPauseRound -states: -- FinishedResetAndPauseErrorRound -- FinishedResetAndPauseRound -- ResetAndPauseRound -transition_func: - (ResetAndPauseRound, DONE): FinishedResetAndPauseRound - (ResetAndPauseRound, NO_MAJORITY): FinishedResetAndPauseErrorRound - (ResetAndPauseRound, RESET_AND_PAUSE_TIMEOUT): FinishedResetAndPauseErrorRound diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/handlers.py b/trader_backup/vendor/valory/skills/reset_pause_abci/handlers.py deleted file mode 100644 index d6c6335de..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/handlers.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the handler for the 'reset_pause_abci' skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIHandler = BaseABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/models.py b/trader_backup/vendor/valory/skills/reset_pause_abci/models.py deleted file mode 100644 index 89d44fc9a..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/models.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the shared state for the 'reset_pause_abci' application.""" - -from packages.valory.skills.abstract_round_abci.models import BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.reset_pause_abci.rounds import Event, ResetPauseAbciApp - - -MARGIN = 5 - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = ResetPauseAbciApp - - def setup(self) -> None: - """Set up.""" - super().setup() - ResetPauseAbciApp.event_to_timeout[ - Event.ROUND_TIMEOUT - ] = self.context.params.round_timeout_seconds - ResetPauseAbciApp.event_to_timeout[Event.RESET_AND_PAUSE_TIMEOUT] = ( - self.context.params.reset_pause_duration + MARGIN - ) - - -Params = BaseParams diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/payloads.py b/trader_backup/vendor/valory/skills/reset_pause_abci/payloads.py deleted file mode 100644 index d5c005863..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/payloads.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the transaction payloads for the reset_pause_abci app.""" - -from dataclasses import dataclass - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class ResetPausePayload(BaseTxPayload): - """Represent a transaction payload of type 'reset'.""" - - period_count: int diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/rounds.py b/trader_backup/vendor/valory/skills/reset_pause_abci/rounds.py deleted file mode 100644 index 1fd666acb..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/rounds.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the data classes for the reset_pause_abci application.""" - -from enum import Enum -from typing import Dict, Optional, Set, Tuple - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AppState, - BaseSynchronizedData, - CollectSameUntilThresholdRound, - DegenerateRound, -) -from packages.valory.skills.reset_pause_abci.payloads import ResetPausePayload - - -class Event(Enum): - """Event enumeration for the reset_pause_abci app.""" - - DONE = "done" - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - RESET_AND_PAUSE_TIMEOUT = "reset_and_pause_timeout" - - -class ResetAndPauseRound(CollectSameUntilThresholdRound): - """A round that represents that consensus is reached (the final round)""" - - payload_class = ResetPausePayload - _allow_rejoin_payloads = True - synchronized_data_class = BaseSynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - if self.threshold_reached: - return self.synchronized_data.create(), Event.DONE - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, Event.NO_MAJORITY - return None - - -class FinishedResetAndPauseRound(DegenerateRound): - """A round that represents reset and pause has finished""" - - -class FinishedResetAndPauseErrorRound(DegenerateRound): - """A round that represents reset and pause has finished with errors""" - - -class ResetPauseAbciApp(AbciApp[Event]): - """ResetPauseAbciApp - - Initial round: ResetAndPauseRound - - Initial states: {ResetAndPauseRound} - - Transition states: - 0. ResetAndPauseRound - - done: 1. - - reset and pause timeout: 2. - - no majority: 2. - 1. FinishedResetAndPauseRound - 2. FinishedResetAndPauseErrorRound - - Final states: {FinishedResetAndPauseErrorRound, FinishedResetAndPauseRound} - - Timeouts: - round timeout: 30.0 - reset and pause timeout: 30.0 - """ - - initial_round_cls: AppState = ResetAndPauseRound - transition_function: AbciAppTransitionFunction = { - ResetAndPauseRound: { - Event.DONE: FinishedResetAndPauseRound, - Event.RESET_AND_PAUSE_TIMEOUT: FinishedResetAndPauseErrorRound, - Event.NO_MAJORITY: FinishedResetAndPauseErrorRound, - }, - FinishedResetAndPauseRound: {}, - FinishedResetAndPauseErrorRound: {}, - } - final_states: Set[AppState] = { - FinishedResetAndPauseRound, - FinishedResetAndPauseErrorRound, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - Event.RESET_AND_PAUSE_TIMEOUT: 30.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = {ResetAndPauseRound: set()} - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedResetAndPauseRound: set(), - FinishedResetAndPauseErrorRound: set(), - } diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/skill.yaml b/trader_backup/vendor/valory/skills/reset_pause_abci/skill.yaml deleted file mode 100644 index ddc4e4b4e..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/skill.yaml +++ /dev/null @@ -1,141 +0,0 @@ -name: reset_pause_abci -author: valory -version: 0.1.0 -type: skill -description: ABCI application for resetting and pausing app executions. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeigyx3zutnbq2sqlgeo2hi2vjgpmnlspnkyh4wemjfrqkrpel27bwi - __init__.py: bafybeicx55fcmu5t2lrrs4wqi6bdvsmoq2csfqebyzwy6oh4olmhnvmelu - behaviours.py: bafybeich7tmipn2zsuqsmhtbrmmqys3mpvn3jctx6g3kz2atet2atl3j6q - dialogues.py: bafybeigabhaykiyzbluu4mk6bbrmqhzld2kyp32pg24bvjmzrrb74einwm - fsm_specification.yaml: bafybeietrxvm2odv3si3ecep3by6rftsirzzazxpmeh73yvtsis2mfaali - handlers.py: bafybeie22h45jr2opf2waszr3qt5km2fppcaahalcavhzutgb6pyyywqxq - models.py: bafybeiagj2e73wvzfqti6chbgkxh5tawzdjwqnxlo2bcfa5lyzy6ogzh2u - payloads.py: bafybeihychpsosovpyq7bh6aih2cyjkxr23j7becd5apetrqivvnolzm7i - rounds.py: bafybeifi2gpj2piilxtqcvv6lxhwpnbl7xs3a3trh3wvlv2wihowoon4tm - tests/__init__.py: bafybeiclijinxvycj7agcagt2deuuyh7zxyp7k2s55la6lh3jghzqvfux4 - tests/test_behaviours.py: bafybeigblrmkjci6at74yetaevgw5zszhivpednbok7fby4tqn7zt2vemy - tests/test_dialogues.py: bafybeif7pe7v34cfznzv4htyuevx733ersmk4bqjcgajn2535jmuujdmzm - tests/test_handlers.py: bafybeiggog2k65ijtvqwkvjvmaoo6khwgfkeodddzl6u76gcvvongwjawy - tests/test_payloads.py: bafybeifj343tlaiasebfgahfxehn4oi74omgah3ju2pze2fefoouid2zdq - tests/test_rounds.py: bafybeifz67lfay4pkz5ipblpfpadl4zmd5riajkv6sdsiby22z24gp3cxa -fingerprint_ignore_patterns: [] -connections: [] -contracts: [] -protocols: [] -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -behaviours: - main: - args: {} - class_name: ResetPauseABCIConsensusBehaviour -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - light_slash_unit_amount: 5000000000000000 - max_attempts: 10 - max_healthcheck: 120 - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 30.0 - serious_slash_unit_amount: 8000000000000000 - service_id: reset_pause_abci - service_registry_address: null - setup: {} - share_tm_config_on_startup: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - sleep_time: 1 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - tx_timeout: 10.0 - use_slashing: false - use_termination: false - class_name: Params - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: {} -is_abstract: true -customs: [] diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/reset_pause_abci/tests/__init__.py deleted file mode 100644 index db0918fb6..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/reset_pause_abci skill.""" diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_behaviours.py b/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_behaviours.py deleted file mode 100644 index 54356764c..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_behaviours.py +++ /dev/null @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/reset_pause_abci skill's behaviours.""" - -# pylint: skip-file - -from pathlib import Path -from typing import Callable, Generator, Optional -from unittest import mock -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData as ResetSynchronizedSata, -) -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - make_degenerate_behaviour, -) -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.reset_pause_abci import PUBLIC_ID -from packages.valory.skills.reset_pause_abci.behaviours import ResetAndPauseBehaviour -from packages.valory.skills.reset_pause_abci.rounds import Event as ResetEvent -from packages.valory.skills.reset_pause_abci.rounds import FinishedResetAndPauseRound - - -PACKAGE_DIR = Path(__file__).parent.parent - - -def test_skill_public_id() -> None: - """Test skill module public ID""" - - assert PUBLIC_ID.name == Path(__file__).parents[1].name - assert PUBLIC_ID.author == Path(__file__).parents[3].name - - -class ResetPauseAbciFSMBehaviourBaseCase(FSMBehaviourBaseCase): - """Base case for testing PauseReset FSMBehaviour.""" - - path_to_skill = PACKAGE_DIR - - -def dummy_reset_tendermint_with_wait_wrapper( - reset_successfully: Optional[bool], -) -> Callable[[], Generator[None, None, Optional[bool]]]: - """Wrapper for a Dummy `reset_tendermint_with_wait` method.""" - - def dummy_reset_tendermint_with_wait() -> Generator[None, None, Optional[bool]]: - """Dummy `reset_tendermint_with_wait` method.""" - yield - return reset_successfully - - return dummy_reset_tendermint_with_wait - - -class TestResetAndPauseBehaviour(ResetPauseAbciFSMBehaviourBaseCase): - """Test ResetBehaviour.""" - - behaviour_class = ResetAndPauseBehaviour - next_behaviour_class = make_degenerate_behaviour(FinishedResetAndPauseRound) - - @pytest.mark.parametrize("tendermint_reset_status", (None, True, False)) - def test_reset_behaviour( - self, - tendermint_reset_status: Optional[bool], - ) -> None: - """Test reset behaviour.""" - dummy_participants = [[i for i in range(4)]] - - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.behaviour_class.auto_behaviour_id(), - synchronized_data=ResetSynchronizedSata( - AbciAppDB( - setup_data=dict( - all_participants=dummy_participants, - participants=dummy_participants, - safe_contract_address=[""], - consensus_threshold=[3], - most_voted_estimate=[0.1], - tx_hashes_history=[["68656c6c6f776f726c64"]], - ), - ) - ), - ) - - assert self.behaviour.current_behaviour is not None - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - - with mock.patch.object( - self.behaviour.current_behaviour, - "send_a2a_transaction", - side_effect=self.behaviour.current_behaviour.send_a2a_transaction, - ), mock.patch.object( - self.behaviour.current_behaviour, - "reset_tendermint_with_wait", - side_effect=dummy_reset_tendermint_with_wait_wrapper( - tendermint_reset_status - ), - ) as mock_reset_tendermint_with_wait, mock.patch.object( - self.behaviour.current_behaviour, - "wait_from_last_timestamp", - side_effect=lambda _: (yield), - ): - if tendermint_reset_status is not None: - # Increase the period_count to force the call to reset_tendermint_with_wait() - self.behaviour.current_behaviour.synchronized_data.create() - - self.behaviour.act_wrapper() - self.behaviour.act_wrapper() - - # now if the first reset attempt has been simulated to fail, let's simulate the second attempt to succeed. - if tendermint_reset_status is not None and not tendermint_reset_status: - mock_reset_tendermint_with_wait.side_effect = ( - dummy_reset_tendermint_with_wait_wrapper(True) - ) - self.behaviour.act_wrapper() - # make sure that the behaviour does not send any txs to other agents when Tendermint reset fails - assert isinstance( - self.behaviour.current_behaviour.send_a2a_transaction, MagicMock - ) - self.behaviour.current_behaviour.send_a2a_transaction.assert_not_called() - self.behaviour.act_wrapper() - - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(ResetEvent.DONE) - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.next_behaviour_class.auto_behaviour_id() - ) diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_dialogues.py b/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_dialogues.py deleted file mode 100644 index d9b2904ca..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.reset_pause_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_handlers.py b/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_handlers.py deleted file mode 100644 index 347f9e9fc..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_handlers.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.reset_pause_abci.handlers # noqa - - -def test_import() -> None: - """Test that the 'handlers.py' Python module can be imported.""" diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_payloads.py b/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_payloads.py deleted file mode 100644 index 15b67fae4..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_payloads.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the payloads.py module of the skill.""" - -# pylint: skip-file - -from packages.valory.skills.reset_pause_abci.payloads import ResetPausePayload - - -def test_reset_pause_payload() -> None: - """Test `ResetPausePayload`.""" - - payload = ResetPausePayload(sender="sender", period_count=1) - - assert payload.period_count == 1 - assert payload.data == {"period_count": 1} - assert ResetPausePayload.from_json(payload.json) == payload diff --git a/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_rounds.py b/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_rounds.py deleted file mode 100644 index adadb778b..000000000 --- a/trader_backup/vendor/valory/skills/reset_pause_abci/tests/test_rounds.py +++ /dev/null @@ -1,106 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the rounds of the skill.""" - -# pylint: skip-file - -import hashlib -import logging # noqa: F401 -from typing import Dict, FrozenSet -from unittest.mock import MagicMock - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData as ResetSynchronizedSata, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.reset_pause_abci.payloads import ResetPausePayload -from packages.valory.skills.reset_pause_abci.rounds import Event as ResetEvent -from packages.valory.skills.reset_pause_abci.rounds import ResetAndPauseRound - - -MAX_PARTICIPANTS: int = 4 -DUMMY_RANDOMNESS = hashlib.sha256("hash".encode() + str(0).encode()).hexdigest() - - -def get_participant_to_period_count( - participants: FrozenSet[str], period_count: int -) -> Dict[str, ResetPausePayload]: - """participant_to_selection""" - return { - participant: ResetPausePayload(sender=participant, period_count=period_count) - for participant in participants - } - - -class TestResetAndPauseRound(BaseCollectSameUntilThresholdRoundTest): - """Test ResetRound.""" - - _synchronized_data_class = ResetSynchronizedSata - _event_class = ResetEvent - - def test_runs( - self, - ) -> None: - """Runs tests.""" - - synchronized_data = self.synchronized_data.update( - most_voted_randomness=DUMMY_RANDOMNESS, consensus_threshold=3 - ) - synchronized_data._db._cross_period_persisted_keys = frozenset( - {"most_voted_randomness"} - ) - test_round = ResetAndPauseRound( - synchronized_data=synchronized_data, - context=MagicMock(), - ) - next_period_count = 1 - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_period_count( - self.participants, next_period_count - ), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.create(), - synchronized_data_attr_checks=[], # [lambda _synchronized_data: _synchronized_data.participants], - most_voted_payload=next_period_count, - exit_event=self._event_class.DONE, - ) - ) - - def test_accepting_payloads_from(self) -> None: - """Test accepting payloads from""" - - alice, *others = self.participants - participants = list(others) - all_participants = participants + [alice] - - synchronized_data = self.synchronized_data.update( - participants=participants, all_participants=all_participants - ) - - test_round = ResetAndPauseRound( - synchronized_data=synchronized_data, - context=MagicMock(), - ) - - assert test_round.accepting_payloads_from != participants - assert test_round.accepting_payloads_from == frozenset(all_participants) diff --git a/trader_backup/vendor/valory/skills/staking_abci/README.md b/trader_backup/vendor/valory/skills/staking_abci/README.md deleted file mode 100644 index bc35afb23..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Staking abci - -## Description - -This module contains the Staking skill for an AEA. diff --git a/trader_backup/vendor/valory/skills/staking_abci/__init__.py b/trader_backup/vendor/valory/skills/staking_abci/__init__.py deleted file mode 100644 index 84bfa5c61..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- 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 the staking skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/staking_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/staking_abci/behaviours.py b/trader_backup/vendor/valory/skills/staking_abci/behaviours.py deleted file mode 100644 index 74df6e501..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/behaviours.py +++ /dev/null @@ -1,551 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviours for the staking skill.""" - -from abc import ABC -from datetime import datetime, timedelta -from pathlib import Path -from typing import Any, Callable, Generator, Optional, Set, Tuple, Type, Union, cast - -from aea.configurations.data_types import PublicId -from aea.contracts.base import Contract - -from packages.valory.contracts.gnosis_safe.contract import GnosisSafeContract -from packages.valory.contracts.mech_activity.contract import MechActivityContract -from packages.valory.contracts.service_staking_token.contract import ( - ServiceStakingTokenContract, -) -from packages.valory.contracts.staking_token.contract import StakingTokenContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - BaseBehaviour, - TimeoutException, -) -from packages.valory.skills.abstract_round_abci.behaviours import AbstractRoundBehaviour -from packages.valory.skills.staking_abci.models import StakingParams -from packages.valory.skills.staking_abci.payloads import CallCheckpointPayload -from packages.valory.skills.staking_abci.rounds import ( - CallCheckpointRound, - StakingAbciApp, - StakingState, - SynchronizedData, -) -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - hash_payload_to_hex, -) -from packages.valory.skills.transaction_settlement_abci.rounds import TX_HASH_LENGTH - - -WaitableConditionType = Generator[None, None, bool] - - -ETH_PRICE = 0 -# setting the safe gas to 0 means that all available gas will be used -# which is what we want in most cases -# more info here: https://safe-docs.dev.gnosisdev.com/safe/docs/contracts_tx_execution/ -SAFE_GAS = 0 - - -NULL_ADDRESS = "0x0000000000000000000000000000000000000000" -CHECKPOINT_FILENAME = "checkpoint.txt" -READ_MODE = "r" -WRITE_MODE = "w" - - -class StakingInteractBaseBehaviour(BaseBehaviour, ABC): - """Base behaviour that contains methods to interact with the staking contract.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize the behaviour.""" - super().__init__(**kwargs) - self._service_staking_state: StakingState = StakingState.UNSTAKED - self._checkpoint_ts = 0 - - @property - def params(self) -> StakingParams: - """Return the params.""" - return cast(StakingParams, self.context.params) - - @property - def use_v2(self) -> bool: - """Whether to use the v2 staking contract.""" - return self.params.mech_activity_checker_contract != NULL_ADDRESS - - @property - def synced_timestamp(self) -> int: - """Return the synchronized timestamp across the agents.""" - return int(self.round_sequence.last_round_transition_timestamp.timestamp()) - - @property - def staking_contract_address(self) -> str: - """Get the staking contract address.""" - return self.params.staking_contract_address - - @property - def mech_activity_checker_contract(self) -> str: - """Get the staking contract address.""" - return self.params.mech_activity_checker_contract - - @property - def service_staking_state(self) -> StakingState: - """Get the service's staking state.""" - return self._service_staking_state - - @service_staking_state.setter - def service_staking_state(self, state: Union[StakingState, int]) -> None: - """Set the service's staking state.""" - if isinstance(state, int): - state = StakingState(state) - self._service_staking_state = state - - @property - def next_checkpoint(self) -> int: - """Get the next checkpoint.""" - return self._next_checkpoint - - @next_checkpoint.setter - def next_checkpoint(self, next_checkpoint: int) -> None: - """Set the next checkpoint.""" - self._next_checkpoint = next_checkpoint - - @property - def is_checkpoint_reached(self) -> bool: - """Whether the next checkpoint is reached.""" - return self.next_checkpoint <= self.synced_timestamp - - @property - def ts_checkpoint(self) -> int: - """Get the last checkpoint timestamp.""" - return self._checkpoint_ts - - @ts_checkpoint.setter - def ts_checkpoint(self, checkpoint_ts: int) -> None: - """Set the last checkpoint timestamp.""" - self._checkpoint_ts = checkpoint_ts - - @property - def liveness_period(self) -> int: - """Get the liveness period.""" - return self._liveness_period - - @liveness_period.setter - def liveness_period(self, liveness_period: int) -> None: - """Set the liveness period.""" - self._liveness_period = liveness_period - - @property - def liveness_ratio(self) -> int: - """Get the liveness ratio.""" - return self._liveness_ratio - - @liveness_ratio.setter - def liveness_ratio(self, liveness_ratio: int) -> None: - """Set the liveness period.""" - self._liveness_ratio = liveness_ratio - - @property - def service_info(self) -> Tuple[Any, Any, Tuple[Any, Any]]: - """Get the service info.""" - return self._service_info - - @service_info.setter - def service_info(self, service_info: Tuple[Any, Any, Tuple[Any, Any]]) -> None: - """Set the service info.""" - self._service_info = service_info - - def wait_for_condition_with_sleep( - self, - condition_gen: Callable[[], WaitableConditionType], - timeout: Optional[float] = None, - ) -> Generator[None, None, None]: - """Wait for a condition to happen and sleep in-between checks. - - This is a modified version of the base `wait_for_condition` method which: - 1. accepts a generator that creates the condition instead of a callable - 2. sleeps in-between checks - - :param condition_gen: a generator of the condition to wait for - :param timeout: the maximum amount of time to wait - :yield: None - """ - - deadline = ( - datetime.now() + timedelta(0, timeout) - if timeout is not None - else datetime.max - ) - - while True: - condition_satisfied = yield from condition_gen() - if condition_satisfied: - break - if timeout is not None and datetime.now() > deadline: - raise TimeoutException() - msg = f"Retrying in {self.params.staking_interaction_sleep_time} seconds." - self.context.logger.info(msg) - yield from self.sleep(self.params.staking_interaction_sleep_time) - - def default_error( - self, contract_id: str, contract_callable: str, response_msg: ContractApiMessage - ) -> None: - """Return a default contract interaction error message.""" - self.context.logger.error( - f"Could not successfully interact with the {contract_id} contract " - f"using {contract_callable!r}: {response_msg}" - ) - - def contract_interact( - self, - contract_address: str, - contract_public_id: PublicId, - contract_callable: str, - data_key: str, - placeholder: str, - **kwargs: Any, - ) -> WaitableConditionType: - """Interact with a contract.""" - contract_id = str(contract_public_id) - response_msg = yield from self.get_contract_api_response( - ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address, - contract_id, - contract_callable, - **kwargs, - ) - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.default_error(contract_id, contract_callable, response_msg) - return False - - data = response_msg.raw_transaction.body.get(data_key, None) - if data is None: - self.default_error(contract_id, contract_callable, response_msg) - return False - - setattr(self, placeholder, data) - return True - - def _staking_contract_interact( - self, - contract_callable: str, - placeholder: str, - data_key: str = "data", - **kwargs: Any, - ) -> WaitableConditionType: - """Interact with the staking contract.""" - contract_public_id = cast( - Contract, - StakingTokenContract if self.use_v2 else ServiceStakingTokenContract, - ) - status = yield from self.contract_interact( - contract_address=self.staking_contract_address, - contract_public_id=contract_public_id.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def _mech_activity_checker_contract_interact( - self, - contract_callable: str, - placeholder: str, - data_key: str = "data", - **kwargs: Any, - ) -> WaitableConditionType: - """Interact with the staking contract.""" - status = yield from self.contract_interact( - contract_address=self.mech_activity_checker_contract, - contract_public_id=MechActivityContract.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def _check_service_staked(self) -> WaitableConditionType: - """Check whether the service is staked.""" - service_id = self.params.on_chain_service_id - if service_id is None: - self.context.logger.warning( - "Cannot perform any staking-related operations without a configured on-chain service id. " - "Assuming service status 'UNSTAKED'." - ) - return True - - status = yield from self._staking_contract_interact( - contract_callable="get_service_staking_state", - placeholder=get_name(CallCheckpointBehaviour.service_staking_state), - service_id=service_id, - ) - - return status - - def _get_next_checkpoint(self) -> WaitableConditionType: - """Get the timestamp in which the next checkpoint is reached.""" - status = yield from self._staking_contract_interact( - contract_callable="get_next_checkpoint_ts", - placeholder=get_name(CallCheckpointBehaviour.next_checkpoint), - ) - return status - - def _get_ts_checkpoint(self) -> WaitableConditionType: - """Get the timestamp in which the next checkpoint is reached.""" - status = yield from self._staking_contract_interact( - contract_callable="ts_checkpoint", - placeholder=get_name(CallCheckpointBehaviour.ts_checkpoint), - ) - return status - - def _get_liveness_period(self) -> WaitableConditionType: - """Get the liveness period.""" - status = yield from self._staking_contract_interact( - contract_callable="get_liveness_period", - placeholder=get_name(CallCheckpointBehaviour.liveness_period), - ) - return status - - def _get_liveness_ratio(self) -> WaitableConditionType: - """Get the liveness ratio.""" - contract_interact = ( - self._mech_activity_checker_contract_interact - if self.use_v2 - else self._staking_contract_interact - ) - status = yield from contract_interact( - contract_callable="liveness_ratio", - placeholder=get_name(CallCheckpointBehaviour.liveness_ratio), - ) - return status - - def _get_service_info(self) -> WaitableConditionType: - """Get the service info.""" - service_id = self.params.on_chain_service_id - if service_id is None: - self.context.logger.warning( - "Cannot perform any staking-related operations without a configured on-chain service id. " - "Assuming service status 'UNSTAKED'." - ) - return True - - status = yield from self._staking_contract_interact( - contract_callable="get_service_info", - placeholder=get_name(CallCheckpointBehaviour.service_info), - service_id=service_id, - ) - return status - - -class CallCheckpointBehaviour( - StakingInteractBaseBehaviour -): # pylint-disable too-many-ancestors - """Behaviour that calls the checkpoint contract function if the service is staked and if it is necessary.""" - - matching_round = CallCheckpointRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize the behaviour.""" - super().__init__(**kwargs) - self._service_staking_state: StakingState = StakingState.UNSTAKED - self._next_checkpoint: int = 0 - self._checkpoint_data: bytes = b"" - self._safe_tx_hash: str = "" - self._checkpoint_filepath: Path = self.params.store_path / CHECKPOINT_FILENAME - - @property - def params(self) -> StakingParams: - """Return the params.""" - return cast(StakingParams, self.context.params) - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return SynchronizedData(super().synchronized_data.db) - - @property - def is_first_period(self) -> bool: - """Return whether it is the first period of the service.""" - return self.synchronized_data.period_count == 0 - - @property - def new_checkpoint_detected(self) -> bool: - """Whether a new checkpoint has been detected.""" - previous_checkpoint = self.synchronized_data.previous_checkpoint - return bool(previous_checkpoint) and previous_checkpoint != self.ts_checkpoint - - @property - def checkpoint_data(self) -> bytes: - """Get the checkpoint data.""" - return self._checkpoint_data - - @checkpoint_data.setter - def checkpoint_data(self, data: bytes) -> None: - """Set the request data.""" - self._checkpoint_data = data - - @property - def safe_tx_hash(self) -> str: - """Get the safe_tx_hash.""" - return self._safe_tx_hash - - @safe_tx_hash.setter - def safe_tx_hash(self, safe_hash: str) -> None: - """Set the safe_tx_hash.""" - length = len(safe_hash) - if length != TX_HASH_LENGTH: - raise ValueError( - f"Incorrect length {length} != {TX_HASH_LENGTH} detected " - f"when trying to assign a safe transaction hash: {safe_hash}" - ) - self._safe_tx_hash = safe_hash[2:] - - def read_stored_timestamp(self) -> Optional[int]: - """Read the timestamp from the agent's data dir.""" - try: - with open(self._checkpoint_filepath, READ_MODE) as checkpoint_file: - try: - return int(checkpoint_file.readline()) - except (ValueError, TypeError, StopIteration): - err = f"Stored checkpoint timestamp could not be parsed from {self._checkpoint_filepath!r}!" - except (FileNotFoundError, PermissionError, OSError): - err = f"Error opening file {self._checkpoint_filepath!r} in {READ_MODE!r} mode!" - - self.context.logger.error(err) - return None - - def store_timestamp(self) -> int: - """Store the timestamp to the agent's data dir.""" - if self.ts_checkpoint == 0: - self.context.logger.warning("No checkpoint timestamp to store!") - return 0 - - try: - with open(self._checkpoint_filepath, WRITE_MODE) as checkpoint_file: - try: - return checkpoint_file.write(str(self.ts_checkpoint)) - except (IOError, OSError): - err = f"Error writing to file {self._checkpoint_filepath!r}!" - except (FileNotFoundError, PermissionError, OSError): - err = f"Error opening file {self._checkpoint_filepath!r} in {WRITE_MODE!r} mode!" - - self.context.logger.error(err) - return 0 - - def _build_checkpoint_tx(self) -> WaitableConditionType: - """Get the request tx data encoded.""" - result = yield from self._staking_contract_interact( - contract_callable="build_checkpoint_tx", - placeholder=get_name(CallCheckpointBehaviour.checkpoint_data), - ) - - return result - - def _get_safe_tx_hash(self) -> WaitableConditionType: - """Prepares and returns the safe tx hash.""" - status = yield from self.contract_interact( - contract_address=self.synchronized_data.safe_contract_address, - contract_public_id=GnosisSafeContract.contract_id, - contract_callable="get_raw_safe_transaction_hash", - data_key="tx_hash", - placeholder=get_name(CallCheckpointBehaviour.safe_tx_hash), - to_address=self.params.staking_contract_address, - value=ETH_PRICE, - data=self.checkpoint_data, - ) - return status - - def _prepare_safe_tx(self) -> Generator[None, None, str]: - """Prepare the safe transaction for calling the checkpoint and return the hex for the tx settlement skill.""" - yield from self.wait_for_condition_with_sleep(self._build_checkpoint_tx) - yield from self.wait_for_condition_with_sleep(self._get_safe_tx_hash) - return hash_payload_to_hex( - self.safe_tx_hash, - ETH_PRICE, - SAFE_GAS, - self.params.staking_contract_address, - self.checkpoint_data, - ) - - def check_new_epoch(self) -> Generator[None, None, bool]: - """Check if a new epoch has been reached.""" - yield from self.wait_for_condition_with_sleep(self._get_ts_checkpoint) - stored_timestamp_invalidated = False - - # if it is the first period of the service, - # 1. check if the stored timestamp is the same as the current checkpoint - # 2. if not, update the corresponding flag - # That way, we protect from the case in which the user stops their service - # before the next checkpoint is reached and restarts it afterward. - if self.is_first_period: - stored_timestamp = self.read_stored_timestamp() - stored_timestamp_invalidated = stored_timestamp != self.ts_checkpoint - - is_checkpoint_reached = ( - stored_timestamp_invalidated or self.new_checkpoint_detected - ) - if is_checkpoint_reached: - self.context.logger.info("An epoch change has been detected.") - status = self.store_timestamp() - if status: - self.context.logger.info( - "Successfully updated the stored checkpoint timestamp." - ) - - return is_checkpoint_reached - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - yield from self.wait_for_condition_with_sleep(self._check_service_staked) - - checkpoint_tx_hex = None - if self.service_staking_state == StakingState.STAKED: - yield from self.wait_for_condition_with_sleep(self._get_next_checkpoint) - if self.is_checkpoint_reached: - checkpoint_tx_hex = yield from self._prepare_safe_tx() - - if self.service_staking_state == StakingState.EVICTED: - self.context.logger.critical("Service has been evicted!") - - tx_submitter = self.matching_round.auto_round_id() - is_checkpoint_reached = yield from self.check_new_epoch() - payload = CallCheckpointPayload( - self.context.agent_address, - tx_submitter, - checkpoint_tx_hex, - self.service_staking_state.value, - self.ts_checkpoint, - is_checkpoint_reached, - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - self.set_done() - - -class StakingRoundBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the staking behaviour.""" - - initial_behaviour_cls = CallCheckpointBehaviour - abci_app_cls = StakingAbciApp - behaviours: Set[Type[BaseBehaviour]] = {CallCheckpointBehaviour} # type: ignore diff --git a/trader_backup/vendor/valory/skills/staking_abci/dialogues.py b/trader_backup/vendor/valory/skills/staking_abci/dialogues.py deleted file mode 100644 index 153b6ce50..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/dialogues.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- 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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_backup/vendor/valory/skills/staking_abci/fsm_specification.yaml b/trader_backup/vendor/valory/skills/staking_abci/fsm_specification.yaml deleted file mode 100644 index f68a2c6a2..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/fsm_specification.yaml +++ /dev/null @@ -1,27 +0,0 @@ -alphabet_in: -- DONE -- NEXT_CHECKPOINT_NOT_REACHED_YET -- NO_MAJORITY -- ROUND_TIMEOUT -- SERVICE_EVICTED -- SERVICE_NOT_STAKED -default_start_state: CallCheckpointRound -final_states: -- CheckpointCallPreparedRound -- FinishedStakingRound -- ServiceEvictedRound -label: StakingAbciApp -start_states: -- CallCheckpointRound -states: -- CallCheckpointRound -- CheckpointCallPreparedRound -- FinishedStakingRound -- ServiceEvictedRound -transition_func: - (CallCheckpointRound, DONE): CheckpointCallPreparedRound - (CallCheckpointRound, NEXT_CHECKPOINT_NOT_REACHED_YET): FinishedStakingRound - (CallCheckpointRound, NO_MAJORITY): CallCheckpointRound - (CallCheckpointRound, ROUND_TIMEOUT): CallCheckpointRound - (CallCheckpointRound, SERVICE_EVICTED): ServiceEvictedRound - (CallCheckpointRound, SERVICE_NOT_STAKED): FinishedStakingRound diff --git a/trader_backup/vendor/valory/skills/staking_abci/handlers.py b/trader_backup/vendor/valory/skills/staking_abci/handlers.py deleted file mode 100644 index f085415b4..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/handlers.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- 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 the handlers for the 'staking_abci' skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIStakingHandler = ABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_backup/vendor/valory/skills/staking_abci/models.py b/trader_backup/vendor/valory/skills/staking_abci/models.py deleted file mode 100644 index b9ee386a2..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/models.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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. -# -# ------------------------------------------------------------------------------ - - -"""Models for the Staking ABCI application.""" - -import os -from pathlib import Path -from typing import Any - -from packages.valory.skills.abstract_round_abci.models import BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.staking_abci.rounds import StakingAbciApp - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -def get_store_path(kwargs: dict) -> Path: - """Get the path of the store.""" - path = kwargs.get("store_path", "") - if not path: - msg = "The path to the store must be provided as a keyword argument." - raise ValueError(msg) - - # check if the path exists, and we can write to it - if ( - not os.path.isdir(path) - or not os.access(path, os.W_OK) - or not os.access(path, os.R_OK) - ): - msg = f"The store path {path!r} is not a directory or is not writable." - raise ValueError(msg) - - return Path(path) - - -class StakingParams(BaseParams): - """Staking parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the parameters' object.""" - self.staking_contract_address: str = self._ensure( - "staking_contract_address", kwargs, str - ) - self.staking_interaction_sleep_time: int = self._ensure( - "staking_interaction_sleep_time", kwargs, int - ) - self.mech_activity_checker_contract: str = self._ensure( - "mech_activity_checker_contract", kwargs, str - ) - self.store_path = get_store_path(kwargs) - super().__init__(*args, **kwargs) - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = StakingAbciApp diff --git a/trader_backup/vendor/valory/skills/staking_abci/payloads.py b/trader_backup/vendor/valory/skills/staking_abci/payloads.py deleted file mode 100644 index 4b1f47e2c..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/payloads.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the transaction payloads for the staking abci.""" - -from dataclasses import dataclass -from typing import Optional - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class MultisigTxPayload(BaseTxPayload): - """Represents a transaction payload for preparing an on-chain transaction to be sent via the agents' multisig.""" - - tx_submitter: str - tx_hash: Optional[str] - - -@dataclass(frozen=True) -class CallCheckpointPayload(MultisigTxPayload): - """A transaction payload for the checkpoint call.""" - - service_staking_state: int - ts_checkpoint: int - is_checkpoint_reached: bool diff --git a/trader_backup/vendor/valory/skills/staking_abci/rounds.py b/trader_backup/vendor/valory/skills/staking_abci/rounds.py deleted file mode 100644 index c6de99b2a..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/rounds.py +++ /dev/null @@ -1,226 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the rounds for the Staking ABCI application.""" - -from abc import ABC -from enum import Enum -from typing import Dict, Optional, Set, Tuple, Type, cast - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AbstractRound, - AppState, - BaseSynchronizedData, - CollectSameUntilThresholdRound, - CollectionRound, - DegenerateRound, - DeserializedCollection, - get_name, -) -from packages.valory.skills.staking_abci.payloads import CallCheckpointPayload -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TxSettlementSyncedData, -) - - -class StakingState(Enum): - """Staking state enumeration for the staking.""" - - UNSTAKED = 0 - STAKED = 1 - EVICTED = 2 - - -class Event(Enum): - """Event enumeration for the staking skill.""" - - DONE = "done" - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - SERVICE_NOT_STAKED = "service_not_staked" - SERVICE_EVICTED = "service_evicted" - NEXT_CHECKPOINT_NOT_REACHED_YET = "next_checkpoint_not_reached_yet" - - -class SynchronizedData(TxSettlementSyncedData): - """Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - def _get_deserialized(self, key: str) -> DeserializedCollection: - """Strictly get a collection and return it deserialized.""" - serialized = self.db.get_strict(key) - return CollectionRound.deserialize_collection(serialized) - - @property - def tx_submitter(self) -> str: - """Get the round that submitted a tx to transaction_settlement_abci.""" - return str(self.db.get_strict("tx_submitter")) - - @property - def service_staking_state(self) -> StakingState: - """Get the service's staking state.""" - return StakingState(self.db.get("service_staking_state", 0)) - - @property - def participant_to_checkpoint(self) -> DeserializedCollection: - """Get the participants to the checkpoint round.""" - return self._get_deserialized("participant_to_checkpoint") - - @property - def previous_checkpoint(self) -> Optional[int]: - """Get the previous checkpoint.""" - previous_checkpoint = self.db.get("previous_checkpoint", None) - if previous_checkpoint is None: - return None - return int(previous_checkpoint) - - @property - def is_checkpoint_reached(self) -> bool: - """Check if the checkpoint is reached.""" - return bool(self.db.get("is_checkpoint_reached", False)) - - -class CallCheckpointRound(CollectSameUntilThresholdRound): - """A round for the checkpoint call preparation.""" - - payload_class = CallCheckpointPayload - done_event: Enum = Event.DONE - no_majority_event: Enum = Event.NO_MAJORITY - selection_key = ( - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.service_staking_state), - get_name(SynchronizedData.previous_checkpoint), - get_name(SynchronizedData.is_checkpoint_reached), - ) - collection_key = get_name(SynchronizedData.participant_to_checkpoint) - synchronized_data_class = SynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - - if event != Event.DONE: - return res - - if synced_data.service_staking_state == StakingState.UNSTAKED: - return synced_data, Event.SERVICE_NOT_STAKED - - if synced_data.service_staking_state == StakingState.EVICTED: - return synced_data, Event.SERVICE_EVICTED - - if synced_data.most_voted_tx_hash is None: - return synced_data, Event.NEXT_CHECKPOINT_NOT_REACHED_YET - - return res - - -class CheckpointCallPreparedRound(DegenerateRound, ABC): - """A round that represents staking has finished with a checkpoint call safe tx prepared.""" - - -class FinishedStakingRound(DegenerateRound, ABC): - """A round that represents staking has finished.""" - - -class ServiceEvictedRound(DegenerateRound, ABC): - """A round that terminates the service if it has been evicted.""" - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """End block.""" - - -class StakingAbciApp(AbciApp[Event]): # pylint: disable=too-few-public-methods - """StakingAbciApp - - Initial round: CallCheckpointRound - - Initial states: {CallCheckpointRound} - - Transition states: - 0. CallCheckpointRound - - done: 1. - - service not staked: 2. - - service evicted: 3. - - next checkpoint not reached yet: 2. - - round timeout: 0. - - no majority: 0. - 1. CheckpointCallPreparedRound - 2. FinishedStakingRound - 3. ServiceEvictedRound - - Final states: {CheckpointCallPreparedRound, FinishedStakingRound, ServiceEvictedRound} - - Timeouts: - round timeout: 30.0 - """ - - initial_round_cls: Type[AbstractRound] = CallCheckpointRound - transition_function: AbciAppTransitionFunction = { - CallCheckpointRound: { - Event.DONE: CheckpointCallPreparedRound, - Event.SERVICE_NOT_STAKED: FinishedStakingRound, - Event.SERVICE_EVICTED: ServiceEvictedRound, - Event.NEXT_CHECKPOINT_NOT_REACHED_YET: FinishedStakingRound, - Event.ROUND_TIMEOUT: CallCheckpointRound, - Event.NO_MAJORITY: CallCheckpointRound, - }, - CheckpointCallPreparedRound: {}, - FinishedStakingRound: {}, - ServiceEvictedRound: {}, - } - cross_period_persisted_keys = frozenset( - { - get_name(SynchronizedData.service_staking_state), - get_name(SynchronizedData.previous_checkpoint), - get_name(SynchronizedData.is_checkpoint_reached), - } - ) - final_states: Set[AppState] = { - CheckpointCallPreparedRound, - FinishedStakingRound, - ServiceEvictedRound, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = {CallCheckpointRound: set()} - db_post_conditions: Dict[AppState, Set[str]] = { - CheckpointCallPreparedRound: { - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.service_staking_state), - get_name(SynchronizedData.previous_checkpoint), - get_name(SynchronizedData.is_checkpoint_reached), - }, - FinishedStakingRound: { - get_name(SynchronizedData.service_staking_state), - }, - ServiceEvictedRound: { - get_name(SynchronizedData.service_staking_state), - }, - } diff --git a/trader_backup/vendor/valory/skills/staking_abci/skill.yaml b/trader_backup/vendor/valory/skills/staking_abci/skill.yaml deleted file mode 100644 index 9d866d5c2..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/skill.yaml +++ /dev/null @@ -1,152 +0,0 @@ -name: staking_abci -author: valory -version: 0.1.0 -type: skill -description: This skill implements the Staking for an AEA. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeifrpl36fddmgvniwvghqtxdzc44ry6l2zvqy37vu3y2xvwyd23ugy - __init__.py: bafybeiageyes36ujnvvodqd5vlnihgz44rupysrk2ebbhskjkueetj6dai - behaviours.py: bafybeiels3us2s5sf2lrloekjky46o2owlo3awsocuxt67h76ap2k5qaqy - dialogues.py: bafybeiebofyykseqp3fmif36cqmmyf3k7d2zbocpl6t6wnlpv4szghrxbm - fsm_specification.yaml: bafybeicuoejmaks3ndwhbflp64kkfdkrdyn74a2fplarg4l3gxlonfmeoq - handlers.py: bafybeichsi2y5zvzffupj2vhgagocwvnm7cbzr6jmavp656mfrzsdvkfnu - models.py: bafybeibhzoi25wqpgxwn7ibgz3juax2aeqep7qdl6q7u3abdnb6jahc264 - payloads.py: bafybeib7hxsibtabb5vt6gjtco2x2s2yodhs24ojqecgrcexqsiv3pvmuy - rounds.py: bafybeiezsn42e2qqdpwgtkvrlgjzfwtg7fldfqglf5ofc36g7uyaobvuhq - tests/__init__.py: bafybeid7m6ynosqeb4mvsss2hqg75aly5o2d47r7yfg2xtgwzkkilv2d2m - tests/test_dialogues.py: bafybeidwjk52mufwvkj4cr3xgqycbdzxc6gvosmqyuqdjarnrgwth6wcai - tests/test_handers.py: bafybeibnxlwznx3tsdpjpzh62bnp6lq7zdpolyjxfvxeumzz52ljxfzpme - tests/test_payloads.py: bafybeidtkbudsmrx77xs2oooji6cpj7kx7nembf77u32if2sb2kvkavvhq - tests/test_rounds.py: bafybeidge7sp3udobhvjpbdj5kirkukd6w5qycqkcuc6sy3qqiedco2q4i -fingerprint_ignore_patterns: [] -connections: [] -contracts: -- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge -- valory/service_staking_token:0.1.0:bafybeihhcs3ewwzhy7yto4y36uqmice3pdvyl54fvxxv6jsxonesie4dxu -- valory/staking_token:0.1.0:bafybeiep4r6qyilbfgzdvx6t7zvpgaioxqktmxm7puwtnbpb2ftlib43gy -- valory/mech_activity:0.1.0:bafybeibmqmle5fnal3gxlpdmcos2kogzra4q3pr3o5nh7shplxuilji3t4 -protocols: -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae -behaviours: - main: - args: {} - class_name: StakingRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIStakingHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 350.0 - service_id: staking - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - sleep_time: 5 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - termination_sleep: 900 - tx_timeout: 10.0 - use_termination: false - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - mech_activity_checker_contract: '0x0000000000000000000000000000000000000000' - staking_contract_address: '0x2Ef503950Be67a98746F484DA0bBAdA339DF3326' - staking_interaction_sleep_time: 5 - store_path: data - class_name: StakingParams - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState -dependencies: {} -is_abstract: true diff --git a/trader_backup/vendor/valory/skills/staking_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/staking_abci/tests/__init__.py deleted file mode 100644 index cce0712e9..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/staking skill.""" diff --git a/trader_backup/vendor/valory/skills/staking_abci/tests/test_dialogues.py b/trader_backup/vendor/valory/skills/staking_abci/tests/test_dialogues.py deleted file mode 100644 index b7073dec1..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.staking_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_backup/vendor/valory/skills/staking_abci/tests/test_handers.py b/trader_backup/vendor/valory/skills/staking_abci/tests/test_handers.py deleted file mode 100644 index ebab67ce4..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/tests/test_handers.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the tests for the handlers for the staking abci.""" - -from unittest.mock import MagicMock - -import pytest -from aea.configurations.data_types import PublicId -from aea.skills.base import Handler - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.staking_abci.handlers import ( - ABCIStakingHandler, - ContractApiHandler, - HttpHandler, - IpfsHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, -) - - -@pytest.mark.parametrize( - "handler, base_handler", - [ - (ABCIStakingHandler, ABCIRoundHandler), - (HttpHandler, BaseHttpHandler), - (SigningHandler, BaseSigningHandler), - (LedgerApiHandler, BaseLedgerApiHandler), - (ContractApiHandler, BaseContractApiHandler), - (TendermintHandler, BaseTendermintHandler), - (IpfsHandler, BaseIpfsHandler), - ], -) -def test_handler(handler: Handler, base_handler: Handler) -> None: - """Test that the 'handlers.py' of the StakingAbci can be imported.""" - handler = handler( - name="dummy_handler", - skill_context=MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")), - ) - - assert isinstance(handler, base_handler) diff --git a/trader_backup/vendor/valory/skills/staking_abci/tests/test_payloads.py b/trader_backup/vendor/valory/skills/staking_abci/tests/test_payloads.py deleted file mode 100644 index f9a7b316b..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/tests/test_payloads.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the transaction payloads for the staking abci.""" -from typing import Dict, Type - -import pytest - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.staking_abci.payloads import ( - CallCheckpointPayload, - MultisigTxPayload, -) - - -@pytest.mark.parametrize( - "payload_class, payload_kwargs", - [ - ( - MultisigTxPayload, - {"tx_submitter": "dummy tx submitter", "tx_hash": "dummy tx hash"}, - ), - ( - CallCheckpointPayload, - { - "service_staking_state": 1, - "tx_submitter": "dummy tx submitter", - "tx_hash": "dummy tx hash", - "ts_checkpoint": 1, - "is_checkpoint_reached": True, - }, - ), - ], -) -def test_payload(payload_class: Type[BaseTxPayload], payload_kwargs: Dict) -> None: - """Test payloads.""" - payload = payload_class(sender="sender", **payload_kwargs) - - # Check each attribute in expected_data - for key, value in payload_kwargs.items(): - assert getattr(payload, key) == value - - assert payload.sender == "sender" - assert payload.data == payload_kwargs - assert payload_class.from_json(payload.json) == payload diff --git a/trader_backup/vendor/valory/skills/staking_abci/tests/test_rounds.py b/trader_backup/vendor/valory/skills/staking_abci/tests/test_rounds.py deleted file mode 100644 index 2a0564afd..000000000 --- a/trader_backup/vendor/valory/skills/staking_abci/tests/test_rounds.py +++ /dev/null @@ -1,381 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for rounds of StakingAbciApp.""" - -import json -from dataclasses import dataclass, field -from typing import Any, Callable, Dict, FrozenSet, Hashable, List, Mapping -from unittest import mock -from unittest.mock import MagicMock, patch - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - BaseTxPayload, - get_name, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.staking_abci.payloads import CallCheckpointPayload -from packages.valory.skills.staking_abci.rounds import ( - CallCheckpointRound, - CheckpointCallPreparedRound, - Event, - FinishedStakingRound, - ServiceEvictedRound, - StakingAbciApp, - StakingState, - SynchronizedData, -) - - -@pytest.fixture -def abci_app() -> StakingAbciApp: - """Fixture for StakingAbciApp.""" - synchronized_data = MagicMock() - logger = MagicMock() - context = MagicMock() - - return StakingAbciApp( - synchronized_data=synchronized_data, logger=logger, context=context - ) - - -DUMMY_SERVICE_STATE = { - "service_staking_state": StakingState.UNSTAKED.value, - "tx_submitter": "dummy_submitter", - "tx_hash": "dummy_tx_hash", - "ts_checkpoint": 0, - "is_checkpoint_reached": True, -} - - -def get_participants() -> FrozenSet[str]: - """Participants""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -def get_checkpoint_payloads(data: Dict) -> Mapping[str, CallCheckpointPayload]: - """Get payloads.""" - return { - participant: CallCheckpointPayload( - participant, - **data, - ) - for participant in get_participants() - } - - -@dataclass -class RoundTestCase: - """RoundTestCase""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, BaseTxPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -MAX_PARTICIPANTS: int = 4 - - -class BaseStakingRoundTestClass(BaseCollectSameUntilThresholdRoundTest): - """Base test class for Staking rounds.""" - - round_class = CallCheckpointRound - synchronized_data: SynchronizedData - _synchronized_data_class = SynchronizedData - _event_class = Event - - def run_test(self, test_case: RoundTestCase) -> None: - """Run the test""" - # Set initial data - self.synchronized_data.update( - self._synchronized_data_class, **test_case.initial_data - ) - - test_round = self.round_class( - synchronized_data=self.synchronized_data, context=mock.MagicMock() - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=test_case.payloads, - synchronized_data_update_fn=lambda sync_data, _: sync_data.update( - **test_case.final_data - ), - synchronized_data_attr_checks=test_case.synchronized_data_attr_checks, - most_voted_payload=test_case.most_voted_payload, - exit_event=test_case.event, - ) - ) - - -class TestCallCheckpointRound(BaseStakingRoundTestClass): - """Tests for CallCheckpointRound.""" - - round_class = CallCheckpointRound - - @pytest.mark.parametrize( - "test_case", - [ - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_checkpoint_payloads( - { - "service_staking_state": StakingState.STAKED.value, - "tx_submitter": "dummy_submitter", - "tx_hash": "dummy_tx_hash", - "ts_checkpoint": 0, - "is_checkpoint_reached": True, - } - ), - final_data={ - "service_staking_state": StakingState.STAKED.value, - "tx_submitter": "dummy_submitter", - "tx_hash": "dummy_tx_hash", - "ts_checkpoint": 0, - "is_checkpoint_reached": True, - }, - event=Event.DONE, - most_voted_payload=DUMMY_SERVICE_STATE["tx_submitter"], - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.service_staking_state - == StakingState.STAKED.value, - lambda synchronized_data: synchronized_data.tx_submitter - == "dummy_submitter", - ], - ), - RoundTestCase( - name="Service not staked", - initial_data={}, - payloads=get_checkpoint_payloads(DUMMY_SERVICE_STATE), - final_data={}, - event=Event.SERVICE_NOT_STAKED, - most_voted_payload=DUMMY_SERVICE_STATE["tx_submitter"], - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.service_staking_state - == 0, - ], - ), - RoundTestCase( - name="Service evicted", - initial_data={}, - payloads=get_checkpoint_payloads( - { - "service_staking_state": StakingState.EVICTED.value, - "tx_submitter": "dummy_submitter", - "tx_hash": "dummy_tx_hash", - "ts_checkpoint": 0, - "is_checkpoint_reached": True, - } - ), - final_data={}, - event=Event.SERVICE_EVICTED, - most_voted_payload=DUMMY_SERVICE_STATE["tx_submitter"], - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.service_staking_state - == 0, - ], - ), - RoundTestCase( - name="Next checkpoint not reached", - initial_data={}, - payloads=get_checkpoint_payloads( - { - "service_staking_state": StakingState.STAKED.value, - "tx_submitter": "dummy_submitter", - "tx_hash": None, - "ts_checkpoint": 0, - "is_checkpoint_reached": True, - } - ), - final_data={}, - event=Event.NEXT_CHECKPOINT_NOT_REACHED_YET, - most_voted_payload=DUMMY_SERVICE_STATE["tx_submitter"], - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.service_staking_state - == 0, - ], - ), - ], - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run the test.""" - - self.run_test(test_case) - - -class TestCheckpointCallPreparedRound: - """Tests for CheckpointCallPreparedRound.""" - - def test_checkpoint_call_prepared_round_initialization(self) -> None: - """Test the initialization of CheckpointCallPreparedRound.""" - round_ = CheckpointCallPreparedRound( - synchronized_data=MagicMock(), context=MagicMock() - ) - assert isinstance(round_, CheckpointCallPreparedRound) - - -class TestFinishedStakingRound: - """Tests for FinishedStakingRound.""" - - def test_finished_staking_round_initialization(self) -> None: - """Test the initialization of FinishedStakingRound.""" - round_ = FinishedStakingRound( - synchronized_data=MagicMock(), context=MagicMock() - ) - assert isinstance(round_, FinishedStakingRound) - - -class TestServiceEvictedRound: - """Tests for ServiceEvictedRound.""" - - def test_service_evicted_round_initialization(self) -> None: - """Test the initialization of ServiceEvictedRound.""" - round_ = ServiceEvictedRound(synchronized_data=MagicMock(), context=MagicMock()) - assert isinstance(round_, ServiceEvictedRound) - - -def test_staking_abci_app_initialization(abci_app: StakingAbciApp) -> None: - """Test the initialization of StakingAbciApp.""" - assert abci_app.initial_round_cls is CallCheckpointRound - assert abci_app.final_states == { - CheckpointCallPreparedRound, - FinishedStakingRound, - ServiceEvictedRound, - } - assert abci_app.transition_function == { - CallCheckpointRound: { - Event.DONE: CheckpointCallPreparedRound, - Event.SERVICE_NOT_STAKED: FinishedStakingRound, - Event.SERVICE_EVICTED: ServiceEvictedRound, - Event.NEXT_CHECKPOINT_NOT_REACHED_YET: FinishedStakingRound, - Event.ROUND_TIMEOUT: CallCheckpointRound, - Event.NO_MAJORITY: CallCheckpointRound, - }, - CheckpointCallPreparedRound: {}, - FinishedStakingRound: {}, - ServiceEvictedRound: {}, - } - assert abci_app.event_to_timeout == {Event.ROUND_TIMEOUT: 30.0} - assert abci_app.db_pre_conditions == {CallCheckpointRound: set()} - assert abci_app.db_post_conditions == { - CheckpointCallPreparedRound: { - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.service_staking_state), - get_name(SynchronizedData.previous_checkpoint), - get_name(SynchronizedData.is_checkpoint_reached), - }, - FinishedStakingRound: { - get_name(SynchronizedData.service_staking_state), - }, - ServiceEvictedRound: { - get_name(SynchronizedData.service_staking_state), - }, - } - - -DUMMY_PARTICIPANT_TO_CHECKPOINT = json.dumps( - { - "agent_0": {"sender": "agent_0", "data": "checkpoint_1"}, - "agent_1": {"sender": "agent_1", "data": "checkpoint_2"}, - } -) - - -@pytest.mark.parametrize( - "key,serialized_data,expected_result,property_to_check", - [ - ( - "participant_to_checkpoint", - DUMMY_PARTICIPANT_TO_CHECKPOINT, - json.loads(DUMMY_PARTICIPANT_TO_CHECKPOINT), - "participant_to_checkpoint", # Corresponds to _get_deserialized method - ), - ], -) -@patch( - "packages.valory.skills.staking_abci.rounds.CollectionRound.deserialize_collection" -) -def test_synchronized_data_get_deserialized( - mock_deserialize_collection: MagicMock, - key: str, - serialized_data: str, - expected_result: Mapping[str, Any], - property_to_check: str, -) -> None: - """Test the deserialization and property access in SynchronizedData.""" - # Mock the db.get_strict to return the serialized data - mock_db = mock.MagicMock() - mock_db.get_strict.return_value = serialized_data - - # Initialize SynchronizedData with the mocked db - synchronized_data = SynchronizedData(db=mock_db) - - # Mock the deserialize_collection function to return the expected deserialized result - mock_deserialize_collection.return_value = expected_result - - # Access the property using the appropriate property access method - deserialized_data = synchronized_data.participant_to_checkpoint - - # Ensure that get_strict is called with the correct key - mock_db.get_strict.assert_called_once_with(key) - - # Ensure that deserialize_collection is called with the correct serialized data - mock_deserialize_collection.assert_called_once_with(serialized_data) - assert deserialized_data == expected_result - - -def test_synchronized_data_tx_submitter() -> None: - """Test the tx_submitter property in SynchronizedData.""" - mock_db = mock.MagicMock() - mock_db.get_strict.return_value = "agent_0" - - synchronized_data = SynchronizedData(db=mock_db) - - assert synchronized_data.tx_submitter == "agent_0" - mock_db.get_strict.assert_called_once_with("tx_submitter") - - -def test_synchronized_data_service_staking_state() -> None: - """Test the service_staking_state property in SynchronizedData.""" - mock_db = mock.MagicMock() - mock_db.get.return_value = 0 - - synchronized_data = SynchronizedData(db=mock_db) - - staking_state = synchronized_data.service_staking_state - assert isinstance(staking_state, StakingState) - mock_db.get.assert_called_once_with("service_staking_state", 0) - - -def test_synchronized_data_initialization() -> None: - """Test the initialization and attributes of SynchronizedData.""" - data = SynchronizedData(db=AbciAppDB(setup_data={"test": ["test"]})) - assert data.db._data == {0: {"test": ["test"]}} diff --git a/trader_backup/vendor/valory/skills/termination_abci/__init__.py b/trader_backup/vendor/valory/skills/termination_abci/__init__.py deleted file mode 100644 index 787baac41..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 the ABCI Termination skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/termination_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/termination_abci/behaviours.py b/trader_backup/vendor/valory/skills/termination_abci/behaviours.py deleted file mode 100644 index 9e5e1ee1f..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/behaviours.py +++ /dev/null @@ -1,568 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2024 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 the termination behaviour classes.""" -import sys -from typing import Callable, Dict, Generator, List, Optional, Set, Type, cast - -from aea.protocols.base import Message -from hexbytes import HexBytes - -from packages.valory.contracts.gnosis_safe.contract import ( - GnosisSafeContract, - SafeOperation, -) -from packages.valory.contracts.multisend.contract import ( - MultiSendContract, - MultiSendOperation, -) -from packages.valory.contracts.service_registry.contract import ServiceRegistryContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - AsyncBehaviour, - BaseBehaviour, -) -from packages.valory.skills.abstract_round_abci.behaviours import AbstractRoundBehaviour -from packages.valory.skills.termination_abci.models import TerminationParams -from packages.valory.skills.termination_abci.payloads import BackgroundPayload -from packages.valory.skills.termination_abci.rounds import ( - BackgroundRound, - SynchronizedData, - TerminationAbciApp, - TerminationRound, -) -from packages.valory.skills.transaction_settlement_abci.behaviours import ( - TransactionSettlementRoundBehaviour, -) -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - hash_payload_to_hex, -) - - -# setting the safe gas to 0 means that all available gas will be used -# which is what we want in most cases -# more info here: https://safe-docs.dev.gnosisdev.com/safe/docs/contracts_tx_execution/ -_SAFE_GAS = 0 - -# hardcoded to 0 because we don't need to send any ETH when handing over multisig ownership -_ETHER_VALUE = 0 - -# payload to represent a non-existing event -_NO_EVENT_FOUND: Dict = {} - - -class BackgroundBehaviour(BaseBehaviour): - """A behaviour responsible for picking up the termination signal, it runs concurrently with other behaviours.""" - - matching_round = BackgroundRound - _service_owner_address: Optional[str] = None - - def async_act(self) -> Generator: - """ - Performs the termination logic. - - This method responsible for checking whether the on-chain termination signal is present. - When an agent picks up the termination signal, it prepares a multisend transaction, - on which the majority of agents in the service have to reach consensus on. - - :return: None - :yield: None - """ - if not self._is_majority_possible() or self._is_termination_majority(): - # if the service has not enough participants to reach - # consensus or if termination majority has already - # been reached, ie the multisend transaction has been - # prepared by enough participants, - # there is no need to run the rest of the act - return - - signal_present = yield from self.check_for_signal() - if signal_present is None: - # if the response is None, something went wrong - self.context.logger.error("Failed checking the termination signal.") - return - if not signal_present: - # the signal is not present, so we sleep and try again - yield from self.sleep(self.params.termination_sleep) - return - - self.context.logger.info( - "Termination signal was picked up, preparing termination transaction." - ) - - background_data = yield from self.get_multisend_payload() - if background_data is None: - self.context.logger.error( - "Couldn't prepare multisend transaction for termination." - ) - return - - self.context.logger.info("Successfully prepared termination multisend tx.") - termination_payload = BackgroundPayload( - self.context.agent_address, background_data=background_data - ) - yield from self.send_a2a_transaction(termination_payload) - yield from self.wait_for_termination_majority() - - @property - def synchronized_data(self) -> SynchronizedData: - """ - Return the synchronized data. - - Note: we instantiate here, rather than cast, as this runs - concurrently and so the instantiation needs to happen somewhere. - """ - return SynchronizedData(db=super().synchronized_data.db) - - @property - def params(self) -> TerminationParams: - """Return the params.""" - return cast(TerminationParams, super().params) - - def check_for_signal(self) -> Generator[None, None, Optional[bool]]: - """ - This method checks for the termination signal. - - We check for the signal by looking at the "SafeReceived" events on the safe contract. - https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/common/EtherPaymentFallback.sol#L10 - In order for an SafeReceived event to qualify as a termination signal it has to fulfill the following: - 1. It MUST be sent by the service owner (self._service_owner). - 2. It MUST be 0 value tx. - - :returns: True if the termination signal is found, false otherwise - """ - if self._service_owner_address is None: - self._service_owner_address = yield from self._get_service_owner() - - termination_signal = yield from self._get_latest_termination_signal() - if termination_signal is None: - # something went wrong, we stop executing the rest of the logic - return None - if termination_signal == _NO_EVENT_FOUND: - # no termination signal has ever been sent to safe - return False - - service_owner_removal = yield from self._get_latest_removed_owner_event() - if service_owner_removal is None: - # something went wrong, we stop executing the rest of the logic - return None - if service_owner_removal == _NO_EVENT_FOUND: - # the service owner has never been removed from the safe - # this means that the observed `termination_signal` is the - # first termination signal ever sent to this safe contract - # as such it is valid signal for terminating the service - return True - - # if both the `termination_signal` and the `service_owner` removal events are present, - # we need to make sure this is not a previous termination that is already taken care of - # if a termination has been previously made, we assume that: - # 1. the service owner has been previously set as the safe owner - # 2. since the service is running again, the ownership of the safe has been handed back to the agent instances - # for 2. to happen, the service owner needs to be removed from being an owner of the safe. When this is done, - # a `RemovedOwner` event is thrown, which is what `_get_latest_removed_owner_event()` captures. - - termination_signal_occurrence = int(termination_signal["block_number"]) - service_owner_removal_occurrence = int(service_owner_removal["block_number"]) - - # if the termination signal has occurred after the owner has been removed the service should terminate, - # otherwise it's a signal that has already been handled previously - return termination_signal_occurrence > service_owner_removal_occurrence - - def _get_latest_removed_owner_event(self) -> Generator[None, None, Optional[Dict]]: - """Returns the latest event in which the service owner was removed from the set of owners of the safe.""" - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_removed_owner_events", - contract_address=self.synchronized_data.safe_contract_address, - removed_owner=self._service_owner_address, - from_block=self.params.termination_from_block, - chain_id=self.params.default_chain_id, - ) - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get the latest `RemovedOwner` event. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - removed_owner_events = cast(List[Dict], response.state.body.get("data")) - if len(removed_owner_events) == 0: - return _NO_EVENT_FOUND - - latest_removed_owner_event = removed_owner_events[0] - for removed_owner_event in removed_owner_events[1:]: - if int(removed_owner_event["block_number"]) > int( - latest_removed_owner_event["block_number"] - ): - latest_removed_owner_event = removed_owner_event - - return latest_removed_owner_event - - def _get_latest_termination_signal(self) -> Generator[None, None, Optional[Dict]]: - """Get the latest termination signal sent by the service owner.""" - self.context.logger.info( - f"Retrieving termination events on chain '{self.params.default_chain_id}' from block {self.params.termination_from_block}" - ) - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_zero_transfer_events", - contract_address=self.synchronized_data.safe_contract_address, - sender_address=self._service_owner_address, - from_block=self.params.termination_from_block, - chain_id=self.params.default_chain_id, - ) - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get the latest Zero Transfer (`SafeReceived`) event. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - zero_transfer_events = cast(List[Dict], response.state.body.get("data")) - if len(zero_transfer_events) == 0: - return _NO_EVENT_FOUND - - latest_zero_transfer_event = zero_transfer_events[0] - for zero_transfer_event in zero_transfer_events[1:]: - if int(zero_transfer_event["block_number"]) > int( - latest_zero_transfer_event["block_number"] - ): - latest_zero_transfer_event = zero_transfer_event - - return latest_zero_transfer_event - - def _get_service_owner(self) -> Generator[None, None, Optional[str]]: - """Method that returns the service owner.""" - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_id=str(ServiceRegistryContract.contract_id), - contract_callable="get_service_owner", - contract_address=self.params.service_registry_address, - service_id=self.params.on_chain_service_id, - chain_id=self.params.default_chain_id, - ) - - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get the service owner for service with id={self.params.on_chain_service_id}. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - service_owner = cast( - Optional[str], response.state.body.get("service_owner", None) - ) - return service_owner - - def get_multisend_payload(self) -> Generator[None, None, Optional[str]]: - """Prepares and returns the multisend to hand over safe ownership to the service_owner.""" - multisend_data_str = yield from self._get_multisend_tx() - if multisend_data_str is None: - return None - multisend_data = bytes.fromhex(multisend_data_str) - tx_hash = yield from self._get_safe_tx_hash(multisend_data) - if tx_hash is None: - return None - - payload_data = hash_payload_to_hex( - safe_tx_hash=tx_hash, - ether_value=_ETHER_VALUE, - safe_tx_gas=_SAFE_GAS, - operation=SafeOperation.DELEGATE_CALL.value, - to_address=self.params.multisend_address, - data=multisend_data, - ) - return payload_data - - def _get_safe_owners(self) -> Generator[None, None, Optional[List[str]]]: - """Retrieves safe owners.""" - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_owners", - contract_address=self.synchronized_data.safe_contract_address, - chain_id=self.params.default_chain_id, - ) - - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get the safe owners for safe deployed at {self.synchronized_data.safe_contract_address}. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - owners = cast(Optional[List[str]], response.state.body.get("owners", None)) - return owners - - def _get_remove_owner_tx( - self, owner: str, threshold: int - ) -> Generator[None, None, Optional[str]]: - """ - Gets a remove owner tx. - - :param owner: the owner to be removed. - :param threshold: the new safe threshold to be set. - :return: the tx data - """ - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_remove_owner_data", - contract_address=self.synchronized_data.safe_contract_address, - owner=owner, - threshold=threshold, - chain_id=self.params.default_chain_id, - ) - - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get a remove owner tx. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - # strip "0x" from the response - tx_data = cast(str, response.state.body.get("data", None))[2:] - return tx_data - - def _get_swap_owner_tx( - self, old_owner: str, new_owner: str - ) -> Generator[None, None, Optional[str]]: - """ - Gets a swap owner tx. - - :param old_owner: the owner to be removed. - :param new_owner: the new safe threshold to be set. - :return: the tx data - """ - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_swap_owner_data", - contract_address=self.synchronized_data.safe_contract_address, - old_owner=old_owner, - new_owner=new_owner, - chain_id=self.params.default_chain_id, - ) - - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get a swap owner tx. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - # strip "0x" from the response - tx_data = cast(str, response.state.body.get("data", None))[2:] - return tx_data - - def _get_safe_tx_hash(self, data: bytes) -> Generator[None, None, Optional[str]]: - """ - Prepares and returns the safe tx hash. - - :param data: the safe tx data. - :return: the tx hash - """ - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_raw_safe_transaction_hash", - to_address=self.params.multisend_address, - value=_ETHER_VALUE, - data=data, - safe_tx_gas=_SAFE_GAS, - operation=SafeOperation.DELEGATE_CALL.value, - chain_id=self.params.default_chain_id, - ) - - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get safe hash. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - # strip "0x" from the response hash - tx_hash = cast(str, response.state.body["tx_hash"])[2:] - return tx_hash - - def _get_multisend_tx(self) -> Generator[None, None, Optional[str]]: - """This method compiles a multisend transaction to give ownership of the safe contract to the service owner.""" - transactions: List[Dict] = [] - threshold = 1 - safe_owners = yield from self._get_safe_owners() - if safe_owners is None: - return None - owner_to_be_swapped = safe_owners[0] - # we remove all but one safe owner - # reverse the list to avoid errors when removing owners - # this is because the owners are stored as a linked list - # in the safe, hence the order is important - safe_owners = list(reversed(safe_owners[1:])) - for owner in safe_owners: - # we generate a tx to remove the current owner - remove_tx_str = yield from self._get_remove_owner_tx(owner, threshold) - if remove_tx_str is None: - return None - remove_tx = bytes.fromhex(remove_tx_str) - # we append it to the list of the multisend txs - transactions.append( - { - "operation": MultiSendOperation.CALL, - "to": self.synchronized_data.safe_contract_address, - "value": _ETHER_VALUE, - "data": HexBytes(remove_tx), - } - ) - - if owner_to_be_swapped != cast(str, self._service_owner_address): - # if the service owner is not the owner to be swapped - # we swap, otherwise it's not necessary - swap_tx = yield from self._get_swap_owner_tx( - owner_to_be_swapped, - cast(str, self._service_owner_address), - ) - if swap_tx is None: - return None - - transactions.append( - { - "operation": MultiSendOperation.CALL, - "to": self.synchronized_data.safe_contract_address, - "value": _ETHER_VALUE, - "data": HexBytes(swap_tx), - } - ) - - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.multisend_address, - contract_id=str(MultiSendContract.contract_id), - contract_callable="get_tx_data", - multi_send_txs=transactions, - chain_id=self.params.default_chain_id, - ) - if response.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.context.logger.error( - f"Couldn't compile the multisend tx. " - f"Expected response performative {ContractApiMessage.Performative.RAW_TRANSACTION.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - # strip "0x" from the response - multisend_data = cast(str, response.raw_transaction.body["data"])[2:] - return multisend_data - - def wait_for_termination_majority(self) -> Generator: - """ - Wait until we reach majority on the termination transaction. - - :yield: None - """ - yield from self.wait_for_condition(self._is_termination_majority) - - def _is_termination_majority(self) -> bool: - """Rely on the round to decide when majority is reached.""" - return self.synchronized_data.termination_majority_reached - - def _is_majority_possible(self) -> bool: - """Checks whether the service has enough participants to reach consensus.""" - return ( - self.synchronized_data.nb_participants - >= self.synchronized_data.consensus_threshold - ) - - def get_callback_request(self) -> Callable[[Message, "BaseBehaviour"], None]: - """Wrapper for callback_request(), overridden to avoid mix-ups with normal (non-background) behaviours.""" - - def callback_request( - message: Message, _current_behaviour: BaseBehaviour - ) -> None: - """ - This method gets called when a response for a prior request is received. - - Overridden to remove the check that checks whether the behaviour that made the request is still active. - The received message gets passed to the behaviour that invoked it, in this case it's always the - background behaviour. - - :param message: the response. - :param _current_behaviour: not used, left in to satisfy the interface. - :return: none - """ - if self.is_stopped: - self.context.logger.info( - "dropping message as behaviour has stopped: %s", message - ) - return - - if self.state != AsyncBehaviour.AsyncState.WAITING_MESSAGE: - self.context.logger.warning( - f"could not send message {message} to {self.behaviour_id}" - ) - return - - self.try_send(message) - - return callback_request - - def is_round_ended(self, round_id: str) -> Callable[[], bool]: - """ - Get a callable to check whether the current round has ended. - - We consider the background round ended when we have majority on the termination transaction. - Overriden to allow for the behaviour to send transactions at any time. - - :return: the termination majority callable - """ - return self._is_termination_majority - - -class TerminationBehaviour(BaseBehaviour): - """Behaviour responsible for terminating the agent.""" - - matching_round = TerminationRound - - def async_act(self) -> Generator: - """Logs termination and terminates.""" - self.context.logger.info("Terminating the agent.") - sys.exit() - yield - - -class TerminationAbciBehaviours(AbstractRoundBehaviour): - """This class defines the behaviours required in terminating a service.""" - - initial_behaviour_cls = TransactionSettlementRoundBehaviour.initial_behaviour_cls - abci_app_cls = TerminationAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - BackgroundBehaviour, # type: ignore - TerminationBehaviour, # type: ignore - *TransactionSettlementRoundBehaviour.behaviours, - } diff --git a/trader_backup/vendor/valory/skills/termination_abci/dialogues.py b/trader_backup/vendor/valory/skills/termination_abci/dialogues.py deleted file mode 100644 index 9ea32cd87..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/dialogues.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_backup/vendor/valory/skills/termination_abci/handlers.py b/trader_backup/vendor/valory/skills/termination_abci/handlers.py deleted file mode 100644 index d2e76dd11..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/handlers.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 the handler for the Termination skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIHandler = BaseABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_backup/vendor/valory/skills/termination_abci/models.py b/trader_backup/vendor/valory/skills/termination_abci/models.py deleted file mode 100644 index 2e7c2b2fe..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/models.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2024 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 the shared state for TerminationAbci.""" - -from typing import Any - -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.termination_abci.rounds import TerminationAbciApp -from packages.valory.skills.transaction_settlement_abci.models import ( - RandomnessApi as TransactionSettlementRandomness, -) -from packages.valory.skills.transaction_settlement_abci.models import TransactionParams - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = TerminationAbciApp - - -class TerminationParams(TransactionParams): - """Defines the class to hold the termination parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Set up the termination parameters.""" - self.termination_sleep: int = self._ensure("termination_sleep", kwargs, int) - self.multisend_address: str = self._ensure("multisend_address", kwargs, str) - self.termination_from_block: int = self._ensure( - "termination_from_block", kwargs, int - ) - super().__init__(*args, **kwargs) - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool -RandomnessApi = TransactionSettlementRandomness diff --git a/trader_backup/vendor/valory/skills/termination_abci/payloads.py b/trader_backup/vendor/valory/skills/termination_abci/payloads.py deleted file mode 100644 index f384da563..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/payloads.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 the termination payload classes.""" - -from dataclasses import dataclass - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class BackgroundPayload(BaseTxPayload): - """Defines the background round payload.""" - - background_data: str diff --git a/trader_backup/vendor/valory/skills/termination_abci/rounds.py b/trader_backup/vendor/valory/skills/termination_abci/rounds.py deleted file mode 100644 index b11cece66..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/rounds.py +++ /dev/null @@ -1,192 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2024 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 the termination round classes.""" - -from enum import Enum -from typing import Dict, Optional, Set, Tuple, cast - -from packages.valory.skills.abstract_round_abci.abci_app_chain import ( - AbciAppTransitionMapping, - chain, -) -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciApp, - AbstractRound, - AppState, - BaseSynchronizedData, - BaseTxPayload, - CollectSameUntilThresholdRound, - TransactionNotValidError, - get_name, -) -from packages.valory.skills.termination_abci.payloads import BackgroundPayload -from packages.valory.skills.transaction_settlement_abci.rounds import ( - FailedRound, - FinishedTransactionSubmissionRound, - TransactionSubmissionAbciApp, -) - - -class Event(Enum): - """Defines the (background) round events.""" - - TERMINATE = "terminate" - - -class SynchronizedData(BaseSynchronizedData): - """ - Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - @property - def termination_majority_reached(self) -> bool: - """Get termination_majority_reached.""" - return cast(bool, self.db.get("termination_majority_reached", False)) - - @property - def most_voted_tx_hash(self) -> str: - """Get the most_voted_tx_hash.""" - return cast(str, self.db.get_strict("most_voted_tx_hash")) # pragma: no cover - - @property - def chain_id(self) -> Optional[str]: - """Get the chain name where to send the transactions to.""" - return cast(str, self.db.get("chain_id", None)) - - -class BackgroundRound(CollectSameUntilThresholdRound): - """Defines the background round, which runs concurrently with other rounds.""" - - payload_class = BackgroundPayload - synchronized_data_class = SynchronizedData - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - # for background round payloads, we don't need to check the round_count, as round_count is irrelevant for the - # background since it's running concurrently in the background. - sender = payload.sender - if sender not in self.accepting_payloads_from: - raise ABCIAppInternalError( - f"{sender} not in list of participants: {sorted(self.accepting_payloads_from)}" - ) - - if sender in self.collection: - raise ABCIAppInternalError( - f"sender {sender} has already sent value for round: {self.round_id}" - ) - - self.collection[sender] = payload - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check Payload""" - # NOTE: the TransactionNotValidError is intercepted in ABCIRoundHandler.deliver_tx - # which means it will be logged instead of raised - # for background round payloads, we don't need to check the round_count, as round_count is irrelevant for the - # background since it's running concurrently in the background. - sender_in_participant_set = payload.sender in self.accepting_payloads_from - if not sender_in_participant_set: - raise TransactionNotValidError( - f"{payload.sender} not in list of participants: {sorted(self.accepting_payloads_from)}" - ) - - if payload.sender in self.collection: - raise TransactionNotValidError( - f"sender {payload.sender} has already sent value for round: {self.round_id}" - ) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - if self.threshold_reached: - state = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{ - get_name(SynchronizedData.termination_majority_reached): True, - get_name( - SynchronizedData.most_voted_tx_hash - ): self.most_voted_payload, - get_name( - SynchronizedData.chain_id - ): self.context.params.default_chain_id, - }, - ) - return state, Event.TERMINATE - - return None - - -class TerminationRound(AbstractRound): - """Round to act as the counterpart of the behaviour responsible for terminating the agent.""" - - payload_class = None - synchronized_data_class = SynchronizedData - - def check_payload(self, payload: BaseTxPayload) -> None: - """No logic required here.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """No logic required here.""" - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """No logic required here.""" - return None - - -class PostTerminationTxAbciApp(AbciApp[Event]): - """PostTerminationTxAbciApp - - Initial round: TerminationRound - - Initial states: {TerminationRound} - - Transition states: - 0. TerminationRound - - terminate: 0. - - Final states: {} - - Timeouts: - - """ - - initial_round_cls = TerminationRound - # the following is not needed, it is added to satisfy the round check - # the TerminationRound when run it terminates the agent, so nothing can come after it - transition_function = {TerminationRound: {Event.TERMINATE: TerminationRound}} - db_pre_conditions: Dict[AppState, Set[str]] = {TerminationRound: set()} - - -termination_transition_function: AbciAppTransitionMapping = { - FinishedTransactionSubmissionRound: PostTerminationTxAbciApp.initial_round_cls, - FailedRound: TransactionSubmissionAbciApp.initial_round_cls, -} -TerminationAbciApp = chain( - ( - TransactionSubmissionAbciApp, - PostTerminationTxAbciApp, - ), - termination_transition_function, -) - -TerminationAbciApp.transition_function[BackgroundRound] = { - Event.TERMINATE: TransactionSubmissionAbciApp.initial_round_cls, -} diff --git a/trader_backup/vendor/valory/skills/termination_abci/skill.yaml b/trader_backup/vendor/valory/skills/termination_abci/skill.yaml deleted file mode 100644 index 4206159ce..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/skill.yaml +++ /dev/null @@ -1,155 +0,0 @@ -name: termination_abci -author: valory -version: 0.1.0 -type: skill -description: Termination skill. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeidztixckwwbn4ujl6kkvghgsk23xecbgnbiw3e4t3owxldhyjo3au - behaviours.py: bafybeihd7m2w5bzqj24rlpnyyxa4xt72ebcgmnvonwjexygvs4xyaqxdeu - dialogues.py: bafybeif7uhfjkcz3ryhti6gafqxhvciw4ec5bdshxvq3355tun5ydkzrna - handlers.py: bafybeibh5b3p4bdvbnwiqwormduqjvuievylb3s2wgj4ald4led7gx2kji - models.py: bafybeihak6dcfqpjxbryeixksdn5lbdifq5ondzlh4wiweoptzzn42wco4 - payloads.py: bafybeihbwfunongkws5lck67sdgpnytq6bdbiv22yuehmyfth4qeypjcpa - rounds.py: bafybeifouwd4dv6ummirb45e7qxnyyadg2bsrl4kx6xbr6rvodz3lsqgqa - tests/__init__.py: bafybeigsjjibb2gcybzp5yrsy25vyiu54rw6oaeyw5onaqemsvul7bmroi - tests/test_behaviours.py: bafybeibkogjosxk6ktneru5ddgzguuiw2wuvx2n63d3rpyqhoy7llnoc5i - tests/test_dialogues.py: bafybeicb6gfanfyt3wiq3svdlvtxiuzpk72oxp7cfdeq4ezed7ixee5yae - tests/test_handlers.py: bafybeiefz2ebr5rlyxziwr4bts2r75abpqgji3k47a6hnrj7e7t2yvgmpu - tests/test_models.py: bafybeih5wtdjuv4hc25fxneeg7mgjiks55xj353zxfamvtrthkw2ydmbbe - tests/test_payloads.py: bafybeibai4dzjjdeyeinyirjndcfzbj2qst6roj6prjvcqwut5m3won3fa - tests/test_rounds.py: bafybeiafy4hqww4qqjfd7wrqhnezf47n66pnodect6hquf4bpkrwiqmufq -fingerprint_ignore_patterns: [] -connections: [] -contracts: -- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge -- valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y -- valory/service_registry:0.1.0:bafybeiaop64kwdoetxtedoehabmsalojmms7ihuoqcdwxtwb2hk5i6bzye -protocols: -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae -behaviours: - main: - args: {} - class_name: TerminationAbciBehaviours -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - finalize_timeout: 60.0 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - history_check_timeout: 1205 - init_fallback_gas: 0 - ipfs_domain_name: null - keeper_allowed_retries: 3 - keeper_timeout: 30.0 - light_slash_unit_amount: 5000000000000000 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761' - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 30.0 - serious_slash_unit_amount: 8000000000000000 - service_id: termination_abci - service_registry_address: '0x48b6af7B12C71f09e2fC8aF4855De4Ff54e775cA' - setup: {} - share_tm_config_on_startup: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - sleep_time: 1 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - termination_from_block: 0 - termination_sleep: 900 - tx_timeout: 10.0 - use_slashing: false - use_termination: false - validate_timeout: 1205 - class_name: TerminationParams - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: - hexbytes: {} -is_abstract: true -customs: [] diff --git a/trader_backup/vendor/valory/skills/termination_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/termination_abci/tests/__init__.py deleted file mode 100644 index 9c9c65fc1..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/termination_abci skill.""" diff --git a/trader_backup/vendor/valory/skills/termination_abci/tests/test_behaviours.py b/trader_backup/vendor/valory/skills/termination_abci/tests/test_behaviours.py deleted file mode 100644 index eaf3f13f7..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/tests/test_behaviours.py +++ /dev/null @@ -1,649 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 package contains round behaviours of Background Behaviours.""" - -import logging -import platform -from dataclasses import dataclass -from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Type -from unittest import mock - -import pytest - -from packages.valory.contracts.gnosis_safe.contract import GnosisSafeContract -from packages.valory.contracts.multisend.contract import MultiSendContract -from packages.valory.contracts.service_registry.contract import ServiceRegistryContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.contract_api.custom_types import RawTransaction, State -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.behaviour_utils import AsyncBehaviour -from packages.valory.skills.abstract_round_abci.behaviours import BaseBehaviour -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.termination_abci import PUBLIC_ID -from packages.valory.skills.termination_abci.behaviours import ( - BackgroundBehaviour, - TerminationAbciBehaviours, - TerminationBehaviour, -) -from packages.valory.skills.termination_abci.rounds import Event, SynchronizedData -from packages.valory.skills.transaction_settlement_abci.behaviours import ( - TransactionSettlementRoundBehaviour, -) - - -SERVICE_REGISTRY_ADDRESS = "0x48b6af7B12C71f09e2fC8aF4855De4Ff54e775cA" -SAFE_ADDRESS = "0x0" -MULTISEND_ADDRESS = "0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761" -SERVICE_OWNER_ADDRESS = "0x0" -SERVICE_ID = None - - -def test_skill_public_id() -> None: - """Test skill module public ID""" - - # pylint: disable=no-member - assert PUBLIC_ID.name == Path(__file__).parents[1].name - assert PUBLIC_ID.author == Path(__file__).parents[3].name - - -@dataclass -class BehaviourTestCase: - """BehaviourTestCase""" - - name: str - initial_data: Dict[str, Any] - ok_reqs: List[Callable] - err_reqs: List[Callable] - expected_log: str - expected_log_level: int - - -class BaseTerminationTest(FSMBehaviourBaseCase): - """Base test case.""" - - path_to_skill = Path(__file__).parents[1] - - behaviour: TerminationAbciBehaviours - behaviour_class: Type[BaseBehaviour] - next_behaviour_class: Type[ - BaseBehaviour - ] = TransactionSettlementRoundBehaviour.initial_behaviour_cls - synchronized_data: SynchronizedData - done_event = Event.TERMINATE - - def fast_forward(self, data: Optional[Dict[str, Any]] = None) -> None: - """Fast-forward on initialization""" - - data = data or {} - self.fast_forward_to_behaviour( - self.behaviour, - self.behaviour_class.auto_behaviour_id(), - SynchronizedData(AbciAppDB(setup_data=AbciAppDB.data_to_lists(data))), - ) - assert ( - self.behaviour.current_behaviour is not None - and self.behaviour.current_behaviour.behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - - def complete(self) -> None: - """Complete test""" - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self.end_round(done_event=self.done_event) - assert ( - self.behaviour.current_behaviour is not None - and self.behaviour.current_behaviour.behaviour_id - == self.next_behaviour_class.auto_behaviour_id() - ) - - -class TestBackgroundBehaviour(BaseTerminationTest): - """Test the background behaviour.""" - - behaviour_class = BackgroundBehaviour - next_behaviour_class = TransactionSettlementRoundBehaviour.initial_behaviour_cls - - # when the service owner ordered termination - _ZERO_TRANSFER_EVENTS = [ - {"block_number": 1}, - {"block_number": 10}, - {"block_number": 20}, - ] - _NUM_ZERO_TRANSFER_EVENTS = len(_ZERO_TRANSFER_EVENTS) - # when the service owner got removed from being a safe owner - # this happens when the operators take over the safe again - _SERVICE_OWNER_REMOVED_EVENTS = [ - {"block_number": 2}, - {"block_number": 11}, - ] - _NUM_SERVICE_OWNER_REMOVED_EVENTS = len(_SERVICE_OWNER_REMOVED_EVENTS) - _SAFE_OWNERS = ["0x1", "0x2", "0x3", "0x4"] - _NUM_SAFE_OWNERS = len(_SAFE_OWNERS) - _SAFE_THRESHOLD = 1 - _MOCK_TX_RESPONSE = b"0xIrrelevantForTests".hex() - _MOCK_TX_HASH = "0x" + "0" * 64 - _INITIAL_DATA: Dict[str, Any] = dict( - all_participants=_SAFE_OWNERS, - safe_contract_address=SAFE_ADDRESS, - participants=_SAFE_OWNERS, - consensus_threshold=3, - ) - - _STATE_ERR_LOG = ( - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {ContractApiMessage.Performative.ERROR}." - ) - _RAW_TRANSACTION_ERR = ( - f"Expected response performative {ContractApiMessage.Performative.RAW_TRANSACTION.value}, " # type: ignore - f"received {ContractApiMessage.Performative.ERROR}." - ) - _SERVICE_OWNER_ERR_LOG = ( - f"Couldn't get the service owner for service with id={SERVICE_ID}. " - f"{_STATE_ERR_LOG}" - ) - _ZERO_TRANSFER_EVENTS_ERR_LOG = ( - f"Couldn't get the latest Zero Transfer (`SafeReceived`) event. " - f"{_STATE_ERR_LOG}" - ) - _SERVICE_OWNER_REMOVED_EVENTS_ERR_LOG = ( - f"Couldn't get the latest `RemovedOwner` event. " f"{_STATE_ERR_LOG}" - ) - _SAFE_OWNERS_ERR_LOG = ( - f"Couldn't get the safe owners for safe deployed at {SAFE_ADDRESS}. " - f"{_STATE_ERR_LOG}" - ) - _REMOVE_OWNER_ERR_LOG = f"Couldn't get a remove owner tx. " f"{_STATE_ERR_LOG}" - _SWAP_OWNER_ERR_LOG = f"Couldn't get a swap owner tx. " f"{_STATE_ERR_LOG}" - _SAFE_HASH_ERR_LOG = f"Couldn't get safe hash. " f"{_STATE_ERR_LOG}" - _MULTISEND_ERR_LOG = "Couldn't compile the multisend tx. " - _SUCCESS_LOG = "Successfully prepared termination multisend tx." - _IS_STOPPED_LOG = "dropping message as behaviour has stopped:" - _IS_NOT_WAITING_MESSAGE = "could not send message" - - def _mock_get_service_owner_request( - self, - error: bool = False, - ) -> None: - """Mock a ServiceRegistryContract.get_service_owner() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(service_owner=SERVICE_OWNER_ADDRESS) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - - self.mock_contract_api_request( - contract_id=str(ServiceRegistryContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SERVICE_REGISTRY_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_zero_transfer_events_request( - self, - error: bool = False, - num_events: int = _NUM_ZERO_TRANSFER_EVENTS, - ) -> None: - """Mock a GnosisSafeContract.get_zero_transfer_events() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(data=self._ZERO_TRANSFER_EVENTS[:num_events]) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - self.mock_contract_api_request( - contract_id=str(GnosisSafeContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SAFE_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_removed_owner_events_request( - self, - error: bool = False, - num_events: int = _NUM_SERVICE_OWNER_REMOVED_EVENTS, - ) -> None: - """Mock a GnosisSafeContract.get_removed_owner_events() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(data=self._SERVICE_OWNER_REMOVED_EVENTS[:num_events]) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - - self.mock_contract_api_request( - contract_id=str(GnosisSafeContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SAFE_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_owners_request( - self, - error: bool = False, - ) -> None: - """Mock a GnosisSafeContract.get_owners() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(owners=self._SAFE_OWNERS) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - self.mock_contract_api_request( - contract_id=str(GnosisSafeContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SAFE_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_remove_owner_data_request(self, error: bool = False) -> None: - """Mock a GnosisSafeContract.get_remove_owner_data() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(data=self._MOCK_TX_RESPONSE) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - self.mock_contract_api_request( - contract_id=str(GnosisSafeContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SAFE_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_swap_owner_data_request( - self, - error: bool = False, - ) -> None: - """Mock a GnosisSafeContract.get_swap_owner_data() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(data=self._MOCK_TX_RESPONSE) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - self.mock_contract_api_request( - contract_id=str(GnosisSafeContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SAFE_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_raw_safe_transaction_hash_request( - self, - error: bool = False, - ) -> None: - """Mock a GnosisSafeContract.get_raw_safe_transaction_hash() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(tx_hash=self._MOCK_TX_HASH) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - self.mock_contract_api_request( - contract_id=str(GnosisSafeContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SAFE_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_tx_data_request( - self, - error: bool = False, - ) -> None: - """Mock a MultiSendContract.get_tx_data() request.""" - if not error: - response_performative = ContractApiMessage.Performative.RAW_TRANSACTION - response_body = dict(data=self._MOCK_TX_RESPONSE) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - self.mock_contract_api_request( - contract_id=str(MultiSendContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=MULTISEND_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - raw_transaction=RawTransaction( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_is_stopped( # pylint: disable=unused-argument, disable=protected-access - self, - error: bool = False, - ) -> None: - """Mock a MultiSendContract.get_tx_data() request.""" - assert self.behaviour.current_behaviour is not None - self.behaviour.current_behaviour._AsyncBehaviour__stopped = True - - def _mock_state_is_not_waiting_message( # pylint: disable=unused-argument, disable=protected-access - self, - error: bool = False, - ) -> None: - """Mock a MultiSendContract.get_tx_data() request.""" - assert self.behaviour.current_behaviour is not None - self.behaviour.current_behaviour._AsyncBehaviour__state = ( - AsyncBehaviour.AsyncState.RUNNING - ) - - @pytest.mark.parametrize( - "test_case", - [ - BehaviourTestCase( - name="agent fails to get the service owner", - initial_data=_INITIAL_DATA, - ok_reqs=[], - err_reqs=[_mock_get_service_owner_request], - expected_log=_SERVICE_OWNER_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to get zero transfer event", - initial_data=_INITIAL_DATA, - ok_reqs=[_mock_get_service_owner_request], - err_reqs=[_mock_get_zero_transfer_events_request], - expected_log=_ZERO_TRANSFER_EVENTS_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to get owner removal event", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - ], - err_reqs=[_mock_get_removed_owner_events_request], - expected_log=_SERVICE_OWNER_REMOVED_EVENTS_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to get the safe owners", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - _mock_get_removed_owner_events_request, - ], - err_reqs=[_mock_get_owners_request], - expected_log=_SAFE_OWNERS_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to get a remove safe owner tx", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - _mock_get_removed_owner_events_request, - _mock_get_owners_request, - ], - err_reqs=[_mock_get_remove_owner_data_request], - expected_log=_REMOVE_OWNER_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to get a swap safe owner tx", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - _mock_get_removed_owner_events_request, - _mock_get_owners_request, - *[_mock_get_remove_owner_data_request] * (_NUM_SAFE_OWNERS - 1), - ], - err_reqs=[_mock_get_swap_owner_data_request], - expected_log=_SWAP_OWNER_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to prepare multisend tx", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - _mock_get_removed_owner_events_request, - _mock_get_owners_request, - *[_mock_get_remove_owner_data_request] * (_NUM_SAFE_OWNERS - 1), - _mock_get_swap_owner_data_request, - ], - err_reqs=[_mock_get_tx_data_request], - expected_log=_MULTISEND_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to get a hash for the multisend tx", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - _mock_get_removed_owner_events_request, - _mock_get_owners_request, - *[_mock_get_remove_owner_data_request] * (_NUM_SAFE_OWNERS - 1), - _mock_get_swap_owner_data_request, - _mock_get_tx_data_request, - ], - err_reqs=[_mock_get_raw_safe_transaction_hash_request], - expected_log=_SAFE_HASH_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent completes the whole flow", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - _mock_get_removed_owner_events_request, - _mock_get_owners_request, - *[_mock_get_remove_owner_data_request] * (_NUM_SAFE_OWNERS - 1), - _mock_get_swap_owner_data_request, - _mock_get_tx_data_request, - _mock_get_raw_safe_transaction_hash_request, - ], - err_reqs=[], - expected_log=_SUCCESS_LOG, - expected_log_level=logging.INFO, - ), - BehaviourTestCase( - name="agent drops message because app already stopped", - initial_data=_INITIAL_DATA, - ok_reqs=[], - err_reqs=[ - _mock_is_stopped, - _mock_get_service_owner_request, - ], - expected_log=_IS_STOPPED_LOG, - expected_log_level=logging.INFO, - ), - BehaviourTestCase( - name="agent could not send message because state != WAITING_MESSAGE", - initial_data=_INITIAL_DATA, - ok_reqs=[], - err_reqs=[ - _mock_state_is_not_waiting_message, - _mock_get_service_owner_request, - ], - expected_log=_IS_NOT_WAITING_MESSAGE, - expected_log_level=logging.WARNING, - ), - ], - ) - def test_run(self, test_case: BehaviourTestCase) -> None: - """Test multiple paths of termination.""" - self.fast_forward(data=test_case.initial_data) - # repeating this check for the `current_behaviour` here to avoid `mypy` reporting: - # `error: Item "None" of "Optional[BaseBehaviour]" has no attribute "context"` when accessing the context below - assert self.behaviour.current_behaviour is not None - - with mock.patch.object( - self.behaviour.current_behaviour.context.logger, "log" - ) as mock_logger: - self.behaviour.act_wrapper() - - # apply the OK mocks first - for ok_req in test_case.ok_reqs: - ok_req(self) - - # apply the failing mocks - for err_req in test_case.err_reqs: - err_req(self, error=True) - - log_found = False - for log_args in mock_logger.call_args_list: - if platform.python_version().startswith("3.7"): - actual_log_level, actual_log = log_args[0][:2] - else: - actual_log_level, actual_log = log_args.args[:2] - - if actual_log.startswith(test_case.expected_log): - assert actual_log_level == test_case.expected_log_level, ( - f"{test_case.expected_log} was expected to log on {test_case.expected_log_level} log level, " - f"but logged on {log_args[0]} instead." - ) - log_found = True - break - - if not log_found: - raise AssertionError( - f'Expected log message "{test_case.expected_log}" was not found in captured logs: ' - f"{mock_logger.call_args_list}." - ) - - if len(test_case.err_reqs) == 0: - # no mocked requests fail, - # the behaviour should complete - self.complete() - - def test_termination_majority_already_reached(self) -> None: - """Tests the background behaviour when the termination is already reached.""" - self.fast_forward( - data=dict( - termination_majority_reached=True, - all_participants=["a"], - participants=["a"], - consensus_threshold=1, - ) - ) - with mock.patch.object( - self.behaviour_class, "check_for_signal" - ) as check_for_signal: - self.behaviour.act_wrapper() - check_for_signal.assert_not_called() - - def test_no_termination_signal_is_present(self) -> None: - """Tests the background behaviour when no termination signal is present.""" - self.fast_forward(self._INITIAL_DATA) - with mock.patch.object(AsyncBehaviour, "sleep") as sleep: - self.behaviour.act_wrapper() - self._mock_get_service_owner_request() - self._mock_get_zero_transfer_events_request(num_events=0) - sleep.assert_called() - - def test_no_remove_owner_event_is_present(self) -> None: - """Tests the background behaviour when the safe owner hasn't been removed.""" - self.fast_forward(self._INITIAL_DATA) - self.behaviour.act_wrapper() - self._mock_get_service_owner_request() - self._mock_get_zero_transfer_events_request() - self._mock_get_removed_owner_events_request(num_events=0) - self._mock_get_owners_request() - for _ in range(self._NUM_SAFE_OWNERS - 1): - self._mock_get_remove_owner_data_request() - self._mock_get_swap_owner_data_request() - self._mock_get_tx_data_request() - self._mock_get_raw_safe_transaction_hash_request() - self.complete() - - -class TestTerminationBehaviour(BaseTerminationTest): - """Test termination behaviour.""" - - behaviour_class = TerminationBehaviour - - def test_run(self) -> None: - """Test that the Termination Behaviour exits the app.""" - self.fast_forward() - with mock.patch("sys.exit") as sys_exit: - self.behaviour.act_wrapper() - sys_exit.assert_called() diff --git a/trader_backup/vendor/valory/skills/termination_abci/tests/test_dialogues.py b/trader_backup/vendor/valory/skills/termination_abci/tests/test_dialogues.py deleted file mode 100644 index 07360efcf..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ -# pylint: disable=unused-import - -"""Test the dialogues.py module of the skill.""" - - -import packages.valory.skills.termination_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_backup/vendor/valory/skills/termination_abci/tests/test_handlers.py b/trader_backup/vendor/valory/skills/termination_abci/tests/test_handlers.py deleted file mode 100644 index 244d6c19f..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/tests/test_handlers.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ -# pylint: disable=unused-import - -"""Test the dialogues.py module of the skill.""" - - -import packages.valory.skills.termination_abci.handlers # noqa - - -def test_import() -> None: - """Test that the 'handlers.py' Python module can be imported.""" diff --git a/trader_backup/vendor/valory/skills/termination_abci/tests/test_models.py b/trader_backup/vendor/valory/skills/termination_abci/tests/test_models.py deleted file mode 100644 index acf0ac453..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/tests/test_models.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ -# pylint: disable=unused-import - -"""Test the models.py module of the skill.""" - - -from packages.valory.skills.abstract_round_abci.test_tools.base import DummyContext -from packages.valory.skills.termination_abci.models import SharedState - - -class TestSharedState: # pylint: disable=too-few-public-methods - """Test SharedState(Model) class.""" - - def test_initialization( # pylint: disable=no-self-use - self, - ) -> None: - """Test initialization.""" - SharedState(name="", skill_context=DummyContext()) diff --git a/trader_backup/vendor/valory/skills/termination_abci/tests/test_payloads.py b/trader_backup/vendor/valory/skills/termination_abci/tests/test_payloads.py deleted file mode 100644 index e6ae87379..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/tests/test_payloads.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Test the payloads.py module of the skill.""" - - -from packages.valory.skills.termination_abci.payloads import BackgroundPayload - - -def test_background_payload() -> None: - """Test `BackgroundPayload`.""" - data = "0xdata" - payload = BackgroundPayload(sender="sender", background_data=data) - - assert payload.background_data == data - assert payload.data == {"background_data": data} diff --git a/trader_backup/vendor/valory/skills/termination_abci/tests/test_rounds.py b/trader_backup/vendor/valory/skills/termination_abci/tests/test_rounds.py deleted file mode 100644 index 163a548ca..000000000 --- a/trader_backup/vendor/valory/skills/termination_abci/tests/test_rounds.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the rounds of the skill.""" - -from copy import deepcopy -from typing import FrozenSet, cast -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciAppDB, - TransactionNotValidError, -) -from packages.valory.skills.termination_abci.payloads import BackgroundPayload -from packages.valory.skills.termination_abci.rounds import ( - BackgroundRound, - Event, - SynchronizedData, - TerminationRound, -) - - -MAX_PARTICIPANTS: int = 4 - - -def get_participants() -> FrozenSet[str]: - """Participants""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -class BaseRoundTestClass: # pylint: disable=too-few-public-methods - """Base test class for Rounds.""" - - synchronized_data: SynchronizedData - participants: FrozenSet[str] - - def setup( - self, - ) -> None: - """Setup the test class.""" - - self.participants = get_participants() - self.synchronized_data = SynchronizedData( - AbciAppDB( - setup_data=dict( - participants=[tuple(self.participants)], - all_participants=[tuple(self.participants)], - consensus_threshold=[3], - ), - ) - ) - - -class TestBackgroundRound(BaseRoundTestClass): - """Tests for BackgroundRound.""" - - def test_run( - self, - ) -> None: - """Run tests.""" - - test_round = BackgroundRound( - synchronized_data=deepcopy(self.synchronized_data), - context=MagicMock( - params=MagicMock( - default_chain_id=1, - ) - ), - ) - payload_data = "0xdata" - first_payload, *payloads = [ - BackgroundPayload(sender=participant, background_data=payload_data) - for participant in self.participants - ] - - test_round.process_payload(first_payload) - assert test_round.collection == {first_payload.sender: first_payload} - assert test_round.end_block() is None - - for payload in payloads: - test_round.process_payload(payload) - - expected_state = self.synchronized_data.update( - most_voted_tx_hash=payload_data, - termination_majority_reached=True, - ) - - res = test_round.end_block() - assert res is not None - actual_state, event = res - - assert ( - cast(SynchronizedData, actual_state).termination_majority_reached - == cast( # pylint: disable=no-member - SynchronizedData, expected_state - ).termination_majority_reached - ) - - assert event == Event.TERMINATE - - def test_bad_payloads(self) -> None: - """Tests the background round when bad payloads are sent.""" - test_round = BackgroundRound( - synchronized_data=deepcopy(self.synchronized_data), - context=MagicMock(), - ) - payload_data = "0xdata" - bad_participant = "non_existent" - bad_participant_payload = BackgroundPayload( - sender=bad_participant, background_data=payload_data - ) - first_payload, *_ = [ - BackgroundPayload(sender=participant, background_data=payload_data) - for participant in self.participants - ] - - with pytest.raises( - TransactionNotValidError, - match=f"{bad_participant} not in list of participants", - ): - test_round.check_payload(bad_participant_payload) - - with pytest.raises( - ABCIAppInternalError, - match=f"{bad_participant} not in list of participants", - ): - test_round.process_payload(bad_participant_payload) - - # a valid payload gets sent for the first time and it goes through - test_round.process_payload(first_payload) - - # a duplicate (valid) payload will not go through - with pytest.raises( - TransactionNotValidError, - match=f"sender {first_payload.sender} has already sent value for round", - ): - test_round.check_payload(first_payload) - - with pytest.raises( - ABCIAppInternalError, - match=f"sender {first_payload.sender} has already sent value for round", - ): - test_round.process_payload(first_payload) - - -class TestTerminationRound(BaseRoundTestClass): - """Tests for TerminationRound.""" - - def test_run( - self, - ) -> None: - """Run tests.""" - - test_round = TerminationRound( - synchronized_data=deepcopy(self.synchronized_data), - context=MagicMock(), - ) - res = test_round.end_block() # pylint: disable=assignment-from-none - assert res is None diff --git a/trader_backup/vendor/valory/skills/trader_abci/README.md b/trader_backup/vendor/valory/skills/trader_abci/README.md deleted file mode 100644 index 6d0eb56d3..000000000 --- a/trader_backup/vendor/valory/skills/trader_abci/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Trader abci - -## Description - -This module contains the trader chained skill for an AEA. diff --git a/trader_backup/vendor/valory/skills/trader_abci/__init__.py b/trader_backup/vendor/valory/skills/trader_abci/__init__.py deleted file mode 100644 index 219bbfad2..000000000 --- a/trader_backup/vendor/valory/skills/trader_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- 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 the trader chained skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/trader_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/trader_abci/behaviours.py b/trader_backup/vendor/valory/skills/trader_abci/behaviours.py deleted file mode 100644 index 3abcf2b38..000000000 --- a/trader_backup/vendor/valory/skills/trader_abci/behaviours.py +++ /dev/null @@ -1,79 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviours for the trader skill.""" - -from typing import Set, Type - -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.check_stop_trading_abci.behaviours import ( - CheckStopTradingRoundBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.round_behaviour import ( - AgentDecisionMakerRoundBehaviour, -) -from packages.valory.skills.market_manager_abci.behaviours import ( - MarketManagerRoundBehaviour, -) -from packages.valory.skills.mech_interact_abci.behaviours.round_behaviour import ( - MechInteractRoundBehaviour, -) -from packages.valory.skills.registration_abci.behaviours import ( - AgentRegistrationRoundBehaviour, - RegistrationStartupBehaviour, -) -from packages.valory.skills.reset_pause_abci.behaviours import ( - ResetPauseABCIConsensusBehaviour, -) -from packages.valory.skills.staking_abci.behaviours import StakingRoundBehaviour -from packages.valory.skills.termination_abci.behaviours import ( - BackgroundBehaviour, - TerminationAbciBehaviours, -) -from packages.valory.skills.trader_abci.composition import TraderAbciApp -from packages.valory.skills.transaction_settlement_abci.behaviours import ( - TransactionSettlementRoundBehaviour, -) -from packages.valory.skills.tx_settlement_multiplexer_abci.behaviours import ( - PostTxSettlementFullBehaviour, -) - - -class TraderConsensusBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the trader.""" - - initial_behaviour_cls = RegistrationStartupBehaviour - abci_app_cls = TraderAbciApp - - behaviours: Set[Type[BaseBehaviour]] = { - *AgentRegistrationRoundBehaviour.behaviours, - *AgentDecisionMakerRoundBehaviour.behaviours, - *MarketManagerRoundBehaviour.behaviours, - *MechInteractRoundBehaviour.behaviours, - *ResetPauseABCIConsensusBehaviour.behaviours, - *TerminationAbciBehaviours.behaviours, - *TransactionSettlementRoundBehaviour.behaviours, - *PostTxSettlementFullBehaviour.behaviours, - *StakingRoundBehaviour.behaviours, - *CheckStopTradingRoundBehaviour.behaviours, - } - background_behaviours_cls = {BackgroundBehaviour} # type: ignore diff --git a/trader_backup/vendor/valory/skills/trader_abci/composition.py b/trader_backup/vendor/valory/skills/trader_abci/composition.py deleted file mode 100644 index 0817e97c1..000000000 --- a/trader_backup/vendor/valory/skills/trader_abci/composition.py +++ /dev/null @@ -1,168 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the trader ABCI application.""" - -from packages.valory.skills.abstract_round_abci.abci_app_chain import ( - AbciAppTransitionMapping, - chain, -) -from packages.valory.skills.abstract_round_abci.base import BackgroundAppConfig -from packages.valory.skills.check_stop_trading_abci.rounds import ( - CheckStopTradingAbciApp, - CheckStopTradingRound, - FinishedCheckStopTradingRound, - FinishedWithSkipTradingRound, -) -from packages.valory.skills.decision_maker_abci.rounds import DecisionMakerAbciApp -from packages.valory.skills.decision_maker_abci.states.check_benchmarking import ( - CheckBenchmarkingModeRound, -) -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) -from packages.valory.skills.decision_maker_abci.states.decision_receive import ( - DecisionReceiveRound, -) -from packages.valory.skills.decision_maker_abci.states.final_states import ( - BenchmarkingDoneRound, - BenchmarkingModeDisabledRound, - FinishedDecisionMakerRound, - FinishedDecisionRequestRound, - FinishedSubscriptionRound, - FinishedWithoutDecisionRound, - FinishedWithoutRedeemingRound, - RefillRequiredRound, -) -from packages.valory.skills.decision_maker_abci.states.handle_failed_tx import ( - HandleFailedTxRound, -) -from packages.valory.skills.decision_maker_abci.states.randomness import RandomnessRound -from packages.valory.skills.decision_maker_abci.states.redeem import RedeemRound -from packages.valory.skills.market_manager_abci.rounds import ( - FailedMarketManagerRound, - FinishedMarketManagerRound, - MarketManagerAbciApp, - UpdateBetsRound, -) -from packages.valory.skills.mech_interact_abci.rounds import MechInteractAbciApp -from packages.valory.skills.mech_interact_abci.states.final_states import ( - FinishedMechRequestRound, - FinishedMechRequestSkipRound, - FinishedMechResponseRound, - FinishedMechResponseTimeoutRound, -) -from packages.valory.skills.mech_interact_abci.states.request import MechRequestRound -from packages.valory.skills.mech_interact_abci.states.response import MechResponseRound -from packages.valory.skills.registration_abci.rounds import ( - AgentRegistrationAbciApp, - FinishedRegistrationRound, -) -from packages.valory.skills.reset_pause_abci.rounds import ( - FinishedResetAndPauseErrorRound, - FinishedResetAndPauseRound, - ResetAndPauseRound, - ResetPauseAbciApp, -) -from packages.valory.skills.staking_abci.rounds import ( - CallCheckpointRound, - CheckpointCallPreparedRound, - FinishedStakingRound, - StakingAbciApp, -) -from packages.valory.skills.termination_abci.rounds import ( - BackgroundRound, - Event, - TerminationAbciApp, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - FailedRound as FailedTransactionSubmissionRound, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - FinishedTransactionSubmissionRound, - RandomnessTransactionSubmissionRound, - TransactionSubmissionAbciApp, -) -from packages.valory.skills.tx_settlement_multiplexer_abci.rounds import ( - ChecksPassedRound, - FinishedBetPlacementTxRound, - FinishedMechRequestTxRound, - FinishedRedeemingTxRound, - FinishedStakingTxRound, - FinishedSubscriptionTxRound, - PostTxSettlementRound, - PreTxSettlementRound, - TxSettlementMultiplexerAbciApp, -) - - -abci_app_transition_mapping: AbciAppTransitionMapping = { - FinishedRegistrationRound: CheckBenchmarkingModeRound, - BenchmarkingModeDisabledRound: UpdateBetsRound, - FinishedMarketManagerRound: CheckStopTradingRound, - FinishedCheckStopTradingRound: RandomnessRound, - FinishedWithSkipTradingRound: RedeemRound, - FailedMarketManagerRound: ResetAndPauseRound, - FinishedDecisionMakerRound: PreTxSettlementRound, - ChecksPassedRound: RandomnessTransactionSubmissionRound, - RefillRequiredRound: ResetAndPauseRound, - FinishedTransactionSubmissionRound: PostTxSettlementRound, - FinishedSubscriptionTxRound: ClaimRound, - FailedTransactionSubmissionRound: HandleFailedTxRound, - FinishedDecisionRequestRound: MechRequestRound, - FinishedMechRequestRound: PreTxSettlementRound, - FinishedMechRequestTxRound: MechResponseRound, - FinishedMechResponseRound: DecisionReceiveRound, - FinishedMechResponseTimeoutRound: MechResponseRound, - FinishedMechRequestSkipRound: RedeemRound, - FinishedSubscriptionRound: PreTxSettlementRound, - FinishedBetPlacementTxRound: RedeemRound, - FinishedRedeemingTxRound: CallCheckpointRound, - FinishedWithoutDecisionRound: RedeemRound, - FinishedWithoutRedeemingRound: CallCheckpointRound, - FinishedStakingRound: ResetAndPauseRound, - CheckpointCallPreparedRound: PreTxSettlementRound, - FinishedStakingTxRound: ResetAndPauseRound, - FinishedResetAndPauseRound: CheckBenchmarkingModeRound, - FinishedResetAndPauseErrorRound: ResetAndPauseRound, - # this has no effect, because the `BenchmarkingDoneRound` is terminal - BenchmarkingDoneRound: ResetAndPauseRound, -} - -termination_config = BackgroundAppConfig( - round_cls=BackgroundRound, - start_event=Event.TERMINATE, - abci_app=TerminationAbciApp, -) - - -TraderAbciApp = chain( - ( - AgentRegistrationAbciApp, - DecisionMakerAbciApp, - MarketManagerAbciApp, - MechInteractAbciApp, - TransactionSubmissionAbciApp, - TxSettlementMultiplexerAbciApp, - ResetPauseAbciApp, - StakingAbciApp, - CheckStopTradingAbciApp, - ), - abci_app_transition_mapping, -).add_background_app(termination_config) diff --git a/trader_backup/vendor/valory/skills/trader_abci/dialogues.py b/trader_backup/vendor/valory/skills/trader_abci/dialogues.py deleted file mode 100644 index 153b6ce50..000000000 --- a/trader_backup/vendor/valory/skills/trader_abci/dialogues.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- 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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_backup/vendor/valory/skills/trader_abci/fsm_specification.yaml b/trader_backup/vendor/valory/skills/trader_abci/fsm_specification.yaml deleted file mode 100644 index b2a80f938..000000000 --- a/trader_backup/vendor/valory/skills/trader_abci/fsm_specification.yaml +++ /dev/null @@ -1,258 +0,0 @@ -alphabet_in: -- BENCHMARKING_DISABLED -- BENCHMARKING_ENABLED -- BENCHMARKING_FINISHED -- BET_PLACEMENT_NO_SELL_DONE -- BET_PLACEMENT_SELL_DONE -- BLACKLIST -- CHECKS_PASSED -- CHECK_HISTORY -- CHECK_LATE_ARRIVING_MESSAGE -- CHECK_TIMEOUT -- DONE -- FETCH_ERROR -- FINALIZATION_FAILED -- FINALIZE_TIMEOUT -- INCORRECT_SERIALIZATION -- INSUFFICIENT_BALANCE -- INSUFFICIENT_FUNDS -- MECH_REQUESTING_DONE -- MECH_RESPONSE_ERROR -- MOCK_MECH_REQUEST -- MOCK_TX -- NEGATIVE -- NEW_SIMULATED_RESAMPLE -- NEXT_CHECKPOINT_NOT_REACHED_YET -- NONE -- NO_MAJORITY -- NO_OP -- NO_REDEEMING -- NO_SUBSCRIPTION -- REDEEMING_DONE -- REDEEM_ROUND_TIMEOUT -- REFILL_REQUIRED -- RESET_AND_PAUSE_TIMEOUT -- RESET_TIMEOUT -- ROUND_TIMEOUT -- SELL_OUTCOME_TOKEN_DONE -- SERVICE_EVICTED -- SERVICE_NOT_STAKED -- SKIP_REQUEST -- SKIP_TRADING -- SLOTS_UNSUPPORTED_ERROR -- STAKING_DONE -- SUBSCRIPTION_DONE -- SUBSCRIPTION_ERROR -- SUSPICIOUS_ACTIVITY -- TIE -- UNPROFITABLE -- UNRECOGNIZED -- VALIDATE_TIMEOUT -default_start_state: RegistrationStartupRound -final_states: -- FailedMultiplexerRound -- FinishedSellOutcomeTokenTxRound -- ImpossibleRound -- ServiceEvictedRound -label: TraderAbciApp -start_states: -- RegistrationRound -- RegistrationStartupRound -states: -- BenchmarkingRandomnessRound -- BetPlacementRound -- BlacklistingRound -- CallCheckpointRound -- CheckBenchmarkingModeRound -- CheckLateTxHashesRound -- CheckStopTradingRound -- CheckTransactionHistoryRound -- ClaimRound -- CollectSignatureRound -- DecisionReceiveRound -- DecisionRequestRound -- FailedMultiplexerRound -- FinalizationRound -- FinishedSellOutcomeTokenTxRound -- HandleFailedTxRound -- ImpossibleRound -- MechRequestRound -- MechResponseRound -- PostTxSettlementRound -- PreTxSettlementRound -- RandomnessRound -- RandomnessTransactionSubmissionRound -- RedeemRound -- RegistrationRound -- RegistrationStartupRound -- ResetAndPauseRound -- ResetRound -- SamplingRound -- SelectKeeperTransactionSubmissionARound -- SelectKeeperTransactionSubmissionBAfterTimeoutRound -- SelectKeeperTransactionSubmissionBRound -- ServiceEvictedRound -- SubscriptionRound -- SynchronizeLateMessagesRound -- ToolSelectionRound -- UpdateBetsRound -- ValidateTransactionRound -transition_func: - (BenchmarkingRandomnessRound, DONE): SamplingRound - (BenchmarkingRandomnessRound, NO_MAJORITY): BenchmarkingRandomnessRound - (BenchmarkingRandomnessRound, ROUND_TIMEOUT): BenchmarkingRandomnessRound - (BetPlacementRound, DONE): PreTxSettlementRound - (BetPlacementRound, INSUFFICIENT_BALANCE): ResetAndPauseRound - (BetPlacementRound, MOCK_TX): RedeemRound - (BetPlacementRound, NONE): ImpossibleRound - (BetPlacementRound, NO_MAJORITY): BetPlacementRound - (BetPlacementRound, ROUND_TIMEOUT): BetPlacementRound - (BlacklistingRound, DONE): RedeemRound - (BlacklistingRound, FETCH_ERROR): ImpossibleRound - (BlacklistingRound, MOCK_TX): RedeemRound - (BlacklistingRound, NONE): ImpossibleRound - (BlacklistingRound, NO_MAJORITY): BlacklistingRound - (BlacklistingRound, ROUND_TIMEOUT): BlacklistingRound - (CallCheckpointRound, DONE): PreTxSettlementRound - (CallCheckpointRound, NEXT_CHECKPOINT_NOT_REACHED_YET): ResetAndPauseRound - (CallCheckpointRound, NO_MAJORITY): CallCheckpointRound - (CallCheckpointRound, ROUND_TIMEOUT): CallCheckpointRound - (CallCheckpointRound, SERVICE_EVICTED): ServiceEvictedRound - (CallCheckpointRound, SERVICE_NOT_STAKED): ResetAndPauseRound - (CheckBenchmarkingModeRound, BENCHMARKING_DISABLED): UpdateBetsRound - (CheckBenchmarkingModeRound, BENCHMARKING_ENABLED): BenchmarkingRandomnessRound - (CheckBenchmarkingModeRound, DONE): ImpossibleRound - (CheckBenchmarkingModeRound, NO_MAJORITY): CheckBenchmarkingModeRound - (CheckBenchmarkingModeRound, ROUND_TIMEOUT): CheckBenchmarkingModeRound - (CheckBenchmarkingModeRound, SUBSCRIPTION_ERROR): ImpossibleRound - (CheckLateTxHashesRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (CheckLateTxHashesRound, CHECK_TIMEOUT): CheckLateTxHashesRound - (CheckLateTxHashesRound, DONE): PostTxSettlementRound - (CheckLateTxHashesRound, NEGATIVE): HandleFailedTxRound - (CheckLateTxHashesRound, NONE): HandleFailedTxRound - (CheckLateTxHashesRound, NO_MAJORITY): HandleFailedTxRound - (CheckStopTradingRound, DONE): RandomnessRound - (CheckStopTradingRound, NONE): CheckStopTradingRound - (CheckStopTradingRound, NO_MAJORITY): CheckStopTradingRound - (CheckStopTradingRound, ROUND_TIMEOUT): CheckStopTradingRound - (CheckStopTradingRound, SKIP_TRADING): RedeemRound - (CheckTransactionHistoryRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (CheckTransactionHistoryRound, CHECK_TIMEOUT): CheckTransactionHistoryRound - (CheckTransactionHistoryRound, DONE): PostTxSettlementRound - (CheckTransactionHistoryRound, NEGATIVE): SelectKeeperTransactionSubmissionBRound - (CheckTransactionHistoryRound, NONE): HandleFailedTxRound - (CheckTransactionHistoryRound, NO_MAJORITY): CheckTransactionHistoryRound - (ClaimRound, DONE): ToolSelectionRound - (ClaimRound, NO_MAJORITY): ClaimRound - (ClaimRound, ROUND_TIMEOUT): ClaimRound - (ClaimRound, SUBSCRIPTION_ERROR): ClaimRound - (CollectSignatureRound, DONE): FinalizationRound - (CollectSignatureRound, NO_MAJORITY): ResetRound - (CollectSignatureRound, ROUND_TIMEOUT): CollectSignatureRound - (DecisionReceiveRound, DONE): BetPlacementRound - (DecisionReceiveRound, MECH_RESPONSE_ERROR): BlacklistingRound - (DecisionReceiveRound, NO_MAJORITY): DecisionReceiveRound - (DecisionReceiveRound, ROUND_TIMEOUT): DecisionReceiveRound - (DecisionReceiveRound, TIE): BlacklistingRound - (DecisionReceiveRound, UNPROFITABLE): BlacklistingRound - (DecisionRequestRound, DONE): MechRequestRound - (DecisionRequestRound, MOCK_MECH_REQUEST): DecisionReceiveRound - (DecisionRequestRound, NO_MAJORITY): DecisionRequestRound - (DecisionRequestRound, ROUND_TIMEOUT): DecisionRequestRound - (DecisionRequestRound, SLOTS_UNSUPPORTED_ERROR): BlacklistingRound - (FinalizationRound, CHECK_HISTORY): CheckTransactionHistoryRound - (FinalizationRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (FinalizationRound, DONE): ValidateTransactionRound - (FinalizationRound, FINALIZATION_FAILED): SelectKeeperTransactionSubmissionBRound - (FinalizationRound, FINALIZE_TIMEOUT): SelectKeeperTransactionSubmissionBAfterTimeoutRound - (FinalizationRound, INSUFFICIENT_FUNDS): SelectKeeperTransactionSubmissionBRound - (HandleFailedTxRound, BLACKLIST): BlacklistingRound - (HandleFailedTxRound, NO_MAJORITY): HandleFailedTxRound - (HandleFailedTxRound, NO_OP): RedeemRound - (MechRequestRound, DONE): PreTxSettlementRound - (MechRequestRound, NO_MAJORITY): MechRequestRound - (MechRequestRound, ROUND_TIMEOUT): MechRequestRound - (MechRequestRound, SKIP_REQUEST): RedeemRound - (MechResponseRound, DONE): DecisionReceiveRound - (MechResponseRound, NO_MAJORITY): MechResponseRound - (MechResponseRound, ROUND_TIMEOUT): MechResponseRound - (PostTxSettlementRound, BET_PLACEMENT_NO_SELL_DONE): RedeemRound - (PostTxSettlementRound, BET_PLACEMENT_SELL_DONE): RedeemRound - (PostTxSettlementRound, MECH_REQUESTING_DONE): MechResponseRound - (PostTxSettlementRound, REDEEMING_DONE): CallCheckpointRound - (PostTxSettlementRound, ROUND_TIMEOUT): PostTxSettlementRound - (PostTxSettlementRound, SELL_OUTCOME_TOKEN_DONE): FinishedSellOutcomeTokenTxRound - (PostTxSettlementRound, STAKING_DONE): ResetAndPauseRound - (PostTxSettlementRound, SUBSCRIPTION_DONE): ClaimRound - (PostTxSettlementRound, UNRECOGNIZED): FailedMultiplexerRound - (PreTxSettlementRound, CHECKS_PASSED): RandomnessTransactionSubmissionRound - (PreTxSettlementRound, NO_MAJORITY): PreTxSettlementRound - (PreTxSettlementRound, REFILL_REQUIRED): PreTxSettlementRound - (PreTxSettlementRound, ROUND_TIMEOUT): PreTxSettlementRound - (RandomnessRound, DONE): SamplingRound - (RandomnessRound, NO_MAJORITY): RandomnessRound - (RandomnessRound, ROUND_TIMEOUT): RandomnessRound - (RandomnessTransactionSubmissionRound, DONE): SelectKeeperTransactionSubmissionARound - (RandomnessTransactionSubmissionRound, NO_MAJORITY): RandomnessTransactionSubmissionRound - (RandomnessTransactionSubmissionRound, ROUND_TIMEOUT): RandomnessTransactionSubmissionRound - (RedeemRound, DONE): PreTxSettlementRound - (RedeemRound, MOCK_TX): SamplingRound - (RedeemRound, NONE): ImpossibleRound - (RedeemRound, NO_MAJORITY): RedeemRound - (RedeemRound, NO_REDEEMING): CallCheckpointRound - (RedeemRound, REDEEM_ROUND_TIMEOUT): CallCheckpointRound - (RegistrationRound, DONE): CheckBenchmarkingModeRound - (RegistrationRound, NO_MAJORITY): RegistrationRound - (RegistrationStartupRound, DONE): CheckBenchmarkingModeRound - (ResetAndPauseRound, DONE): CheckBenchmarkingModeRound - (ResetAndPauseRound, NO_MAJORITY): ResetAndPauseRound - (ResetAndPauseRound, RESET_AND_PAUSE_TIMEOUT): ResetAndPauseRound - (ResetRound, DONE): RandomnessTransactionSubmissionRound - (ResetRound, NO_MAJORITY): HandleFailedTxRound - (ResetRound, RESET_TIMEOUT): HandleFailedTxRound - (SamplingRound, BENCHMARKING_ENABLED): ToolSelectionRound - (SamplingRound, BENCHMARKING_FINISHED): ResetAndPauseRound - (SamplingRound, DONE): SubscriptionRound - (SamplingRound, FETCH_ERROR): ImpossibleRound - (SamplingRound, NEW_SIMULATED_RESAMPLE): SamplingRound - (SamplingRound, NONE): RedeemRound - (SamplingRound, NO_MAJORITY): SamplingRound - (SamplingRound, ROUND_TIMEOUT): SamplingRound - (SelectKeeperTransactionSubmissionARound, DONE): CollectSignatureRound - (SelectKeeperTransactionSubmissionARound, INCORRECT_SERIALIZATION): HandleFailedTxRound - (SelectKeeperTransactionSubmissionARound, NO_MAJORITY): ResetRound - (SelectKeeperTransactionSubmissionARound, ROUND_TIMEOUT): SelectKeeperTransactionSubmissionARound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, CHECK_HISTORY): CheckTransactionHistoryRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, DONE): FinalizationRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, INCORRECT_SERIALIZATION): HandleFailedTxRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, NO_MAJORITY): ResetRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, ROUND_TIMEOUT): SelectKeeperTransactionSubmissionBAfterTimeoutRound - (SelectKeeperTransactionSubmissionBRound, DONE): FinalizationRound - (SelectKeeperTransactionSubmissionBRound, INCORRECT_SERIALIZATION): HandleFailedTxRound - (SelectKeeperTransactionSubmissionBRound, NO_MAJORITY): ResetRound - (SelectKeeperTransactionSubmissionBRound, ROUND_TIMEOUT): SelectKeeperTransactionSubmissionBRound - (SubscriptionRound, DONE): PreTxSettlementRound - (SubscriptionRound, MOCK_TX): ToolSelectionRound - (SubscriptionRound, NONE): SubscriptionRound - (SubscriptionRound, NO_MAJORITY): SubscriptionRound - (SubscriptionRound, NO_SUBSCRIPTION): ToolSelectionRound - (SubscriptionRound, ROUND_TIMEOUT): SubscriptionRound - (SubscriptionRound, SUBSCRIPTION_ERROR): SubscriptionRound - (SynchronizeLateMessagesRound, DONE): CheckLateTxHashesRound - (SynchronizeLateMessagesRound, NONE): SelectKeeperTransactionSubmissionBRound - (SynchronizeLateMessagesRound, ROUND_TIMEOUT): SynchronizeLateMessagesRound - (SynchronizeLateMessagesRound, SUSPICIOUS_ACTIVITY): HandleFailedTxRound - (ToolSelectionRound, DONE): DecisionRequestRound - (ToolSelectionRound, NONE): ToolSelectionRound - (ToolSelectionRound, NO_MAJORITY): ToolSelectionRound - (ToolSelectionRound, ROUND_TIMEOUT): ToolSelectionRound - (UpdateBetsRound, DONE): CheckStopTradingRound - (UpdateBetsRound, FETCH_ERROR): ResetAndPauseRound - (UpdateBetsRound, NO_MAJORITY): UpdateBetsRound - (UpdateBetsRound, ROUND_TIMEOUT): UpdateBetsRound - (ValidateTransactionRound, DONE): PostTxSettlementRound - (ValidateTransactionRound, NEGATIVE): CheckTransactionHistoryRound - (ValidateTransactionRound, NONE): SelectKeeperTransactionSubmissionBRound - (ValidateTransactionRound, NO_MAJORITY): ValidateTransactionRound - (ValidateTransactionRound, VALIDATE_TIMEOUT): CheckTransactionHistoryRound diff --git a/trader_backup/vendor/valory/skills/trader_abci/handlers.py b/trader_backup/vendor/valory/skills/trader_abci/handlers.py deleted file mode 100644 index 5f35925a0..000000000 --- a/trader_backup/vendor/valory/skills/trader_abci/handlers.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the handlers for the 'trader_abci' skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.decision_maker_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.decision_maker_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) - - -TraderHandler = ABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_backup/vendor/valory/skills/trader_abci/models.py b/trader_backup/vendor/valory/skills/trader_abci/models.py deleted file mode 100644 index 989c91347..000000000 --- a/trader_backup/vendor/valory/skills/trader_abci/models.py +++ /dev/null @@ -1,150 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Custom objects for the trader ABCI application.""" - -from typing import Dict, Type, Union, cast - -from packages.valory.skills.abstract_round_abci.models import ApiSpecs -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.check_stop_trading_abci.models import CheckStopTradingParams -from packages.valory.skills.decision_maker_abci.models import ( - AccuracyInfoFields as BaseAccuracyInfoFields, -) -from packages.valory.skills.decision_maker_abci.models import ( - AgentToolsSpecs as DecisionMakerAgentToolsSpecs, -) -from packages.valory.skills.decision_maker_abci.models import ( - BenchmarkingMode as BaseBenchmarkingMode, -) -from packages.valory.skills.decision_maker_abci.models import ( - ConditionalTokensSubgraph as DecisionMakerConditionalTokensSubgraph, -) -from packages.valory.skills.decision_maker_abci.models import DecisionMakerParams -from packages.valory.skills.decision_maker_abci.models import ( - RealitioSubgraph as DecisionMakerRealitioSubgraph, -) -from packages.valory.skills.decision_maker_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.decision_maker_abci.models import ( - TradesSubgraph as DecisionMakerTradesSubgraph, -) -from packages.valory.skills.decision_maker_abci.rounds import ( - Event as DecisionMakerEvent, -) -from packages.valory.skills.market_manager_abci.models import ( - NetworkSubgraph as MarketManagerNetworkSubgraph, -) -from packages.valory.skills.market_manager_abci.models import ( - OmenSubgraph as MarketManagerOmenSubgraph, -) -from packages.valory.skills.market_manager_abci.rounds import ( - Event as MarketManagerEvent, -) -from packages.valory.skills.mech_interact_abci.models import ( - MechResponseSpecs as BaseMechResponseSpecs, -) -from packages.valory.skills.reset_pause_abci.rounds import Event as ResetPauseEvent -from packages.valory.skills.termination_abci.models import TerminationParams -from packages.valory.skills.trader_abci.composition import TraderAbciApp -from packages.valory.skills.transaction_settlement_abci.rounds import Event as TSEvent -from packages.valory.skills.tx_settlement_multiplexer_abci.models import ( - TxSettlementMultiplexerParams, -) - - -EventType = Union[ - Type[MarketManagerEvent], - Type[DecisionMakerEvent], - Type[TSEvent], - Type[ResetPauseEvent], -] -EventToTimeoutMappingType = Dict[ - Union[MarketManagerEvent, DecisionMakerEvent, TSEvent, ResetPauseEvent], - float, -] - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool -OmenSubgraph = MarketManagerOmenSubgraph -NetworkSubgraph = MarketManagerNetworkSubgraph -MechResponseSpecs = BaseMechResponseSpecs -AgentToolsSpecs = DecisionMakerAgentToolsSpecs -TradesSubgraph = DecisionMakerTradesSubgraph -ConditionalTokensSubgraph = DecisionMakerConditionalTokensSubgraph -RealitioSubgraph = DecisionMakerRealitioSubgraph -BenchmarkingMode = BaseBenchmarkingMode -AccuracyInfoFields = BaseAccuracyInfoFields - - -MARGIN = 5 - - -class RandomnessApi(ApiSpecs): - """A model for randomness api specifications.""" - - -class TraderParams( - # also contains the `StakingParams`. Must be before `MechInteractParams` because of the mech's contract address - CheckStopTradingParams, - # also contains the `MechInteractParams` - DecisionMakerParams, - TerminationParams, - TxSettlementMultiplexerParams, -): - """A model to represent the trader params.""" - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = TraderAbciApp - - @property - def params(self) -> TraderParams: - """Get the parameters.""" - return cast(TraderParams, self.context.params) - - def setup(self) -> None: - """Set up.""" - super().setup() - - events = (MarketManagerEvent, DecisionMakerEvent, TSEvent, ResetPauseEvent) - round_timeout = self.params.round_timeout_seconds - round_timeout_overrides = { - cast(EventType, event).ROUND_TIMEOUT: round_timeout for event in events - } - reset_pause_timeout = self.params.reset_pause_duration + MARGIN - event_to_timeout_overrides: EventToTimeoutMappingType = { - **round_timeout_overrides, - TSEvent.RESET_TIMEOUT: round_timeout, - TSEvent.VALIDATE_TIMEOUT: self.params.validate_timeout, - TSEvent.FINALIZE_TIMEOUT: self.params.finalize_timeout, - TSEvent.CHECK_TIMEOUT: self.params.history_check_timeout, - DecisionMakerEvent.REDEEM_ROUND_TIMEOUT: self.params.redeem_round_timeout, - ResetPauseEvent.RESET_AND_PAUSE_TIMEOUT: reset_pause_timeout, - } - - for event, override in event_to_timeout_overrides.items(): - TraderAbciApp.event_to_timeout[event] = override diff --git a/trader_backup/vendor/valory/skills/trader_abci/skill.yaml b/trader_backup/vendor/valory/skills/trader_abci/skill.yaml deleted file mode 100644 index ebacf4aee..000000000 --- a/trader_backup/vendor/valory/skills/trader_abci/skill.yaml +++ /dev/null @@ -1,424 +0,0 @@ -name: trader_abci -author: valory -version: 0.1.0 -type: skill -description: This skill implements the trader skill for an AEA. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeiab4xgadptz4mhvno4p6xvkh7p4peg7iuhotabydriu74dmj6ljga - __init__.py: bafybeido7wa33h4dtleap57vzgyb4fsofk4vindsqcekyfo5i56i2rll2a - behaviours.py: bafybeigc6hszbu66ccajny5eh7thfgsrlr36je4mzziwp4mupgvtaeu6aa - composition.py: bafybeifxerfvssuhodqmtvkz6umlmrmdqjv5ptpszhnwlavzxaavdpdyly - dialogues.py: bafybeiebofyykseqp3fmif36cqmmyf3k7d2zbocpl6t6wnlpv4szghrxbm - fsm_specification.yaml: bafybeiab3boumxzlycla4yp7gyfrdncks64gnfdskoatwqsynjtru36kye - handlers.py: bafybeibbxybbi66em63ad33cllymypr3za3f5xvor3m2krhuxoyxnqjnxu - models.py: bafybeih2vkf4ln7n7ar27iemho7w7sdr4clmhbnhbcznmsri6mc2skkky4 - tests/__init__.py: bafybeiadatapyjh3e7ucg2ehz77oms3ihrbutwb2cs2tkjehy54utwvuyi - tests/tests_handlers.py: bafybeifxvd63qblqpsmyvj7k4dbqubab2pshao5zd2zs2srs7rt32zvciu -fingerprint_ignore_patterns: [] -connections: [] -contracts: [] -protocols: [] -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/registration_abci:0.1.0:bafybeibc7duasoaw5b4ene5oxfba2dmdzstsrws6ipi57ymgdtoxjadn54 -- valory/reset_pause_abci:0.1.0:bafybeigrdlxed3xlsnxtjhnsbl3cojruihxcqx4jxhgivkd5i2fkjncgba -- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae -- valory/termination_abci:0.1.0:bafybeib5l7jhew5ic6iq24dd23nidcoimzqkrk556gqywhoziatj33zvwm -- valory/market_manager_abci:0.1.0:bafybeibo63iiziwvqn6fmx36ungyg35z3chfv432kf6spuiszm6na22vdy -- valory/decision_maker_abci:0.1.0:bafybeigwqeptzd5pfvfuhau2m5gzicwimrb4weanykppgqqb3inureedeu -- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeielsstfertfjl2qkysp7kakqsjiimgurfglaajvccjihnumljg62e -- valory/staking_abci:0.1.0:bafybeicupccurmrg7qesivonlyt3nryarsmk5qf5yh6auno64wn45bybvq -- valory/check_stop_trading_abci:0.1.0:bafybeieduekpd4zbvjztyxyooppqnmjvup6jfp74uo6hhupvtvzzscdzkq -- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm -behaviours: - main: - args: {} - class_name: TraderConsensusBehaviour -handlers: - abci: - args: {} - class_name: TraderHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - finalize_timeout: 60.0 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - history_check_timeout: 1205 - init_fallback_gas: 0 - keeper_allowed_retries: 3 - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - multisend_batch_size: 1 - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - round_timeout_seconds: 350.0 - service_id: trader - service_registry_address: null - agent_registry_address: '0x0000000000000000000000000000000000000000' - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - sleep_time: 5 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - termination_sleep: 900 - tx_timeout: 10.0 - use_termination: false - termination_from_block: 0 - validate_timeout: 1205 - creator_per_subgraph: - omen_subgraph: [] - slot_count: 2 - opening_margin: 300 - languages: - - en_US - average_block_time: 5 - abt_error_mult: 5 - the_graph_error_message_key: message - the_graph_payment_required_error: payment required for subsequent requests for - this API key - mech_contract_address: '0x77af31de935740567cf4ff1986d04b2c964a786a' - mech_request_price: null - mech_chain_id: gnosis - mech_wrapped_native_token_address: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d' - sample_bets_closing_days: 10 - trading_strategy: strategy_name - use_fallback_strategy: true - bet_threshold: 100000000000000000 - ipfs_address: https://gateway.autonolas.tech/ipfs/ - tools_accuracy_hash: QmR8etyW3TPFadNtNrW54vfnFqmh8vBrMARWV76EmxCZyk - prompt_template: With the given question "@{question}" and the `yes` option - represented by `@{yes}` and the `no` option represented by `@{no}`, what are - the respective probabilities of `p_yes` and `p_no` occurring? - dust_threshold: 10000000000000 - conditional_tokens_address: '0xCeAfDD6bc0bEF976fdCd1112955828E00543c0Ce' - realitio_proxy_address: '0xAB16D643bA051C11962DA645f74632d3130c81E2' - realitio_address: '0x79e32aE03fb27B07C89c0c568F80287C01ca2E57' - event_filtering_batch_size: 5000 - reduce_factor: 0.25 - max_filtering_retries: 6 - minimum_batch_size: 500 - redeeming_batch_size: 5 - slippage: 0.01 - policy_epsilon: 0.1 - store_path: /data/ - policy_store_update_offset: 259200 - use_subgraph_for_redeeming: true - irrelevant_tools: - - openai-text-davinci-002 - - openai-text-davinci-003 - - openai-gpt-3.5-turbo - - openai-gpt-4 - - stabilityai-stable-diffusion-v1-5 - - stabilityai-stable-diffusion-xl-beta-v2-2-2 - - stabilityai-stable-diffusion-512-v2-1 - - stabilityai-stable-diffusion-768-v2-1 - staking_contract_address: '0x2Ef503950Be67a98746F484DA0bBAdA339DF3326' - staking_interaction_sleep_time: 5 - disable_trading: false - stop_trading_if_staking_kpi_met: true - agent_balance_threshold: 10000000000000000 - refill_check_interval: 10 - mech_activity_checker_contract: '0x0000000000000000000000000000000000000000' - redeem_round_timeout: 3600.0 - tool_punishment_multiplier: 1 - use_nevermined: true - mech_to_subscription_params: - - - base_url - - https://marketplace-api.gnosis.nevermined.app/api/v1/metadata/assets/ddo - - - did - - did:nv:0ea01d5de3b34e3792db825f2a5f5595c393c68b19fd5efdacd00fcc63a53483 - - - escrow_payment_condition_address - - '0x9dDC4F1Ea5b94C138A23b60EC48c0d01d172629a' - - - lock_payment_condition_address - - '0xDE85A368Ee6f374d236500d176814365370778dA' - - - transfer_nft_condition_address - - '0xbBa4A25262745a55f020D0a3E9a82c25bb6F4979' - - - token_address - - '0xa30DE8C6aC39B825192e5F1FADe0770332D279A8' - - - order_address - - '0xc7751eff5396a846e7bc83ac31d3cb7d37cb49e4' - - - nft_amount - - '100' - - - payment_token - - '0x0000000000000000000000000000000000000000' - - - order_address - - '0xc7751eff5396a846e7bc83ac31d3cb7d37cb49e4' - - - price - - '1000000000000000000' - contract_timeout: 300.0 - file_hash_to_strategies_json: - - - hash - - - strategy_name - strategies_kwargs: - - - bet_kelly_fraction - - 1.0 - - - floor_balance - - 500000000000000000 - - - bet_amount_per_threshold - - 0.0: 0 - 0.1: 0 - 0.2: 0 - 0.3: 0 - 0.4: 0 - 0.5: 0 - 0.6: 0 - 0.7: 0 - 0.8: 0 - 0.9: 0 - 1.0: 0 - service_endpoint: trader.staging.autonolas.tech/ - rpc_sleep_time: 10 - safe_voting_range: 600 - rebet_chance: 0.6 - mech_interaction_sleep_time: 10 - use_mech_marketplace: false - mech_marketplace_config: - mech_marketplace_address: '0x0000000000000000000000000000000000000000' - priority_mech_address: '0x0000000000000000000000000000000000000000' - priority_mech_staking_instance_address: '0x0000000000000000000000000000000000000000' - priority_mech_service_id: 0 - requester_staking_instance_address: '0x0000000000000000000000000000000000000000' - response_timeout: 300 - expected_mech_response_time: 300 - mech_invalid_response: Invalid Response - mech_consecutive_failures_threshold: 2 - tool_quarantine_duration: 18000 - class_name: TraderParams - benchmarking_mode: - args: - enabled: false - native_balance: 10000000000000000000 - collateral_balance: 10000000000000000000 - mech_cost: 10000000000000000 - pool_fee: 20000000000000000 - outcome_token_amounts: - - 11000000000000000000 - - 9000000000000000000 - outcome_token_marginal_prices: - - 0.4 - - 0.6 - sep: ',' - dataset_filename: benchmark_data.csv - question_field: question - question_id_field: question_id - answer_field: answer - p_yes_field_part: p_yes_ - p_no_field_part: p_no_ - confidence_field_part: confidence_ - part_prefix_mode: true - bet_amount_field: collateral_amount - results_filename: benchmarking_results.csv - randomness: benchmarking_randomness - nr_mech_calls: 60 - class_name: BenchmarkingMode - acc_info_fields: - args: - tool: tool - requests: total_requests - accuracy: tool_accuracy - sep: ',' - max: max - datetime_format: '%Y-%m-%d %H:%M:%S' - class_name: AccuracyInfoFields - network_subgraph: - args: - api_id: network - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:blocks - response_index: 0 - response_type: dict - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/stakewise/ethereum-gnosis - class_name: NetworkSubgraph - omen_subgraph: - args: - api_id: omen - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:fixedProductMarketMakers - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/protofire/omen-xdai - class_name: OmenSubgraph - randomness_api: - args: - api_id: cloudflare - headers: {} - method: GET - parameters: {} - response_key: null - response_type: dict - retries: 5 - url: https://drand.cloudflare.com/public/latest - class_name: RandomnessApi - mech_response: - args: - api_id: mech_response - headers: - Content-Type: application/json - method: GET - parameters: {} - response_key: result - response_type: str - retries: 5 - url: '' - class_name: MechResponseSpecs - agent_tools: - args: - api_id: agent_tools - headers: - Content-Type: application/json - method: GET - parameters: {} - response_key: tools - response_type: list - retries: 5 - url: '' - class_name: AgentToolsSpecs - trades_subgraph: - args: - api_id: trades - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:fpmmTrades - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/protofire/omen-xdai - class_name: TradesSubgraph - conditional_tokens_subgraph: - args: - api_id: conditional_tokens - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:user:userPositions - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/gnosis/conditional-tokens-gc - class_name: ConditionalTokensSubgraph - realitio_subgraph: - args: - api_id: realitio - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:answers - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/realityeth/realityeth-gnosis - class_name: RealitioSubgraph - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: {} -is_abstract: false diff --git a/trader_backup/vendor/valory/skills/trader_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/trader_abci/tests/__init__.py deleted file mode 100644 index 18184313e..000000000 --- a/trader_backup/vendor/valory/skills/trader_abci/tests/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the tests for trader abci.""" diff --git a/trader_backup/vendor/valory/skills/trader_abci/tests/tests_handlers.py b/trader_backup/vendor/valory/skills/trader_abci/tests/tests_handlers.py deleted file mode 100644 index 9b62aae4c..000000000 --- a/trader_backup/vendor/valory/skills/trader_abci/tests/tests_handlers.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the tests for the handlers for the trader abci.""" - -from unittest.mock import MagicMock - -import pytest -from aea.configurations.data_types import PublicId -from aea.skills.base import Handler - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.decision_maker_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.decision_maker_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.trader_abci.handlers import ( - ContractApiHandler, - HttpHandler, - IpfsHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, - TraderHandler, -) - - -@pytest.mark.parametrize( - "handler, base_handler", - [ - (TraderHandler, ABCIRoundHandler), - (HttpHandler, BaseHttpHandler), - (SigningHandler, BaseSigningHandler), - (LedgerApiHandler, BaseLedgerApiHandler), - (ContractApiHandler, BaseContractApiHandler), - (TendermintHandler, BaseTendermintHandler), - (IpfsHandler, BaseIpfsHandler), - ], -) -def test_handler(handler: Handler, base_handler: Handler) -> None: - """Test that the 'handlers.py' of the TraderAbci can be imported.""" - handler = handler( - name="dummy_handler", - skill_context=MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")), - ) - - assert isinstance(handler, base_handler) diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/README.md b/trader_backup/vendor/valory/skills/transaction_settlement_abci/README.md deleted file mode 100644 index 29124a9ec..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Transaction settlement abci - -## Description - -This module contains the ABCI transaction settlement skill for an AEA. - -## Behaviours - -* `BaseResetBehaviour` - - Reset state. - -* `FinalizeBehaviour` - - Finalize state. - -* `RandomnessTransactionSubmissionBehaviour` - - Retrieve randomness. - -* `ResetAndPauseBehaviour` - - Reset and pause state. - -* `ResetBehaviour` - - Reset state. - -* `SelectKeeperTransactionSubmissionBehaviourA` - - Select the keeper agent. - -* `SelectKeeperTransactionSubmissionBehaviourB` - - Select the keeper agent. - -* `SignatureBehaviour` - - Signature state. - -* `TransactionSettlementBaseState` - - Base state behaviour for the common apps' skill. - -* `ValidateTransactionBehaviour` - - Validate a transaction. - - -## Handlers - -No Handlers (the skill is purely behavioural). - diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/__init__.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/__init__.py deleted file mode 100644 index 1df75f1f6..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the ABCI transaction settlement skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/transaction_settlement_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/behaviours.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/behaviours.py deleted file mode 100644 index d3a7ca2a7..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/behaviours.py +++ /dev/null @@ -1,984 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the behaviours for the 'abci' skill.""" - -import binascii -import pprint -import re -from abc import ABC -from collections import deque -from typing import ( - Any, - Deque, - Dict, - Generator, - Iterator, - List, - Optional, - Set, - Tuple, - Type, - Union, - cast, -) - -from aea.protocols.base import Message -from web3.types import Nonce, TxData, Wei - -from packages.valory.contracts.gnosis_safe.contract import GnosisSafeContract -from packages.valory.protocols.contract_api.message import ContractApiMessage -from packages.valory.skills.abstract_round_abci.behaviour_utils import RPCResponseStatus -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.abstract_round_abci.common import ( - RandomnessBehaviour, - SelectKeeperBehaviour, -) -from packages.valory.skills.abstract_round_abci.utils import VerifyDrand -from packages.valory.skills.transaction_settlement_abci.models import TransactionParams -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - VerificationStatus, - skill_input_hex_to_payload, - tx_hist_payload_to_hex, -) -from packages.valory.skills.transaction_settlement_abci.payloads import ( - CheckTransactionHistoryPayload, - FinalizationTxPayload, - RandomnessPayload, - ResetPayload, - SelectKeeperPayload, - SignaturePayload, - SynchronizeLateMessagesPayload, - ValidatePayload, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - CheckLateTxHashesRound, - CheckTransactionHistoryRound, - CollectSignatureRound, - FinalizationRound, - RandomnessTransactionSubmissionRound, - ResetRound, - SelectKeeperTransactionSubmissionARound, - SelectKeeperTransactionSubmissionBAfterTimeoutRound, - SelectKeeperTransactionSubmissionBRound, - SynchronizeLateMessagesRound, - SynchronizedData, - TransactionSubmissionAbciApp, - ValidateTransactionRound, -) - - -TxDataType = Dict[str, Union[VerificationStatus, Deque[str], int, Set[str], str]] - -drand_check = VerifyDrand() - -REVERT_CODE_RE = r"\s(GS\d{3})[^\d]" - -# This mapping was copied from: -# https://github.com/safe-global/safe-contracts/blob/ce5cbd256bf7a8a34538c7e5f1f2366a9d685f34/docs/error_codes.md -REVERT_CODES_TO_REASONS: Dict[str, str] = { - "GS000": "Could not finish initialization", - "GS001": "Threshold needs to be defined", - "GS010": "Not enough gas to execute Safe transaction", - "GS011": "Could not pay gas costs with ether", - "GS012": "Could not pay gas costs with token", - "GS013": "Safe transaction failed when gasPrice and safeTxGas were 0", - "GS020": "Signatures data too short", - "GS021": "Invalid contract signature location: inside static part", - "GS022": "Invalid contract signature location: length not present", - "GS023": "Invalid contract signature location: data not complete", - "GS024": "Invalid contract signature provided", - "GS025": "Hash has not been approved", - "GS026": "Invalid owner provided", - "GS030": "Only owners can approve a hash", - "GS031": "Method can only be called from this contract", - "GS100": "Modules have already been initialized", - "GS101": "Invalid module address provided", - "GS102": "Module has already been added", - "GS103": "Invalid prevModule, module pair provided", - "GS104": "Method can only be called from an enabled module", - "GS200": "Owners have already been setup", - "GS201": "Threshold cannot exceed owner count", - "GS202": "Threshold needs to be greater than 0", - "GS203": "Invalid owner address provided", - "GS204": "Address is already an owner", - "GS205": "Invalid prevOwner, owner pair provided", - "GS300": "Guard does not implement IERC165", -} - - -class TransactionSettlementBaseBehaviour(BaseBehaviour, ABC): - """Base behaviour for the common apps' skill.""" - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return cast(SynchronizedData, super().synchronized_data) - - @property - def params(self) -> TransactionParams: - """Return the params.""" - return cast(TransactionParams, super().params) - - @staticmethod - def serialized_keepers(keepers: Deque[str], keeper_retries: int) -> str: - """Get the keepers serialized.""" - if len(keepers) == 0: - return "" - keepers_ = "".join(keepers) - keeper_retries_ = keeper_retries.to_bytes(32, "big").hex() - concatenated = keeper_retries_ + keepers_ - - return concatenated - - def get_gas_price_params(self, tx_body: dict) -> List[str]: - """Guess the gas strategy from the transaction params""" - strategy_to_params: Dict[str, List[str]] = { - "eip": ["maxPriorityFeePerGas", "maxFeePerGas"], - "gas_station": ["gasPrice"], - } - - for strategy, params in strategy_to_params.items(): - if all(param in tx_body for param in params): - self.context.logger.info(f"Detected gas strategy: {strategy}") - return params - - return [] - - def _get_tx_data( - self, - message: ContractApiMessage, - use_flashbots: bool, - manual_gas_limit: int = 0, - raise_on_failed_simulation: bool = False, - chain_id: Optional[str] = None, - ) -> Generator[None, None, TxDataType]: - """Get the transaction data from a `ContractApiMessage`.""" - tx_data: TxDataType = { - "status": VerificationStatus.PENDING, - "keepers": self.synchronized_data.keepers, - "keeper_retries": self.synchronized_data.keeper_retries, - "blacklisted_keepers": self.synchronized_data.blacklisted_keepers, - "tx_digest": "", - } - - # Check for errors in the transaction preparation - if ( - message.performative == ContractApiMessage.Performative.ERROR - and message.message is not None - ): - if self._safe_nonce_reused(message.message): - tx_data["status"] = VerificationStatus.VERIFIED - else: - tx_data["status"] = VerificationStatus.ERROR - self.context.logger.warning(self._parse_revert_reason(message)) - return tx_data - - # Check that we have a RAW_TRANSACTION response - if message.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.context.logger.warning( - f"get_raw_safe_transaction unsuccessful! Received: {message}" - ) - return tx_data - - if manual_gas_limit > 0: - message.raw_transaction.body["gas"] = manual_gas_limit - - # Send transaction - tx_digest, rpc_status = yield from self.send_raw_transaction( - message.raw_transaction, - use_flashbots, - raise_on_failed_simulation=raise_on_failed_simulation, - chain_id=chain_id, - ) - - # Handle transaction results - if rpc_status == RPCResponseStatus.ALREADY_KNOWN: - self.context.logger.warning( - "send_raw_transaction unsuccessful! Transaction is already in the mempool! Will attempt to verify it." - ) - - if rpc_status == RPCResponseStatus.INCORRECT_NONCE: - tx_data["status"] = VerificationStatus.ERROR - self.context.logger.warning( - "send_raw_transaction unsuccessful! Incorrect nonce." - ) - - if rpc_status == RPCResponseStatus.INSUFFICIENT_FUNDS: - # blacklist self. - tx_data["status"] = VerificationStatus.INSUFFICIENT_FUNDS - blacklisted = cast(Deque[str], tx_data["keepers"]).popleft() - tx_data["keeper_retries"] = 1 - cast(Set[str], tx_data["blacklisted_keepers"]).add(blacklisted) - self.context.logger.warning( - "send_raw_transaction unsuccessful! Insufficient funds." - ) - - if rpc_status not in { - RPCResponseStatus.SUCCESS, - RPCResponseStatus.ALREADY_KNOWN, - }: - self.context.logger.warning( - f"send_raw_transaction unsuccessful! Received: {rpc_status}" - ) - return tx_data - - tx_data["tx_digest"] = cast(str, tx_digest) - - nonce = Nonce(int(cast(str, message.raw_transaction.body["nonce"]))) - fallback_gas = message.raw_transaction.body["gas"] - - # Get the gas params - gas_price_params = self.get_gas_price_params(message.raw_transaction.body) - - gas_price = { - gas_price_param: Wei( - int( - cast( - str, - message.raw_transaction.body[gas_price_param], - ) - ) - ) - for gas_price_param in gas_price_params - } - - # Set hash, nonce and tip. - self.params.mutable_params.tx_hash = cast(str, tx_data["tx_digest"]) - if nonce == self.params.mutable_params.nonce: - self.context.logger.info( - "Attempting to replace transaction " - f"with old gas price parameters {self.params.mutable_params.gas_price}, using new gas price parameters {gas_price}" - ) - else: - self.context.logger.info( - f"Sent transaction for mining with gas parameters {gas_price}" - ) - self.params.mutable_params.nonce = nonce - self.params.mutable_params.gas_price = gas_price - self.params.mutable_params.fallback_gas = fallback_gas - - return tx_data - - def _verify_tx(self, tx_hash: str) -> Generator[None, None, ContractApiMessage]: - """Verify a transaction.""" - tx_params = skill_input_hex_to_payload( - self.synchronized_data.most_voted_tx_hash - ) - chain_id = self.synchronized_data.get_chain_id(self.params.default_chain_id) - contract_api_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="verify_tx", - tx_hash=tx_hash, - owners=tuple(self.synchronized_data.participants), - to_address=tx_params["to_address"], - value=tx_params["ether_value"], - data=tx_params["data"], - safe_tx_gas=tx_params["safe_tx_gas"], - signatures_by_owner={ - key: payload.signature - for key, payload in self.synchronized_data.participant_to_signature.items() - }, - operation=tx_params["operation"], - chain_id=chain_id, - ) - return contract_api_msg - - @staticmethod - def _safe_nonce_reused(revert_reason: str) -> bool: - """Check for GS026.""" - return "GS026" in revert_reason - - @staticmethod - def _parse_revert_reason(message: ContractApiMessage) -> str: - """Parse a revert reason and log a relevant message.""" - default_message = f"get_raw_safe_transaction unsuccessful! Received: {message}" - - revert_reason = message.message - if not revert_reason: - return default_message - - revert_match = re.findall(REVERT_CODE_RE, revert_reason) - if revert_match is None or len(revert_match) != 1: - return default_message - - revert_code = revert_match.pop() - revert_explanation = REVERT_CODES_TO_REASONS.get(revert_code, None) - if revert_explanation is None: - return default_message - - return f"Received a {revert_code} revert error: {revert_explanation}." - - def _get_safe_nonce(self) -> Generator[None, None, ContractApiMessage]: - """Get the safe nonce.""" - chain_id = self.synchronized_data.get_chain_id(self.params.default_chain_id) - contract_api_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_safe_nonce", - chain_id=chain_id, - ) - return contract_api_msg - - -class RandomnessTransactionSubmissionBehaviour(RandomnessBehaviour): - """Retrieve randomness.""" - - matching_round = RandomnessTransactionSubmissionRound - payload_class = RandomnessPayload - - -class SelectKeeperTransactionSubmissionBehaviourA( # pylint: disable=too-many-ancestors - SelectKeeperBehaviour, TransactionSettlementBaseBehaviour -): - """Select the keeper agent.""" - - matching_round = SelectKeeperTransactionSubmissionARound - payload_class = SelectKeeperPayload - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - keepers = deque((self._select_keeper(),)) - payload = self.payload_class( - self.context.agent_address, self.serialized_keepers(keepers, 1) - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class SelectKeeperTransactionSubmissionBehaviourB( # pylint: disable=too-many-ancestors - SelectKeeperTransactionSubmissionBehaviourA -): - """Select the keeper b agent.""" - - matching_round = SelectKeeperTransactionSubmissionBRound - - def async_act(self) -> Generator: - """ - Do the action. - - Steps: - - If we have not selected enough keepers for the period, - select a keeper randomly and add it to the keepers' queue, with top priority. - - Otherwise, cycle through the keepers' subset, using the following logic: - A `PENDING` verification status means that we have not received any errors, - therefore, all we know is that the tx has not been mined yet due to low pricing. - Consequently, we are going to retry with the same keeper in order to replace the transaction. - However, if we receive a status other than `PENDING`, we need to cycle through the keepers' subset. - Moreover, if the current keeper has reached the allowed number of retries, then we cycle anyway. - - Send the transaction with the keepers and wait for it to be mined. - - Wait until ABCI application transitions to the next round. - - Go to the next behaviour (set done event). - """ - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - keepers = self.synchronized_data.keepers - keeper_retries = 1 - - if self.synchronized_data.keepers_threshold_exceeded: - keepers.rotate(-1) - self.context.logger.info(f"Rotated keepers to: {keepers}.") - elif ( - self.synchronized_data.keeper_retries - != self.params.keeper_allowed_retries - and self.synchronized_data.final_verification_status - == VerificationStatus.PENDING - ): - keeper_retries += self.synchronized_data.keeper_retries - self.context.logger.info( - f"Kept keepers and incremented retries: {keepers}." - ) - else: - keepers.appendleft(self._select_keeper()) - - payload = self.payload_class( - self.context.agent_address, - self.serialized_keepers(keepers, keeper_retries), - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class SelectKeeperTransactionSubmissionBehaviourBAfterTimeout( # pylint: disable=too-many-ancestors - SelectKeeperTransactionSubmissionBehaviourB -): - """Select the keeper b agent after a timeout.""" - - matching_round = SelectKeeperTransactionSubmissionBAfterTimeoutRound - - -class ValidateTransactionBehaviour(TransactionSettlementBaseBehaviour): - """Validate a transaction.""" - - matching_round = ValidateTransactionRound - - def async_act(self) -> Generator: - """ - Do the action. - - Steps: - - Validate that the transaction hash provided by the keeper points to a - valid transaction. - - Send the transaction with the validation result and wait for it to be - mined. - - Wait until ABCI application transitions to the next round. - - Go to the next behaviour (set done event). - """ - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - is_correct = yield from self.has_transaction_been_sent() - if is_correct: - self.context.logger.info( - f"Finalized with transaction hash: {self.synchronized_data.to_be_validated_tx_hash}" - ) - payload = ValidatePayload(self.context.agent_address, is_correct) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - def has_transaction_been_sent(self) -> Generator[None, None, Optional[bool]]: - """Transaction verification.""" - - to_be_validated_tx_hash = self.synchronized_data.to_be_validated_tx_hash - - response = yield from self.get_transaction_receipt( - to_be_validated_tx_hash, - self.params.retry_timeout, - self.params.retry_attempts, - chain_id=self.synchronized_data.get_chain_id(self.params.default_chain_id), - ) - if response is None: # pragma: nocover - self.context.logger.error( - f"tx {to_be_validated_tx_hash} receipt check timed out!" - ) - return None - - contract_api_msg = yield from self._verify_tx(to_be_validated_tx_hash) - if ( - contract_api_msg.performative != ContractApiMessage.Performative.STATE - ): # pragma: nocover - self.context.logger.error( - f"verify_tx unsuccessful! Received: {contract_api_msg}" - ) - return False - - verified = cast(bool, contract_api_msg.state.body["verified"]) - verified_log = ( - f"Verified result: {verified}" - if verified - else f"Verified result: {verified}, all: {contract_api_msg.state.body}" - ) - self.context.logger.info(verified_log) - return verified - - -class CheckTransactionHistoryBehaviour(TransactionSettlementBaseBehaviour): - """Check the transaction history.""" - - matching_round = CheckTransactionHistoryRound - check_expected_to_be_verified = "The next tx check" - - @property - def history(self) -> List[str]: - """Get the history of hashes.""" - return self.synchronized_data.tx_hashes_history - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - verification_status, tx_hash = yield from self._check_tx_history() - if verification_status == VerificationStatus.VERIFIED: - msg = f"A previous transaction {tx_hash} has already been verified " - msg += ( - f"for {self.synchronized_data.to_be_validated_tx_hash}." - if self.synchronized_data.tx_hashes_history - else "and was synced after the finalization round timed out." - ) - self.context.logger.info(msg) - elif verification_status == VerificationStatus.NOT_VERIFIED: - self.context.logger.info( - f"No previous transaction has been verified for " - f"{self.synchronized_data.to_be_validated_tx_hash}." - ) - - verified_res = tx_hist_payload_to_hex(verification_status, tx_hash) - payload = CheckTransactionHistoryPayload( - self.context.agent_address, verified_res - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - def _check_tx_history( # pylint: disable=too-many-return-statements - self, - ) -> Generator[None, None, Tuple[VerificationStatus, Optional[str]]]: - """Check the transaction history.""" - if not self.history: - self.context.logger.error( - "An unexpected error occurred! The synchronized data do not contain any transaction hashes, " - f"but entered the `{self.behaviour_id}` behaviour." - ) - return VerificationStatus.ERROR, None - - contract_api_msg = yield from self._get_safe_nonce() - if ( - contract_api_msg.performative != ContractApiMessage.Performative.STATE - ): # pragma: nocover - self.context.logger.error( - f"get_safe_nonce unsuccessful! Received: {contract_api_msg}" - ) - return VerificationStatus.ERROR, None - - safe_nonce = cast(int, contract_api_msg.state.body["safe_nonce"]) - if safe_nonce == self.params.mutable_params.nonce: - # if we have reached this state it means that the transaction didn't go through in the expected time - # as such we assume it is not verified - self.context.logger.info( - f"Safe nonce is the same as the nonce used in the transaction: {safe_nonce}. " - f"No transaction has gone through yet." - ) - return VerificationStatus.NOT_VERIFIED, None - - self.context.logger.info( - f"A transaction with nonce {safe_nonce} has already been sent. " - ) - self.context.logger.info( - f"Starting check for the transaction history: {self.history}. " - ) - was_nonce_reused = False - for tx_hash in self.history[::-1]: - self.context.logger.info(f"Checking hash {tx_hash}...") - contract_api_msg = yield from self._verify_tx(tx_hash) - - if ( - contract_api_msg.performative != ContractApiMessage.Performative.STATE - ): # pragma: nocover - self.context.logger.error( - f"verify_tx unsuccessful for {tx_hash}! Received: {contract_api_msg}" - ) - return VerificationStatus.ERROR, tx_hash - - verified = cast(bool, contract_api_msg.state.body["verified"]) - verified_log = f"Verified result for {tx_hash}: {verified}" - - if verified: - self.context.logger.info(verified_log) - return VerificationStatus.VERIFIED, tx_hash - - self.context.logger.info( - verified_log + f", all: {contract_api_msg.state.body}" - ) - - status = cast(int, contract_api_msg.state.body["status"]) - if status == -1: - self.context.logger.info(f"Tx hash {tx_hash} has no receipt!") - # this loop might take a long time - # we do not want to starve the rest of the behaviour - # we yield which freezes this loop here until the - # AbstractRoundBehaviour it belongs to, sends a tick to it - yield - continue - - tx_data = cast(TxData, contract_api_msg.state.body["transaction"]) - revert_reason = yield from self._get_revert_reason(tx_data) - - if revert_reason is not None: - if self._safe_nonce_reused(revert_reason): - self.context.logger.info( - f"The safe's nonce has been reused for {tx_hash}. " - f"{self.check_expected_to_be_verified} is expected to be verified!" - ) - was_nonce_reused = True - # this loop might take a long time - # we do not want to starve the rest of the behaviour - # we yield which freezes this loop here until the - # AbstractRoundBehaviour it belongs to, sends a tick to it - yield - continue - - self.context.logger.warning( - f"Payload is invalid for {tx_hash}! Cannot continue. Received: {revert_reason}" - ) - - return VerificationStatus.INVALID_PAYLOAD, tx_hash - - if was_nonce_reused: - self.context.logger.info( - f"Safe nonce {safe_nonce} was used, but no valid transaction was found. " - f"We cannot resend the transaction with the same nonce." - ) - return VerificationStatus.BAD_SAFE_NONCE, None - - return VerificationStatus.NOT_VERIFIED, None - - def _get_revert_reason(self, tx: TxData) -> Generator[None, None, Optional[str]]: - """Get the revert reason of the given transaction.""" - chain_id = self.synchronized_data.get_chain_id(self.params.default_chain_id) - contract_api_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="revert_reason", - tx=tx, - chain_id=chain_id, - ) - - if ( - contract_api_msg.performative != ContractApiMessage.Performative.STATE - ): # pragma: nocover - self.context.logger.error( - f"An unexpected error occurred while checking {tx['hash'].hex()}: {contract_api_msg}" - ) - return None - - return cast(str, contract_api_msg.state.body["revert_reason"]) - - -class CheckLateTxHashesBehaviour( # pylint: disable=too-many-ancestors - CheckTransactionHistoryBehaviour -): - """Check the late-arriving transaction hashes.""" - - matching_round = CheckLateTxHashesRound - check_expected_to_be_verified = "One of the next tx checks" - - @property - def history(self) -> List[str]: - """Get the history of hashes.""" - return [ - hash_ - for hashes in self.synchronized_data.late_arriving_tx_hashes.values() - for hash_ in hashes - ] - - -class SynchronizeLateMessagesBehaviour(TransactionSettlementBaseBehaviour): - """Synchronize late-arriving messages behaviour.""" - - matching_round = SynchronizeLateMessagesRound - - def __init__(self, **kwargs: Any): - """Initialize a `SynchronizeLateMessagesBehaviour`""" - super().__init__(**kwargs) - # if we timed out during finalization, but we managed to receive a tx hash, - # then we sync it here by initializing the `_tx_hashes` with the unsynced hash. - self._tx_hashes: str = self.params.mutable_params.tx_hash - self._messages_iterator: Iterator[ContractApiMessage] = iter( - self.params.mutable_params.late_messages - ) - self.use_flashbots = False - - def setup(self) -> None: - """Setup the `SynchronizeLateMessagesBehaviour`.""" - tx_params = skill_input_hex_to_payload( - self.synchronized_data.most_voted_tx_hash - ) - self.use_flashbots = tx_params["use_flashbots"] - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - current_message = next(self._messages_iterator, None) - if current_message is not None: - chain_id = self.synchronized_data.get_chain_id( - self.params.default_chain_id - ) - tx_data = yield from self._get_tx_data( - current_message, - self.use_flashbots, - chain_id=chain_id, - ) - self.context.logger.info( - f"Found a late arriving message {current_message}. Result data: {tx_data}" - ) - # here, we concatenate the tx_hashes of all the late-arriving messages. Later, we will parse them. - self._tx_hashes += cast(str, tx_data["tx_digest"]) - return - - payload = SynchronizeLateMessagesPayload( - self.context.agent_address, self._tx_hashes - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - # reset the local parameters if we were able to send them. - self.params.mutable_params.tx_hash = "" - self.params.mutable_params.late_messages = [] - yield from self.wait_until_round_end() - - self.set_done() - - -class SignatureBehaviour(TransactionSettlementBaseBehaviour): - """Signature behaviour.""" - - matching_round = CollectSignatureRound - - def async_act(self) -> Generator: - """ - Do the action. - - Steps: - - Request the signature of the transaction hash. - - Send the signature as a transaction and wait for it to be mined. - - Wait until ABCI application transitions to the next round. - - Go to the next behaviour (set done event). - """ - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - self.context.logger.info( - f"Agreement reached on tx data: {self.synchronized_data.most_voted_tx_hash}" - ) - signature_hex = yield from self._get_safe_tx_signature() - payload = SignaturePayload(self.context.agent_address, signature_hex) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - def _get_safe_tx_signature(self) -> Generator[None, None, str]: - """Get signature of safe transaction hash.""" - tx_params = skill_input_hex_to_payload( - self.synchronized_data.most_voted_tx_hash - ) - # is_deprecated_mode=True because we want to call Account.signHash, - # which is the same used by gnosis-py - safe_tx_hash_bytes = binascii.unhexlify(tx_params["safe_tx_hash"]) - signature_hex = yield from self.get_signature( - safe_tx_hash_bytes, is_deprecated_mode=True - ) - # remove the leading '0x' - signature_hex = signature_hex[2:] - self.context.logger.info(f"Signature: {signature_hex}") - return signature_hex - - -class FinalizeBehaviour(TransactionSettlementBaseBehaviour): - """Finalize behaviour.""" - - matching_round = FinalizationRound - - def _i_am_not_sending(self) -> bool: - """Indicates if the current agent is the sender or not.""" - return ( - self.context.agent_address - != self.synchronized_data.most_voted_keeper_address - ) - - def async_act(self) -> Generator[None, None, None]: - """ - Do the action. - - Steps: - - If the agent is the keeper, then prepare the transaction and send it. - - Otherwise, wait until the next round. - - If a timeout is hit, set exit A event, otherwise set done event. - """ - if self._i_am_not_sending(): - yield from self._not_sender_act() - else: - yield from self._sender_act() - - def _not_sender_act(self) -> Generator: - """Do the non-sender action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - self.context.logger.info( - f"Waiting for the keeper to do its keeping: {self.synchronized_data.most_voted_keeper_address}" - ) - yield from self.wait_until_round_end() - self.set_done() - - def _sender_act(self) -> Generator[None, None, None]: - """Do the sender action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - self.context.logger.info( - "I am the designated sender, attempting to send the safe transaction..." - ) - tx_data = yield from self._send_safe_transaction() - if ( - tx_data["tx_digest"] == "" - and tx_data["status"] == VerificationStatus.PENDING - ) or tx_data["status"] == VerificationStatus.ERROR: - self.context.logger.error( - "Did not succeed with finalising the transaction!" - ) - elif tx_data["status"] == VerificationStatus.VERIFIED: - self.context.logger.error( - "Trying to finalize a transaction which has been verified already!" - ) - else: # pragma: no cover - self.context.logger.info( - f"Finalization tx digest: {cast(str, tx_data['tx_digest'])}" - ) - self.context.logger.debug( - f"Signatures: {pprint.pformat(self.synchronized_data.participant_to_signature)}" - ) - - tx_hashes_history = self.synchronized_data.tx_hashes_history - - if tx_data["tx_digest"] != "": - tx_hashes_history.append(cast(str, tx_data["tx_digest"])) - - tx_data_serialized = { - "status_value": cast(VerificationStatus, tx_data["status"]).value, - "serialized_keepers": self.serialized_keepers( - cast(Deque[str], tx_data["keepers"]), - cast(int, tx_data["keeper_retries"]), - ), - "blacklisted_keepers": "".join( - cast(Set[str], tx_data["blacklisted_keepers"]) - ), - "tx_hashes_history": "".join(tx_hashes_history), - "received_hash": bool(tx_data["tx_digest"]), - } - - payload = FinalizationTxPayload( - self.context.agent_address, - cast(Dict[str, Union[str, int, bool]], tx_data_serialized), - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - # reset the local tx hash parameter if we were able to send it - self.params.mutable_params.tx_hash = "" - yield from self.wait_until_round_end() - - self.set_done() - - def _send_safe_transaction( - self, - ) -> Generator[None, None, TxDataType]: - """Send a Safe transaction using the participants' signatures.""" - tx_params = skill_input_hex_to_payload( - self.synchronized_data.most_voted_tx_hash - ) - chain_id = self.synchronized_data.get_chain_id(self.params.default_chain_id) - contract_api_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_raw_safe_transaction", - sender_address=self.context.agent_address, - owners=tuple(self.synchronized_data.participants), - to_address=tx_params["to_address"], - value=tx_params["ether_value"], - data=tx_params["data"], - safe_tx_gas=tx_params["safe_tx_gas"], - signatures_by_owner={ - key: payload.signature - for key, payload in self.synchronized_data.participant_to_signature.items() - }, - nonce=self.params.mutable_params.nonce, - old_price=self.params.mutable_params.gas_price, - operation=tx_params["operation"], - fallback_gas=self.params.mutable_params.fallback_gas, - gas_price=self.params.gas_params.gas_price, - max_fee_per_gas=self.params.gas_params.max_fee_per_gas, - max_priority_fee_per_gas=self.params.gas_params.max_priority_fee_per_gas, - chain_id=chain_id, - ) - - tx_data = yield from self._get_tx_data( - contract_api_msg, - tx_params["use_flashbots"], - tx_params["gas_limit"], - tx_params["raise_on_failed_simulation"], - chain_id, - ) - return tx_data - - def handle_late_messages(self, behaviour_id: str, message: Message) -> None: - """Store a potentially late-arriving message locally. - - :param behaviour_id: the id of the behaviour in which the message belongs to. - :param message: the late arriving message to handle. - """ - if ( - isinstance(message, ContractApiMessage) - and behaviour_id == self.behaviour_id - ): - self.context.logger.info(f"Late message arrived: {message}") - self.params.mutable_params.late_messages.append(message) - else: - super().handle_late_messages(behaviour_id, message) - - -class ResetBehaviour(TransactionSettlementBaseBehaviour): - """Reset behaviour.""" - - matching_round = ResetRound - - def async_act(self) -> Generator: - """Do the action.""" - self.context.logger.info( - f"Period {self.synchronized_data.period_count} was not finished. Resetting!" - ) - payload = ResetPayload( - self.context.agent_address, self.synchronized_data.period_count - ) - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - self.set_done() - - -class TransactionSettlementRoundBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the basic transaction settlement.""" - - initial_behaviour_cls = RandomnessTransactionSubmissionBehaviour - abci_app_cls = TransactionSubmissionAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - RandomnessTransactionSubmissionBehaviour, # type: ignore - SelectKeeperTransactionSubmissionBehaviourA, # type: ignore - SelectKeeperTransactionSubmissionBehaviourB, # type: ignore - SelectKeeperTransactionSubmissionBehaviourBAfterTimeout, # type: ignore - ValidateTransactionBehaviour, # type: ignore - CheckTransactionHistoryBehaviour, # type: ignore - SignatureBehaviour, # type: ignore - FinalizeBehaviour, # type: ignore - SynchronizeLateMessagesBehaviour, # type: ignore - CheckLateTxHashesBehaviour, # type: ignore - ResetBehaviour, # type: ignore - } diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/dialogues.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/dialogues.py deleted file mode 100644 index e244bde0b..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/dialogues.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/fsm_specification.yaml b/trader_backup/vendor/valory/skills/transaction_settlement_abci/fsm_specification.yaml deleted file mode 100644 index 70b6e1f22..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/fsm_specification.yaml +++ /dev/null @@ -1,88 +0,0 @@ -alphabet_in: -- CHECK_HISTORY -- CHECK_LATE_ARRIVING_MESSAGE -- CHECK_TIMEOUT -- DONE -- FINALIZATION_FAILED -- FINALIZE_TIMEOUT -- INCORRECT_SERIALIZATION -- INSUFFICIENT_FUNDS -- NEGATIVE -- NONE -- NO_MAJORITY -- RESET_TIMEOUT -- ROUND_TIMEOUT -- SUSPICIOUS_ACTIVITY -- VALIDATE_TIMEOUT -default_start_state: RandomnessTransactionSubmissionRound -final_states: -- FailedRound -- FinishedTransactionSubmissionRound -label: TransactionSubmissionAbciApp -start_states: -- RandomnessTransactionSubmissionRound -states: -- CheckLateTxHashesRound -- CheckTransactionHistoryRound -- CollectSignatureRound -- FailedRound -- FinalizationRound -- FinishedTransactionSubmissionRound -- RandomnessTransactionSubmissionRound -- ResetRound -- SelectKeeperTransactionSubmissionARound -- SelectKeeperTransactionSubmissionBAfterTimeoutRound -- SelectKeeperTransactionSubmissionBRound -- SynchronizeLateMessagesRound -- ValidateTransactionRound -transition_func: - (CheckLateTxHashesRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (CheckLateTxHashesRound, CHECK_TIMEOUT): CheckLateTxHashesRound - (CheckLateTxHashesRound, DONE): FinishedTransactionSubmissionRound - (CheckLateTxHashesRound, NEGATIVE): FailedRound - (CheckLateTxHashesRound, NONE): FailedRound - (CheckLateTxHashesRound, NO_MAJORITY): FailedRound - (CheckTransactionHistoryRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (CheckTransactionHistoryRound, CHECK_TIMEOUT): CheckTransactionHistoryRound - (CheckTransactionHistoryRound, DONE): FinishedTransactionSubmissionRound - (CheckTransactionHistoryRound, NEGATIVE): SelectKeeperTransactionSubmissionBRound - (CheckTransactionHistoryRound, NONE): FailedRound - (CheckTransactionHistoryRound, NO_MAJORITY): CheckTransactionHistoryRound - (CollectSignatureRound, DONE): FinalizationRound - (CollectSignatureRound, NO_MAJORITY): ResetRound - (CollectSignatureRound, ROUND_TIMEOUT): CollectSignatureRound - (FinalizationRound, CHECK_HISTORY): CheckTransactionHistoryRound - (FinalizationRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (FinalizationRound, DONE): ValidateTransactionRound - (FinalizationRound, FINALIZATION_FAILED): SelectKeeperTransactionSubmissionBRound - (FinalizationRound, FINALIZE_TIMEOUT): SelectKeeperTransactionSubmissionBAfterTimeoutRound - (FinalizationRound, INSUFFICIENT_FUNDS): SelectKeeperTransactionSubmissionBRound - (RandomnessTransactionSubmissionRound, DONE): SelectKeeperTransactionSubmissionARound - (RandomnessTransactionSubmissionRound, NO_MAJORITY): RandomnessTransactionSubmissionRound - (RandomnessTransactionSubmissionRound, ROUND_TIMEOUT): RandomnessTransactionSubmissionRound - (ResetRound, DONE): RandomnessTransactionSubmissionRound - (ResetRound, NO_MAJORITY): FailedRound - (ResetRound, RESET_TIMEOUT): FailedRound - (SelectKeeperTransactionSubmissionARound, DONE): CollectSignatureRound - (SelectKeeperTransactionSubmissionARound, INCORRECT_SERIALIZATION): FailedRound - (SelectKeeperTransactionSubmissionARound, NO_MAJORITY): ResetRound - (SelectKeeperTransactionSubmissionARound, ROUND_TIMEOUT): SelectKeeperTransactionSubmissionARound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, CHECK_HISTORY): CheckTransactionHistoryRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, DONE): FinalizationRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, INCORRECT_SERIALIZATION): FailedRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, NO_MAJORITY): ResetRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, ROUND_TIMEOUT): SelectKeeperTransactionSubmissionBAfterTimeoutRound - (SelectKeeperTransactionSubmissionBRound, DONE): FinalizationRound - (SelectKeeperTransactionSubmissionBRound, INCORRECT_SERIALIZATION): FailedRound - (SelectKeeperTransactionSubmissionBRound, NO_MAJORITY): ResetRound - (SelectKeeperTransactionSubmissionBRound, ROUND_TIMEOUT): SelectKeeperTransactionSubmissionBRound - (SynchronizeLateMessagesRound, DONE): CheckLateTxHashesRound - (SynchronizeLateMessagesRound, NONE): SelectKeeperTransactionSubmissionBRound - (SynchronizeLateMessagesRound, ROUND_TIMEOUT): SynchronizeLateMessagesRound - (SynchronizeLateMessagesRound, SUSPICIOUS_ACTIVITY): FailedRound - (ValidateTransactionRound, DONE): FinishedTransactionSubmissionRound - (ValidateTransactionRound, NEGATIVE): CheckTransactionHistoryRound - (ValidateTransactionRound, NONE): SelectKeeperTransactionSubmissionBRound - (ValidateTransactionRound, NO_MAJORITY): ValidateTransactionRound - (ValidateTransactionRound, VALIDATE_TIMEOUT): CheckTransactionHistoryRound diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/handlers.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/handlers.py deleted file mode 100644 index 9a4990be8..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/handlers.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the handler for the 'transaction_settlement_abci' skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIHandler = BaseABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/models.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/models.py deleted file mode 100644 index e65bb6932..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/models.py +++ /dev/null @@ -1,123 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Custom objects for the transaction settlement ABCI application.""" -from dataclasses import dataclass, field -from typing import Any, Dict, List, Optional - -from web3.types import Nonce, Wei - -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.abstract_round_abci.models import ApiSpecs, BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.abstract_round_abci.models import TypeCheckMixin -from packages.valory.skills.transaction_settlement_abci.rounds import ( - TransactionSubmissionAbciApp, -) - - -_MINIMUM_VALIDATE_TIMEOUT = 300 # 5 minutes -BenchmarkTool = BaseBenchmarkTool - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = TransactionSubmissionAbciApp - - -@dataclass -class MutableParams(TypeCheckMixin): - """Collection for the mutable parameters.""" - - fallback_gas: int - tx_hash: str = "" - nonce: Optional[Nonce] = None - gas_price: Optional[Dict[str, Wei]] = None - late_messages: List[ContractApiMessage] = field(default_factory=list) - - -@dataclass -class GasParams(BaseParams): - """Gas parameters.""" - - gas_price: Optional[int] = None - max_fee_per_gas: Optional[int] = None - max_priority_fee_per_gas: Optional[int] = None - - -class TransactionParams(BaseParams): # pylint: disable=too-many-instance-attributes - """Transaction settlement agent-specific parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """ - Initialize the parameters object. - - We keep track of the nonce and tip across rounds and periods. - We reuse it each time a new raw transaction is generated. If - at the time of the new raw transaction being generated the nonce - on the ledger does not match the nonce on the skill, then we ignore - the skill nonce and tip (effectively we price fresh). Otherwise, we - are in a re-submission scenario where we need to take account of the - old tip. - - :param args: positional arguments - :param kwargs: keyword arguments - """ - self.mutable_params = MutableParams( - fallback_gas=self._ensure("init_fallback_gas", kwargs, int) - ) - self.keeper_allowed_retries: int = self._ensure( - "keeper_allowed_retries", kwargs, int - ) - self.validate_timeout: int = self._ensure_gte( - "validate_timeout", - kwargs, - int, - min_value=_MINIMUM_VALIDATE_TIMEOUT, - ) - self.finalize_timeout: float = self._ensure("finalize_timeout", kwargs, float) - self.history_check_timeout: int = self._ensure( - "history_check_timeout", kwargs, int - ) - self.gas_params = self._get_gas_params(kwargs) - super().__init__(*args, **kwargs) - - @staticmethod - def _get_gas_params(kwargs: Dict[str, Any]) -> GasParams: - """Get the gas parameters.""" - gas_params = kwargs.pop("gas_params", {}) - gas_price = gas_params.get("gas_price", None) - max_fee_per_gas = gas_params.get("max_fee_per_gas", None) - max_priority_fee_per_gas = gas_params.get("max_priority_fee_per_gas", None) - return GasParams( - gas_price=gas_price, - max_fee_per_gas=max_fee_per_gas, - max_priority_fee_per_gas=max_priority_fee_per_gas, - ) - - -RandomnessApi = ApiSpecs -Requests = BaseRequests diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/payload_tools.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/payload_tools.py deleted file mode 100644 index 44a86883f..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/payload_tools.py +++ /dev/null @@ -1,183 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Tools for payload serialization and deserialization.""" - -from enum import Enum -from typing import Any, Optional, Tuple - -from packages.valory.contracts.gnosis_safe.contract import SafeOperation - - -NULL_ADDRESS: str = "0x" + "0" * 40 -MAX_UINT256 = 2**256 - 1 - - -class VerificationStatus(Enum): - """Tx verification status enumeration.""" - - VERIFIED = 1 - NOT_VERIFIED = 2 - INVALID_PAYLOAD = 3 - PENDING = 4 - ERROR = 5 - INSUFFICIENT_FUNDS = 6 - BAD_SAFE_NONCE = 7 - - -class PayloadDeserializationError(Exception): - """Exception for payload deserialization errors.""" - - def __init__(self, *args: Any) -> None: - """Initialize the exception. - - :param args: extra arguments to pass to the constructor of `Exception`. - """ - msg: str = "Cannot decode provided payload!" - if not args: - args = (msg,) - - super().__init__(*args) - - -def tx_hist_payload_to_hex( - verification: VerificationStatus, tx_hash: Optional[str] = None -) -> str: - """Serialise history payload to a hex string.""" - if tx_hash is None: - tx_hash = "" - else: - tx_hash = tx_hash[2:] if tx_hash.startswith("0x") else tx_hash - if len(tx_hash) != 64: - raise ValueError("Cannot encode tx_hash of non-32 bytes") - verification_ = verification.value.to_bytes(32, "big").hex() - concatenated = verification_ + tx_hash - return concatenated - - -def tx_hist_hex_to_payload(payload: str) -> Tuple[VerificationStatus, Optional[str]]: - """Decode history payload.""" - if len(payload) != 64 and len(payload) != 64 * 2: - raise PayloadDeserializationError() - - verification_value = int.from_bytes(bytes.fromhex(payload[:64]), "big") - - try: - verification_status = VerificationStatus(verification_value) - except ValueError as e: - raise PayloadDeserializationError(str(e)) from e - - if len(payload) == 64: - return verification_status, None - - return verification_status, "0x" + payload[64:] - - -def hash_payload_to_hex( # pylint: disable=too-many-arguments, too-many-locals - safe_tx_hash: str, - ether_value: int, - safe_tx_gas: int, - to_address: str, - data: bytes, - operation: int = SafeOperation.CALL.value, - base_gas: int = 0, - safe_gas_price: int = 0, - gas_token: str = NULL_ADDRESS, - refund_receiver: str = NULL_ADDRESS, - use_flashbots: bool = False, - gas_limit: int = 0, - raise_on_failed_simulation: bool = False, -) -> str: - """Serialise to a hex string.""" - if len(safe_tx_hash) != 64: # should be exactly 32 bytes! - raise ValueError( - "cannot encode safe_tx_hash of non-32 bytes" - ) # pragma: nocover - - if len(to_address) != 42 or len(gas_token) != 42 or len(refund_receiver) != 42: - raise ValueError("cannot encode address of non 42 length") # pragma: nocover - - if ( - ether_value > MAX_UINT256 - or safe_tx_gas > MAX_UINT256 - or base_gas > MAX_UINT256 - or safe_gas_price > MAX_UINT256 - or gas_limit > MAX_UINT256 - ): - raise ValueError( - "Value is bigger than the max 256 bit value" - ) # pragma: nocover - - if operation not in [v.value for v in SafeOperation]: - raise ValueError("SafeOperation value is not valid") # pragma: nocover - - if not isinstance(use_flashbots, bool): - raise ValueError( - f"`use_flashbots` value ({use_flashbots}) is not valid. A boolean value was expected instead" - ) - - ether_value_ = ether_value.to_bytes(32, "big").hex() - safe_tx_gas_ = safe_tx_gas.to_bytes(32, "big").hex() - operation_ = operation.to_bytes(1, "big").hex() - base_gas_ = base_gas.to_bytes(32, "big").hex() - safe_gas_price_ = safe_gas_price.to_bytes(32, "big").hex() - use_flashbots_ = use_flashbots.to_bytes(32, "big").hex() - gas_limit_ = gas_limit.to_bytes(32, "big").hex() - raise_on_failed_simulation_ = raise_on_failed_simulation.to_bytes(32, "big").hex() - - concatenated = ( - safe_tx_hash - + ether_value_ - + safe_tx_gas_ - + to_address - + operation_ - + base_gas_ - + safe_gas_price_ - + gas_token - + refund_receiver - + use_flashbots_ - + gas_limit_ - + raise_on_failed_simulation_ - + data.hex() - ) - return concatenated - - -def skill_input_hex_to_payload(payload: str) -> dict: - """Decode payload.""" - if len(payload) < 234: - raise PayloadDeserializationError() # pragma: nocover - tx_params = dict( - safe_tx_hash=payload[:64], - ether_value=int.from_bytes(bytes.fromhex(payload[64:128]), "big"), - safe_tx_gas=int.from_bytes(bytes.fromhex(payload[128:192]), "big"), - to_address=payload[192:234], - operation=int.from_bytes(bytes.fromhex(payload[234:236]), "big"), - base_gas=int.from_bytes(bytes.fromhex(payload[236:300]), "big"), - safe_gas_price=int.from_bytes(bytes.fromhex(payload[300:364]), "big"), - gas_token=payload[364:406], - refund_receiver=payload[406:448], - use_flashbots=bool.from_bytes(bytes.fromhex(payload[448:512]), "big"), - gas_limit=int.from_bytes(bytes.fromhex(payload[512:576]), "big"), - raise_on_failed_simulation=bool.from_bytes( - bytes.fromhex(payload[576:640]), "big" - ), - data=bytes.fromhex(payload[640:]), - ) - return tx_params diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/payloads.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/payloads.py deleted file mode 100644 index 16dad1edc..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/payloads.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the transaction payloads for common apps.""" - -from dataclasses import dataclass -from typing import Dict, Optional, Union - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class RandomnessPayload(BaseTxPayload): - """Represent a transaction payload of type 'randomness'.""" - - round_id: int - randomness: str - - -@dataclass(frozen=True) -class SelectKeeperPayload(BaseTxPayload): - """Represent a transaction payload of type 'select_keeper'.""" - - keepers: str - - -@dataclass(frozen=True) -class ValidatePayload(BaseTxPayload): - """Represent a transaction payload of type 'validate'.""" - - vote: Optional[bool] = None - - -@dataclass(frozen=True) -class CheckTransactionHistoryPayload(BaseTxPayload): - """Represent a transaction payload of type 'check'.""" - - verified_res: str - - -@dataclass(frozen=True) -class SynchronizeLateMessagesPayload(BaseTxPayload): - """Represent a transaction payload of type 'synchronize'.""" - - tx_hashes: str - - -@dataclass(frozen=True) -class SignaturePayload(BaseTxPayload): - """Represent a transaction payload of type 'signature'.""" - - signature: str - - -@dataclass(frozen=True) -class FinalizationTxPayload(BaseTxPayload): - """Represent a transaction payload of type 'finalization'.""" - - tx_data: Optional[Dict[str, Union[str, int, bool]]] = None - - -@dataclass(frozen=True) -class ResetPayload(BaseTxPayload): - """Represent a transaction payload of type 'reset'.""" - - period_count: int diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/rounds.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/rounds.py deleted file mode 100644 index d6231ee3d..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/rounds.py +++ /dev/null @@ -1,831 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the data classes for the `transaction settlement` ABCI application.""" - -import textwrap -from abc import ABC -from collections import deque -from enum import Enum -from typing import Deque, Dict, List, Mapping, Optional, Set, Tuple, cast - -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciApp, - AbciAppTransitionFunction, - AppState, - BaseSynchronizedData, - BaseTxPayload, - CollectDifferentUntilThresholdRound, - CollectNonEmptyUntilThresholdRound, - CollectSameUntilThresholdRound, - CollectionRound, - DegenerateRound, - OnlyKeeperSendsRound, - TransactionNotValidError, - VALUE_NOT_PROVIDED, - VotingRound, - get_name, -) -from packages.valory.skills.abstract_round_abci.utils import filter_negative -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - VerificationStatus, - tx_hist_hex_to_payload, -) -from packages.valory.skills.transaction_settlement_abci.payloads import ( - CheckTransactionHistoryPayload, - FinalizationTxPayload, - RandomnessPayload, - ResetPayload, - SelectKeeperPayload, - SignaturePayload, - SynchronizeLateMessagesPayload, - ValidatePayload, -) - - -ADDRESS_LENGTH = 42 -TX_HASH_LENGTH = 66 -RETRIES_LENGTH = 64 - - -class Event(Enum): - """Event enumeration for the price estimation demo.""" - - DONE = "done" - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - NEGATIVE = "negative" - NONE = "none" - FINALIZE_TIMEOUT = "finalize_timeout" - VALIDATE_TIMEOUT = "validate_timeout" - CHECK_TIMEOUT = "check_timeout" - RESET_TIMEOUT = "reset_timeout" - CHECK_HISTORY = "check_history" - CHECK_LATE_ARRIVING_MESSAGE = "check_late_arriving_message" - FINALIZATION_FAILED = "finalization_failed" - SUSPICIOUS_ACTIVITY = "suspicious_activity" - INSUFFICIENT_FUNDS = "insufficient_funds" - INCORRECT_SERIALIZATION = "incorrect_serialization" - - -class SynchronizedData( - BaseSynchronizedData -): # pylint: disable=too-many-instance-attributes - """ - Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - @property - def participant_to_signature(self) -> Mapping[str, SignaturePayload]: - """Get the participant_to_signature.""" - serialized = self.db.get_strict("participant_to_signature") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(Mapping[str, SignaturePayload], deserialized) - - @property - def tx_hashes_history(self) -> List[str]: - """Get the current cycle's tx hashes history, which has not yet been verified.""" - raw = cast(str, self.db.get("tx_hashes_history", "")) - return textwrap.wrap(raw, TX_HASH_LENGTH) - - @property - def keepers(self) -> Deque[str]: - """Get the current cycle's keepers who have tried to submit a transaction.""" - if self.is_keeper_set: - keepers_unparsed = cast(str, self.db.get_strict("keepers")) - keepers_parsed = textwrap.wrap( - keepers_unparsed[RETRIES_LENGTH:], ADDRESS_LENGTH - ) - return deque(keepers_parsed) - return deque() - - @property - def keepers_threshold_exceeded(self) -> bool: - """Check if the number of selected keepers has exceeded the allowed limit.""" - malicious_threshold = self.nb_participants // 3 - return len(self.keepers) > malicious_threshold - - @property - def most_voted_randomness_round(self) -> int: # pragma: no cover - """Get the first in priority keeper to try to re-submit a transaction.""" - round_ = self.db.get_strict("most_voted_randomness_round") - return cast(int, round_) - - @property - def most_voted_keeper_address(self) -> str: - """Get the first in priority keeper to try to re-submit a transaction.""" - return self.keepers[0] - - @property # TODO: overrides base property, investigate - def is_keeper_set(self) -> bool: - """Check whether keeper is set.""" - return bool(self.db.get("keepers", False)) - - @property - def keeper_retries(self) -> int: - """Get the number of times the current keeper has retried.""" - if self.is_keeper_set: - keepers_unparsed = cast(str, self.db.get_strict("keepers")) - keeper_retries = int.from_bytes( - bytes.fromhex(keepers_unparsed[:RETRIES_LENGTH]), "big" - ) - return keeper_retries - return 0 - - @property - def to_be_validated_tx_hash(self) -> str: - """ - Get the tx hash which is ready for validation. - - This will always be the last hash in the `tx_hashes_history`, - due to the way we are inserting the hashes in the array. - We keep the hashes sorted by the time of their finalization. - If this property is accessed before the finalization succeeds, - then it is incorrectly used and raises an error. - - :return: the tx hash which is ready for validation. - """ - if not self.tx_hashes_history: - raise ValueError( - "FSM design error: tx hash should exist" - ) # pragma: no cover - return self.tx_hashes_history[-1] - - @property - def final_tx_hash(self) -> str: - """Get the verified tx hash.""" - return cast(str, self.db.get_strict("final_tx_hash")) - - @property - def final_verification_status(self) -> VerificationStatus: - """Get the final verification status.""" - status_value = self.db.get("final_verification_status", None) - if status_value is None: - return VerificationStatus.NOT_VERIFIED - return VerificationStatus(status_value) - - @property - def most_voted_tx_hash(self) -> str: - """Get the most_voted_tx_hash.""" - return cast(str, self.db.get_strict("most_voted_tx_hash")) - - @property - def missed_messages(self) -> Dict[str, int]: - """The number of missed messages per agent address.""" - default = dict.fromkeys(self.all_participants, 0) - missed_messages = self.db.get("missed_messages", default) - return cast(Dict[str, int], missed_messages) - - @property - def n_missed_messages(self) -> int: - """The number of missed messages in total.""" - return sum(self.missed_messages.values()) - - @property - def should_check_late_messages(self) -> bool: - """Check if we should check for late-arriving messages.""" - return self.n_missed_messages > 0 - - @property - def late_arriving_tx_hashes(self) -> Dict[str, List[str]]: - """Get the late_arriving_tx_hashes.""" - late_arrivals = cast( - Dict[str, str], self.db.get_strict("late_arriving_tx_hashes") - ) - parsed_hashes = { - sender: textwrap.wrap(hashes, TX_HASH_LENGTH) - for sender, hashes in late_arrivals.items() - } - return parsed_hashes - - @property - def suspects(self) -> Tuple[str]: - """Get the suspect agents.""" - return cast(Tuple[str], self.db.get("suspects", tuple())) - - @property - def most_voted_check_result(self) -> str: # pragma: no cover - """Get the most voted checked result.""" - return cast(str, self.db.get_strict("most_voted_check_result")) - - @property - def participant_to_check( - self, - ) -> Mapping[str, CheckTransactionHistoryPayload]: # pragma: no cover - """Get the mapping from participants to checks.""" - serialized = self.db.get_strict("participant_to_check") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(Mapping[str, CheckTransactionHistoryPayload], deserialized) - - @property - def participant_to_late_messages( - self, - ) -> Mapping[str, SynchronizeLateMessagesPayload]: # pragma: no cover - """Get the mapping from participants to checks.""" - serialized = self.db.get_strict("participant_to_late_message") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(Mapping[str, SynchronizeLateMessagesPayload], deserialized) - - def get_chain_id(self, default_chain_id: str) -> str: - """Get the chain id.""" - return cast(str, self.db.get("chain_id", default_chain_id)) - - -class FailedRound(DegenerateRound, ABC): - """A round that represents that the period failed""" - - -class CollectSignatureRound(CollectDifferentUntilThresholdRound): - """A round in which agents sign the transaction""" - - payload_class = SignaturePayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_signature) - - -class FinalizationRound(OnlyKeeperSendsRound): - """A round that represents transaction signing has finished""" - - keeper_payload: Optional[FinalizationTxPayload] = None - payload_class = FinalizationTxPayload - synchronized_data_class = SynchronizedData - - def end_block( # pylint: disable=too-many-return-statements - self, - ) -> Optional[ - Tuple[BaseSynchronizedData, Enum] - ]: # pylint: disable=too-many-return-statements - """Process the end of the block.""" - if self.keeper_payload is None: - return None - - if self.keeper_payload.tx_data is None: - return self.synchronized_data, Event.FINALIZATION_FAILED - - verification_status = VerificationStatus( - self.keeper_payload.tx_data["status_value"] - ) - synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{ - get_name( - SynchronizedData.tx_hashes_history - ): self.keeper_payload.tx_data["tx_hashes_history"], - get_name( - SynchronizedData.final_verification_status - ): verification_status.value, - get_name(SynchronizedData.keepers): self.keeper_payload.tx_data[ - "serialized_keepers" - ], - get_name( - SynchronizedData.blacklisted_keepers - ): self.keeper_payload.tx_data["blacklisted_keepers"], - }, - ), - ) - - # check if we succeeded in finalization. - # we may fail in any of the following cases: - # 1. Getting raw safe transaction. - # 2. Requesting transaction signature. - # 3. Requesting transaction digest. - if self.keeper_payload.tx_data["received_hash"]: - return synchronized_data, Event.DONE - # If keeper has been blacklisted, return an `INSUFFICIENT_FUNDS` event. - if verification_status == VerificationStatus.INSUFFICIENT_FUNDS: - return synchronized_data, Event.INSUFFICIENT_FUNDS - # This means that getting raw safe transaction succeeded, - # but either requesting tx signature or requesting tx digest failed. - if verification_status not in ( - VerificationStatus.ERROR, - VerificationStatus.VERIFIED, - ): - return synchronized_data, Event.FINALIZATION_FAILED - # if there is a tx hash history, then check it for validated txs. - if synchronized_data.tx_hashes_history: - return synchronized_data, Event.CHECK_HISTORY - # if there could be any late messages, check if any has arrived. - if synchronized_data.should_check_late_messages: - return synchronized_data, Event.CHECK_LATE_ARRIVING_MESSAGE - # otherwise fail. - return synchronized_data, Event.FINALIZATION_FAILED - - -class RandomnessTransactionSubmissionRound(CollectSameUntilThresholdRound): - """A round for generating randomness""" - - payload_class = RandomnessPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_randomness) - selection_key = ( - get_name(SynchronizedData.most_voted_randomness_round), - get_name(SynchronizedData.most_voted_randomness), - ) - - -class SelectKeeperTransactionSubmissionARound(CollectSameUntilThresholdRound): - """A round in which a keeper is selected for transaction submission""" - - payload_class = SelectKeeperPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_selection) - selection_key = get_name(SynchronizedData.keepers) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - - if self.threshold_reached and self.most_voted_payload is not None: - if ( - len(self.most_voted_payload) < RETRIES_LENGTH + ADDRESS_LENGTH - or (len(self.most_voted_payload) - RETRIES_LENGTH) % ADDRESS_LENGTH != 0 - ): - # if we cannot parse the keepers' payload, then the developer has serialized it incorrectly. - return self.synchronized_data, Event.INCORRECT_SERIALIZATION - - return super().end_block() - - -class SelectKeeperTransactionSubmissionBRound(SelectKeeperTransactionSubmissionARound): - """A round in which a new keeper is selected for transaction submission""" - - -class SelectKeeperTransactionSubmissionBAfterTimeoutRound( - SelectKeeperTransactionSubmissionBRound -): - """A round in which a new keeper is selected for tx submission after a round timeout of the previous keeper""" - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.threshold_reached: - synchronized_data = cast(SynchronizedData, self.synchronized_data) - keeper = synchronized_data.most_voted_keeper_address - missed_messages = synchronized_data.missed_messages - missed_messages[keeper] += 1 - - synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{get_name(SynchronizedData.missed_messages): missed_messages}, - ), - ) - if synchronized_data.keepers_threshold_exceeded: - # we only stop re-selection if there are any previous transaction hashes or any missed messages. - if len(synchronized_data.tx_hashes_history) > 0: - return synchronized_data, Event.CHECK_HISTORY - if synchronized_data.should_check_late_messages: - return synchronized_data, Event.CHECK_LATE_ARRIVING_MESSAGE - return super().end_block() - - -class ValidateTransactionRound(VotingRound): - """A round in which agents validate the transaction""" - - payload_class = ValidatePayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - negative_event = Event.NEGATIVE - none_event = Event.NONE - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_votes) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - # if reached participant threshold, set the result - - if self.positive_vote_threshold_reached: - # We obtain the latest tx hash from the `tx_hashes_history`. - # We keep the hashes sorted by their finalization time. - # If this property is accessed before the finalization succeeds, - # then it is incorrectly used. - final_tx_hash = cast( - SynchronizedData, self.synchronized_data - ).to_be_validated_tx_hash - - # We only set the final tx hash if we are about to exit from the transaction settlement skill. - # Then, the skills which use the transaction settlement can check the tx hash - # and if it is None, then it means that the transaction has failed. - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{ - self.collection_key: self.serialized_collection, - get_name( - SynchronizedData.final_verification_status - ): VerificationStatus.VERIFIED.value, - get_name(SynchronizedData.final_tx_hash): final_tx_hash, - }, - ) - return synchronized_data, self.done_event - if self.negative_vote_threshold_reached: - return self.synchronized_data, self.negative_event - if self.none_vote_threshold_reached: - return self.synchronized_data, self.none_event - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, self.no_majority_event - return None - - -class CheckTransactionHistoryRound(CollectSameUntilThresholdRound): - """A round in which agents check the transaction history to see if any previous tx has been validated""" - - payload_class = CheckTransactionHistoryPayload - synchronized_data_class = SynchronizedData - collection_key = get_name(SynchronizedData.participant_to_check) - selection_key = get_name(SynchronizedData.most_voted_check_result) - - def end_block( # pylint: disable=too-many-return-statements - self, - ) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.threshold_reached: - return_status, return_tx_hash = tx_hist_hex_to_payload( - self.most_voted_payload - ) - - if return_status == VerificationStatus.NOT_VERIFIED: - # We don't update the synchronized_data as we need to repeat all checks again later - synchronized_data = self.synchronized_data - else: - # We only set the final tx hash if we are about to exit from the transaction settlement skill. - # Then, the skills which use the transaction settlement can check the tx hash - # and if it is None, then it means that the transaction has failed. - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{ - self.collection_key: self.serialized_collection, - self.selection_key: self.most_voted_payload, - get_name( - SynchronizedData.final_verification_status - ): return_status.value, - get_name(SynchronizedData.final_tx_hash): return_tx_hash, - }, - ) - - if return_status == VerificationStatus.VERIFIED: - return synchronized_data, Event.DONE - if ( - return_status == VerificationStatus.NOT_VERIFIED - and cast( - SynchronizedData, self.synchronized_data - ).should_check_late_messages - ): - return synchronized_data, Event.CHECK_LATE_ARRIVING_MESSAGE - if return_status == VerificationStatus.NOT_VERIFIED: - return synchronized_data, Event.NEGATIVE - if return_status == VerificationStatus.BAD_SAFE_NONCE: - # in case a bad nonce was used, we need to recreate the tx from scratch - return synchronized_data, Event.NONE - - return synchronized_data, Event.NONE - - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, Event.NO_MAJORITY - return None - - -class CheckLateTxHashesRound(CheckTransactionHistoryRound): - """A round in which agents check the late-arriving transaction hashes to see if any of them has been validated""" - - -class SynchronizeLateMessagesRound(CollectNonEmptyUntilThresholdRound): - """A round in which agents synchronize potentially late arriving messages""" - - payload_class = SynchronizeLateMessagesPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - none_event = Event.NONE - required_block_confirmations = 3 - selection_key = get_name(SynchronizedData.late_arriving_tx_hashes) - collection_key = get_name(SynchronizedData.participant_to_late_messages) - # if the payload is serialized to bytes, we verify that the length specified matches - _hash_length = TX_HASH_LENGTH - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - result = super().end_block() - if result is None: - return None - - synchronized_data, event = cast(Tuple[SynchronizedData, Event], result) - - late_arriving_tx_hashes_counts = { - sender: len(hashes) - for sender, hashes in synchronized_data.late_arriving_tx_hashes.items() - } - missed_after_sync = { - sender: missed - late_arriving_tx_hashes_counts.get(sender, 0) - for sender, missed in synchronized_data.missed_messages.items() - } - suspects = tuple(filter_negative(missed_after_sync)) - - if suspects: - synchronized_data = cast( - SynchronizedData, - synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{get_name(SynchronizedData.suspects): suspects}, - ), - ) - return synchronized_data, Event.SUSPICIOUS_ACTIVITY - - synchronized_data = cast( - SynchronizedData, - synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{get_name(SynchronizedData.missed_messages): missed_after_sync}, - ), - ) - return synchronized_data, event - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - # TODO: move check into payload definition via `post_init` - payload = cast(SynchronizeLateMessagesPayload, payload) - if self._hash_length: - content = payload.tx_hashes - if not content or len(content) % self._hash_length: - msg = f"Expecting serialized data of chunk size {self._hash_length}" - raise ABCIAppInternalError(f"{msg}, got: {content} in {self.round_id}") - super().process_payload(payload) - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check Payload""" - # TODO: move check into payload definition via `post_init` - payload = cast(SynchronizeLateMessagesPayload, payload) - if self._hash_length: - content = payload.tx_hashes - if not content or len(content) % self._hash_length: - msg = f"Expecting serialized data of chunk size {self._hash_length}" - raise TransactionNotValidError( - f"{msg}, got: {content} in {self.round_id}" - ) - super().check_payload(payload) - - -class FinishedTransactionSubmissionRound(DegenerateRound, ABC): - """A round that represents the transition to the ResetAndPauseRound""" - - -class ResetRound(CollectSameUntilThresholdRound): - """A round that represents the reset of a period""" - - payload_class = ResetPayload - synchronized_data_class = SynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - if self.threshold_reached: - synchronized_data = cast(SynchronizedData, self.synchronized_data) - # we could have used the `synchronized_data.create()` here and set the `cross_period_persisted_keys` - # with the corresponding properties' keys. However, the cross period keys would get passed over - # for all the following periods, even those that the tx settlement succeeds. - # Therefore, we need to manually call the db's create method and pass the keys we want to keep only - # for the next period, which comes after a `NO_MAJORITY` event of the tx settlement skill. - # TODO investigate the following: - # This probably indicates an issue with the logic of this skill. We should not increase the period since - # we have a failure. We could instead just remove the `ResetRound` and transition to the - # `RandomnessTransactionSubmissionRound` directly. This would save us one round, would allow us to remove - # this hacky logic for the `create`, and would also not increase the period count in non-successful events - self.synchronized_data.db.create( - **{ - db_key: synchronized_data.db.get(db_key, default) - for db_key, default in { - "all_participants": VALUE_NOT_PROVIDED, - "participants": VALUE_NOT_PROVIDED, - "consensus_threshold": VALUE_NOT_PROVIDED, - "safe_contract_address": VALUE_NOT_PROVIDED, - "tx_hashes_history": "", - "keepers": VALUE_NOT_PROVIDED, - "missed_messages": dict.fromkeys( - synchronized_data.all_participants, 0 - ), - "late_arriving_tx_hashes": VALUE_NOT_PROVIDED, - "suspects": tuple(), - }.items() - } - ) - return self.synchronized_data, Event.DONE - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, Event.NO_MAJORITY - return None - - -class TransactionSubmissionAbciApp(AbciApp[Event]): - """TransactionSubmissionAbciApp - - Initial round: RandomnessTransactionSubmissionRound - - Initial states: {RandomnessTransactionSubmissionRound} - - Transition states: - 0. RandomnessTransactionSubmissionRound - - done: 1. - - round timeout: 0. - - no majority: 0. - 1. SelectKeeperTransactionSubmissionARound - - done: 2. - - round timeout: 1. - - no majority: 10. - - incorrect serialization: 12. - 2. CollectSignatureRound - - done: 3. - - round timeout: 2. - - no majority: 10. - 3. FinalizationRound - - done: 4. - - check history: 5. - - finalize timeout: 7. - - finalization failed: 6. - - check late arriving message: 8. - - insufficient funds: 6. - 4. ValidateTransactionRound - - done: 11. - - negative: 5. - - none: 6. - - validate timeout: 5. - - no majority: 4. - 5. CheckTransactionHistoryRound - - done: 11. - - negative: 6. - - none: 12. - - check timeout: 5. - - no majority: 5. - - check late arriving message: 8. - 6. SelectKeeperTransactionSubmissionBRound - - done: 3. - - round timeout: 6. - - no majority: 10. - - incorrect serialization: 12. - 7. SelectKeeperTransactionSubmissionBAfterTimeoutRound - - done: 3. - - check history: 5. - - check late arriving message: 8. - - round timeout: 7. - - no majority: 10. - - incorrect serialization: 12. - 8. SynchronizeLateMessagesRound - - done: 9. - - round timeout: 8. - - none: 6. - - suspicious activity: 12. - 9. CheckLateTxHashesRound - - done: 11. - - negative: 12. - - none: 12. - - check timeout: 9. - - no majority: 12. - - check late arriving message: 8. - 10. ResetRound - - done: 0. - - reset timeout: 12. - - no majority: 12. - 11. FinishedTransactionSubmissionRound - 12. FailedRound - - Final states: {FailedRound, FinishedTransactionSubmissionRound} - - Timeouts: - round timeout: 30.0 - finalize timeout: 30.0 - validate timeout: 30.0 - check timeout: 30.0 - reset timeout: 30.0 - """ - - initial_round_cls: AppState = RandomnessTransactionSubmissionRound - initial_states: Set[AppState] = {RandomnessTransactionSubmissionRound} - transition_function: AbciAppTransitionFunction = { - RandomnessTransactionSubmissionRound: { - Event.DONE: SelectKeeperTransactionSubmissionARound, - Event.ROUND_TIMEOUT: RandomnessTransactionSubmissionRound, - Event.NO_MAJORITY: RandomnessTransactionSubmissionRound, - }, - SelectKeeperTransactionSubmissionARound: { - Event.DONE: CollectSignatureRound, - Event.ROUND_TIMEOUT: SelectKeeperTransactionSubmissionARound, - Event.NO_MAJORITY: ResetRound, - Event.INCORRECT_SERIALIZATION: FailedRound, - }, - CollectSignatureRound: { - Event.DONE: FinalizationRound, - Event.ROUND_TIMEOUT: CollectSignatureRound, - Event.NO_MAJORITY: ResetRound, - }, - FinalizationRound: { - Event.DONE: ValidateTransactionRound, - Event.CHECK_HISTORY: CheckTransactionHistoryRound, - Event.FINALIZE_TIMEOUT: SelectKeeperTransactionSubmissionBAfterTimeoutRound, - Event.FINALIZATION_FAILED: SelectKeeperTransactionSubmissionBRound, - Event.CHECK_LATE_ARRIVING_MESSAGE: SynchronizeLateMessagesRound, - Event.INSUFFICIENT_FUNDS: SelectKeeperTransactionSubmissionBRound, - }, - ValidateTransactionRound: { - Event.DONE: FinishedTransactionSubmissionRound, - Event.NEGATIVE: CheckTransactionHistoryRound, - Event.NONE: SelectKeeperTransactionSubmissionBRound, - # even in case of timeout we might've sent the transaction - # so we need to check the history - Event.VALIDATE_TIMEOUT: CheckTransactionHistoryRound, - Event.NO_MAJORITY: ValidateTransactionRound, - }, - CheckTransactionHistoryRound: { - Event.DONE: FinishedTransactionSubmissionRound, - Event.NEGATIVE: SelectKeeperTransactionSubmissionBRound, - Event.NONE: FailedRound, - Event.CHECK_TIMEOUT: CheckTransactionHistoryRound, - Event.NO_MAJORITY: CheckTransactionHistoryRound, - Event.CHECK_LATE_ARRIVING_MESSAGE: SynchronizeLateMessagesRound, - }, - SelectKeeperTransactionSubmissionBRound: { - Event.DONE: FinalizationRound, - Event.ROUND_TIMEOUT: SelectKeeperTransactionSubmissionBRound, - Event.NO_MAJORITY: ResetRound, - Event.INCORRECT_SERIALIZATION: FailedRound, - }, - SelectKeeperTransactionSubmissionBAfterTimeoutRound: { - Event.DONE: FinalizationRound, - Event.CHECK_HISTORY: CheckTransactionHistoryRound, - Event.CHECK_LATE_ARRIVING_MESSAGE: SynchronizeLateMessagesRound, - Event.ROUND_TIMEOUT: SelectKeeperTransactionSubmissionBAfterTimeoutRound, - Event.NO_MAJORITY: ResetRound, - Event.INCORRECT_SERIALIZATION: FailedRound, - }, - SynchronizeLateMessagesRound: { - Event.DONE: CheckLateTxHashesRound, - Event.ROUND_TIMEOUT: SynchronizeLateMessagesRound, - Event.NONE: SelectKeeperTransactionSubmissionBRound, - Event.SUSPICIOUS_ACTIVITY: FailedRound, - }, - CheckLateTxHashesRound: { - Event.DONE: FinishedTransactionSubmissionRound, - Event.NEGATIVE: FailedRound, - Event.NONE: FailedRound, - Event.CHECK_TIMEOUT: CheckLateTxHashesRound, - Event.NO_MAJORITY: FailedRound, - Event.CHECK_LATE_ARRIVING_MESSAGE: SynchronizeLateMessagesRound, - }, - ResetRound: { - Event.DONE: RandomnessTransactionSubmissionRound, - Event.RESET_TIMEOUT: FailedRound, - Event.NO_MAJORITY: FailedRound, - }, - FinishedTransactionSubmissionRound: {}, - FailedRound: {}, - } - final_states: Set[AppState] = { - FinishedTransactionSubmissionRound, - FailedRound, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - Event.FINALIZE_TIMEOUT: 30.0, - Event.VALIDATE_TIMEOUT: 30.0, - Event.CHECK_TIMEOUT: 30.0, - Event.RESET_TIMEOUT: 30.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = { - RandomnessTransactionSubmissionRound: { - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.participants), - } - } - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedTransactionSubmissionRound: { - get_name(SynchronizedData.final_tx_hash), - get_name(SynchronizedData.final_verification_status), - }, - FailedRound: set(), - } diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/skill.yaml b/trader_backup/vendor/valory/skills/transaction_settlement_abci/skill.yaml deleted file mode 100644 index c526f2da2..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/skill.yaml +++ /dev/null @@ -1,174 +0,0 @@ -name: transaction_settlement_abci -author: valory -version: 0.1.0 -type: skill -description: ABCI application for transaction settlement. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeihvqvbj2tiiyimz3e27gqhb7ku5rut7hycfahi4qle732kvj5fs7q - __init__.py: bafybeicyrp6x2efg43gfdekxuofrlidc3w6aubzmyioqwnryropp6u7sby - behaviours.py: bafybeibv5y34bwaloj455bjws3a2aeh2bgi4dclq2f5d35apm2mloen5xa - dialogues.py: bafybeigabhaykiyzbluu4mk6bbrmqhzld2kyp32pg24bvjmzrrb74einwm - fsm_specification.yaml: bafybeigdj64py4zjihcxdkvtrydbxyeh4slr2kkghltz3upnupdgad4et4 - handlers.py: bafybeie42qa3csgy6oompuqs2qnkat5mnslepbbwmgoxv6ljme4jofa5pe - models.py: bafybeiguxishqvtvlyznok3xjnzm4t6vfflamcvz5vtecq5esbldsxuc5e - payload_tools.py: bafybeiatlbw3vyo5ppjhxf4psdvkwubmrjolsprf44lis5ozfkjo7o3cba - payloads.py: bafybeiclhjnsgylqzfnu2azlqxor3vyldaoof757dnfwz5xbwejk2ro2cm - rounds.py: bafybeieo5l6gh276hhtztphloyknb5ew66hvqhzzjiv26isaz7ptvtqjgu - test_tools/__init__.py: bafybeibj2blgxzvcgdi5gzcnlzs2nt7bpdifzvjjlxlrkeutjy2qrqbwau - test_tools/integration.py: bafybeictb7ym4xsbo3ti5y2a2fpg344graa4d7352oozsea5rbab3kq4ae - tests/__init__.py: bafybeifukcwmf2ewkjqdu7j6xzmaovgrul7jnea5lrl4o3ianoofje6vfa - tests/test_behaviours.py: bafybeia2vob5legv3tdrdj4gjgmnz6enhaterbetkc6ntdemnwgg5or4gq - tests/test_dialogues.py: bafybeictrjf6jzsj4y6u2ftdrb2nyriiipia5b7wc4fsli3lwbjpd3mbam - tests/test_handlers.py: bafybeievntkwacpfaom3qabvrlworjqyd4sgfjknjlhys7f5tuq7725xli - tests/test_models.py: bafybeihvrv7vtaei64nv7okkfz2gg2g4ey4nei27ayc74h5bdlqpbk4xde - tests/test_payload_tools.py: bafybeihmgkcrlqhz4ncak276lnccmilig6gx3crmn33n46jcco6g5pzrje - tests/test_payloads.py: bafybeidvjqvjvnuw5vt4zgnqwzopvprznmefosqy3wcxukvobaiishygze - tests/test_rounds.py: bafybeic3kzqy3pe6d4skntnfc5443y6dshcustiuv2d6cw4z56gw2ewehy - tests/test_tools/__init__.py: bafybeiaq2ftmklvu5vqq6vdfa7mrlmrnusluki35jm5n2yzf57ox5dif74 - tests/test_tools/test_integration.py: bafybeigv6fxogm3aq3extahr75owdqnzepouv3rtxl3m4gai2urtz6u4ea -fingerprint_ignore_patterns: [] -connections: [] -contracts: -- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge -protocols: -- open_aea/signing:1.0.0:bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi -- valory/abci:0.1.0:bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -behaviours: - main: - args: {} - class_name: TransactionSettlementRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - default_chain_id: ethereum - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - finalize_timeout: 60.0 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - history_check_timeout: 1205 - init_fallback_gas: 0 - keeper_allowed_retries: 3 - keeper_timeout: 30.0 - light_slash_unit_amount: 5000000000000000 - max_attempts: 10 - max_healthcheck: 120 - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 30.0 - serious_slash_unit_amount: 8000000000000000 - service_id: registration - service_registry_address: null - setup: {} - share_tm_config_on_startup: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - sleep_time: 1 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - tx_timeout: 10.0 - use_slashing: false - use_termination: false - validate_timeout: 1205 - class_name: TransactionParams - randomness_api: - args: - api_id: cloudflare - headers: {} - method: GET - parameters: {} - response_key: null - response_type: dict - retries: 5 - url: https://drand.cloudflare.com/public/latest - class_name: RandomnessApi - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: - open-aea-test-autonomy: - version: ==0.14.14.post1 - web3: - version: <7,>=6.0.0 -is_abstract: true -customs: [] diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/test_tools/__init__.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/test_tools/__init__.py deleted file mode 100644 index 55be4e300..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/test_tools/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for transaction_settlement_abci derived skills.""" diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/test_tools/integration.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/test_tools/integration.py deleted file mode 100644 index deb1c53c5..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/test_tools/integration.py +++ /dev/null @@ -1,338 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Integration tests for various transaction settlement skill's failure modes.""" - - -import binascii -import os -import tempfile -from abc import ABC -from math import ceil -from typing import Any, Dict, Union, cast - -from aea.crypto.base import Crypto -from aea.crypto.registries import make_crypto, make_ledger_api -from aea_ledger_ethereum import EthereumApi -from aea_test_autonomy.helpers.contracts import get_register_contract -from web3.types import Nonce, Wei - -from packages.open_aea.protocols.signing import SigningMessage -from packages.valory.contracts.gnosis_safe.tests.test_contract import ( - PACKAGE_DIR as GNOSIS_SAFE_PACKAGE, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.contract_api.custom_types import RawTransaction, State -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.protocols.ledger_api.custom_types import ( - SignedTransaction, - TransactionDigest, - TransactionReceipt, -) -from packages.valory.skills.abstract_round_abci.test_tools.integration import ( - ExpectedContentType, - ExpectedTypesType, - HandlersType, - IntegrationBaseCase, -) -from packages.valory.skills.transaction_settlement_abci.behaviours import ( - FinalizeBehaviour, - ValidateTransactionBehaviour, -) -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - VerificationStatus, - skill_input_hex_to_payload, -) -from packages.valory.skills.transaction_settlement_abci.payloads import SignaturePayload -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TxSettlementSynchronizedSata, -) - - -# pylint: disable=protected-access,too-many-ancestors,unbalanced-tuple-unpacking,too-many-locals,consider-using-with,unspecified-encoding,too-many-arguments,unidiomatic-typecheck - - -DUMMY_MAX_FEE_PER_GAS = 4000000000 -DUMMY_MAX_PRIORITY_FEE_PER_GAS = 3000000000 -DUMMY_REPRICING_MULTIPLIER = 1.1 - - -class _SafeConfiguredHelperIntegration(IntegrationBaseCase, ABC): # pragma: no cover - """Base test class for integration tests with Gnosis, but no contract, deployed.""" - - safe_owners: Dict[str, Crypto] - keeper_address: str - - @classmethod - def setup_class(cls, **kwargs: Any) -> None: - """Setup.""" - super().setup_class() - - # safe configuration - cls.safe_owners = {} - for address, p_key in cls.agents.items(): - with tempfile.TemporaryDirectory() as temp_dir: - fp = os.path.join(temp_dir, "key.txt") - f = open(fp, "w") - f.write(p_key) - f.close() - crypto = make_crypto("ethereum", private_key_path=str(fp)) - cls.safe_owners[address] = crypto - cls.keeper_address = cls.current_agent - assert cls.keeper_address in cls.safe_owners # nosec - - -class _GnosisHelperIntegration( - _SafeConfiguredHelperIntegration, ABC -): # pragma: no cover - """Class that assists Gnosis instantiation.""" - - safe_contract_address: str = "0x68FCdF52066CcE5612827E872c45767E5a1f6551" - ethereum_api: EthereumApi - gnosis_instance: Any - - @classmethod - def setup_class(cls, **kwargs: Any) -> None: - """Setup.""" - super().setup_class() - - # register gnosis contract - gnosis = get_register_contract(GNOSIS_SAFE_PACKAGE) - - cls.ethereum_api = make_ledger_api("ethereum") - cls.gnosis_instance = gnosis.get_instance( - cls.ethereum_api, cls.safe_contract_address - ) - - -class _TxHelperIntegration(_GnosisHelperIntegration, ABC): # pragma: no cover - """Class that assists tx settlement related operations.""" - - tx_settlement_synchronized_data: TxSettlementSynchronizedSata - - def sign_tx(self) -> None: - """Sign a transaction""" - tx_params = skill_input_hex_to_payload( - self.tx_settlement_synchronized_data.most_voted_tx_hash - ) - safe_tx_hash_bytes = binascii.unhexlify(tx_params["safe_tx_hash"]) - participant_to_signature = {} - for address, crypto in self.safe_owners.items(): - signature_hex = crypto.sign_message( - safe_tx_hash_bytes, - is_deprecated_mode=True, - ) - signature_hex = signature_hex[2:] - participant_to_signature[address] = SignaturePayload( - sender=address, - signature=signature_hex, - ).json - - # FIXME: The following loop is a patch. The - # [_get_python_modules](https://github.com/valory-xyz/open-aea/blob/d0e60881b1371442c3572df86c53fc92dc9228fa/aea/skills/base.py#L907-L925) - # is getting the python modules from the skill directory. - # As we can see from the code, the path will end up being relative, which means that the - # [_metaclass_registry_key](https://github.com/valory-xyz/open-autonomy/blob/5d151f1fff4934f70be8c5f6be77705cc2e6ef4c/packages/valory/skills/abstract_round_abci/base.py#L167) - # inserted in the `_MetaPayload`'s registry will also be relative. However, this is causing issues when calling - # `BaseTxPayload.from_json(payload_json)` later from the property below - # (`self.tx_settlement_synchronized_data.participant_to_signature`) because the `payload_json` will have been - # serialized using an imported payload (the `SignaturePayload` above), and therefore a key error will be - # raised since the imported payload's path is not relative and the registry has a relative path as a key. - for payload in participant_to_signature.values(): - registry_key = "_metaclass_registry_key" - payload_value = payload[registry_key] - payload_cls_name = payload_value.split(".")[-1] - patched_registry_key = f"payloads.{payload_cls_name}" - payload[registry_key] = patched_registry_key - - self.tx_settlement_synchronized_data.update( - participant_to_signature=participant_to_signature, - ) - - actual_safe_owners = self.gnosis_instance.functions.getOwners().call() - expected_safe_owners = ( - self.tx_settlement_synchronized_data.participant_to_signature.keys() - ) - assert len(actual_safe_owners) == len(expected_safe_owners) # nosec - assert all( # nosec - owner == signer - for owner, signer in zip(actual_safe_owners, expected_safe_owners) - ) - - def send_tx(self, simulate_timeout: bool = False) -> None: - """Send a transaction""" - - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=FinalizeBehaviour.auto_behaviour_id(), - synchronized_data=self.tx_settlement_synchronized_data, - ) - behaviour = cast(FinalizeBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == FinalizeBehaviour.auto_behaviour_id() - stored_nonce = behaviour.params.mutable_params.nonce - stored_gas_price = behaviour.params.mutable_params.gas_price - - handlers: HandlersType = [ - self.contract_handler, - self.signing_handler, - self.ledger_handler, - ] - expected_content: ExpectedContentType = [ - {"performative": ContractApiMessage.Performative.RAW_TRANSACTION}, - {"performative": SigningMessage.Performative.SIGNED_TRANSACTION}, - {"performative": LedgerApiMessage.Performative.TRANSACTION_DIGEST}, - ] - expected_types: ExpectedTypesType = [ - { - "raw_transaction": RawTransaction, - }, - { - "signed_transaction": SignedTransaction, - }, - { - "transaction_digest": TransactionDigest, - }, - ] - msg1, _, msg3 = self.process_n_messages( - 3, - self.tx_settlement_synchronized_data, - None, - handlers, - expected_content, - expected_types, - fail_send_a2a=simulate_timeout, - ) - assert msg1 is not None and isinstance(msg1, ContractApiMessage) # nosec - assert msg3 is not None and isinstance(msg3, LedgerApiMessage) # nosec - nonce_used = Nonce(int(cast(str, msg1.raw_transaction.body["nonce"]))) - gas_price_used = { - gas_price_param: Wei( - int( - cast( - str, - msg1.raw_transaction.body[gas_price_param], - ) - ) - ) - for gas_price_param in ("maxPriorityFeePerGas", "maxFeePerGas") - } - tx_digest = msg3.transaction_digest.body - tx_data = { - "status": VerificationStatus.PENDING, - "tx_digest": cast(str, tx_digest), - } - - behaviour = cast(FinalizeBehaviour, self.behaviour.current_behaviour) - assert behaviour.params.mutable_params.gas_price == gas_price_used # nosec - assert behaviour.params.mutable_params.nonce == nonce_used # nosec - if simulate_timeout: - assert behaviour.params.mutable_params.tx_hash == tx_digest # nosec - else: - assert behaviour.params.mutable_params.tx_hash == "" # nosec - - # if we are repricing - if nonce_used == stored_nonce: - assert stored_nonce is not None # nosec - assert stored_gas_price is not None # nosec - assert gas_price_used == { # nosec - gas_price_param: ceil( - stored_gas_price[gas_price_param] * DUMMY_REPRICING_MULTIPLIER - ) - for gas_price_param in ("maxPriorityFeePerGas", "maxFeePerGas") - }, "The repriced parameters do not match the ones returned from the gas pricing method!" - # if we are not repricing - else: - assert gas_price_used == { # nosec - "maxPriorityFeePerGas": DUMMY_MAX_PRIORITY_FEE_PER_GAS, - "maxFeePerGas": DUMMY_MAX_FEE_PER_GAS, - }, "The used parameters do not match the ones returned from the gas pricing method!" - - update_params: Dict[str, Union[int, str, Dict[str, int]]] - if not simulate_timeout: - hashes = self.tx_settlement_synchronized_data.tx_hashes_history - hashes.append(tx_digest) - update_params = dict( - tx_hashes_history="".join(hashes), - final_verification_status=VerificationStatus(tx_data["status"]).value, - ) - else: - # store the tx hash that we have missed and update missed messages. - assert isinstance( # nosec - self.behaviour.current_behaviour, FinalizeBehaviour - ) - self.mock_a2a_transaction() - self.behaviour.current_behaviour.params.mutable_params.tx_hash = tx_digest - missed_messages = self.tx_settlement_synchronized_data.missed_messages - missed_messages[ - self.tx_settlement_synchronized_data.most_voted_keeper_address - ] += 1 - update_params = dict(missed_messages=missed_messages) - - self.tx_settlement_synchronized_data.update( - synchronized_data_class=None, **update_params - ) - - def validate_tx( - self, simulate_timeout: bool = False, mining_interval_secs: float = 0 - ) -> None: - """Validate the sent transaction.""" - - if simulate_timeout: - missed_messages = self.tx_settlement_synchronized_data.missed_messages - missed_messages[ - tuple(self.tx_settlement_synchronized_data.all_participants)[0] - ] += 1 - self.tx_settlement_synchronized_data.update(missed_messages=missed_messages) - else: - handlers: HandlersType = [ - self.ledger_handler, - self.contract_handler, - ] - expected_content: ExpectedContentType = [ - {"performative": LedgerApiMessage.Performative.TRANSACTION_RECEIPT}, - {"performative": ContractApiMessage.Performative.STATE}, - ] - expected_types: ExpectedTypesType = [ - { - "transaction_receipt": TransactionReceipt, - }, - { - "state": State, - }, - ] - _, verif_msg = self.process_n_messages( - 2, - self.tx_settlement_synchronized_data, - ValidateTransactionBehaviour.auto_behaviour_id(), - handlers, - expected_content, - expected_types, - mining_interval_secs=mining_interval_secs, - ) - assert verif_msg is not None and isinstance( # nosec - verif_msg, ContractApiMessage - ) - assert verif_msg.state.body[ # nosec - "verified" - ], f"Message not verified: {verif_msg.state.body}" - - self.tx_settlement_synchronized_data.update( - final_verification_status=VerificationStatus.VERIFIED.value, - final_tx_hash=self.tx_settlement_synchronized_data.to_be_validated_tx_hash, - ) diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/__init__.py deleted file mode 100644 index 932ecb0c4..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/transaction_settlement_abci skill.""" -from pathlib import Path - - -PACKAGE_DIR = Path(__file__).parents[1] diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_behaviours.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_behaviours.py deleted file mode 100644 index fbc6d9f93..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_behaviours.py +++ /dev/null @@ -1,1392 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/registration_abci skill's behaviours.""" - -# pylint: skip-file - -import logging -import time -from collections import deque -from pathlib import Path -from typing import ( - Any, - Callable, - Deque, - Dict, - Generator, - List, - Optional, - Set, - Tuple, - Type, - Union, - cast, -) -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from _pytest.logging import LogCaptureFixture -from _pytest.monkeypatch import MonkeyPatch -from aea.helpers.transaction.base import ( - RawTransaction, - SignedMessage, - SignedTransaction, -) -from aea.helpers.transaction.base import State as TrState -from aea.helpers.transaction.base import TransactionDigest, TransactionReceipt -from aea.skills.base import SkillContext -from web3.types import Nonce - -from packages.open_aea.protocols.signing import SigningMessage -from packages.valory.contracts.gnosis_safe.contract import ( - PUBLIC_ID as GNOSIS_SAFE_CONTRACT_ID, -) -from packages.valory.protocols.abci import AbciMessage # noqa: F401 -from packages.valory.protocols.contract_api.message import ContractApiMessage -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - BaseBehaviour, - RPCResponseStatus, - make_degenerate_behaviour, -) -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.abstract_round_abci.test_tools.common import ( - BaseRandomnessBehaviourTest, - BaseSelectKeeperBehaviourTest, -) -from packages.valory.skills.transaction_settlement_abci import PUBLIC_ID -from packages.valory.skills.transaction_settlement_abci.behaviours import ( - CheckLateTxHashesBehaviour, - CheckTransactionHistoryBehaviour, - FinalizeBehaviour, - REVERT_CODES_TO_REASONS, - RandomnessTransactionSubmissionBehaviour, - ResetBehaviour, - SelectKeeperTransactionSubmissionBehaviourA, - SelectKeeperTransactionSubmissionBehaviourB, - SignatureBehaviour, - SynchronizeLateMessagesBehaviour, - TransactionSettlementBaseBehaviour, - TxDataType, - ValidateTransactionBehaviour, -) -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - VerificationStatus, - hash_payload_to_hex, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - Event as TransactionSettlementEvent, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - FinishedTransactionSubmissionRound, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TransactionSettlementSynchronizedSata, -) - - -PACKAGE_DIR = Path(__file__).parent.parent - - -def mock_yield_and_return( - return_value: Any, -) -> Callable[[], Generator[None, None, Any]]: - """Wrapper for a Dummy generator that returns a `bool`.""" - - def yield_and_return(*_: Any, **__: Any) -> Generator[None, None, Any]: - """Dummy generator that returns a `bool`.""" - yield - return return_value - - return yield_and_return - - -def test_skill_public_id() -> None: - """Test skill module public ID""" - - assert PUBLIC_ID.name == Path(__file__).parents[1].name - assert PUBLIC_ID.author == Path(__file__).parents[3].name - - -class TransactionSettlementFSMBehaviourBaseCase(FSMBehaviourBaseCase): - """Base case for testing TransactionSettlement FSMBehaviour.""" - - path_to_skill = PACKAGE_DIR - - def ffw_signature(self, db_items: Optional[Dict] = None) -> None: - """Fast-forward to the `SignatureBehaviour`.""" - if db_items is None: - db_items = {} - - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=SignatureBehaviour.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists(db_items), - ) - ), - ) - - -class TestTransactionSettlementBaseBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test `TransactionSettlementBaseBehaviour`.""" - - @pytest.mark.parametrize( - "message, tx_digest, rpc_status, expected_data, replacement", - ( - ( - MagicMock( - performative=ContractApiMessage.Performative.ERROR, message="GS026" - ), - None, - RPCResponseStatus.SUCCESS, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.VERIFIED, - "tx_digest": "", - }, - False, - ), - ( - MagicMock( - performative=ContractApiMessage.Performative.ERROR, message="test" - ), - None, - RPCResponseStatus.SUCCESS, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.ERROR, - "tx_digest": "", - }, - False, - ), - ( - MagicMock(performative=ContractApiMessage.Performative.RAW_MESSAGE), - None, - RPCResponseStatus.SUCCESS, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.PENDING, - "tx_digest": "", - }, - False, - ), - ( - MagicMock(performative=ContractApiMessage.Performative.RAW_TRANSACTION), - None, - RPCResponseStatus.INCORRECT_NONCE, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.ERROR, - "tx_digest": "", - }, - False, - ), - ( - MagicMock(performative=ContractApiMessage.Performative.RAW_TRANSACTION), - None, - RPCResponseStatus.INSUFFICIENT_FUNDS, - { - "blacklisted_keepers": {"agent_1" + "-" * 35}, - "keeper_retries": 1, - "keepers": deque(("agent_3" + "-" * 35,)), - "status": VerificationStatus.INSUFFICIENT_FUNDS, - "tx_digest": "", - }, - False, - ), - ( - MagicMock(performative=ContractApiMessage.Performative.RAW_TRANSACTION), - None, - RPCResponseStatus.UNCLASSIFIED_ERROR, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.PENDING, - "tx_digest": "", - }, - False, - ), - ( - MagicMock(performative=ContractApiMessage.Performative.RAW_TRANSACTION), - None, - RPCResponseStatus.UNDERPRICED, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.PENDING, - "tx_digest": "", - }, - False, - ), - ( - MagicMock(performative=ContractApiMessage.Performative.RAW_TRANSACTION), - "test_digest_0", - RPCResponseStatus.ALREADY_KNOWN, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.PENDING, - "tx_digest": "test_digest_0", - }, - False, - ), - ( - MagicMock( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=MagicMock( - body={ - "nonce": 0, - "maxPriorityFeePerGas": 10, - "maxFeePerGas": 20, - "gas": 0, - } - ), - ), - "test_digest_1", - RPCResponseStatus.SUCCESS, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.PENDING, - "tx_digest": "test_digest_1", - }, - False, - ), - ( - MagicMock( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=MagicMock( - body={ - "nonce": 0, - "maxPriorityFeePerGas": 10, - "maxFeePerGas": 20, - "gas": 0, - } - ), - ), - "test_digest_2", - RPCResponseStatus.SUCCESS, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.PENDING, - "tx_digest": "test_digest_2", - }, - True, - ), - ), - ) - def test__get_tx_data( - self, - message: ContractApiMessage, - tx_digest: Optional[str], - rpc_status: RPCResponseStatus, - expected_data: TxDataType, - replacement: bool, - monkeypatch: MonkeyPatch, - ) -> None: - """Test `_get_tx_data`.""" - # fast-forward to any behaviour of the tx settlement skill - init_db_items = dict( - most_voted_tx_hash="b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d90000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000002625a000x77E9b2EF921253A171Fa0CB9ba80558648Ff7215b0e6add595e00477c" - "f347d09797b156719dc5233283ac76e4efce2a674fe72d9b0e6add595e00477cf347d09797b156719dc5233283" - "ac76e4efce2a674fe72d9", - keepers=int(2).to_bytes(32, "big").hex() - + "".join(deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35))), - ) - self.ffw_signature(init_db_items) - behaviour = cast(SignatureBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == SignatureBehaviour.auto_behaviour_id() - # Set `nonce` to the same value as the returned, so that we test the tx replacement logging. - if replacement: - behaviour.params.mutable_params.nonce = Nonce(0) - - # patch the `send_raw_transaction` method - def dummy_send_raw_transaction( - *_: Any, **kwargs: Any - ) -> Generator[None, None, Tuple[Optional[str], RPCResponseStatus]]: - """Dummy `send_raw_transaction` method.""" - yield - return tx_digest, rpc_status - - monkeypatch.setattr( - BaseBehaviour, "send_raw_transaction", dummy_send_raw_transaction - ) - # call `_get_tx_data` - tx_data_iterator = cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - )._get_tx_data(message, use_flashbots=False) - - if message.performative == ContractApiMessage.Performative.RAW_TRANSACTION: - next(tx_data_iterator) - - try: - next(tx_data_iterator) - except StopIteration as res: - assert res.value == expected_data - - """Test the serialized_keepers method.""" - behaviour_ = self.behaviour.current_behaviour - assert behaviour_ is not None - assert behaviour_.serialized_keepers(deque([]), 1) == "" - assert ( - behaviour_.serialized_keepers(deque(["-" * 42]), 1) - == "0000000000000000000000000000000000000000000000000000000000000001" - "------------------------------------------" - ) - - @pytest.mark.parametrize( - argnames=["tx_body", "expected_params"], - argvalues=[ - [ - {"maxPriorityFeePerGas": "dummy", "maxFeePerGas": "dummy"}, - ["maxPriorityFeePerGas", "maxFeePerGas"], - ], - [{"gasPrice": "dummy"}, ["gasPrice"]], - [ - {"maxPriorityFeePerGas": "dummy"}, - [], - ], - [ - {"maxFeePerGas": "dummy"}, - [], - ], - [ - {}, - [], - ], - [ - { - "maxPriorityFeePerGas": "dummy", - "maxFeePerGas": "dummy", - "gasPrice": "dummy", - }, - ["maxPriorityFeePerGas", "maxFeePerGas"], - ], - ], - ) - def test_get_gas_price_params( - self, tx_body: dict, expected_params: List[str] - ) -> None: - """Test the get_gas_price_params method""" - # fast-forward to any behaviour of the tx settlement skill - self.ffw_signature() - - assert ( - cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - ).get_gas_price_params(tx_body) - == expected_params - ) - - def test_parse_revert_reason_successful(self) -> None: - """Test `_parse_revert_reason` method.""" - # fast-forward to any behaviour of the tx settlement skill - self.ffw_signature() - - for code, explanation in REVERT_CODES_TO_REASONS.items(): - message = MagicMock( - performative=ContractApiMessage.Performative.ERROR, - message=f"some text {code}.", - ) - - expected = f"Received a {code} revert error: {explanation}." - - assert ( - cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - )._parse_revert_reason(message) - == expected - ) - - @pytest.mark.parametrize( - "message", - ( - MagicMock( - performative=ContractApiMessage.Performative.ERROR, - message="Non existing code should be invalid GS086.", - ), - MagicMock( - performative=ContractApiMessage.Performative.ERROR, - message="Code not matching the regex should be invalid GS0265.", - ), - MagicMock( - performative=ContractApiMessage.Performative.ERROR, - message="No code in the message should be invalid.", - ), - MagicMock( - performative=ContractApiMessage.Performative.ERROR, - message="", # empty message should be invalid - ), - MagicMock( - performative=ContractApiMessage.Performative.ERROR, - message=None, # `None` message should be invalid - ), - ), - ) - def test_parse_revert_reason_unsuccessful( - self, message: ContractApiMessage - ) -> None: - """Test `_parse_revert_reason` method.""" - # fast-forward to any behaviour of the tx settlement skill - self.ffw_signature() - - expected = f"get_raw_safe_transaction unsuccessful! Received: {message}" - - assert ( - cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - )._parse_revert_reason(message) - == expected - ) - - -class TestRandomnessInOperation(BaseRandomnessBehaviourTest): - """Test randomness in operation.""" - - path_to_skill = PACKAGE_DIR - - randomness_behaviour_class = RandomnessTransactionSubmissionBehaviour - next_behaviour_class = SelectKeeperTransactionSubmissionBehaviourA - done_event = TransactionSettlementEvent.DONE - - -class TestSelectKeeperTransactionSubmissionBehaviourA(BaseSelectKeeperBehaviourTest): - """Test SelectKeeperBehaviour.""" - - path_to_skill = PACKAGE_DIR - - select_keeper_behaviour_class = SelectKeeperTransactionSubmissionBehaviourA - next_behaviour_class = SignatureBehaviour - done_event = TransactionSettlementEvent.DONE - _synchronized_data = TransactionSettlementSynchronizedSata - - -class TestSelectKeeperTransactionSubmissionBehaviourB( - TestSelectKeeperTransactionSubmissionBehaviourA -): - """Test SelectKeeperBehaviour.""" - - select_keeper_behaviour_class = SelectKeeperTransactionSubmissionBehaviourB - next_behaviour_class = FinalizeBehaviour - - @mock.patch.object( - TransactionSettlementSynchronizedSata, - "keepers", - new_callable=mock.PropertyMock, - ) - @mock.patch.object( - TransactionSettlementSynchronizedSata, - "keeper_retries", - new_callable=mock.PropertyMock, - ) - @mock.patch.object( - TransactionSettlementSynchronizedSata, - "final_verification_status", - new_callable=mock.PropertyMock, - ) - @pytest.mark.parametrize( - "keepers, keeper_retries, blacklisted_keepers, final_verification_status", - ( - ( - deque(f"keeper_{i}" for i in range(4)), - 1, - set(), - VerificationStatus.NOT_VERIFIED, - ), - (deque(("test_keeper",)), 2, set(), VerificationStatus.PENDING), - (deque(("test_keeper",)), 2, set(), VerificationStatus.NOT_VERIFIED), - (deque(("test_keeper",)), 2, {"a1"}, VerificationStatus.NOT_VERIFIED), - ( - deque(("test_keeper",)), - 2, - {"test_keeper"}, - VerificationStatus.NOT_VERIFIED, - ), - ( - deque(("test_keeper",)), - 2, - {"a_1", "a_2", "test_keeper"}, - VerificationStatus.NOT_VERIFIED, - ), - (deque(("test_keeper",)), 1, set(), VerificationStatus.NOT_VERIFIED), - (deque(("test_keeper",)), 3, set(), VerificationStatus.NOT_VERIFIED), - ), - ) - def test_select_keeper( - self, - final_verification_status_mock: mock.PropertyMock, - keeper_retries_mock: mock.PropertyMock, - keepers_mock: mock.PropertyMock, - keepers: Deque[str], - keeper_retries: int, - blacklisted_keepers: Set[str], - final_verification_status: VerificationStatus, - ) -> None: - """Test select keeper agent.""" - keepers_mock.return_value = keepers - keeper_retries_mock.return_value = keeper_retries - final_verification_status_mock.return_value = final_verification_status - super().test_select_keeper(blacklisted_keepers=blacklisted_keepers) - - @mock.patch.object( - TransactionSettlementSynchronizedSata, - "final_verification_status", - new_callable=mock.PropertyMock, - return_value=VerificationStatus.PENDING, - ) - @pytest.mark.skip # Needs to be investigated, fails in CI only. look at #1710 - def test_select_keeper_tx_pending( - self, _: mock.PropertyMock, caplog: LogCaptureFixture - ) -> None: - """Test select keeper while tx is pending""" - - with caplog.at_level(logging.INFO): - super().test_select_keeper(blacklisted_keepers=set()) - assert "Kept keepers and incremented retries" in caplog.text - - -class TestSignatureBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test SignatureBehaviour.""" - - def test_signature_behaviour( - self, - ) -> None: - """Test signature behaviour.""" - - init_db_items = dict( - most_voted_tx_hash="b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d90000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000002625a000x77E9b2EF921253A171Fa0CB9ba80558648Ff7215b0e6add595e00477c" - "f347d09797b156719dc5233283ac76e4efce2a674fe72d9b0e6add595e00477cf347d09797b156719dc5233283" - "ac76e4efce2a674fe72d9", - ) - self.ffw_signature(init_db_items) - - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == SignatureBehaviour.auto_behaviour_id() - ) - self.behaviour.act_wrapper() - self.mock_signing_request( - request_kwargs=dict( - performative=SigningMessage.Performative.SIGN_MESSAGE, - ), - response_kwargs=dict( - performative=SigningMessage.Performative.SIGNED_MESSAGE, - signed_message=SignedMessage( - ledger_id="ethereum", body="stub_signature" - ), - ), - ) - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == FinalizeBehaviour.auto_behaviour_id() - - -class TestFinalizeBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test FinalizeBehaviour.""" - - behaviour_class = FinalizeBehaviour - - def test_non_sender_act( - self, - ) -> None: - """Test finalize behaviour.""" - participants = (self.skill.skill_context.agent_address, "a_1", "a_2") - retries = 1 - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.behaviour_class.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - most_voted_keeper_address="most_voted_keeper_address", - participants=participants, - # keeper needs to have length == 42 in order to be parsed - keepers=retries.to_bytes(32, "big").hex() - + "other_agent" - + "-" * 31, - ) - ), - ) - ), - ) - assert self.behaviour.current_behaviour is not None - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - cast( - FinalizeBehaviour, self.behaviour.current_behaviour - ).params.mutable_params.tx_hash = "test" - self.behaviour.act_wrapper() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(ValidateTransactionBehaviour, self.behaviour.current_behaviour) - assert ( - behaviour.behaviour_id == ValidateTransactionBehaviour.auto_behaviour_id() - ) - assert behaviour.params.mutable_params.tx_hash == "test" - - @pytest.mark.parametrize( - "resubmitting, response_kwargs", - ( - ( - ( - True, - dict( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - callable="get_deploy_transaction", - raw_transaction=RawTransaction( - ledger_id="ethereum", - body={ - "tx_hash": "0x3b", - "nonce": 0, - "maxFeePerGas": int(10e10), - "maxPriorityFeePerGas": int(10e10), - }, - ), - ), - ) - ), - ( - False, - dict( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - callable="get_deploy_transaction", - raw_transaction=RawTransaction( - ledger_id="ethereum", - body={ - "tx_hash": "0x3b", - "nonce": 0, - "maxFeePerGas": int(10e10), - "maxPriorityFeePerGas": int(10e10), - }, - ), - ), - ), - ( - False, - dict( - performative=ContractApiMessage.Performative.ERROR, - callable="get_deploy_transaction", - code=500, - message="GS026", - data=b"", - ), - ), - ( - False, - dict( - performative=ContractApiMessage.Performative.ERROR, - callable="get_deploy_transaction", - code=500, - message="other error", - data=b"", - ), - ), - ), - ) - @mock.patch.object(SkillContext, "agent_address", new_callable=mock.PropertyMock) - def test_sender_act( - self, - agent_address_mock: mock.PropertyMock, - resubmitting: bool, - response_kwargs: Dict[ - str, - Union[ - int, - str, - bytes, - Dict[str, Union[int, str]], - ContractApiMessage.Performative, - RawTransaction, - ], - ], - ) -> None: - """Test finalize behaviour.""" - nonce: Optional[int] = None - max_priority_fee_per_gas: Optional[int] = None - - if resubmitting: - nonce = 0 - max_priority_fee_per_gas = 1 - - # keepers need to have length == 42 in order to be parsed - agent_address_mock.return_value = "-" * 42 - retries = 1 - participants = ( - self.skill.skill_context.agent_address, - "a_1" + "-" * 39, - "a_2" + "-" * 39, - ) - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.behaviour_class.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - safe_contract_address="safe_contract_address", - participants=participants, - participant_to_signature={}, - most_voted_tx_hash=hash_payload_to_hex( - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - 1, - 1, - "0x77E9b2EF921253A171Fa0CB9ba80558648Ff7215", - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ), - nonce=nonce, - max_priority_fee_per_gas=max_priority_fee_per_gas, - keepers=retries.to_bytes(32, "big").hex() - + self.skill.skill_context.agent_address, - ) - ), - ) - ), - ) - - assert self.behaviour.current_behaviour is not None - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - cast( - FinalizeBehaviour, self.behaviour.current_behaviour - ).params.mutable_params.tx_hash = "test" - self.behaviour.act_wrapper() - - self.mock_contract_api_request( - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=response_kwargs, - ) - - if ( - response_kwargs["performative"] - == ContractApiMessage.Performative.RAW_TRANSACTION - ): - self.mock_signing_request( - request_kwargs=dict( - performative=SigningMessage.Performative.SIGN_TRANSACTION - ), - response_kwargs=dict( - performative=SigningMessage.Performative.SIGNED_TRANSACTION, - signed_transaction=SignedTransaction(ledger_id="ethereum", body={}), - ), - ) - self.mock_ledger_api_request( - request_kwargs=dict( - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION - ), - response_kwargs=dict( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, - transaction_digest=TransactionDigest( - ledger_id="ethereum", body="tx_hash" - ), - ), - ) - - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - assert ( - self.behaviour.current_behaviour.behaviour_id - == ValidateTransactionBehaviour.auto_behaviour_id() - ) - assert ( - cast( - ValidateTransactionBehaviour, self.behaviour.current_behaviour - ).params.mutable_params.tx_hash - == "" - ) - - def test_sender_act_tx_data_contains_tx_digest(self) -> None: - """Test finalize behaviour.""" - - max_priority_fee_per_gas: Optional[int] = None - - retries = 1 - participants = ( - self.skill.skill_context.agent_address, - "a_1" + "-" * 39, - "a_2" + "-" * 39, - ) - kwargs = dict( - safe_contract_address="safe_contract_address", - participants=participants, - participant_to_signature={}, - most_voted_tx_hash=hash_payload_to_hex( - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - 1, - 1, - "0x77E9b2EF921253A171Fa0CB9ba80558648Ff7215", - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ), - nonce=None, - max_priority_fee_per_gas=max_priority_fee_per_gas, - keepers=retries.to_bytes(32, "big").hex() - + self.skill.skill_context.agent_address, - ) - - db = AbciAppDB(setup_data=AbciAppDB.data_to_lists(kwargs)) - - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.behaviour_class.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata(db), - ) - - response_kwargs = dict( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - callable="get_deploy_transaction", - raw_transaction=RawTransaction( - ledger_id="ethereum", - body={ - "tx_hash": "0x3b", - "nonce": 0, - "maxFeePerGas": int(10e10), - "maxPriorityFeePerGas": int(10e10), - }, - ), - ) - - # mock the returned tx_data - return_value = dict( - status=VerificationStatus.PENDING, - keepers=deque(), - keeper_retries=1, - blacklisted_keepers=set(), - tx_digest="dummy_tx_digest", - ) - - current_behaviour = cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - ) - current_behaviour._get_tx_data = mock_yield_and_return(return_value) # type: ignore - - self.behaviour.act_wrapper() - self.mock_contract_api_request( - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=response_kwargs, - ) - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - - current_behaviour = cast( - ValidateTransactionBehaviour, self.behaviour.current_behaviour - ) - current_behaviour_id = current_behaviour.behaviour_id - expected_behaviour_id = ValidateTransactionBehaviour.auto_behaviour_id() - assert current_behaviour_id == expected_behaviour_id - - def test_handle_late_messages(self) -> None: - """Test `handle_late_messages.`""" - participants = (self.skill.skill_context.agent_address, "a_1", "a_2") - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.behaviour_class.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - most_voted_keeper_address="most_voted_keeper_address", - participants=participants, - keepers="keepers", - ) - ), - ) - ), - ) - self.behaviour.current_behaviour = cast( - BaseBehaviour, self.behaviour.current_behaviour - ) - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - - message = ContractApiMessage(ContractApiMessage.Performative.RAW_MESSAGE) # type: ignore - self.behaviour.current_behaviour.handle_late_messages( - self.behaviour.current_behaviour.behaviour_id, message - ) - assert cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - ).params.mutable_params.late_messages == [message] - - with mock.patch.object(self.behaviour.context.logger, "warning") as mock_info: - self.behaviour.current_behaviour.handle_late_messages( - "other_behaviour_id", message - ) - mock_info.assert_called_with( - f"No callback defined for request with nonce: {message.dialogue_reference[0]}, " - "arriving for behaviour: other_behaviour_id" - ) - message = MagicMock() - self.behaviour.current_behaviour.handle_late_messages( - self.behaviour.current_behaviour.behaviour_id, message - ) - mock_info.assert_called_with( - f"No callback defined for request with nonce: {message.dialogue_reference[0]}, " - f"arriving for behaviour: {FinalizeBehaviour.auto_behaviour_id()}" - ) - - -class TestValidateTransactionBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test ValidateTransactionBehaviour.""" - - def _fast_forward(self) -> None: - """Fast-forward to relevant behaviour.""" - participants = (self.skill.skill_context.agent_address, "a_1", "a_2") - most_voted_keeper_address = self.skill.skill_context.agent_address - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=ValidateTransactionBehaviour.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - safe_contract_address="safe_contract_address", - tx_hashes_history="t" * 66, - final_tx_hash="dummy_hash", - participants=participants, - most_voted_keeper_address=most_voted_keeper_address, - participant_to_signature={}, - most_voted_tx_hash=hash_payload_to_hex( - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - 1, - 1, - "0x77E9b2EF921253A171Fa0CB9ba80558648Ff7215", - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ), - max_priority_fee_per_gas=int(10e10), - ) - ), - ) - ), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == ValidateTransactionBehaviour.auto_behaviour_id() - ) - - def test_validate_transaction_safe_behaviour( - self, - ) -> None: - """Test ValidateTransactionBehaviour.""" - self._fast_forward() - self.behaviour.act_wrapper() - self.mock_ledger_api_request( - request_kwargs=dict( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT - ), - response_kwargs=dict( - performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - transaction_receipt=TransactionReceipt( - ledger_id="ethereum", receipt={"status": 1}, transaction={} - ), - ), - ) - self.mock_contract_api_request( - request_kwargs=dict(performative=ContractApiMessage.Performative.GET_STATE), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=dict( - performative=ContractApiMessage.Performative.STATE, - callable="get_deploy_transaction", - state=TrState(ledger_id="ethereum", body={"verified": True}), - ), - ) - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert ( - behaviour.behaviour_id - == make_degenerate_behaviour( - FinishedTransactionSubmissionRound - ).auto_behaviour_id() - ) - - def test_validate_transaction_safe_behaviour_no_tx_sent( - self, - ) -> None: - """Test ValidateTransactionBehaviour when tx cannot be sent.""" - self._fast_forward() - - with mock.patch.object(self.behaviour.context.logger, "error") as mock_logger: - self.behaviour.act_wrapper() - self.mock_ledger_api_request( - request_kwargs=dict( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, - ), - response_kwargs=dict( - performative=LedgerApiMessage.Performative.ERROR, - code=1, - ), - ) - behaviour = cast( - TransactionSettlementBaseBehaviour, - self.behaviour.current_behaviour, - ) - latest_tx_hash = behaviour.synchronized_data.tx_hashes_history[-1] - mock_logger.assert_any_call(f"tx {latest_tx_hash} receipt check timed out!") - - -class TestCheckTransactionHistoryBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test CheckTransactionHistoryBehaviour.""" - - def _fast_forward(self, hashes_history: str) -> None: - """Fast-forward to relevant behaviour.""" - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=CheckTransactionHistoryBehaviour.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - safe_contract_address="safe_contract_address", - participants=( - self.skill.skill_context.agent_address, - "a_1", - "a_2", - ), - participant_to_signature={}, - most_voted_tx_hash="b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002625a000x77E9b2EF921253A171Fa0CB9ba80558648Ff7215b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - tx_hashes_history=hashes_history, - ) - ), - ) - ), - ) - assert ( - cast(BaseBehaviour, self.behaviour.current_behaviour).behaviour_id - == CheckTransactionHistoryBehaviour.auto_behaviour_id() - ) - - @pytest.mark.parametrize( - "verified, status, hashes_history, revert_reason", - ( - (False, -1, "0x" + "t" * 64, "test"), - (False, 0, "", "test"), - (False, 0, "0x" + "t" * 64, "test"), - (False, 0, "0x" + "t" * 64, "GS026"), - (True, 1, "0x" + "t" * 64, "test"), - ), - ) - def test_check_tx_history_behaviour( - self, - verified: bool, - status: int, - hashes_history: str, - revert_reason: str, - ) -> None: - """Test CheckTransactionHistoryBehaviour.""" - self._fast_forward(hashes_history) - self.behaviour.act_wrapper() - - if hashes_history: - self.mock_contract_api_request( - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE - ), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=dict( - performative=ContractApiMessage.Performative.STATE, - callable="get_safe_nonce", - state=TrState( - ledger_id="ethereum", - body={ - "safe_nonce": 0, - }, - ), - ), - ) - self.mock_contract_api_request( - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE - ), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=dict( - performative=ContractApiMessage.Performative.STATE, - callable="verify_tx", - state=TrState( - ledger_id="ethereum", - body={ - "verified": verified, - "status": status, - "transaction": {}, - }, - ), - ), - ) - - if not verified and status != -1: - self.mock_contract_api_request( - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE - ), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=dict( - performative=ContractApiMessage.Performative.STATE, - callable="revert_reason", - state=TrState( - ledger_id="ethereum", body={"revert_reason": revert_reason} - ), - ), - ) - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert ( - behaviour.behaviour_id - == make_degenerate_behaviour( - FinishedTransactionSubmissionRound - ).auto_behaviour_id() - ) - - @pytest.mark.parametrize( - "verified, status, hashes_history, revert_reason", - ((False, 0, "0x" + "t" * 64, "test"),), - ) - def test_check_tx_history_behaviour_negative( - self, - verified: bool, - status: int, - hashes_history: str, - revert_reason: str, - ) -> None: - """Test CheckTransactionHistoryBehaviour.""" - self._fast_forward(hashes_history) - self.behaviour.act_wrapper() - self.behaviour.context.params.mutable_params.nonce = 1 - if hashes_history: - self.mock_contract_api_request( - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE - ), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=dict( - performative=ContractApiMessage.Performative.STATE, - callable="get_safe_nonce", - state=TrState( - ledger_id="ethereum", - body={ - "safe_nonce": 1, - }, - ), - ), - ) - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert ( - behaviour.behaviour_id - == make_degenerate_behaviour( - FinishedTransactionSubmissionRound - ).auto_behaviour_id() - ) - - -class TestCheckLateTxHashesBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test CheckLateTxHashesBehaviour.""" - - def _fast_forward(self, late_arriving_tx_hashes: Dict[str, str]) -> None: - """Fast-forward to relevant behaviour.""" - - agent_address = self.skill.skill_context.agent_address - kwargs = dict( - safe_contract_address="safe_contract_address", - participants=(agent_address, "a_1", "a_2"), - participant_to_signature={}, - most_voted_tx_hash="", - late_arriving_tx_hashes=late_arriving_tx_hashes, - ) - abci_app_db = AbciAppDB(setup_data=AbciAppDB.data_to_lists(kwargs)) - - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=CheckLateTxHashesBehaviour.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata(abci_app_db), - ) - - current_behaviour = self.behaviour.current_behaviour - current_behaviour_id = cast(BaseBehaviour, current_behaviour).behaviour_id - assert current_behaviour_id == CheckLateTxHashesBehaviour.auto_behaviour_id() - - def test_check_tx_history_behaviour(self) -> None: - """Test CheckTransactionHistoryBehaviour.""" - self._fast_forward(late_arriving_tx_hashes={}) - self.behaviour.act_wrapper() - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - next_degen_behaviour = make_degenerate_behaviour( - FinishedTransactionSubmissionRound - ) - assert behaviour.behaviour_id == next_degen_behaviour.auto_behaviour_id() - - -class TestSynchronizeLateMessagesBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test `SynchronizeLateMessagesBehaviour`""" - - def _check_behaviour_id( - self, expected: Type[TransactionSettlementBaseBehaviour] - ) -> None: - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == expected.auto_behaviour_id() - - @pytest.mark.parametrize("late_messages", ([], [MagicMock, MagicMock])) - def test_async_act(self, late_messages: List[MagicMock]) -> None: - """Test `async_act`""" - cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - ).params.mutable_params.late_messages = late_messages - - participants = (self.skill.skill_context.agent_address, "a_1", "a_2") - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=SynchronizeLateMessagesBehaviour.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=dict( - participants=[participants], - participant_to_signature=[{}], - safe_contract_address=["safe_contract_address"], - most_voted_tx_hash=[ - hash_payload_to_hex( - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - 1, - 1, - "0x77E9b2EF921253A171Fa0CB9ba80558648Ff7215", - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9" - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ) - ], - ), - ) - ), - ) - self._check_behaviour_id(SynchronizeLateMessagesBehaviour) # type: ignore - - if not late_messages: - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - self._check_behaviour_id(CheckLateTxHashesBehaviour) # type: ignore - - else: - - def _dummy_get_tx_data( - _current_message: ContractApiMessage, - _use_flashbots: bool, - chain_id: Optional[str] = None, - ) -> Generator[None, None, TxDataType]: - yield - return { - "status": VerificationStatus.PENDING, - "tx_digest": "test", - } - - cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - )._get_tx_data = _dummy_get_tx_data # type: ignore - for _ in range(len(late_messages)): - self.behaviour.act_wrapper() - - -class TestResetBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test the reset behaviour.""" - - behaviour_class = ResetBehaviour - next_behaviour_class = RandomnessTransactionSubmissionBehaviour - - def test_reset_behaviour( - self, - ) -> None: - """Test reset behaviour.""" - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.behaviour_class.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB(setup_data=dict(estimate=[1.0])), - ), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - self.behaviour.context.params.__dict__["reset_pause_duration"] = 0.1 - self.behaviour.act_wrapper() - time.sleep(0.3) - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == self.next_behaviour_class.auto_behaviour_id() diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_dialogues.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_dialogues.py deleted file mode 100644 index 519ea4df0..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.transaction_settlement_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_handlers.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_handlers.py deleted file mode 100644 index c458846bd..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_handlers.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.transaction_settlement_abci.handlers # noqa - - -def test_import() -> None: - """Test that the 'handlers.py' Python module can be imported.""" diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_models.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_models.py deleted file mode 100644 index 746f0a312..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_models.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ -# pylint: disable=unused-import - -"""Test the models.py module of the skill.""" -from typing import Any, Dict -from unittest.mock import MagicMock - -import pytest -import yaml -from aea.exceptions import AEAEnforceError - -from packages.valory.skills.abstract_round_abci.test_tools.base import DummyContext -from packages.valory.skills.transaction_settlement_abci.models import ( - TransactionParams, - _MINIMUM_VALIDATE_TIMEOUT, -) -from packages.valory.skills.transaction_settlement_abci.tests import PACKAGE_DIR - - -class TestTransactionParams: # pylint: disable=too-few-public-methods - """Test TransactionParams class.""" - - default_config: Dict - - def setup_class(self) -> None: - """Read the default config only once.""" - skill_yaml = PACKAGE_DIR / "skill.yaml" - with open(skill_yaml, "r", encoding="utf-8") as skill_file: - skill = yaml.safe_load(skill_file) - self.default_config = skill["models"]["params"]["args"] - - def test_ensure_validate_timeout( # pylint: disable=no-self-use - self, - ) -> None: - """Test that `_ensure_validate_timeout` raises when `validate_timeout` is lower than the allowed minimum.""" - dummy_value = 0 - mock_args, mock_kwargs = ( - MagicMock(), - { - **self.default_config, - "validate_timeout": dummy_value, - "skill_context": DummyContext(), - }, - ) - with pytest.raises( - expected_exception=AEAEnforceError, - match=f"`validate_timeout` must be greater than or equal to {_MINIMUM_VALIDATE_TIMEOUT}", - ): - TransactionParams(mock_args, **mock_kwargs) - - @pytest.mark.parametrize( - "gas_params", - [ - {}, - {"gas_price": 1}, - {"max_fee_per_gas": 1}, - {"max_priority_fee_per_gas": 1}, - { - "gas_price": 1, - "max_fee_per_gas": 1, - "max_priority_fee_per_gas": 1, - }, - ], - ) - def test_gas_params(self, gas_params: Dict[str, Any]) -> None: - """Test that gas params are being handled properly.""" - mock_args, mock_kwargs = ( - MagicMock(), - { - **self.default_config, - "gas_params": gas_params, - "skill_context": DummyContext(), - }, - ) - params = TransactionParams(mock_args, **mock_kwargs) - # verify that the gas params are being set properly - for key, value in gas_params.items(): - assert getattr(params.gas_params, key) == value diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_payload_tools.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_payload_tools.py deleted file mode 100644 index 91a90cf81..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_payload_tools.py +++ /dev/null @@ -1,101 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/transaction settlement skill's payload tools.""" - -# pylint: skip-file - -import pytest - -from packages.valory.contracts.gnosis_safe.contract import SafeOperation -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - NULL_ADDRESS, - PayloadDeserializationError, - VerificationStatus, - hash_payload_to_hex, - skill_input_hex_to_payload, - tx_hist_hex_to_payload, - tx_hist_payload_to_hex, -) - - -class TestTxHistPayloadEncodingDecoding: - """Tests for the transaction history's payload encoding - decoding.""" - - @staticmethod - @pytest.mark.parametrize( - "verification_status, tx_hash", - ( - ( - VerificationStatus.VERIFIED, - "0xb0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ), - (VerificationStatus.ERROR, None), - ), - ) - def test_tx_hist_payload_to_hex_and_back( - verification_status: VerificationStatus, tx_hash: str - ) -> None: - """Test `tx_hist_payload_to_hex` and `tx_hist_hex_to_payload` functions.""" - intermediate = tx_hist_payload_to_hex(verification_status, tx_hash) - verification_status_, tx_hash_ = tx_hist_hex_to_payload(intermediate) - assert verification_status == verification_status_ - assert tx_hash == tx_hash_ - - @staticmethod - def test_invalid_tx_hash_during_serialization() -> None: - """Test encoding when transaction hash is invalid.""" - with pytest.raises(ValueError): - tx_hist_payload_to_hex(VerificationStatus.VERIFIED, "") - - @staticmethod - @pytest.mark.parametrize( - "payload", - ("0000000000000000000000000000000000000000000000000000000000000008", ""), - ) - def test_invalid_payloads_during_deserialization(payload: str) -> None: - """Test decoding payload is invalid.""" - with pytest.raises(PayloadDeserializationError): - tx_hist_hex_to_payload(payload) - - -@pytest.mark.parametrize("use_flashbots", (True, False)) -def test_payload_to_hex_and_back(use_flashbots: bool) -> None: - """Test `payload_to_hex` function.""" - tx_params = dict( - safe_tx_hash="b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ether_value=0, - safe_tx_gas=40000000, - to_address="0x77E9b2EF921253A171Fa0CB9ba80558648Ff7215", - data=( - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9" - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9" - ), - operation=SafeOperation.CALL.value, - base_gas=0, - safe_gas_price=0, - gas_token=NULL_ADDRESS, - use_flashbots=use_flashbots, - gas_limit=0, - refund_receiver=NULL_ADDRESS, - raise_on_failed_simulation=False, - ) - - intermediate = hash_payload_to_hex(**tx_params) # type: ignore - assert tx_params == skill_input_hex_to_payload(intermediate) diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_payloads.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_payloads.py deleted file mode 100644 index e53cd26d1..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_payloads.py +++ /dev/null @@ -1,126 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the payloads of the skill.""" - -# pylint: skip-file - -from typing import Optional - -import pytest - -from packages.valory.skills.transaction_settlement_abci.payloads import ( - CheckTransactionHistoryPayload, - FinalizationTxPayload, - RandomnessPayload, - ResetPayload, - SelectKeeperPayload, - SignaturePayload, - SynchronizeLateMessagesPayload, - ValidatePayload, -) - - -def test_randomness_payload() -> None: - """Test `RandomnessPayload`.""" - - payload = RandomnessPayload(sender="sender", round_id=1, randomness="test") - - assert payload.round_id == 1 - assert payload.randomness == "test" - assert payload.data == {"round_id": 1, "randomness": "test"} - - -def test_select_keeper_payload() -> None: - """Test `SelectKeeperPayload`.""" - - payload = SelectKeeperPayload(sender="sender", keepers="test") - - assert payload.keepers == "test" - assert payload.data == {"keepers": "test"} - - -@pytest.mark.parametrize("vote", (None, True, False)) -def test_validate_payload(vote: Optional[bool]) -> None: - """Test `ValidatePayload`.""" - - payload = ValidatePayload(sender="sender", vote=vote) - - assert payload.vote is vote - assert payload.data == {"vote": vote} - - -def test_tx_history_payload() -> None: - """Test `CheckTransactionHistoryPayload`.""" - - payload = CheckTransactionHistoryPayload(sender="sender", verified_res="test") - - assert payload.verified_res == "test" - assert payload.data == {"verified_res": "test"} - - -def test_synchronize_payload() -> None: - """Test `SynchronizeLateMessagesPayload`.""" - - tx_hashes = "test" - payload = SynchronizeLateMessagesPayload(sender="sender", tx_hashes=tx_hashes) - - assert payload.tx_hashes == tx_hashes - assert payload.data == {"tx_hashes": tx_hashes} - - -def test_signature_payload() -> None: - """Test `SignaturePayload`.""" - - payload = SignaturePayload(sender="sender", signature="sign") - - assert payload.signature == "sign" - assert payload.data == {"signature": "sign"} - - -def test_finalization_tx_payload() -> None: - """Test `FinalizationTxPayload`.""" - - payload = FinalizationTxPayload( - sender="sender", - tx_data={ - "tx_digest": "hash", - "nonce": 0, - "max_fee_per_gas": 0, - "max_priority_fee_per_gas": 0, - }, - ) - - assert payload.data == { - "tx_data": { - "tx_digest": "hash", - "nonce": 0, - "max_fee_per_gas": 0, - "max_priority_fee_per_gas": 0, - } - } - - -def test_reset_payload() -> None: - """Test `ResetPayload`.""" - - payload = ResetPayload(sender="sender", period_count=1) - - assert payload.period_count == 1 - assert payload.data == {"period_count": 1} diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_rounds.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_rounds.py deleted file mode 100644 index ecdb1af88..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_rounds.py +++ /dev/null @@ -1,1023 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/registration_abci skill's rounds.""" - -# pylint: skip-file - -import hashlib -import logging # noqa: F401 -from collections import deque -from typing import ( - Any, - Deque, - Dict, - FrozenSet, - List, - Mapping, - Optional, - Type, - Union, - cast, -) -from unittest import mock -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciAppDB, -) -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData as SynchronizedData, -) -from packages.valory.skills.abstract_round_abci.base import ( - BaseTxPayload, - CollectSameUntilThresholdRound, - CollectionRound, - MAX_INT_256, - TransactionNotValidError, - VotingRound, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectDifferentUntilThresholdRoundTest, - BaseCollectNonEmptyUntilThresholdRound, - BaseCollectSameUntilThresholdRoundTest, - BaseOnlyKeeperSendsRoundTest, - BaseVotingRoundTest, -) -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - VerificationStatus, -) -from packages.valory.skills.transaction_settlement_abci.payloads import ( - CheckTransactionHistoryPayload, - FinalizationTxPayload, - RandomnessPayload, - ResetPayload, - SelectKeeperPayload, - SignaturePayload, - SynchronizeLateMessagesPayload, - ValidatePayload, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - CheckTransactionHistoryRound, - CollectSignatureRound, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - Event as TransactionSettlementEvent, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - FinalizationRound, - ResetRound, - SelectKeeperTransactionSubmissionARound, - SelectKeeperTransactionSubmissionBAfterTimeoutRound, - SelectKeeperTransactionSubmissionBRound, - SynchronizeLateMessagesRound, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TransactionSettlementSynchronizedSata, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - TX_HASH_LENGTH, - ValidateTransactionRound, -) - - -MAX_PARTICIPANTS: int = 4 -RANDOMNESS: str = "d1c29dce46f979f9748210d24bce4eae8be91272f5ca1a6aea2832d3dd676f51" -DUMMY_RANDOMNESS = hashlib.sha256("hash".encode() + str(0).encode()).hexdigest() - - -def get_participants() -> FrozenSet[str]: - """Participants""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -def get_participant_to_randomness( - participants: FrozenSet[str], round_id: int -) -> Dict[str, RandomnessPayload]: - """participant_to_randomness""" - return { - participant: RandomnessPayload( - sender=participant, - round_id=round_id, - randomness=RANDOMNESS, - ) - for participant in participants - } - - -def get_most_voted_randomness() -> str: - """most_voted_randomness""" - return RANDOMNESS - - -def get_participant_to_selection( - participants: FrozenSet[str], - keepers: str, -) -> Dict[str, SelectKeeperPayload]: - """participant_to_selection""" - return { - participant: SelectKeeperPayload(sender=participant, keepers=keepers) - for participant in participants - } - - -def get_participant_to_period_count( - participants: FrozenSet[str], period_count: int -) -> Dict[str, ResetPayload]: - """participant_to_selection""" - return { - participant: ResetPayload(sender=participant, period_count=period_count) - for participant in participants - } - - -def get_safe_contract_address() -> str: - """safe_contract_address""" - return "0x6f6ab56aca12" - - -def get_participant_to_votes( - participants: FrozenSet[str], vote: Optional[bool] = True -) -> Dict[str, ValidatePayload]: - """participant_to_votes""" - return { - participant: ValidatePayload(sender=participant, vote=vote) - for participant in participants - } - - -def get_participant_to_votes_serialized( - participants: FrozenSet[str], vote: Optional[bool] = True -) -> Dict[str, Dict[str, Any]]: - """participant_to_votes""" - return CollectionRound.serialize_collection( - get_participant_to_votes(participants, vote) - ) - - -def get_most_voted_tx_hash() -> str: - """most_voted_tx_hash""" - return "tx_hash" - - -def get_participant_to_signature( - participants: FrozenSet[str], -) -> Dict[str, SignaturePayload]: - """participant_to_signature""" - return { - participant: SignaturePayload(sender=participant, signature="signature") - for participant in participants - } - - -def get_final_tx_hash() -> str: - """final_tx_hash""" - return "tx_hash" - - -def get_participant_to_check( - participants: FrozenSet[str], - status: str, - tx_hash: str, -) -> Dict[str, CheckTransactionHistoryPayload]: - """Get participants to check""" - return { - participant: CheckTransactionHistoryPayload( - sender=participant, - verified_res=status + tx_hash, - ) - for participant in participants - } - - -def get_participant_to_late_arriving_tx_hashes( - participants: FrozenSet[str], -) -> Dict[str, SynchronizeLateMessagesPayload]: - """participant_to_selection""" - return { - participant: SynchronizeLateMessagesPayload( - sender=participant, tx_hashes="1" * TX_HASH_LENGTH + "2" * TX_HASH_LENGTH - ) - for participant in participants - } - - -def get_late_arriving_tx_hashes_deserialized() -> Dict[str, List[str]]: - """Get dummy late-arriving tx hashes.""" - # We want the tx hashes to have a size which can be divided by 64 to be able to parse it. - # Otherwise, they are not valid. - return { - "sender": [ - "t" * TX_HASH_LENGTH, - "e" * TX_HASH_LENGTH, - "s" * TX_HASH_LENGTH, - "t" * TX_HASH_LENGTH, - ] - } - - -def get_late_arriving_tx_hashes_serialized() -> Dict[str, str]: - """Get dummy late-arriving tx hashes.""" - # We want the tx hashes to have a size which can be divided by 64 to be able to parse it. - # Otherwise, they are not valid. - deserialized = get_late_arriving_tx_hashes_deserialized() - return {sender: "".join(hash_) for sender, hash_ in deserialized.items()} - - -def get_keepers(keepers: Deque[str], retries: int = 1) -> str: - """Get dummy keepers.""" - return retries.to_bytes(32, "big").hex() + "".join(keepers) - - -class BaseValidateRoundTest(BaseVotingRoundTest): - """Test BaseValidateRound.""" - - test_class: Type[VotingRound] - test_payload: Type[ValidatePayload] - - def test_positive_votes( - self, - ) -> None: - """Test ValidateRound.""" - - self.synchronized_data.update(tx_hashes_history="t" * 66) - - test_round = self.test_class( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_voting_round_positive( - test_round=test_round, - round_payloads=get_participant_to_votes(self.participants), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.update( - participant_to_votes=get_participant_to_votes_serialized( - self.participants - ) - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.participant_to_votes.keys() - ], - exit_event=self._event_class.DONE, - ) - ) - - def test_negative_votes( - self, - ) -> None: - """Test ValidateRound.""" - - test_round = self.test_class( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_voting_round_negative( - test_round=test_round, - round_payloads=get_participant_to_votes(self.participants, vote=False), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.update( - participant_to_votes=get_participant_to_votes_serialized( - self.participants, vote=False - ) - ), - synchronized_data_attr_checks=[], - exit_event=self._event_class.NEGATIVE, - ) - ) - - def test_none_votes( - self, - ) -> None: - """Test ValidateRound.""" - - test_round = self.test_class( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_voting_round_none( - test_round=test_round, - round_payloads=get_participant_to_votes(self.participants, vote=None), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.update( - participant_to_votes=get_participant_to_votes_serialized( - self.participants, vote=None - ) - ), - synchronized_data_attr_checks=[], - exit_event=self._event_class.NONE, - ) - ) - - -class BaseSelectKeeperRoundTest(BaseCollectSameUntilThresholdRoundTest): - """Test SelectKeeperTransactionSubmissionARound""" - - test_class: Type[CollectSameUntilThresholdRound] - test_payload: Type[BaseTxPayload] - - _synchronized_data_class = SynchronizedData - - @staticmethod - def _participant_to_selection( - participants: FrozenSet[str], keepers: str - ) -> Mapping[str, BaseTxPayload]: - """Get participant to selection""" - return get_participant_to_selection(participants, keepers) - - def test_run( - self, - most_voted_payload: str = "keeper", - keepers: str = "", - exit_event: Optional[Any] = None, - ) -> None: - """Run tests.""" - test_round = self.test_class( - synchronized_data=self.synchronized_data.update( - keepers=keepers, - ), - context=MagicMock(), - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=self._participant_to_selection( - self.participants, most_voted_payload - ), - synchronized_data_update_fn=lambda _synchronized_data, _test_round: _synchronized_data.update( - participant_to_selection=CollectionRound.serialize_collection( - self._participant_to_selection( - self.participants, most_voted_payload - ) - ) - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.participant_to_selection.keys() - if exit_event is None - else None - ], - most_voted_payload=most_voted_payload, - exit_event=self._event_class.DONE if exit_event is None else exit_event, - ) - ) - - -class TestSelectKeeperTransactionSubmissionARound(BaseSelectKeeperRoundTest): - """Test SelectKeeperTransactionSubmissionARound""" - - test_class = SelectKeeperTransactionSubmissionARound - test_payload = SelectKeeperPayload - _synchronized_data_class = TransactionSettlementSynchronizedSata - _event_class = TransactionSettlementEvent - - @pytest.mark.parametrize( - "most_voted_payload, keepers, exit_event", - ( - ( - "incorrectly_serialized", - "", - TransactionSettlementEvent.INCORRECT_SERIALIZATION, - ), - ( - int(1).to_bytes(32, "big").hex() + "new_keeper" + "-" * 32, - "", - TransactionSettlementEvent.DONE, - ), - ), - ) - def test_run( - self, - most_voted_payload: str, - keepers: str, - exit_event: TransactionSettlementEvent, - ) -> None: - """Run tests.""" - super().test_run(most_voted_payload, keepers, exit_event) - - -class TestSelectKeeperTransactionSubmissionBRound( - TestSelectKeeperTransactionSubmissionARound -): - """Test SelectKeeperTransactionSubmissionBRound.""" - - test_class = SelectKeeperTransactionSubmissionBRound - - @pytest.mark.parametrize( - "most_voted_payload, keepers, exit_event", - ( - ( - int(1).to_bytes(32, "big").hex() + "new_keeper" + "-" * 32, - "", - TransactionSettlementEvent.DONE, - ), - ( - int(1).to_bytes(32, "big").hex() + "new_keeper" + "-" * 32, - int(1).to_bytes(32, "big").hex() - + "".join( - [keeper + "-" * 30 for keeper in ("test_keeper1", "test_keeper2")] - ), - TransactionSettlementEvent.DONE, - ), - ), - ) - def test_run( - self, - most_voted_payload: str, - keepers: str, - exit_event: TransactionSettlementEvent, - ) -> None: - """Run tests.""" - super().test_run(most_voted_payload, keepers, exit_event) - - -class TestSelectKeeperTransactionSubmissionBAfterTimeoutRound( - TestSelectKeeperTransactionSubmissionBRound -): - """Test SelectKeeperTransactionSubmissionBAfterTimeoutRound.""" - - test_class = SelectKeeperTransactionSubmissionBAfterTimeoutRound - - @mock.patch.object( - TransactionSettlementSynchronizedSata, - "keepers_threshold_exceeded", - new_callable=mock.PropertyMock, - ) - @pytest.mark.parametrize( - "keepers", (f"{int(1).to_bytes(32, 'big').hex()}keeper" + "-" * 36,) - ) - @pytest.mark.parametrize( - "attrs, threshold_exceeded, exit_event", - ( - ( - { - "tx_hashes_history": "t" * 66, - "missed_messages": {f"keeper{'-' * 36}": 10}, - }, - True, - # Since the threshold has been exceeded, we should return a `CHECK_HISTORY` event. - TransactionSettlementEvent.CHECK_HISTORY, - ), - ( - { - "missed_messages": {f"keeper{'-' * 36}": 10}, - }, - True, - TransactionSettlementEvent.CHECK_LATE_ARRIVING_MESSAGE, - ), - ( - { - "missed_messages": {f"keeper{'-' * 36}": 10}, - }, - False, - TransactionSettlementEvent.DONE, - ), - ), - ) - def test_run( - self, - threshold_exceeded_mock: mock.PropertyMock, - keepers: str, - attrs: Dict[str, Union[str, int]], - threshold_exceeded: bool, - exit_event: TransactionSettlementEvent, - ) -> None: - """Test `SelectKeeperTransactionSubmissionBAfterTimeoutRound`.""" - self.synchronized_data.update(participant_to_selection=dict.fromkeys(self.participants), **attrs) # type: ignore - threshold_exceeded_mock.return_value = threshold_exceeded - most_voted_payload = int(1).to_bytes(32, "big").hex() + "new_keeper" + "-" * 32 - super().test_run(most_voted_payload, keepers, exit_event) - initial_missed_messages = cast(Dict[str, int], (attrs["missed_messages"])) - expected_missed_messages = { - sender: missed + 1 for sender, missed in initial_missed_messages.items() - } - synchronized_data = cast( - TransactionSettlementSynchronizedSata, self.synchronized_data - ) - assert synchronized_data.missed_messages == expected_missed_messages - - -class TestFinalizationRound(BaseOnlyKeeperSendsRoundTest): - """Test FinalizationRound.""" - - _synchronized_data_class = TransactionSettlementSynchronizedSata - _event_class = TransactionSettlementEvent - _round_class = FinalizationRound - - @pytest.mark.parametrize( - "tx_hashes_history, tx_digest, missed_messages, status, exit_event", - ( - ( - "", - "", - {"test": 1}, - VerificationStatus.ERROR.value, - TransactionSettlementEvent.CHECK_LATE_ARRIVING_MESSAGE, - ), - ( - "", - "", - {}, - VerificationStatus.ERROR.value, - TransactionSettlementEvent.FINALIZATION_FAILED, - ), - ( - "t" * 66, - "", - {}, - VerificationStatus.VERIFIED.value, - TransactionSettlementEvent.CHECK_HISTORY, - ), - ( - "t" * 66, - "", - {}, - VerificationStatus.ERROR.value, - TransactionSettlementEvent.CHECK_HISTORY, - ), - ( - "", - "", - {}, - VerificationStatus.PENDING.value, - TransactionSettlementEvent.FINALIZATION_FAILED, - ), - ( - "", - "tx_digest" + "t" * 57, - {}, - VerificationStatus.PENDING.value, - TransactionSettlementEvent.DONE, - ), - ( - "t" * 66, - "tx_digest" + "t" * 57, - {}, - VerificationStatus.PENDING.value, - TransactionSettlementEvent.DONE, - ), - ( - "t" * 66, - "", - {}, - VerificationStatus.INSUFFICIENT_FUNDS.value, - TransactionSettlementEvent.INSUFFICIENT_FUNDS, - ), - ), - ) - def test_finalization_round( - self, - tx_hashes_history: str, - tx_digest: str, - missed_messages: int, - status: int, - exit_event: TransactionSettlementEvent, - ) -> None: - """Runs tests.""" - keeper_retries = 2 - blacklisted_keepers = "" - self.participants = frozenset([f"agent_{i}" + "-" * 35 for i in range(4)]) - keepers = deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)) - self.synchronized_data = cast( - TransactionSettlementSynchronizedSata, - self.synchronized_data.update( - participants=tuple(self.participants), - missed_messages=missed_messages, - tx_hashes_history=tx_hashes_history, - keepers=get_keepers(keepers, keeper_retries), - blacklisted_keepers=blacklisted_keepers, - ), - ) - - sender = keepers[0] - tx_hashes_history += ( - tx_digest - if exit_event == TransactionSettlementEvent.DONE - else tx_hashes_history - ) - if status == VerificationStatus.INSUFFICIENT_FUNDS.value: - popped = keepers.popleft() - blacklisted_keepers += popped - keeper_retries = 1 - - test_round = self._round_class( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_round( - test_round=test_round, - keeper_payloads=FinalizationTxPayload( - sender=sender, - tx_data={ - "status_value": status, - "serialized_keepers": get_keepers(keepers, keeper_retries), - "blacklisted_keepers": blacklisted_keepers, - "tx_hashes_history": tx_hashes_history, - "received_hash": bool(tx_digest), - }, - ), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.update( - tx_hashes_history=tx_hashes_history, - blacklisted_keepers=blacklisted_keepers, - keepers=get_keepers(keepers, keeper_retries), - keeper_retries=keeper_retries, - final_verification_status=VerificationStatus(status).value, - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.tx_hashes_history, - lambda _synchronized_data: _synchronized_data.blacklisted_keepers, - lambda _synchronized_data: _synchronized_data.keepers, - lambda _synchronized_data: _synchronized_data.keeper_retries, - lambda _synchronized_data: _synchronized_data.final_verification_status, - ], - exit_event=exit_event, - ) - ) - - def test_finalization_round_no_tx_data(self) -> None: - """Test finalization round when `tx_data` is `None`.""" - keepers = deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)) - keeper_retries = 2 - self.synchronized_data = cast( - TransactionSettlementSynchronizedSata, - self.synchronized_data.update( - participants=tuple(f"agent_{i}" + "-" * 35 for i in range(4)), - keepers=get_keepers(keepers, keeper_retries), - ), - ) - - sender = keepers[0] - - test_round = self._round_class( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_round( - test_round=test_round, - keeper_payloads=FinalizationTxPayload( - sender=sender, - tx_data=None, - ), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data, - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.tx_hashes_history, - lambda _synchronized_data: _synchronized_data.blacklisted_keepers, - lambda _synchronized_data: _synchronized_data.keepers, - lambda _synchronized_data: _synchronized_data.keeper_retries, - lambda _synchronized_data: _synchronized_data.final_verification_status, - ], - exit_event=TransactionSettlementEvent.FINALIZATION_FAILED, - ) - ) - - -class TestCollectSignatureRound(BaseCollectDifferentUntilThresholdRoundTest): - """Test CollectSignatureRound.""" - - _synchronized_data_class = TransactionSettlementSynchronizedSata - _event_class = TransactionSettlementEvent - - def test_run( - self, - ) -> None: - """Runs tests.""" - - test_round = CollectSignatureRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_signature(self.participants), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data, - synchronized_data_attr_checks=[], - exit_event=self._event_class.DONE, - ) - ) - - -class TestValidateTransactionRound(BaseValidateRoundTest): - """Test ValidateRound.""" - - test_class = ValidateTransactionRound - _event_class = TransactionSettlementEvent - _synchronized_data_class = TransactionSettlementSynchronizedSata - - -class TestCheckTransactionHistoryRound(BaseCollectSameUntilThresholdRoundTest): - """Test CheckTransactionHistoryRound""" - - _event_class = TransactionSettlementEvent - _synchronized_data_class = TransactionSettlementSynchronizedSata - - @pytest.mark.parametrize( - "expected_status, expected_tx_hash, missed_messages, expected_event", - ( - ( - "0000000000000000000000000000000000000000000000000000000000000001", - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - {}, - TransactionSettlementEvent.DONE, - ), - ( - "0000000000000000000000000000000000000000000000000000000000000002", - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - {}, - TransactionSettlementEvent.NEGATIVE, - ), - ( - "0000000000000000000000000000000000000000000000000000000000000003", - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - {}, - TransactionSettlementEvent.NONE, - ), - ( - "0000000000000000000000000000000000000000000000000000000000000007", - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - {}, - TransactionSettlementEvent.NONE, - ), - ( - "0000000000000000000000000000000000000000000000000000000000000002", - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - {"test": 1}, - TransactionSettlementEvent.CHECK_LATE_ARRIVING_MESSAGE, - ), - ), - ) - def test_run( - self, - expected_status: str, - expected_tx_hash: str, - missed_messages: int, - expected_event: TransactionSettlementEvent, - ) -> None: - """Run tests.""" - keepers = get_keepers(deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35))) - self.synchronized_data.update(missed_messages=missed_messages, keepers=keepers) - - test_round = CheckTransactionHistoryRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_check( - self.participants, expected_status, expected_tx_hash - ), - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - participant_to_check=CollectionRound.serialize_collection( - get_participant_to_check( - self.participants, expected_status, expected_tx_hash - ) - ), - final_verification_status=int(expected_status), - tx_hashes_history=[expected_tx_hash], - keepers=keepers, - final_tx_hash="0xb0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.final_verification_status, - lambda _synchronized_data: _synchronized_data.final_tx_hash, - lambda _synchronized_data: _synchronized_data.keepers, - ] - if expected_event - not in { - TransactionSettlementEvent.NEGATIVE, - TransactionSettlementEvent.CHECK_LATE_ARRIVING_MESSAGE, - } - else [ - lambda _synchronized_data: _synchronized_data.final_verification_status, - lambda _synchronized_data: _synchronized_data.keepers, - ], - most_voted_payload=expected_status + expected_tx_hash, - exit_event=expected_event, - ) - ) - - -class TestSynchronizeLateMessagesRound(BaseCollectNonEmptyUntilThresholdRound): - """Test `SynchronizeLateMessagesRound`.""" - - _event_class = TransactionSettlementEvent - _synchronized_data_class = TransactionSettlementSynchronizedSata - - @pytest.mark.parametrize( - "missed_messages, expected_event", - ( - ( - {f"agent_{i}": 0 for i in range(4)}, - TransactionSettlementEvent.SUSPICIOUS_ACTIVITY, - ), - ({f"agent_{i}": 2 for i in range(4)}, TransactionSettlementEvent.DONE), - ), - ) - def test_runs( - self, missed_messages: int, expected_event: TransactionSettlementEvent - ) -> None: - """Runs tests.""" - self.synchronized_data.update(missed_messages=missed_messages) - test_round = SynchronizeLateMessagesRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - late_arriving_tx_hashes = { - p: "".join(("1" * TX_HASH_LENGTH, "2" * TX_HASH_LENGTH)) - for p in self.participants - } - test_round.required_block_confirmations = 0 - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_late_arriving_tx_hashes( - self.participants - ), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.update( - late_arriving_tx_hashes=late_arriving_tx_hashes, - suspects=tuple() - if expected_event == TransactionSettlementEvent.DONE - else tuple(sorted(late_arriving_tx_hashes.keys())), - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.late_arriving_tx_hashes, - lambda _synchronized_data: _synchronized_data.suspects, - ], - exit_event=expected_event, - ) - ) - - @pytest.mark.parametrize("correct_serialization", (True, False)) - def test_check_payload(self, correct_serialization: bool) -> None: - """Test the `check_payload` method.""" - - test_round = SynchronizeLateMessagesRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - sender = list(test_round.accepting_payloads_from).pop() - hash_length = TX_HASH_LENGTH - if not correct_serialization: - hash_length -= 1 - tx_hashes = "0" * hash_length - payload = SynchronizeLateMessagesPayload(sender=sender, tx_hashes=tx_hashes) - - if correct_serialization: - test_round.check_payload(payload) - return - - with pytest.raises( - TransactionNotValidError, match="Expecting serialized data of chunk size" - ): - test_round.check_payload(payload) - - with pytest.raises( - ABCIAppInternalError, match="Expecting serialized data of chunk size" - ): - test_round.process_payload(payload) - assert payload not in test_round.collection - - -def test_synchronized_datas() -> None: - """Test SynchronizedData.""" - - participants = get_participants() - participant_to_randomness = get_participant_to_randomness(participants, 1) - participant_to_randomness_serialized = CollectionRound.serialize_collection( - participant_to_randomness - ) - most_voted_randomness = get_most_voted_randomness() - participant_to_selection = get_participant_to_selection(participants, "test") - participant_to_selection_serialized = CollectionRound.serialize_collection( - participant_to_selection - ) - safe_contract_address = get_safe_contract_address() - most_voted_tx_hash = get_most_voted_tx_hash() - participant_to_signature = get_participant_to_signature(participants) - participant_to_signature_serialized = CollectionRound.serialize_collection( - participant_to_signature - ) - final_tx_hash = get_final_tx_hash() - actual_keeper_randomness = int(most_voted_randomness, base=16) / MAX_INT_256 - late_arriving_tx_hashes_serialized = get_late_arriving_tx_hashes_serialized() - late_arriving_tx_hashes_deserialized = get_late_arriving_tx_hashes_deserialized() - keepers = get_keepers(deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35))) - expected_keepers = deque(["agent_1" + "-" * 35, "agent_3" + "-" * 35]) - - # test `keeper_retries` property when no `keepers` are set. - synchronized_data_____ = TransactionSettlementSynchronizedSata( - AbciAppDB(setup_data=dict()) - ) - assert synchronized_data_____.keepers == deque() - assert synchronized_data_____.keeper_retries == 0 - - synchronized_data_____ = TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - all_participants=tuple(participants), - participants=tuple(participants), - consensus_threshold=3, - participant_to_randomness=participant_to_randomness_serialized, - most_voted_randomness=most_voted_randomness, - participant_to_selection=participant_to_selection_serialized, - safe_contract_address=safe_contract_address, - most_voted_tx_hash=most_voted_tx_hash, - participant_to_signature=participant_to_signature_serialized, - final_tx_hash=final_tx_hash, - late_arriving_tx_hashes=late_arriving_tx_hashes_serialized, - keepers=keepers, - blacklisted_keepers="t" * 42, - ) - ), - ) - ) - assert ( - abs(synchronized_data_____.keeper_randomness - actual_keeper_randomness) < 1e-10 - ) # avoid equality comparisons between floats - assert synchronized_data_____.most_voted_randomness == most_voted_randomness - assert synchronized_data_____.safe_contract_address == safe_contract_address - assert synchronized_data_____.most_voted_tx_hash == most_voted_tx_hash - assert synchronized_data_____.participant_to_randomness == participant_to_randomness - assert synchronized_data_____.participant_to_selection == participant_to_selection - assert synchronized_data_____.participant_to_signature == participant_to_signature - assert synchronized_data_____.final_tx_hash == final_tx_hash - assert ( - synchronized_data_____.late_arriving_tx_hashes - == late_arriving_tx_hashes_deserialized - ) - assert synchronized_data_____.keepers == expected_keepers - assert synchronized_data_____.keeper_retries == 1 - assert ( - synchronized_data_____.most_voted_keeper_address == expected_keepers.popleft() - ) - assert synchronized_data_____.keepers_threshold_exceeded - assert synchronized_data_____.blacklisted_keepers == {"t" * 42} - updated_synchronized_data = synchronized_data_____.create() - assert updated_synchronized_data.blacklisted_keepers == set() - - -class TestResetRound(BaseCollectSameUntilThresholdRoundTest): - """Test ResetRound.""" - - _synchronized_data_class = TransactionSettlementSynchronizedSata - _event_class = TransactionSettlementEvent - - def test_runs( - self, - ) -> None: - """Runs tests.""" - randomness = DUMMY_RANDOMNESS - synchronized_data = self.synchronized_data.update( - most_voted_randomness=randomness, - late_arriving_tx_hashes={}, - keepers="", - ) - synchronized_data._db._cross_period_persisted_keys = frozenset( - {"most_voted_randomness"} - ) - test_round = ResetRound( - synchronized_data=synchronized_data, - context=MagicMock(), - ) - next_period_count = 1 - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_period_count( - self.participants, next_period_count - ), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.create(), - synchronized_data_attr_checks=[], # [lambda _synchronized_data: _synchronized_data.participants], - most_voted_payload=next_period_count, - exit_event=self._event_class.DONE, - ) - ) diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/__init__.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/__init__.py deleted file mode 100644 index d1ae9fb95..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Package for `test_tools` testing.""" diff --git a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/test_integration.py b/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/test_integration.py deleted file mode 100644 index 84a67929f..000000000 --- a/trader_backup/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/test_integration.py +++ /dev/null @@ -1,214 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Test transaction settlement integration test tool.""" - -from pathlib import Path -from typing import cast -from unittest import mock - -import pytest -from aea.exceptions import AEAActException -from web3.types import Nonce, Wei - -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.skills import transaction_settlement_abci -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.tests.test_tools.base import ( - FSMBehaviourTestToolSetup, -) -from packages.valory.skills.transaction_settlement_abci.behaviours import ( - FinalizeBehaviour, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TxSettlementSynchronizedSata, -) -from packages.valory.skills.transaction_settlement_abci.test_tools.integration import ( - _GnosisHelperIntegration, - _SafeConfiguredHelperIntegration, - _TxHelperIntegration, -) - - -DUMMY_TX_HASH = "a" * 234 - - -class Test_SafeConfiguredHelperIntegration(FSMBehaviourTestToolSetup): - """Test_SafeConfiguredHelperIntegration""" - - test_cls = _SafeConfiguredHelperIntegration - - def test_instantiation(self) -> None: - """Test instantiation""" - - self.set_path_to_skill() - self.test_cls.make_ledger_api_connection_callable = ( - lambda *_, **__: mock.MagicMock() - ) - test_instance = cast(_SafeConfiguredHelperIntegration, self.setup_test_cls()) - - assert test_instance.keeper_address in test_instance.safe_owners - - -class Test_GnosisHelperIntegration(FSMBehaviourTestToolSetup): - """Test_SafeConfiguredHelperIntegration""" - - test_cls = _GnosisHelperIntegration - - def test_instantiation(self) -> None: - """Test instantiation""" - - self.set_path_to_skill() - self.test_cls.make_ledger_api_connection_callable = ( - lambda *_, **__: mock.MagicMock() - ) - test_instance = cast(_GnosisHelperIntegration, self.setup_test_cls()) - - assert test_instance.safe_contract_address - assert test_instance.gnosis_instance - assert test_instance.ethereum_api - - -class Test_TxHelperIntegration(FSMBehaviourTestToolSetup): - """Test_SafeConfiguredHelperIntegration""" - - test_cls = _TxHelperIntegration - - def instantiate_test(self) -> _TxHelperIntegration: - """Instantiate the test""" - - path_to_skill = Path(transaction_settlement_abci.__file__).parent - self.set_path_to_skill(path_to_skill=path_to_skill) - self.test_cls.make_ledger_api_connection_callable = ( - lambda *_, **__: mock.MagicMock() - ) - - db = AbciAppDB( - setup_data={"all_participants": [f"agent_{i}" for i in range(4)]} - ) - self.test_cls.tx_settlement_synchronized_data = TxSettlementSynchronizedSata(db) - - test_instance = cast(_TxHelperIntegration, self.setup_test_cls()) - return test_instance - - def test_sign_tx(self) -> None: - """Test sign_tx""" - - test_instance = self.instantiate_test() - test_instance.tx_settlement_synchronized_data.db.update( - most_voted_tx_hash=DUMMY_TX_HASH - ) - - target = test_instance.gnosis_instance.functions.getOwners - return_value = test_instance.safe_owners - with mock.patch.object( - target, "call", new_callable=lambda: lambda: return_value - ): - test_instance.sign_tx() - - def test_sign_tx_failure(self) -> None: - """Test sign_tx failure""" - - test_instance = self.instantiate_test() - test_instance.tx_settlement_synchronized_data.db.update( - most_voted_tx_hash=DUMMY_TX_HASH - ) - - target = test_instance.gnosis_instance.functions.getOwners - with mock.patch.object(target, "call", new_callable=lambda: lambda: {}): - with pytest.raises(AssertionError): - test_instance.sign_tx() - - def test_send_tx(self) -> None: - """Test send tx""" - - test_instance = self.instantiate_test() - - nonce = Nonce(0) - gas_price = {"maxPriorityFeePerGas": Wei(0), "maxFeePerGas": Wei(0)} - behaviour = cast(FinalizeBehaviour, test_instance.behaviour.current_behaviour) - behaviour.params.mutable_params.gas_price = gas_price - behaviour.params.mutable_params.nonce = nonce - - contract_api_message = ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, # type: ignore - raw_transaction=ContractApiMessage.RawTransaction( - ledger_id="", body={"nonce": str(nonce), **gas_price} - ), - ) - - ledger_api_message = LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, # type: ignore - transaction_digest=LedgerApiMessage.TransactionDigest( - ledger_id="", body="" - ), - ) - - return_value = contract_api_message, None, ledger_api_message - - with mock.patch.object( - test_instance, - "process_n_messages", - new_callable=lambda: lambda *x, **__: return_value, - ): - test_instance.send_tx() - - def test_validate_tx(self) -> None: - """Test validate_tx""" - - test_instance = self.instantiate_test() - test_instance.tx_settlement_synchronized_data.db.update( - tx_hashes_history="a" * 64 - ) - - contract_api_message = ContractApiMessage( - performative=ContractApiMessage.Performative.STATE, # type: ignore - state=ContractApiMessage.State( - ledger_id="", - body={"verified": True}, - ), - ) - return_value = None, contract_api_message - - with mock.patch.object( - test_instance, - "process_n_messages", - new_callable=lambda: lambda *x, **__: return_value, - ): - test_instance.validate_tx() - - def test_validate_tx_timeout(self) -> None: - """Test validate_tx timeout""" - - test_instance = self.instantiate_test() - synchronized_data = test_instance.tx_settlement_synchronized_data - assert synchronized_data.n_missed_messages == 0 - test_instance.validate_tx(simulate_timeout=True) - assert synchronized_data.n_missed_messages == 1 - - def test_validate_tx_failure(self) -> None: - """Test validate tx failure""" - - test_instance = self.instantiate_test() - - with pytest.raises( - AEAActException, match="FSM design error: tx hash should exist" - ): - test_instance.validate_tx() diff --git a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/README.md b/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/README.md deleted file mode 100644 index f726ff7a5..000000000 --- a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Transaction Settlement Multiplexer abci - -## Description - -This module contains a multiplexer for the transaction settlement skill. -This is necessary in order to be able to chain the tx settlement multiple times for the FSM. diff --git a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/__init__.py b/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/__init__.py deleted file mode 100644 index bac79e138..000000000 --- a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- 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 skill that acts as a multiplexer for the transaction settlement skill.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/tx_settlement_multiplexer_abci:0.1.0") diff --git a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/behaviours.py b/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/behaviours.py deleted file mode 100644 index c19209f9f..000000000 --- a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/behaviours.py +++ /dev/null @@ -1,184 +0,0 @@ -# -*- 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 package contains the behaviours of the transaction settlement multiplexer.""" - -from typing import Generator, Optional, Set, Type, cast - -from aea.exceptions import AEAEnforceError - -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.models import RedeemingProgress -from packages.valory.skills.decision_maker_abci.payloads import VotingPayload -from packages.valory.skills.tx_settlement_multiplexer_abci.models import ( - TxSettlementMultiplexerParams, -) -from packages.valory.skills.tx_settlement_multiplexer_abci.rounds import ( - PostTxSettlementRound, - PreTxSettlementRound, - SynchronizedData, - TxSettlementMultiplexerAbciApp, -) - - -class PreTxSettlementBehaviour(BaseBehaviour): - """ - The pre transaction settlement behaviour. - - This behaviour should be executed before a tx is sent via the transaction_settlement_abci. - """ - - matching_round = PreTxSettlementRound - - @property - def params(self) -> TxSettlementMultiplexerParams: - """Return the params.""" - return cast(TxSettlementMultiplexerParams, self.context.params) - - def _get_balance(self, agent: str) -> Generator[None, None, Optional[int]]: - """Get the given agent's balance.""" - self.context.logger.info(f"Checking balance for agent with address {agent}...") - ledger_api_response = yield from self.get_ledger_api_response( - performative=LedgerApiMessage.Performative.GET_STATE, # type: ignore - ledger_callable="get_balance", - account=agent, - ) - - try: - balance = int(ledger_api_response.state.body["get_balance_result"]) - except (AEAEnforceError, KeyError, ValueError, TypeError): - balance = None - - if balance is None: - log_msg = f"Failed to get the balance for agent with address {agent}." - self.context.logger.error(f"{log_msg}: {ledger_api_response}") - return None - - self.context.logger.info(f"The agent with address {agent} has {balance} WEI.") - return balance - - def _check_balance(self, agent: str) -> Generator[None, None, bool]: - """Check if the given agent's balance is sufficient.""" - balance = None - while balance is None: - balance = yield from self._get_balance(agent) - - threshold = self.params.agent_balance_threshold - refill_required = balance < threshold - if refill_required: - msg = f"Please refill agent with address {agent}. Balance is below {threshold}." - self.context.logger.warning(msg) - - return refill_required - - def _refill_required(self) -> Generator[None, None, bool]: - """Check whether a refill is required.""" - refill_required = False - for agent in self.synchronized_data.all_participants: - refill_required |= yield from self._check_balance(agent) - return refill_required - - def async_act(self) -> Generator: - """Check whether the agents' balances are sufficient.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - refill_required = yield from self._refill_required() - if refill_required: - # pause to give the user some time to refill before transitioning to the same round again - yield from self.sleep(self.params.refill_check_interval) - - payload = VotingPayload(self.context.agent_address, not refill_required) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class PostTxSettlementBehaviour(BaseBehaviour): - """ - The post transaction settlement behaviour. - - This behaviour should be executed after a tx is settled via the transaction_settlement_abci. - """ - - matching_round = PostTxSettlementRound - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return SynchronizedData(super().synchronized_data.db) - - @property - def redeeming_progress(self) -> RedeemingProgress: - """Get the redeeming progress.""" - return self.shared_state.redeeming_progress # type: ignore - - @redeeming_progress.setter - def redeeming_progress(self, value: RedeemingProgress) -> None: - """Set the redeeming progress.""" - self.shared_state.redeeming_progress = value - - def _on_redeem_round_tx_settled(self) -> None: - """Handle the redeem round.""" - self.context.logger.info( - "Redeeming transaction was settled. Resetting the redeeming progress." - ) - claimed_condition_ids = self.redeeming_progress.claimed_condition_ids - claimed_condition_ids.extend(self.redeeming_progress.claiming_condition_ids) - self.redeeming_progress = RedeemingProgress() - self.redeeming_progress.claimed_condition_ids = claimed_condition_ids - self.context.logger.info( - f"The following condition ids were claimed so far: {claimed_condition_ids}" - ) - - def _on_tx_settled(self) -> None: - """Handle the tx settled event.""" - tx_submitter = self.synchronized_data.tx_submitter - handler_name = f"_on_{tx_submitter}_tx_settled" - handler = getattr(self, handler_name, None) - if handler is None: - self.context.logger.info( - f"No post tx settlement handler exists for {tx_submitter} txs." - ) - return - handler() - - def async_act(self) -> Generator: - """Simply log that a tx is settled and wait for the round end.""" - msg = f"The transaction submitted by {self.synchronized_data.tx_submitter} was successfully settled." - self.context.logger.info(msg) - self._on_tx_settled() - yield from self.wait_until_round_end() - self.set_done() - - -class PostTxSettlementFullBehaviour(AbstractRoundBehaviour): - """The post tx settlement full behaviour.""" - - initial_behaviour_cls = PostTxSettlementBehaviour - abci_app_cls = TxSettlementMultiplexerAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - PreTxSettlementBehaviour, # type: ignore - PostTxSettlementBehaviour, # type: ignore - } diff --git a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/dialogues.py b/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/dialogues.py deleted file mode 100644 index 153b6ce50..000000000 --- a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/dialogues.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- 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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/fsm_specification.yaml b/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/fsm_specification.yaml deleted file mode 100644 index d671e1d6b..000000000 --- a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/fsm_specification.yaml +++ /dev/null @@ -1,52 +0,0 @@ -alphabet_in: -- BET_PLACEMENT_NO_SELL_DONE -- BET_PLACEMENT_SELL_DONE -- CHECKS_PASSED -- MECH_REQUESTING_DONE -- NO_MAJORITY -- REDEEMING_DONE -- REFILL_REQUIRED -- ROUND_TIMEOUT -- SELL_OUTCOME_TOKEN_DONE -- STAKING_DONE -- SUBSCRIPTION_DONE -- UNRECOGNIZED -default_start_state: PreTxSettlementRound -final_states: -- ChecksPassedRound -- FailedMultiplexerRound -- FinishedBetPlacementTxRound -- FinishedMechRequestTxRound -- FinishedRedeemingTxRound -- FinishedSellOutcomeTokenTxRound -- FinishedStakingTxRound -- FinishedSubscriptionTxRound -label: TxSettlementMultiplexerAbciApp -start_states: -- PostTxSettlementRound -- PreTxSettlementRound -states: -- ChecksPassedRound -- FailedMultiplexerRound -- FinishedBetPlacementTxRound -- FinishedMechRequestTxRound -- FinishedRedeemingTxRound -- FinishedSellOutcomeTokenTxRound -- FinishedStakingTxRound -- FinishedSubscriptionTxRound -- PostTxSettlementRound -- PreTxSettlementRound -transition_func: - (PostTxSettlementRound, BET_PLACEMENT_NO_SELL_DONE): FinishedBetPlacementTxRound - (PostTxSettlementRound, BET_PLACEMENT_SELL_DONE): FinishedBetPlacementTxRound - (PostTxSettlementRound, MECH_REQUESTING_DONE): FinishedMechRequestTxRound - (PostTxSettlementRound, REDEEMING_DONE): FinishedRedeemingTxRound - (PostTxSettlementRound, ROUND_TIMEOUT): PostTxSettlementRound - (PostTxSettlementRound, SELL_OUTCOME_TOKEN_DONE): FinishedSellOutcomeTokenTxRound - (PostTxSettlementRound, STAKING_DONE): FinishedStakingTxRound - (PostTxSettlementRound, SUBSCRIPTION_DONE): FinishedSubscriptionTxRound - (PostTxSettlementRound, UNRECOGNIZED): FailedMultiplexerRound - (PreTxSettlementRound, CHECKS_PASSED): ChecksPassedRound - (PreTxSettlementRound, NO_MAJORITY): PreTxSettlementRound - (PreTxSettlementRound, REFILL_REQUIRED): PreTxSettlementRound - (PreTxSettlementRound, ROUND_TIMEOUT): PreTxSettlementRound diff --git a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/handlers.py b/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/handlers.py deleted file mode 100644 index 0f3ed315d..000000000 --- a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/handlers.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- 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 the handlers for the skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -TxSettlementMultiplexerHandler = ABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/models.py b/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/models.py deleted file mode 100644 index 49c0e5dbd..000000000 --- a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/models.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - - -"""Custom objects for the TxSettlementMultiplexer ABCI application.""" - -from typing import Any - -from packages.valory.skills.abstract_round_abci.models import BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.tx_settlement_multiplexer_abci.rounds import ( - TxSettlementMultiplexerAbciApp, -) - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -class TxSettlementMultiplexerParams(BaseParams): - """Staking parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the parameters' object.""" - self.agent_balance_threshold: int = self._ensure( - "agent_balance_threshold", kwargs, int - ) - self.refill_check_interval: int = self._ensure( - "refill_check_interval", kwargs, int - ) - super().__init__(*args, **kwargs) - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = TxSettlementMultiplexerAbciApp diff --git a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/rounds.py b/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/rounds.py deleted file mode 100644 index ec8912db0..000000000 --- a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/rounds.py +++ /dev/null @@ -1,265 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the rounds of `TxSettlementMultiplexerAbciApp`.""" - -import json -from enum import Enum -from typing import Any, Dict, Optional, Set, Tuple - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AppState, - BaseSynchronizedData, - CollectSameUntilThresholdRound, - DegenerateRound, - VotingRound, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import VotingPayload -from packages.valory.skills.decision_maker_abci.states.base import SynchronizedData -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) -from packages.valory.skills.decision_maker_abci.states.order_subscription import ( - SubscriptionRound, -) -from packages.valory.skills.decision_maker_abci.states.redeem import RedeemRound -from packages.valory.skills.decision_maker_abci.states.sell_outcome_token import ( - SellOutcomeTokenRound, -) -from packages.valory.skills.mech_interact_abci.states.request import MechRequestRound -from packages.valory.skills.staking_abci.rounds import CallCheckpointRound - - -class Event(Enum): - """Multiplexing events.""" - - CHECKS_PASSED = "checks_passed" - REFILL_REQUIRED = "refill_required" - MECH_REQUESTING_DONE = "mech_requesting_done" - BET_PLACEMENT_NO_SELL_DONE = "bet_placement_done_no_sell" - BET_PLACEMENT_SELL_DONE = "bet_placement_done_sell" - REDEEMING_DONE = "redeeming_done" - SELL_OUTCOME_TOKEN_DONE = "sell_outcome_token_done" # nosec - STAKING_DONE = "staking_done" - SUBSCRIPTION_DONE = "subscription_done" - ROUND_TIMEOUT = "round_timeout" - UNRECOGNIZED = "unrecognized" - NO_MAJORITY = "no_majority" - - -class PreTxSettlementRound(VotingRound): - """A round that will be called before the tx settlement.""" - - payload_class = VotingPayload - synchronized_data_class = SynchronizedData - done_event = Event.CHECKS_PASSED - negative_event = Event.REFILL_REQUIRED - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_votes) - - -class PostTxSettlementRound(CollectSameUntilThresholdRound): - """A round that will be called after tx settlement is done.""" - - payload_class: Any = object() - synchronized_data_class = SynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """ - The end block. - - This is a special type of round. No consensus is necessary here. - There is no need to send a tx through, nor to check for a majority. - We simply use this round to check which round submitted the tx, - and move to the next state in accordance with that. - - :return: the synchronized data and the event, otherwise `None` if the round is still running. - """ - submitter_to_event: Dict[str, Event] = { - MechRequestRound.auto_round_id(): Event.MECH_REQUESTING_DONE, - BetPlacementRound.auto_round_id(): Event.BET_PLACEMENT_NO_SELL_DONE, - RedeemRound.auto_round_id(): Event.REDEEMING_DONE, - CallCheckpointRound.auto_round_id(): Event.STAKING_DONE, - SubscriptionRound.auto_round_id(): Event.SUBSCRIPTION_DONE, - SellOutcomeTokenRound.auto_round_id(): Event.SELL_OUTCOME_TOKEN_DONE, - } - - synced_data = SynchronizedData(self.synchronized_data.db) - event = submitter_to_event.get(synced_data.tx_submitter, Event.UNRECOGNIZED) - - if synced_data.vote != synced_data.previous_vote: - event = Event.BET_PLACEMENT_SELL_DONE - - # if a mech request was just performed, increase the utilized tool's counter - if event == Event.MECH_REQUESTING_DONE: - policy = synced_data.policy - policy.tool_used(synced_data.mech_tool) - policy_update = policy.serialize() - self.synchronized_data.update(policy=policy_update) - - # if a bet was just placed, edit the utilized tools mapping - if ( - event == Event.BET_PLACEMENT_NO_SELL_DONE - or event == Event.BET_PLACEMENT_SELL_DONE - ): - utilized_tools = synced_data.utilized_tools - utilized_tools[synced_data.final_tx_hash] = synced_data.mech_tool - tools_update = json.dumps(utilized_tools, sort_keys=True) - vote = synced_data.vote - self.synchronized_data.update( - utilized_tools=tools_update, previous_vote=vote - ) - - # if all tokens for an outcome have been sold, set the previous vote to None as we no longer have any - # investment in that outcome - if event == Event.SELL_OUTCOME_TOKEN_DONE: - self.synchronized_data.update(previous_vote=None) - - return synced_data, event - - -class ChecksPassedRound(DegenerateRound): - """Round that represents all the pre tx settlement checks have passed.""" - - -class FinishedMechRequestTxRound(DegenerateRound): - """Finished mech requesting round.""" - - -class FinishedBetPlacementTxRound(DegenerateRound): - """Finished bet placement round.""" - - -class FinishedRedeemingTxRound(DegenerateRound): - """Finished redeeming round.""" - - -class FinishedStakingTxRound(DegenerateRound): - """Finished staking round.""" - - -class FinishedSubscriptionTxRound(DegenerateRound): - """Finished subscription round.""" - - -class FinishedSellOutcomeTokenTxRound(DegenerateRound): - """Finished sell outcome token round.""" - - -class FailedMultiplexerRound(DegenerateRound): - """Round that represents failure in identifying the transmitter round.""" - - -class TxSettlementMultiplexerAbciApp(AbciApp[Event]): - """TxSettlementMultiplexerAbciApp - - Initial round: PreTxSettlementRound - - Initial states: {PostTxSettlementRound, PreTxSettlementRound} - - Transition states: - 0. PreTxSettlementRound - - checks passed: 2. - - refill required: 0. - - no majority: 0. - - round timeout: 0. - 1. PostTxSettlementRound - - mech requesting done: 3. - - bet placement done no sell: 4. - - bet placement done sell: 4. - - redeeming done: 6. - - sell outcome token done: 8. - - staking done: 7. - - subscription done: 5. - - round timeout: 1. - - unrecognized: 9. - 2. ChecksPassedRound - 3. FinishedMechRequestTxRound - 4. FinishedBetPlacementTxRound - 5. FinishedSubscriptionTxRound - 6. FinishedRedeemingTxRound - 7. FinishedStakingTxRound - 8. FinishedSellOutcomeTokenTxRound - 9. FailedMultiplexerRound - - Final states: {ChecksPassedRound, FailedMultiplexerRound, FinishedBetPlacementTxRound, FinishedMechRequestTxRound, FinishedRedeemingTxRound, FinishedSellOutcomeTokenTxRound, FinishedStakingTxRound, FinishedSubscriptionTxRound} - - Timeouts: - round timeout: 30.0 - """ - - initial_round_cls: AppState = PreTxSettlementRound - initial_states: Set[AppState] = {PreTxSettlementRound, PostTxSettlementRound} - transition_function: AbciAppTransitionFunction = { - PreTxSettlementRound: { - Event.CHECKS_PASSED: ChecksPassedRound, - Event.REFILL_REQUIRED: PreTxSettlementRound, - Event.NO_MAJORITY: PreTxSettlementRound, - Event.ROUND_TIMEOUT: PreTxSettlementRound, - }, - PostTxSettlementRound: { - Event.MECH_REQUESTING_DONE: FinishedMechRequestTxRound, - Event.BET_PLACEMENT_NO_SELL_DONE: FinishedBetPlacementTxRound, - Event.BET_PLACEMENT_SELL_DONE: FinishedBetPlacementTxRound, - Event.REDEEMING_DONE: FinishedRedeemingTxRound, - Event.SELL_OUTCOME_TOKEN_DONE: FinishedSellOutcomeTokenTxRound, - Event.STAKING_DONE: FinishedStakingTxRound, - Event.SUBSCRIPTION_DONE: FinishedSubscriptionTxRound, - Event.ROUND_TIMEOUT: PostTxSettlementRound, - Event.UNRECOGNIZED: FailedMultiplexerRound, - }, - ChecksPassedRound: {}, - FinishedMechRequestTxRound: {}, - FinishedBetPlacementTxRound: {}, - FinishedSubscriptionTxRound: {}, - FinishedRedeemingTxRound: {}, - FinishedStakingTxRound: {}, - FinishedSellOutcomeTokenTxRound: {}, - FailedMultiplexerRound: {}, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - } - final_states: Set[AppState] = { - ChecksPassedRound, - FinishedMechRequestTxRound, - FinishedBetPlacementTxRound, - FinishedRedeemingTxRound, - FinishedStakingTxRound, - FinishedSubscriptionTxRound, - FinishedSellOutcomeTokenTxRound, - FailedMultiplexerRound, - } - db_pre_conditions: Dict[AppState, Set[str]] = { - PreTxSettlementRound: {get_name(SynchronizedData.tx_submitter)}, - PostTxSettlementRound: {get_name(SynchronizedData.tx_submitter)}, - } - db_post_conditions: Dict[AppState, Set[str]] = { - ChecksPassedRound: set(), - FinishedMechRequestTxRound: set(), - FinishedBetPlacementTxRound: set(), - FinishedRedeemingTxRound: set(), - FinishedStakingTxRound: set(), - FailedMultiplexerRound: set(), - FinishedSubscriptionTxRound: set(), - FinishedSellOutcomeTokenTxRound: set(), - } diff --git a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/skill.yaml b/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/skill.yaml deleted file mode 100644 index ce91d392d..000000000 --- a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/skill.yaml +++ /dev/null @@ -1,144 +0,0 @@ -name: tx_settlement_multiplexer_abci -author: valory -version: 0.1.0 -type: skill -description: This skill implements a multiplexer for the transaction settlement skill. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeiegcjg2wjrsqhrmvyulioch3d67rnbzkx5af3ztkaw7kxathjreda - __init__.py: bafybeide6k22zk4f3hyzhpapaoddsnxpw5elqcfvrxxj4nfvpzctv6jqhu - behaviours.py: bafybeictumcqn2pgo7y2duemvzoaafognfhl6s6il3tv53hq66tf7xgpsu - dialogues.py: bafybeiebofyykseqp3fmif36cqmmyf3k7d2zbocpl6t6wnlpv4szghrxbm - fsm_specification.yaml: bafybeieoyrx3nt3qsvd5n2bkryzq6twvrphmbqn3fs4gts6eoy2tvksxoy - handlers.py: bafybeiafbqr7ojfcbwohvee7x4zzswad3ymfrrbjlfz7uuuttmn3qdfs6q - models.py: bafybeigtmxoecoow663hgqnyinxarlrttyyt5ghpbdamdv4tc4kikcfx3a - rounds.py: bafybeihbxi4m7eyvkmenhcdzy3ijzajaxqrcyts3asvqe36l2til7kngzy - tests/__init__.py: bafybeiat74pbtmxvylsz7karp57qp2v7y6wtrsz572jkrghbcssoudgjay - tests/test_handlers.py: bafybeiayuktfupylm3p3ygufjb66swzxhpbmioqoffwuauakfgbkwrv7ma -fingerprint_ignore_patterns: [] -connections: [] -contracts: [] -protocols: -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/decision_maker_abci:0.1.0:bafybeigwqeptzd5pfvfuhau2m5gzicwimrb4weanykppgqqb3inureedeu -- valory/staking_abci:0.1.0:bafybeicupccurmrg7qesivonlyt3nryarsmk5qf5yh6auno64wn45bybvq -- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm -behaviours: - main: - args: {} - class_name: PostTxSettlementFullBehaviour -handlers: - abci: - args: {} - class_name: TxSettlementMultiplexerHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - retry_timeout: 3 - round_timeout_seconds: 350.0 - service_id: tx_settlement_multiplexer - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - sleep_time: 5 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - termination_sleep: 900 - tx_timeout: 10.0 - use_termination: false - agent_balance_threshold: 10000000000000000 - refill_check_interval: 10 - class_name: TxSettlementMultiplexerParams - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState -dependencies: {} -is_abstract: true diff --git a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/__init__.py b/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/__init__.py deleted file mode 100644 index 0d6412538..000000000 --- a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the tests for tx settlement multiplexer abci.""" diff --git a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/test_handlers.py b/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/test_handlers.py deleted file mode 100644 index 3287c3c47..000000000 --- a/trader_backup/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/test_handlers.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the tests for the handlers of the tx settlement multiplexer abci.""" -from unittest.mock import MagicMock - -import pytest -from aea.configurations.data_types import PublicId -from aea.skills.base import Handler - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.tx_settlement_multiplexer_abci.handlers import ( - ContractApiHandler, - HttpHandler, - IpfsHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, - TxSettlementMultiplexerHandler, -) - - -@pytest.mark.parametrize( - "handler, base_handler", - [ - (TxSettlementMultiplexerHandler, ABCIRoundHandler), - (HttpHandler, BaseHttpHandler), - (SigningHandler, BaseSigningHandler), - (LedgerApiHandler, BaseLedgerApiHandler), - (ContractApiHandler, BaseContractApiHandler), - (TendermintHandler, BaseTendermintHandler), - (IpfsHandler, BaseIpfsHandler), - ], -) -def test_handler(handler: Handler, base_handler: Handler) -> None: - """Test that the 'handlers.py' of the TxSettlementMultiplexerAbci can be imported.""" - handler = handler( - name="dummy_handler", - skill_context=MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")), - ) - - assert isinstance(handler, base_handler) diff --git a/trader_backup/vendor/w1kke/customs/__init__.py b/trader_backup/vendor/w1kke/customs/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_backup/vendor/w1kke/customs/always_blue/__init__.py b/trader_backup/vendor/w1kke/customs/always_blue/__init__.py deleted file mode 100644 index e4e892ea4..000000000 --- a/trader_backup/vendor/w1kke/customs/always_blue/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the always blue strategy.""" diff --git a/trader_backup/vendor/w1kke/customs/always_blue/always_blue.py b/trader_backup/vendor/w1kke/customs/always_blue/always_blue.py deleted file mode 100644 index a99654fa3..000000000 --- a/trader_backup/vendor/w1kke/customs/always_blue/always_blue.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the always blue strategy.""" - -from typing import Dict, Any, List, Union - - -def get_always_blue() -> Dict[str, Union[int, List[str]]]: - """ALWAYS BLUE.""" - return {"bet_amount": 0, "info": ["ALWAYS BLUE!"]} - - -def run(*_args, **kwargs) -> Dict[str, Union[int, List[str]]]: - """Run the strategy.""" - return get_always_blue() diff --git a/trader_backup/vendor/w1kke/customs/always_blue/component.yaml b/trader_backup/vendor/w1kke/customs/always_blue/component.yaml deleted file mode 100644 index 0c867096c..000000000 --- a/trader_backup/vendor/w1kke/customs/always_blue/component.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: always_blue -author: w1kke -version: 0.1.0 -type: custom -description: A simple testing strategy strategy. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeibkl7srd6nmuo7p6vcrueviwryjo6y25xfkckndkghnos7okadzpm - always_blue.py: bafybeidyj2m7hwfrufjpzsqdihsvdmbzvqjatqasfs4r7ihxx2pwhoe6li -fingerprint_ignore_patterns: [] -entry_point: always_blue.py -callable: run -dependencies: {} diff --git a/trader_old/.certs/acn_cosmos_9005.txt b/trader_old/.certs/acn_cosmos_9005.txt deleted file mode 100644 index 3cd826f09..000000000 --- a/trader_old/.certs/acn_cosmos_9005.txt +++ /dev/null @@ -1 +0,0 @@ -307832386466623164626539323137623838623332346236343266373939373864396463646535306338376363666437353666373662353939313032616239633832343531383964343035353838363761326662356137613634643934323937326236353830646437353439306466346536386238326666333032643664653465373162 \ No newline at end of file diff --git a/trader_old/0x4BAc760A2baB94A0bd3B47Ace29180Ab1E922965/0.json b/trader_old/0x4BAc760A2baB94A0bd3B47Ace29180Ab1E922965/0.json deleted file mode 100644 index 0637a088a..000000000 --- a/trader_old/0x4BAc760A2baB94A0bd3B47Ace29180Ab1E922965/0.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/trader_old/README.md b/trader_old/README.md deleted file mode 100644 index c87f0282c..000000000 --- a/trader_old/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Trader Agent - -This agent uses `trader_abci` skill, which: -1. Searches for new questions on the supported prediction markets -2. Selects a question to investigate its answer -3. Predicts the answer for the selected question -4. Decides whether answering this question is profitable -5. Submits the answer if it is profitable, otherwise temporarily blacklists the question diff --git a/trader_old/__init__.py b/trader_old/__init__.py deleted file mode 100644 index 1fc7bb6b7..000000000 --- a/trader_old/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Implements the trader agent.""" diff --git a/trader_old/aea-config.yaml b/trader_old/aea-config.yaml deleted file mode 100644 index b2662b49c..000000000 --- a/trader_old/aea-config.yaml +++ /dev/null @@ -1,408 +0,0 @@ -agent_name: trader -author: valory -version: 0.1.0 -license: Apache-2.0 -description: Trader agent. -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeiexvxghmwzokfocrlq6johtoz7dvpqm6gg6vmcapu43yjjfqc435q - __init__.py: bafybeighcq4pmuzte6vhvvprrvo563vzghkoit2h6qdqxf2ma5bghevkee -fingerprint_ignore_patterns: [] -connections: -- valory/abci:0.1.0:bafybeia6etkacvqend7xj6viejkqgo7ozu3yn4yg3qezfthf2xhrjjwse4 -- valory/http_client:0.23.0:bafybeihi772xgzpqeipp3fhmvpct4y6e6tpjp4sogwqrnf3wqspgeilg4u -- valory/http_server:0.22.0:bafybeihpgu56ovmq4npazdbh6y6ru5i7zuv6wvdglpxavsckyih56smu7m -- valory/ipfs:0.1.0:bafybeigcijdbwgdekow5c2ikeltetoteabfp52ewy3xfkd7ygaqbl7j3ke -- valory/ledger:0.19.0:bafybeig7woeog4srdby75hpjkmx4rhpkzncbf4h2pm5r6varsp26pf2uhu -- valory/p2p_libp2p_client:0.1.0:bafybeid3xg5k2ol5adflqloy75ibgljmol6xsvzvezebsg7oudxeeolz7e -contracts: -- valory/agent_registry:0.1.0:bafybeiblc4i5xjxbywnfccwtv3unhaghrgqls7panfbuqbpstbc34h42xq -- valory/conditional_tokens:0.1.0:bafybeibnzmqmeph4cj5vfh3s622mo2o5627vjjwc6bptrhj4dk65mzgvhe -- valory/erc20:0.1.0:bafybeid2p2jyvjjlcsqugnawksdzsca6ljghpqbp2kfi3cxuxoy2233dbi -- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge -- valory/gnosis_safe_proxy_factory:0.1.0:bafybeieg57u3z7cdlmdamad5e6lk7kmsli2zurzkg3sl4y7lhekcu4y3au -- valory/market_maker:0.1.0:bafybeibevdc5trbi2qgt2tvwbsr2h5xvonfhcjwfmozftzvef575fdvbjq -- valory/mech:0.1.0:bafybeiejfjfoxqggghcme43sx53q5gruefrws3k2jam2opkxl5uzffoarm -- valory/mech_activity:0.1.0:bafybeibmqmle5fnal3gxlpdmcos2kogzra4q3pr3o5nh7shplxuilji3t4 -- valory/mech_marketplace:0.1.0:bafybeiba7kh3wygwtpyf7oo3sili6givzo2gyadhbb66rvwsokswsywvuu -- valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y -- valory/realitio:0.1.0:bafybeietgux6kkhdquspy35qera7gjwwqwrremmoeatjzwwokjb2lzsata -- valory/realitio_proxy:0.1.0:bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4 -- valory/service_registry:0.1.0:bafybeiaop64kwdoetxtedoehabmsalojmms7ihuoqcdwxtwb2hk5i6bzye -- valory/service_staking_token:0.1.0:bafybeihhcs3ewwzhy7yto4y36uqmice3pdvyl54fvxxv6jsxonesie4dxu -- valory/staking_token:0.1.0:bafybeiep4r6qyilbfgzdvx6t7zvpgaioxqktmxm7puwtnbpb2ftlib43gy -- valory/transfer_nft_condition:0.1.0:bafybeid6z2tf7nc4rhwggktxk5f62bowxdczykrxc3y76sbt2ttlw5hmtq -protocols: -- open_aea/signing:1.0.0:bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi -- valory/abci:0.1.0:bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u -- valory/acn:1.1.0:bafybeidluaoeakae3exseupaea4i3yvvk5vivyt227xshjlffywwxzcxqe -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -- valory/ipfs:0.1.0:bafybeiftxi2qhreewgsc5wevogi7yc5g6hbcbo4uiuaibauhv3nhfcdtvm -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -- valory/tendermint:0.1.0:bafybeig4mi3vmlv5zpbjbfuzcgida6j5f2nhrpedxicmrrfjweqc5r7cra -skills: -- valory/abstract_abci:0.1.0:bafybeieeaseuy5rbbw465knz27vccvpkfge43q7isl7fkdlfapwd7bpi24 -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/check_stop_trading_abci:0.1.0:bafybeieduekpd4zbvjztyxyooppqnmjvup6jfp74uo6hhupvtvzzscdzkq -- valory/decision_maker_abci:0.1.0:bafybeibqiruzwnj7usv4nmtjiyrzaaukive4wiebdxd5gymwgrlsn2fara -- valory/market_manager_abci:0.1.0:bafybeibo63iiziwvqn6fmx36ungyg35z3chfv432kf6spuiszm6na22vdy -- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm -- valory/registration_abci:0.1.0:bafybeibc7duasoaw5b4ene5oxfba2dmdzstsrws6ipi57ymgdtoxjadn54 -- valory/reset_pause_abci:0.1.0:bafybeigrdlxed3xlsnxtjhnsbl3cojruihxcqx4jxhgivkd5i2fkjncgba -- valory/staking_abci:0.1.0:bafybeicupccurmrg7qesivonlyt3nryarsmk5qf5yh6auno64wn45bybvq -- valory/termination_abci:0.1.0:bafybeib5l7jhew5ic6iq24dd23nidcoimzqkrk556gqywhoziatj33zvwm -- valory/trader_abci:0.1.0:bafybeibphcwnjh5lfvcahcsuhidnw6wgpocezlmusug72u6raohizsrsqe -- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae -- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeicwknp3cym5n3aig5ykyqwqufeabx3wsu2nk3jv7ftpdhulcr3rou -customs: -- jhehemann/kelly_criterion:0.1.0:bafybeif55cu7cf6znyma7kxus4wxa2doarhau2xmndo57iegshxorivwmq -- valory/bet_amount_per_threshold:0.1.0:bafybeihufqu2ra7vud4h6g2nwahx7mvdido7ff6prwnib2tdlc4np7dw24 -- valory/kelly_criterion_no_conf:0.1.0:bafybeibxfp27rzrfnp7sxq62vwv32pdvrijxi7vzg7ihukkaka3bwzrgae -- valory/mike_strat:0.1.0:bafybeihjiol7f4ch4piwfikurdtfwzsh6qydkbsztpbwbwb2yrqdqf726m -- w1kke/always_blue:0.1.0:bafybeieshu32h3es2fslduuhr7nimuvh2vuibyeqdunzrcggaeohekg3jm -default_ledger: ethereum -required_ledgers: -- ethereum -- cosmos -default_routing: {} -connection_private_key_paths: {} -private_key_paths: - ethereum: ethereum_private_key.txt -logging_config: - version: 1 - disable_existing_loggers: false - formatters: - standard: - format: '[%(asctime)s] [%(levelname)s] %(message)s' - handlers: - logfile: - class: logging.FileHandler - formatter: standard - filename: ${LOG_FILE:str:log.txt} - level: ${LOG_LEVEL:str:INFO} - console: - class: logging.StreamHandler - formatter: standard - stream: ext://sys.stdout - loggers: - aea: - handlers: - - logfile - - console - propagate: true -dependencies: - open-aea-ledger-cosmos: - version: ==1.53.0 - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 -skill_exception_policy: stop_and_exit -connection_exception_policy: just_log -default_connection: null ---- -public_id: valory/abci:0.1.0 -type: connection -config: - target_skill_id: valory/trader_abci:0.1.0 - host: ${str:localhost} - port: ${int:26658} - use_tendermint: ${bool:false} ---- -public_id: valory/trader_abci:0.1.0 -type: skill -models: - benchmark_tool: - args: - log_dir: ${str:.} - params: - args: - setup: - all_participants: ${list:["0x0000000000000000000000000000000000000000"]} - consensus_threshold: ${int:null} - safe_contract_address: ${str:0x0000000000000000000000000000000000000000} - cleanup_history_depth: ${int:1} - cleanup_history_depth_current: ${int:null} - finalize_timeout: ${float:60.0} - genesis_config: - genesis_time: ${str:2022-09-26T00:00:00.000000000Z} - chain_id: ${str:chain-c4daS1} - consensus_params: - block: - max_bytes: ${str:22020096} - max_gas: ${str:-1} - time_iota_ms: ${str:1000} - evidence: - max_age_num_blocks: ${str:100000} - max_age_duration: ${str:172800000000000} - max_bytes: ${str:1048576} - validator: - pub_key_types: ${list:["ed25519"]} - version: ${dict:{}} - voting_power: ${str:10} - init_fallback_gas: ${int:0} - keeper_allowed_retries: ${int:3} - keeper_timeout: ${float:30.0} - max_attempts: ${int:10} - reset_tendermint_after: ${int:2} - retry_attempts: ${int:400} - retry_timeout: ${int:3} - request_retry_delay: ${float:1.0} - request_timeout: ${float:10.0} - service_id: ${str:trader} - tendermint_url: ${str:http://localhost:26657} - tendermint_com_url: ${str:http://localhost:8080} - tendermint_check_sleep_delay: ${int:3} - tendermint_max_retries: ${int:5} - tx_timeout: ${float:10.0} - round_timeout_seconds: ${float:350.0} - validate_timeout: ${int:1205} - history_check_timeout: ${int:1205} - reset_pause_duration: ${int:30} - max_healthcheck: ${int:43200} - multisend_address: ${str:0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761} - multisend_batch_size: ${int:1} - drand_public_key: ${str:868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31} - service_registry_address: ${str:null} - agent_registry_address: ${str:0xE49CB081e8d96920C38aA7AB90cb0294ab4Bc8EA} - share_tm_config_on_startup: ${bool:false} - sleep_time: ${int:10} - tendermint_p2p_url: ${str:localhost:26656} - termination_sleep: ${int:900} - termination_from_block: ${int:0} - use_termination: ${bool:false} - on_chain_service_id: ${int:null} - creator_per_subgraph: - omen_subgraph: ${list:["0x89c5cc945dd550BcFfb72Fe42BfF002429F46Fec"]} - slot_count: ${int:2} - opening_margin: ${int:86400} - languages: ${list:["en_US"]} - average_block_time: ${int:5} - abt_error_mult: ${int:5} - the_graph_error_message_key: ${str:message} - the_graph_payment_required_error: ${str:payment required for subsequent requests - for this API key} - mech_contract_address: ${str:0x77af31De935740567Cf4fF1986D04B2c964A786a} - mech_request_price: ${int:null} - mech_chain_id: ${str:gnosis} - mech_activity_checker_contract: ${str:0x0000000000000000000000000000000000000000} - mech_wrapped_native_token_address: ${str:0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d} - sample_bets_closing_days: ${int:10} - trading_strategy: ${str:kelly_criterion_no_conf} - use_fallback_strategy: ${bool:true} - bet_threshold: ${int:100000000000000000} - ipfs_address: ${str:https://gateway.autonolas.tech/ipfs/} - tools_accuracy_hash: ${str:QmR8etyW3TPFadNtNrW54vfnFqmh8vBrMARWV76EmxCZyk} - prompt_template: ${str:With the given question "@{question}" and the `yes` option - represented by `@{yes}` and the `no` option represented by `@{no}`, what are - the respective probabilities of `p_yes` and `p_no` occurring?} - dust_threshold: ${int:10000000000000} - conditional_tokens_address: ${str:0xCeAfDD6bc0bEF976fdCd1112955828E00543c0Ce} - realitio_proxy_address: ${str:0xAB16D643bA051C11962DA645f74632d3130c81E2} - realitio_address: ${str:0x79e32aE03fb27B07C89c0c568F80287C01ca2E57} - event_filtering_batch_size: ${int:5000} - reduce_factor: ${float:0.25} - minimum_batch_size: ${int:500} - use_subgraph_for_redeeming: ${bool:true} - max_filtering_retries: ${int:6} - redeeming_batch_size: ${int:5} - slippage: ${float:0.01} - redeem_round_timeout: ${float:3600.0} - policy_epsilon: ${float:0.1} - store_path: ${str:./data/} - irrelevant_tools: ${list:["openai-text-davinci-002", "openai-text-davinci-003", - "openai-gpt-3.5-turbo", "openai-gpt-4", "stabilityai-stable-diffusion-v1-5", - "stabilityai-stable-diffusion-xl-beta-v2-2-2", "stabilityai-stable-diffusion-512-v2-1", - "stabilityai-stable-diffusion-768-v2-1"]} - use_nevermined: ${bool:true} - mech_to_subscription_params: ${list:[["base_url", "https://marketplace-api.gnosis.nevermined.app/api/v1/metadata/assets/ddo"], - ["did", "did:nv:01706149da2f9f3f67cf79ec86c37d63cec87fc148f5633b12bf6695653d5b3c"], - ["escrow_payment_condition_address", "0x31B2D187d674C9ACBD2b25f6EDce3d2Db2B7f446"], - ["lock_payment_condition_address", "0x2749DDEd394196835199471027713773736bffF2"], - ["transfer_nft_condition_address", "0x659fCA7436936e9fe8383831b65B8B442eFc8Ea8"], - ["token_address", "0x1b5DeaD7309b56ca7663b3301A503e077Be18cba"], ["order_address", - "0x72201948087aE83f8Eac22cf7A9f2139e4cFA829"], ["nft_amount", "100"], ["payment_token", - "0x0000000000000000000000000000000000000000"], ["order_address", "0x72201948087aE83f8Eac22cf7A9f2139e4cFA829"], - ["price", "1000000000000000000"]]} - staking_contract_address: ${str:0x2Ef503950Be67a98746F484DA0bBAdA339DF3326} - staking_interaction_sleep_time: ${int:5} - disable_trading: ${bool:false} - stop_trading_if_staking_kpi_met: ${bool:true} - agent_balance_threshold: ${int:10000000000000000} - refill_check_interval: ${int:10} - tool_punishment_multiplier: ${int:1} - contract_timeout: ${float:300.0} - file_hash_to_strategies_json: ${list:[["bafybeihufqu2ra7vud4h6g2nwahx7mvdido7ff6prwnib2tdlc4np7dw24",["bet_amount_per_threshold"]],["bafybeibxfp27rzrfnp7sxq62vwv32pdvrijxi7vzg7ihukkaka3bwzrgae",["kelly_criterion_no_conf"]]]} - strategies_kwargs: ${list:[["bet_kelly_fraction",1.0],["floor_balance",500000000000000000],["bet_amount_per_threshold",{"0.0":0,"0.1":0,"0.2":0,"0.3":0,"0.4":0,"0.5":0,"0.6":60000000000000000,"0.7":90000000000000000,"0.8":100000000000000000,"0.9":1000000000000000000,"1.0":10000000000000000000}]]} - service_endpoint: ${str:https://trader.staging.autonolas.tech/} - rpc_sleep_time: ${int:10} - safe_voting_range: ${int:600} - rebet_chance: ${float:0.6} - mech_interaction_sleep_time: ${int:10} - use_mech_marketplace: ${bool:false} - policy_store_update_offset: ${int:259200} - mech_marketplace_config: - mech_marketplace_address: ${str:0x0000000000000000000000000000000000000000} - priority_mech_address: ${str:0x0000000000000000000000000000000000000000} - priority_mech_staking_instance_address: ${str:0x0000000000000000000000000000000000000000} - priority_mech_service_id: ${int:0} - requester_staking_instance_address: ${str:0x0000000000000000000000000000000000000000} - response_timeout: ${int:300} - expected_mech_response_time: ${int:300} - mech_invalid_response: ${str:Invalid Response} - mech_consecutive_failures_threshold: ${int:2} - tool_quarantine_duration: ${int:18000} - benchmarking_mode: - args: - enabled: ${bool:true} - native_balance: ${int:10000000000000000000} - collateral_balance: ${int:10000000000000000000} - mech_cost: ${int:10000000000000000} - pool_fee: ${int:20000000000000000} - sep: ${str:,} - dataset_filename: ${str:markets_test2.csv} - question_field: ${str:question} - question_id_field: ${str:question_id} - answer_field: ${str:answer} - p_yes_field_part: ${str:p_yes_} - p_no_field_part: ${str:p_no_} - confidence_field_part: ${str:confidence_} - info_utility_field_part: ${str:info_utility_} - part_prefix_mode: ${bool:true} - bet_amount_field: ${str:collateral_amount} - results_filename: ${str:benchmarking_results.csv} - randomness: ${str:benchmarking_randomness} - nr_mech_calls: ${int:60} - acc_info_fields: - args: - tool: ${str:tool} - requests: ${str:total_requests} - accuracy: ${str:tool_accuracy} - sep: ${str:,} - max: ${str:max} - datetime_format: ${str:%Y-%m-%d %H:%M:%S} - network_subgraph: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:POST} - response_key: ${str:data:blocks} - response_index: ${int:0} - response_type: ${str:dict} - error_key: ${str:errors} - error_index: ${int:0} - error_type: ${str:dict} - retries: ${int:5} - url: ${str:https://api.thegraph.com/subgraphs/name/stakewise/ethereum-gnosis} - omen_subgraph: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:POST} - response_key: ${str:data:fixedProductMarketMakers} - response_type: ${str:list} - error_key: ${str:errors} - error_index: ${int:0} - error_type: ${str:dict} - retries: ${int:5} - url: ${str:https://api.thegraph.com/subgraphs/name/protofire/omen-xdai} - randomness_api: - args: - method: ${str:GET} - response_key: ${str:null} - response_type: ${str:dict} - retries: ${int:5} - url: ${str:https://drand.cloudflare.com/public/latest} - mech_response: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:GET} - response_key: ${str:result} - response_type: ${str:str} - retries: ${int:5} - url: ${str:''} - agent_tools: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:GET} - response_key: ${str:tools} - response_type: ${str:list} - retries: ${int:5} - url: ${str:''} - trades_subgraph: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:POST} - response_key: ${str:data:fpmmTrades} - response_type: ${str:list} - error_key: ${str:errors} - error_index: ${int:0} - error_type: ${str:dict} - retries: ${int:5} - url: ${str:https://api.thegraph.com/subgraphs/name/protofire/omen-xdai} - conditional_tokens_subgraph: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:POST} - response_key: ${str:data:user:userPositions} - response_type: ${str:list} - error_key: ${str:errors} - error_index: ${int:0} - error_type: ${str:dict} - retries: ${int:5} - url: ${str:https://api.thegraph.com/subgraphs/name/gnosis/conditional-tokens-gc} - realitio_subgraph: - args: - headers: - Content-Type: ${str:application/json} - method: ${str:POST} - response_key: ${str:data:answers} - response_type: ${str:list} - error_key: ${str:errors} - error_index: ${int:0} - error_type: ${str:dict} - retries: ${int:5} - url: ${str:https://api.thegraph.com/subgraphs/name/realityeth/realityeth-gnosis} ---- -public_id: valory/p2p_libp2p_client:0.1.0 -type: connection -config: - nodes: - - uri: ${str:acn.staging.autonolas.tech:9005} - public_key: ${str:02d3a830c9d6ea1ae91936951430dee11f4662f33118b02190693be835359a9d77} -cert_requests: -- identifier: acn - ledger_id: ethereum - message_format: '{public_key}' - not_after: '2024-01-01' - not_before: '2023-01-01' - public_key: ${str:02d3a830c9d6ea1ae91936951430dee11f4662f33118b02190693be835359a9d77} - save_path: .certs/acn_cosmos_9005.txt -is_abstract: true ---- -public_id: valory/ledger:0.19.0 -type: connection -config: - ledger_apis: - ethereum: - address: ${str:http://host.docker.internal:8545} - chain_id: ${int:1337} - default_gas_price_strategy: ${str:eip1559} - poa_chain: ${bool:false} - gnosis: - address: ${str:https://rpc.gnosischain.com} - chain_id: ${int:100} - poa_chain: ${bool:false} - default_gas_price_strategy: ${str:eip1559} ---- -public_id: valory/http_server:0.22.0:bafybeicblltx7ha3ulthg7bzfccuqqyjmihhrvfeztlgrlcoxhr7kf6nbq -type: connection -config: - host: ${str:0.0.0.0} - port: ${int:8716} - target_skill_id: valory/trader_abci:0.1.0 diff --git a/trader_old/data/available_tools_store.json b/trader_old/data/available_tools_store.json deleted file mode 100644 index b5f237842..000000000 --- a/trader_old/data/available_tools_store.json +++ /dev/null @@ -1 +0,0 @@ -["prediction-online", "prediction-offline", "claude-prediction-offline", "claude-prediction-online", "prediction-online-sme", "prediction-offline-sme", "prediction-request-rag", "prediction-request-rag-claude", "prediction-request-reasoning", "prediction-request-reasoning-claude", "prediction-url-cot-claude", "superforcaster"] \ No newline at end of file diff --git a/trader_old/data/benchmarking_results.csv b/trader_old/data/benchmarking_results.csv deleted file mode 100644 index 318426c22..000000000 --- a/trader_old/data/benchmarking_results.csv +++ /dev/null @@ -1,159 +0,0 @@ -question_id,question,answer,p_yes,p_no,confidence,info_utility,collateral_amount,l0_start,l1_start,l0_end,l1_end -16,"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",yes,0.2,0.8,0.8,0.54,813433492621134848,6829378464124429312,7174884252996530176,7615288074131442688,6434425004413068288 -37,"Will any regulatory body impose penalties on CrowdStrike regarding the software update issue by December 24th, 2024?",yes,0.8,0.2,0.8,0.54,768540040008750336,6713006125431115776,7299263412612062208,6054359726413270016,8093341362956745344 -14,"Will CrowdStrike issue a public apology specifically addressing Delta Airlines before December 24th, 2024?",yes,0.8,0.2,0.8,0.54,822740070267325568,7447751901935623168,6579166525037603840,6670130234184115200,7346183399669952000 -18,"Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?",no,0.2,0.8,0.8,0.54,735303296304110208,7580636800397400064,6463836916369778688,8371473456154892032,5853210937911308288 -33,"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",yes,0.8,0.2,0.8,0.54,828999865829784832,7603583397009488896,6444329922030162944,6803215557190453248,7202476474262370176 -34,"Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?",no,0.2,0.8,0.8,0.54,833559154458933120,6382785525064408064,7676899029049789440,7138454118417912960,6864231272927171584 -12,"Will Notre Dame cathedral in Paris reopen to the public on December 31, 2024?",no,0.2,0.8,0.8,0.54,722730382367103360,7718021398376549376,6348777422450127872,8510680928852605824,5757471160019870720 -31,"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",no,0.2,0.8,0.8,0.54,836011162945628544,6347983720511538176,7718986399046947840,7102133424009088768,6899335322869780480 -15,"Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?",yes,0.8,0.2,0.8,0.54,839036884585969664,7770115198421651456,6306212810069199872,6941874941313186816,7058611745997649280 -36,"Will the US unemployment rate be above 4% in December 19th, 2024?",no,0.8,0.2,0.8,0.54,839388422701602432,7777211499434802176,6300458718855853056,6947833888026206208,7052557788470717056 -32,"Will Keiichi Ishii announce his resignation as leader of Komeito before December 30, 2024?",yes,0.8,0.2,0.8,0.54,843247684796343040,7843818870114099200,6246957102323708928,7003205908492904448,6996795559099138560 -20,"Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?",yes,0.2,0.8,0.8,0.54,696917062446403584,7993723958564144128,6129808866805242880,8788569434963169792,5575423891522720768 -17,"Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?",yes,0.8,0.2,0.8,0.54,851824891020058880,7998003560152404992,6126528905804374016,7131243675558478848,6871171737959522048 -19,"Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?",yes,0.8,0.2,0.8,0.54,687475014397188864,6094847400418020352,8039577823825300480,5550043078272043008,8828760301308457088 -39,"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",no,0.2,0.8,0.8,0.54,683171818320666752,8137309462365664256,6021646371767063552,8932463230577482112,5485608922773271552 -11,"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",yes,0.8,0.2,0.8,0.54,864643364823210368,8245212024748660736,5942842931500439552,7336068645260313600,6679326812414428928 -13,"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",no,0.8,0.2,0.8,0.54,864666039302367744,8247178618240060416,5941425821871740928,7337765842766164992,6677781909367681920 -40,"Will the Federal Reserve issue a statement or report addressing the economic impact of inflation on high-income households by December 30, 2024?",yes,0.8,0.2,0.8,0.54,894887798540904192,8930011344563093504,5487115089706233856,7900332515745550336,6202270588274840320 -38,"Will a class-action lawsuit be filed against Hot Topic or Robling due to the data breach before December 25th, 2024?",yes,0.8,0.2,0.8,0.54,895125129503478016,8936278530007503872,5483266869476018176,7905482328690592768,6198230286616301568 -35,"Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?",no,0.2,0.8,0.8,0.54,601433484607172864,8951406991179005952,5473999791126257664,9735948804205914240,5032894172454160384 -16,"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",yes,0.8,0.2,0.8,0.54,769644123203022848,7615288074131442688,6434425004413068288,6867531894258012160,7135023288493091712 -37,"Will any regulatory body impose penalties on CrowdStrike regarding the software update issue by December 24th, 2024?",yes,0.8,0.2,0.8,0.54,759038177274369792,6054359726413270016,8093341362956745344,5466968087276639232,8962920437388041728 -14,"Will CrowdStrike issue a public apology specifically addressing Delta Airlines before December 24th, 2024?",yes,0.8,0.2,0.8,0.54,817752649256177152,6670130234184115200,7346183399669952000,5977483578377789440,8197429463001210752 -18,"Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?",no,0.2,0.8,0.8,0.54,734388467231641984,8371473456154892032,5853210937911308288,9243726193924509056,5300892624037860352 -33,"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",yes,0.8,0.2,0.8,0.54,828022673475815168,6803215557190453248,7202476474262370176,6087851350557477888,8048816762832582272 -34,"Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?",no,0.2,0.8,0.8,0.54,832631074361408896,7138454118417912960,6864231272927171584,7982646606412105344,6138315074682183680 -12,"Will Notre Dame cathedral in Paris reopen to the public on December 31, 2024?",no,0.8,0.2,0.8,0.54,835149334626456448,8510680928852605824,5757471160019870720,7607805311349823488,6440753672665438592 -31,"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",no,0.2,0.8,0.8,0.54,835201760265622912,7102133424009088768,6899335322869780480,7945060320521095424,6167354056889806848 -15,"Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?",yes,0.2,0.8,0.8,0.54,717209794713883392,6941874941313186816,7058611745997649280,7649855765145099392,6405349526099279872 -36,"Will the US unemployment rate be above 4% in December 19th, 2024?",no,0.2,0.8,0.8,0.54,716544385694882304,6947833888026206208,7052557788470717056,7655832539190741888,6400348982186532864 -32,"Will Keiichi Ishii announce his resignation as leader of Komeito before December 30, 2024?",yes,0.2,0.8,0.8,0.54,710420576662694656,7003205908492904448,6996795559099138560,7711406779615716736,6354223217678814208 -20,"Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?",yes,0.2,0.8,0.8,0.54,696445838632758784,8788569434963169792,5575423891522720768,9661858452610571648,5071488082788101120 -17,"Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?",yes,0.8,0.2,0.8,0.54,851305291354845184,7131243675558478848,6871171737959522048,6358836671776261120,7705812010786002560 -19,"Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?",yes,0.2,0.8,0.8,0.54,853566490895827968,5550043078272043008,8828760301308457088,6226470153788060032,7869627379517650944 -39,"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",no,0.2,0.8,0.8,0.54,682799605000728704,8932463230577482112,5485608922773271552,9804841510819725440,4997531061152603136 -11,"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",yes,0.8,0.2,0.8,0.54,864228601091805568,7336068645260313600,6679326812414428928,6527515571687417856,7506684505286150016 -13,"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",no,0.2,0.8,0.8,0.54,672193608244320256,7337765842766164992,6677781909367681920,8044745679076715264,6090932138158488576 -40,"Will the Federal Reserve issue a statement or report addressing the economic impact of inflation on high-income households by December 30, 2024?",yes,0.2,0.8,0.8,0.54,603476365178993920,7900332515745550336,6202270588274840320,8594706534398763264,5701183606896447488 -38,"Will a class-action lawsuit be filed against Hot Topic or Robling due to the data breach before December 25th, 2024?",yes,0.8,0.2,0.8,0.54,894819191754834816,7905482328690592768,6198230286616301568,6993863791441476608,7006141592285830528 -35,"Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?",no,0.2,0.8,0.8,0.54,601229675634863360,9735948804205914240,5032894172454160384,10588962251340768640,4627460069922871296 -16,"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",yes,0.8,0.2,0.8,0.54,753030073966701696,6867531894258012160,7135023288493091712,6206354126820632576,7895134405600140800 -37,"Will any regulatory body impose penalties on CrowdStrike regarding the software update issue by December 24th, 2024?",yes,0.8,0.2,0.8,0.54,735083998276980992,5466968087276639232,8962920437388041728,4951726166612883456,9895539121364084992 -14,"Will CrowdStrike issue a public apology specifically addressing Delta Airlines before December 24th, 2024?",yes,0.8,0.2,0.8,0.54,817502456054136448,5977483578377789440,8197429463001210752,5356933657851410432,9147023862836710272 -18,"Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?",no,0.2,0.8,0.8,0.54,734156165517634560,9243726193924509056,5300892624037860352,10206557298503013760,4800835244141212672 -33,"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",yes,0.8,0.2,0.8,0.54,827760777592088320,6087851350557477888,8048816762832582272,5447889517986297856,8994308683798687232 -34,"Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?",no,0.2,0.8,0.8,0.54,832386132055515904,7982646606412105344,6138315074682183680,8926395455934991488,5489337800670798848 -12,"Will Notre Dame cathedral in Paris reopen to the public on December 31, 2024?",no,0.8,0.2,0.8,0.54,834903986290690560,7607805311349823488,6440753672665438592,6800925337167340544,7204901917127800960 -31,"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",no,0.2,0.8,0.8,0.54,834943961037738752,7945060320521095424,6167354056889806848,8887740141287966720,5513212495083049984 -15,"Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?",yes,0.8,0.2,0.8,0.54,838020607929035776,7649855765145099392,6405349526099279872,6835316835041516544,7168650873475184768 -36,"Will the US unemployment rate be above 4% in December 19th, 2024?",no,0.2,0.8,0.8,0.54,716319825920572288,7655832539190741888,6400348982186532864,8435733226256191616,5808623706530651136 -32,"Will Keiichi Ishii announce his resignation as leader of Komeito before December 30, 2024?",yes,0.8,0.2,0.8,0.54,842356399912248576,7711406779615716736,6354223217678814208,6885764245473724416,7116130941051252864 -20,"Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?",yes,0.8,0.2,0.8,0.54,850820763792527104,9661858452610571648,5071488082788101120,8615949914487721984,5687126838748967680 -17,"Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?",yes,0.8,0.2,0.8,0.54,851036761085544576,6358836671776261120,7705812010786002560,5670285182201811968,8641540667796352256 -19,"Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?",yes,0.8,0.2,0.8,0.54,691873738757824000,6226470153788060032,7869627379517650944,5666659410645379072,8647069895880571392 -39,"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",no,0.8,0.2,0.8,0.54,858451583280278016,9804841510819725440,4997531061152603136,8732584380895200256,5611168224975900544 -11,"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",yes,0.2,0.8,0.8,0.54,672187158971960064,6527515571687417856,7506684505286150016,7156398939718043520,6847019068214574080 -13,"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",no,0.2,0.8,0.8,0.54,666581439282683776,8044745679076715264,6090932138158488576,8813370378303970304,5559734573350526976 -40,"Will the Federal Reserve issue a statement or report addressing the economic impact of inflation on high-income households by December 30, 2024?",yes,0.8,0.2,0.8,0.54,894313917594319488,8594706534398763264,5701183606896447488,7604252460967090176,6443762914437523200 -38,"Will a class-action lawsuit be filed against Hot Topic or Robling due to the data breach before December 25th, 2024?",yes,0.8,0.2,0.8,0.54,894539616310804608,6993863791441476608,7006141592285830528,6187591227850887168,7919075161178510592 -35,"Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?",no,0.2,0.8,0.8,0.54,601040115365416960,10588962251340768640,4627460069922871296,11516419813952064640,4254794527430897152 -16,"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",yes,0.8,0.2,0.8,0.54,769145728755566208,6206354126820632576,7895134405600140800,5597299120600962048,8754222160408508032 -37,"Will any regulatory body impose penalties on CrowdStrike regarding the software update issue by December 24th, 2024?",yes,0.2,0.8,0.8,0.54,806810543882226944,4951726166612883456,9895539121364084992,5517243325490025088,8881246867183978496 -14,"Will CrowdStrike issue a public apology specifically addressing Delta Airlines before December 24th, 2024?",yes,0.8,0.2,0.8,0.54,817226115546015616,5356933657851410432,9147023862836710272,4800974341931909120,10206261585701877248 -18,"Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?",no,0.2,0.8,0.8,0.54,733908021502696576,10206557298503013760,4800835244141212672,11269318034958926208,4348089196524178432 -33,"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",yes,0.8,0.2,0.8,0.54,827481021167360256,5447889517986297856,8994308683798687232,4875374408551581696,10050510154471879936 -34,"Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?",no,0.2,0.8,0.8,0.54,832094155096944000,8926395455934991488,5489337800670798848,9981348889951206400,4909156121106146304 -12,"Will Notre Dame cathedral in Paris reopen to the public on December 31, 2024?",no,0.2,0.8,0.8,0.54,721516913314281728,6800925337167340544,7204901917127800960,7498224137923760000,6534880672901302272 -31,"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",no,0.2,0.8,0.8,0.54,834662113565429120,8887740141287966720,5513212495083049984,9941912763121836544,4928629044277957632 -15,"Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?",yes,0.8,0.2,0.8,0.54,837737748040211072,6835316835041516544,7168650873475184768,6107727634620130304,8022623622287236096 -36,"Will the US unemployment rate be above 4% in December 19th, 2024?",no,0.8,0.2,0.8,0.54,838143539005005568,8435733226256191616,5808623706530651136,7537321618051778560,6500983039206619776 -32,"Will Keiichi Ishii announce his resignation as leader of Komeito before December 30, 2024?",yes,0.8,0.2,0.8,0.54,842063095166568064,6885764245473724416,7116130941051252864,6148750581212143616,7969098657168220288 -20,"Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?",yes,0.8,0.2,0.8,0.54,850533346775666048,8615949914487721984,5687126838748967680,7683543289509916672,6377266080728411904 -17,"Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?",yes,0.8,0.2,0.8,0.54,850749297657731456,5670285182201811968,8641540667796352256,5056476795681313792,9690541849583966080 -19,"Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?",yes,0.8,0.2,0.8,0.54,691640059044731648,5666659410645379072,8647069895880571392,5157336855307638784,9501027637853822464 -39,"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",no,0.2,0.8,0.8,0.54,682338408219938944,8732584380895200256,5611168224975900544,9584865671401370752,5112226053016335360 -11,"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",yes,0.8,0.2,0.8,0.54,863657471004244224,7156398939718043520,6847019068214574080,6368112198886497280,7694588045821169792 -13,"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",no,0.2,0.8,0.8,0.54,671754715365989760,8813370378303970304,5559734573350526976,9661967482468454528,5071430853903205376 -40,"Will the Federal Reserve issue a statement or report addressing the economic impact of inflation on high-income households by December 30, 2024?",yes,0.8,0.2,0.8,0.54,893992186647079040,7604252460967090176,6443762914437523200,6728217262619282432,7282761255679843584 -38,"Will a class-action lawsuit be filed against Hot Topic or Robling due to the data breach before December 25th, 2024?",yes,0.8,0.2,0.8,0.54,894217833910163840,6187591227850887168,7919075161178510592,5474495088642966528,8950597124774527104 -35,"Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?",no,0.2,0.8,0.8,0.54,600823930130005248,11516419813952064640,4254794527430897152,12524747977084655744,3912254369481178624 -16,"Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?",yes,0.8,0.2,0.8,0.7,768417865886670464,6829378464124429312,7174884252996530176,6159755559639692288,7954861118363306880 -14,"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",yes,0.8,0.2,0.8,0.7,816458364477526528,7447751901935623168,6579166525037603840,6675451791677727744,7340327146259702912 -18,"Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?",no,0.2,0.8,0.8,0.7,733218608279383296,7580636800397400064,6463836916369778688,8369231323263526784,5854779024185552896 -12,"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",no,0.2,0.8,0.8,0.7,720855392362466304,7718021398376549376,6348777422450127872,8508624520635954944,5758862655316422656 -15,"Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?",yes,0.8,0.2,0.8,0.7,836988524518835200,7770115198421651456,6306212810069199872,6943681882185610240,7056774897149614720 -20,"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",yes,0.8,0.2,0.8,0.7,849792117890902272,7993723958564144128,6129808866805242880,7129326173009589248,6873019807328443904 -17,"Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?",yes,0.8,0.2,0.8,0.7,850007949243672704,7998003560152404992,6126528905804374016,7132892496796547072,6869583415424582912 -19,"Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?",yes,0.8,0.2,0.8,0.7,691037415263925248,6094847400418020352,8039577823825300480,5547473517966963712,8832849736244887936 -11,"Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?",yes,0.8,0.2,0.8,0.7,862911819823913088,8245212024748660736,5942842931500439552,7337688912374441984,6677851921109017216 -13,"Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?",no,0.2,0.8,0.8,0.7,671169515669167616,8247178618240060416,5941425821871740928,9040568072643808896,5420013389232798720 -37,"Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?",yes,0.8,0.2,0.8,0.7,757676477411858944,6713006125431115776,7299263412612062208,6062768100162307072,8082116813718839040 -33,"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",yes,0.8,0.2,0.8,0.7,826555969330999296,7603583397009488896,6444329922030162944,6805327337248869376,7200241453750380032 -34,"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",no,0.2,0.8,0.8,0.7,831156343539399936,6382785525064408064,7676899029049789440,7136275834203835008,6866326517978089472 -31,"Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?",no,0.8,0.2,0.8,0.7,716812322158993024,6347983720511538176,7718986399046947840,5761138634561848320,8505263127334307584 -36,"Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?",no,0.2,0.8,0.8,0.7,715308058626604544,7777211499434802176,6300458718855853056,8568358040436432640,5718715274123182080 -32,"Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?",yes,0.8,0.2,0.8,0.7,841149886771591296,7843818870114099200,6246957102323708928,7005073533752241152,6994930140833701632 -39,"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",no,0.2,0.8,0.8,0.7,681637302176288000,8137309462365664256,6021646371767063552,8930677184575783680,5486705989622840320 -40,"Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?",yes,0.2,0.8,0.8,0.7,602476282975841280,8930011344563093504,5487115089706233856,9713584938088593152,5044481549532016640 -38,"Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?",yes,0.2,0.8,0.8,0.7,601810135980886400,8936278530007503872,5483266869476018176,9719666471573281280,5041325249514305536 -35,"Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?",no,0.2,0.8,0.8,0.7,600219810406354304,8951406991179005952,5473999791126257664,9734365623052380544,5033712714053080064 -16,"Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?",yes,0.8,0.2,0.8,0.7,768091148638155648,6159755559639692288,7954861118363306880,5556021037134952448,8819261063357601280 -14,"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",yes,0.8,0.2,0.8,0.7,816111253307116928,6675451791677727744,7340327146259702912,5983499694649194496,8189187348637912448 -18,"Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?",no,0.2,0.8,0.8,0.7,732906914621495296,8369231323263526784,5854779024185552896,9239491237271442176,5303322308736819200 -12,"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",no,0.8,0.2,0.8,0.7,833502178321639808,8508624520635954944,5758862655316422656,7607558829450218496,6440962350539078272 -15,"Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?",yes,0.2,0.8,0.8,0.7,715795390417409280,6943681882185610240,7056774897149614720,7650450423115372288,6404851647943430144 -20,"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",yes,0.8,0.2,0.8,0.7,849430390853509888,7129326173009589248,6873019807328443904,6358692342689511424,7705986916686498432 -17,"Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?",yes,0.8,0.2,0.8,0.7,849646163667908608,7132892496796547072,6869583415424582912,6361649808704265216,7702404482082027904 -19,"Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?",yes,0.8,0.2,0.8,0.7,690743318793541632,5547473517966963712,8832849736244887936,5049451890505373696,9704023538106397824 -11,"Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?",yes,0.8,0.2,0.8,0.7,862544609688791424,7337688912374441984,6677851921109017216,6530359728932641792,7503415130855101184 -13,"Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?",no,0.2,0.8,0.8,0.7,670883927338612096,9040568072643808896,5420013389232798720,9909912567461361152,4944544128561611776 -37,"Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?",yes,0.8,0.2,0.8,0.7,757354109330176000,6062768100162307072,8082116813718839040,5475739370322735104,8948563232495849216 -33,"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",yes,0.8,0.2,0.8,0.7,826204327531035776,6805327337248869376,7200241453750380032,6091147596571503616,8044461117241750016 -34,"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",no,0.2,0.8,0.8,0.7,830802777168446080,7136275834203835008,6866326517978089472,7978357600462374784,6141614910462308352 -31,"Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?",no,0.2,0.8,0.8,0.7,833374589653056640,5761138634561848320,8505263127334307584,6443411759025184896,7604666880300872704 -36,"Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?",no,0.8,0.2,0.8,0.7,836869542873870080,8568358040436432640,5718715274123182080,7657061345745166336,6399321853053724672 -32,"Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?",yes,0.8,0.2,0.8,0.7,840773114111599488,7005073533752241152,6994930140833701632,6256315513666781184,7832085816797538560 -39,"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",no,0.8,0.2,0.8,0.7,856891722838158592,8930677184575783680,5486705989622840320,7955599523674761216,6159183837017284480 -40,"Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?",yes,0.8,0.2,0.8,0.7,892693462215400832,9713584938088593152,5044481549532016640,8595986229484902400,5700334864651852160 -38,"Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?",yes,0.8,0.2,0.8,0.7,892918901646441088,9719666471573281280,5041325249514305536,8600952064105698304,5697043726646426752 -35,"Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?",no,0.2,0.8,0.8,0.7,599951259638977664,9734365623052380544,5033712714053080064,10585426862227805056,4629005578872562688 -16,"Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?",yes,0.8,0.2,0.8,0.7,752606551874116352,5556021037134952448,8819261063357601280,5021382046051102720,9758269645810840448 -14,"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",yes,0.2,0.8,0.8,0.7,721934822384619008,5983499694649194496,8189187348637912448,6595602900238704384,7429191954267988992 -18,"Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?",no,0.2,0.8,0.8,0.7,732611716921105024,9239491237271442176,5303322308736819200,10199856641245109248,4803989087636677632 -12,"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",no,0.2,0.8,0.8,0.7,720258789109788160,7607558829450218496,6440962350539078272,8386201645895708416,5842931289874372608 -15,"Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?",yes,0.8,0.2,0.8,0.7,836295869538877568,7650450423115372288,6404851647943430144,6837346530210085888,7166522829214334976 -20,"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",yes,0.8,0.2,0.8,0.7,849088931997298944,6358692342689511424,7705986916686498432,5671605464393356288,8639529020067531648 -17,"Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?",yes,0.2,0.8,0.8,0.7,694391818629403648,6361649808704265216,7702404482082027904,6991964680576448512,7008044553789169664 -19,"Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?",yes,0.2,0.8,0.8,0.7,851545022670189440,5049451890505373696,9704023538106397824,5663410544188394112,8652030365392137216 -11,"Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?",yes,0.8,0.2,0.8,0.7,862197389131655296,6530359728932641792,7503415130855101184,5812114358792056832,8430666875278718848 -13,"Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?",no,0.2,0.8,0.8,0.7,670613885356441600,9909912567461361152,4944544128561611776,10862469987815059200,4510944569233847808 -37,"Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?",yes,0.8,0.2,0.8,0.7,757049289705859968,5475739370322735104,8948563232495849216,4945742550711413760,9907511257930654336 -33,"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",yes,0.8,0.2,0.8,0.7,825871827689847424,6091147596571503616,8044461117241750016,5452147154845496320,8987284937174181632 -34,"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",no,0.2,0.8,0.8,0.7,830468457476586624,7978357600462374784,6141614910462308352,8919426315071009792,5493626862212595712 -31,"Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?",no,0.2,0.8,0.8,0.7,833039265901815168,6443411759025184896,7604666880300872704,7206177259463659264,6799721715927784448 -36,"Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?",no,0.2,0.8,0.8,0.7,714700205058061568,7657061345745166336,6399321853053724672,8435323549347363712,5808905812959730688 -32,"Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?",yes,0.8,0.2,0.8,0.7,840435161277037184,6256315513666781184,7832085816797538560,5587830787239006208,8769055804607016576 -39,"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",no,0.8,0.2,0.8,0.7,851416748995079680,7955599523674761216,6159183837017284480,7091931097893402624,6909260584124262784 -40,"Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?",yes,0.8,0.2,0.8,0.7,892354856564955776,8595986229484902400,5700334864651852160,7607305085757933568,6441177190558017280 -38,"Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?",yes,0.8,0.2,0.8,0.7,892580241666810880,8600952064105698304,5697043726646426752,7611331736438313984,6437769591018945664 -35,"Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?",no,0.2,0.8,0.8,0.7,599723735307162368,10585426862227805056,4629005578872562688,11510544158425503232,4256966423618896384 -16,"Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?",yes,0.2,0.8,0.8,0.7,795815251781556992,5021382046051102720,9758269645810840448,5586715768222575488,8770805967741124608 -14,"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",yes,0.8,0.2,0.8,0.7,815436593569452928,6595602900238704384,7429191954267988992,5912434274689271808,8287618554977542016 -18,"Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?",no,0.2,0.8,0.8,0.7,732301093680515584,10199856641245109248,4803989087636677632,11259594230421785088,4351844213675936256 -12,"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",no,0.2,0.8,0.8,0.7,719953431542885888,8386201645895708416,5842931289874372608,9244175596268345856,5300634923008184320 -15,"Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?",yes,0.8,0.2,0.8,0.7,835941350055594368,6837346530210085888,7166522829214334976,6110936135136494592,8018411404802798336 -20,"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",yes,0.8,0.2,0.8,0.7,848729022444868480,5671605464393356288,8639529020067531648,5058993295174857728,9685721474811002240 -17,"Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?",yes,0.2,0.8,0.8,0.7,694097508758114560,6991964680576448512,7008044553789169664,7684437787341728512,6376523742662837248 -19,"Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?",yes,0.2,0.8,0.8,0.7,851184138643626880,5663410544188394112,8652030365392137216,6351728087649955328,7714436028090311680 -11,"Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?",yes,0.8,0.2,0.8,0.7,861832024451489792,5812114358792056832,8430666875278718848,5173106724170639360,9472064392380337024 -13,"Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?",no,0.2,0.8,0.8,0.7,670329732225676160,10862469987815059200,4510944569233847808,11906146410383631488,4115521371152125440 -37,"Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?",yes,0.8,0.2,0.8,0.7,756728541594488576,4945742550711413760,9907511257930654336,4467227316688220672,10968772468092390144 -33,"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",yes,0.8,0.2,0.8,0.7,825521952898360576,5452147154845496320,8987284937174181632,4880398855881607168,10040162996298490624 -34,"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",no,0.2,0.8,0.8,0.7,830116667716069248,8919426315071009792,5493626862212595712,9971050951771828736,4914226217176519680 -31,"Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?",no,0.2,0.8,0.8,0.7,832686419593027968,7206177259463659264,6799721715927784448,8058876952039331968,6080251664296767488 -36,"Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?",no,0.2,0.8,0.8,0.7,714397510880023680,8435323549347363712,5808905812959730688,9292325053408102784,5273168955925460992 -32,"Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?",yes,0.8,0.2,0.8,0.7,840079247800963584,5587830787239006208,8769055804607016576,4990999217339565056,9817673348808755328 -39,"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",no,0.2,0.8,0.8,0.7,680769775060952320,7091931097893402624,6909260584124262784,7782496981921859712,6296179762590748672 -40,"Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?",yes,0.8,0.2,0.8,0.7,891957186120974848,7607305085757933568,6441177190558017280,6732683781246016512,7277929811064374528 diff --git a/trader_old/data/bets.json b/trader_old/data/bets.json deleted file mode 100644 index 2828685a7..000000000 --- a/trader_old/data/bets.json +++ /dev/null @@ -1,1322 +0,0 @@ -[ - { - "id": "1", - "market": "omen_subgraph", - "title": "Will the number of migrant arrivals in the Canary Islands exceed 45,000 by December 10th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1735924988, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8260595624276564992, - 5931775652593000448 - ], - "outcomeTokenMarginalPrices": [ - 0.4179552195242021, - 0.5820447804757978 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.9051181150903505, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "2", - "market": "omen_subgraph", - "title": "Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1735924988, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 6816094858560068608, - 7188867088383137792 - ], - "outcomeTokenMarginalPrices": [ - 0.5133085770327435, - 0.48669142296725654 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.997519905535335, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "3", - "market": "omen_subgraph", - "title": "Will any U.S. state government announce new measures to support households earning over $150,000 who are living paycheck to paycheckby December 10th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1735924988, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7123594880765731840, - 6878549499256880128 - ], - "outcomeTokenMarginalPrices": [ - 0.4912497195123031, - 0.5087502804876969 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.998927974190889, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "4", - "market": "omen_subgraph", - "title": "Will the US unemployment rate be above 4% in December 19th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1735924988, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 6566843813393801216, - 7461727641528355840 - ], - "outcomeTokenMarginalPrices": [ - 0.531895044731036, - 0.468104955268964 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.985743367733646, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "5", - "market": "omen_subgraph", - "title": "Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1735924988, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8672523313665560576, - 5650028051557866496 - ], - "outcomeTokenMarginalPrices": [ - 0.39448474698975033, - 0.6055152530102497 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.842356330308139, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "6", - "market": "omen_subgraph", - "title": "Will at least 100,000 Americans die of H5N1 by the end of 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1735924988, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8330922612584986624, - 5881701496780064768 - ], - "outcomeTokenMarginalPrices": [ - 0.41383642116479147, - 0.5861635788352085 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.8952783979860115, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "7", - "market": "omen_subgraph", - "title": "Will any European country publicly announce a policy change to attract more American immigrants by December 24th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1735924988, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7299440008754813952, - 6712843716946820096 - ], - "outcomeTokenMarginalPrices": [ - 0.4790684979232883, - 0.5209315020767117 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.993863521350646, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "8", - "market": "omen_subgraph", - "title": "Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1735924988, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8282670984015906816, - 5915966008375963648 - ], - "outcomeTokenMarginalPrices": [ - 0.416657317990871, - 0.583342682009129 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.9020709560017535, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "9", - "market": "omen_subgraph", - "title": "Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1735924988, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7599337989828836352, - 6447930078328264704 - ], - "outcomeTokenMarginalPrices": [ - 0.45901666053805057, - 0.5409833394619494 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.976445492782348, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "10", - "market": "omen_subgraph", - "title": "Will Yuki Tsunoda score higher than Daniel Ricciardo in the 2024 Formula 1 Driver World Championship?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1735924988, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8763558214301901824, - 5591336167543596032 - ], - "outcomeTokenMarginalPrices": [ - 0.3895073010509159, - 0.6104926989490841 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.826939815310636, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "11", - "market": "omen_subgraph", - "title": "Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736443388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7282554748260174848, - 6728408050994227200 - ], - "outcomeTokenMarginalPrices": [ - 0.48022453184675373, - 0.5197754681532463 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.994522889263192, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "12", - "market": "omen_subgraph", - "title": "Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736443388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 6070852985676408832, - 8071353418639978496 - ], - "outcomeTokenMarginalPrices": [ - 0.5707280171060504, - 0.42927198289394963 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.929611773314885, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "13", - "market": "omen_subgraph", - "title": "Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736443388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7128062778178256896, - 6874237997735914496 - ], - "outcomeTokenMarginalPrices": [ - 0.49093631880558675, - 0.5090636811944133 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.998849801067914, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "14", - "market": "omen_subgraph", - "title": "Will Israel conduct another airstrike on Iranian territory by December 30, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736443388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7033878486275975168, - 6966284688540677120 - ], - "outcomeTokenMarginalPrices": [ - 0.4975859639315888, - 0.5024140360684112 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.999918413542592, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "15", - "market": "omen_subgraph", - "title": "Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736443388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 6652037415638244352, - 7366164219823255552 - ], - "outcomeTokenMarginalPrices": [ - 0.5254714129085754, - 0.47452858709142465 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.990910999032273, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "16", - "market": "omen_subgraph", - "title": "Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736443388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 6953521145722576896, - 7046789529092335616 - ], - "outcomeTokenMarginalPrices": [ - 0.5033309397746987, - 0.49666906022530133 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.999844666039569, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "17", - "market": "omen_subgraph", - "title": "Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736443388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8890112678807707648, - 5511741163507008512 - ], - "outcomeTokenMarginalPrices": [ - 0.38271053323098736, - 0.6172894667690128 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.804679527580118, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "18", - "market": "omen_subgraph", - "title": "Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736443388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 6276190571229275136, - 7807283645053929472 - ], - "outcomeTokenMarginalPrices": [ - 0.5543577902125321, - 0.44564220978746794 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.958510272038781, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "19", - "market": "omen_subgraph", - "title": "Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736443388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 6024075346146384896, - 8134028408417137664 - ], - "outcomeTokenMarginalPrices": [ - 0.5745139708977857, - 0.42548602910221434 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.921830896204025, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "20", - "market": "omen_subgraph", - "title": "Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736443388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7694554086912568320, - 6368140303717223424 - ], - "outcomeTokenMarginalPrices": [ - 0.4528392729604095, - 0.5471607270395905 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.96879255694407, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "21", - "market": "omen_subgraph", - "title": "Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736011388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8985287505114697728, - 5453359168764239872 - ], - "outcomeTokenMarginalPrices": [ - 0.37769184965443836, - 0.6223081503455616 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.787339714967367, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "22", - "market": "omen_subgraph", - "title": "Will Banijay UK announce any findings from their investigation into the allegations against Gregg Wallace before December 8th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736011388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8892963273182005248, - 5509974402769262592 - ], - "outcomeTokenMarginalPrices": [ - 0.3825590672359378, - 0.6174409327640622 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.80416746950392, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "23", - "market": "omen_subgraph", - "title": "Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736011388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8326762770344762368, - 5884639847614056448 - ], - "outcomeTokenMarginalPrices": [ - 0.41407875111339754, - 0.5859212488866024 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.895871057523787, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "24", - "market": "omen_subgraph", - "title": "Will any mainstream U.S. news outlet publish a major story based on the leaked Trump campaign emails by December 10th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736011388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9042443445387492352, - 5418889296453899264 - ], - "outcomeTokenMarginalPrices": [ - 0.3747157605173741, - 0.6252842394826259 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.776692145147437, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "25", - "market": "omen_subgraph", - "title": "Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736011388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 6656279358380887040, - 7361469878559762432 - ], - "outcomeTokenMarginalPrices": [ - 0.5251534860646709, - 0.47484651393532906 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.991136618548067, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "26", - "market": "omen_subgraph", - "title": "Will Romania's Social Democratic Party (PSD) form a governing coalition with the centrist Save Romania Union (USR) before December 9th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736011388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7760395002644244480, - 6314111586240641024 - ], - "outcomeTokenMarginalPrices": [ - 0.44862045758869507, - 0.5513795424113049 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.962943914310567, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "27", - "market": "omen_subgraph", - "title": "Will Red Bull win the World Constructors\u2019 Championship in the 2024 F1 Season?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736011388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9163934168081288192, - 5347048451163136000 - ], - "outcomeTokenMarginalPrices": [ - 0.3684828651143097, - 0.6315171348856903 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.753505435947022, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "28", - "market": "omen_subgraph", - "title": "Will Sydney Nicole Gifford announce any changes to her content creation strategy as a result of the lawsuit with Alyssa Sheil by the end of 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736011388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7859762341831588864, - 6234285194503903232 - ], - "outcomeTokenMarginalPrices": [ - 0.44233462235964915, - 0.5576653776403508 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.953290014621335, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "29", - "market": "omen_subgraph", - "title": "Will the Pentagon release any additional reports or information regarding extraterrestrial life by December 29, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736011388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8461396449696163840, - 5791006282628385792 - ], - "outcomeTokenMarginalPrices": [ - 0.40631789540260066, - 0.5936821045973995 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.876033595215166, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "30", - "market": "omen_subgraph", - "title": "Will the United States issue new sanctions specifically targeting Russian entities involved in Syrian military operations before December 10th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736011388, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9078559902328067072, - 5397331793496748032 - ], - "outcomeTokenMarginalPrices": [ - 0.37284969429920956, - 0.6271503057007906 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.769876568520163, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "31", - "market": "omen_subgraph", - "title": "Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736529788, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 8123448777749497856, - 6031920843055385600 - ], - "outcomeTokenMarginalPrices": [ - 0.4261224542091757, - 0.5738775457908243 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.9231678596342885, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "32", - "market": "omen_subgraph", - "title": "Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736529788, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 6459840276540017664, - 7585326866045222912 - ], - "outcomeTokenMarginalPrices": [ - 0.5400666855039662, - 0.4599333144960338 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.9774890540719845, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "33", - "market": "omen_subgraph", - "title": "Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736529788, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7487295145879413760, - 6544419452593216512 - ], - "outcomeTokenMarginalPrices": [ - 0.46640197865096145, - 0.5335980213490386 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.984178541563796, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "34", - "market": "omen_subgraph", - "title": "Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736529788, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9474100947694919680, - 5171994711743266816 - ], - "outcomeTokenMarginalPrices": [ - 0.3531312939643644, - 0.6468687060356357 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.691203053617035, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "35", - "market": "omen_subgraph", - "title": "Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736529788, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9707409744887453696, - 5047690505266510848 - ], - "outcomeTokenMarginalPrices": [ - 0.34209801490259883, - 0.6579019850974012 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.6417712071442825, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "36", - "market": "omen_subgraph", - "title": "Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736529788, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 6545148797759109120, - 7486460814577100800 - ], - "outcomeTokenMarginalPrices": [ - 0.5335425529509606, - 0.46645744704903935 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.9842307980006115, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "37", - "market": "omen_subgraph", - "title": "Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736529788, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7572327254363097088, - 6470930052813908992 - ], - "outcomeTokenMarginalPrices": [ - 0.46078555076441197, - 0.5392144492355881 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.978437968940135, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "38", - "market": "omen_subgraph", - "title": "Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736529788, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 7765145118013647872, - 6310249100989676544 - ], - "outcomeTokenMarginalPrices": [ - 0.44831775244135963, - 0.5516822475586404 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.962504813377749, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "39", - "market": "omen_subgraph", - "title": "Will any Democratic senator join the DOGE Caucus before December 10th, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736529788, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 9797655806143834112, - 5001196303433468928 - ], - "outcomeTokenMarginalPrices": [ - 0.33794488021113933, - 0.6620551197888607 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.622135235514504, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - }, - { - "id": "40", - "market": "omen_subgraph", - "title": "Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?", - "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", - "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", - "fee": 10000000000000000, - "openingTimestamp": 1736529788, - "outcomeSlotCount": 2, - "outcomeTokenAmounts": [ - 6650082179830834176, - 7368329995772544000 - ], - "outcomeTokenMarginalPrices": [ - 0.5256180160400654, - 0.4743819839599346 - ], - "outcomes": [ - "Yes", - "No" - ], - "scaledLiquidityMeasure": 6.990806003732152, - "prediction_response": { - "p_yes": 0.5, - "p_no": 0.5, - "confidence": 0.5, - "info_utility": 0.5 - }, - "position_liquidity": 0, - "potential_net_profit": 0, - "processed_timestamp": 0, - "n_bets": 0 - } -] \ No newline at end of file diff --git a/trader_old/data/markets_test.csv b/trader_old/data/markets_test.csv deleted file mode 100644 index dd8962bf5..000000000 --- a/trader_old/data/markets_test.csv +++ /dev/null @@ -1,161 +0,0 @@ -question,question_id,answer,p_yes_prediction-online,p_no_prediction-online,confidence_prediction-online,info_utility_prediction-online,p_yes_prediction-offline,p_no_prediction-offline,confidence_prediction-offline,info_utility_prediction-offline,p_yes_claude-prediction-offline,p_no_claude-prediction-offline,confidence_claude-prediction-offline,info_utility_claude-prediction-offline,p_yes_claude-prediction-online,p_no_claude-prediction-online,confidence_claude-prediction-online,info_utility_claude-prediction-online,p_yes_prediction-online-sme,p_no_prediction-online-sme,confidence_prediction-online-sme,info_utility_prediction-online-sme,p_yes_prediction-offline-sme,p_no_prediction-offline-sme,confidence_prediction-offline-sme,info_utility_prediction-offline-sme,p_yes_prediction-request-rag,p_no_prediction-request-rag,confidence_prediction-request-rag,info_utility_prediction-request-rag,p_yes_prediction-request-rag-claude,p_no_prediction-request-rag-claude,confidence_prediction-request-rag-claude,info_utility_prediction-request-rag-claude,p_yes_prediction-request-reasoning,p_no_prediction-request-reasoning,confidence_prediction-request-reasoning,info_utility_prediction-request-reasoning,p_yes_prediction-request-reasoning-claude,p_no_prediction-request-reasoning-claude,confidence_prediction-request-reasoning-claude,info_utility_prediction-request-reasoning-claude,p_yes_prediction-url-cot-claude,p_no_prediction-url-cot-claude,confidence_prediction-url-cot-claude,info_utility_prediction-url-cot-claude,p_yes_superforcaster,p_no_superforcaster,confidence_superforcaster,info_utility_superforcaster -"Will the number of migrant arrivals in the Canary Islands exceed 45,000 by December 10th, 2024?",1,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the number of migrant arrivals in the Canary Islands exceed 45,000 by December 10th, 2024?",1,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the number of migrant arrivals in the Canary Islands exceed 45,000 by December 10th, 2024?",1,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the number of migrant arrivals in the Canary Islands exceed 45,000 by December 10th, 2024?",1,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?",2,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?",2,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?",2,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?",2,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?",3,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?",3,no,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?",3,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?",3,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?",4,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?",4,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?",4,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?",4,no,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?",5,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?",5,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?",5,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?",5,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?",6,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?",6,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?",6,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?",6,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",7,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",7,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",7,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",7,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?",8,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?",8,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?",8,no,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?",8,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?",9,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?",9,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?",9,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?",9,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -Will Red Bull win the World Constructors’ Championship in the 2024 F1 Season?,10,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -Will Red Bull win the World Constructors’ Championship in the 2024 F1 Season?,10,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -Will Red Bull win the World Constructors’ Championship in the 2024 F1 Season?,10,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -Will Red Bull win the World Constructors’ Championship in the 2024 F1 Season?,10,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any European country publicly announce a policy change to attract more American immigrants by December 24th, 2024?",11,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any European country publicly announce a policy change to attract more American immigrants by December 24th, 2024?",11,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any European country publicly announce a policy change to attract more American immigrants by December 24th, 2024?",11,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any European country publicly announce a policy change to attract more American immigrants by December 24th, 2024?",11,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",12,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",12,no,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",12,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",12,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?",13,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?",13,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?",13,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?",13,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the US unemployment rate be above 4% in December 19th, 2024?",14,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the US unemployment rate be above 4% in December 19th, 2024?",14,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the US unemployment rate be above 4% in December 19th, 2024?",14,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the US unemployment rate be above 4% in December 19th, 2024?",14,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?",15,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?",15,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?",15,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?",15,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Banijay UK announce any findings from their investigation into the allegations against Gregg Wallace before December 8th, 2024?",16,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Banijay UK announce any findings from their investigation into the allegations against Gregg Wallace before December 8th, 2024?",16,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Banijay UK announce any findings from their investigation into the allegations against Gregg Wallace before December 8th, 2024?",16,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Banijay UK announce any findings from their investigation into the allegations against Gregg Wallace before December 8th, 2024?",16,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -Will Sydney Nicole Gifford announce any changes to her content creation strategy as a result of the lawsuit with Alyssa Sheil by the end of 2024?,17,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -Will Sydney Nicole Gifford announce any changes to her content creation strategy as a result of the lawsuit with Alyssa Sheil by the end of 2024?,17,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -Will Sydney Nicole Gifford announce any changes to her content creation strategy as a result of the lawsuit with Alyssa Sheil by the end of 2024?,17,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -Will Sydney Nicole Gifford announce any changes to her content creation strategy as a result of the lawsuit with Alyssa Sheil by the end of 2024?,17,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?",18,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?",18,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?",18,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?",18,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?",19,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?",19,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?",19,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?",19,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any U.S. state government announce new measures to support households earning over $150,000 who are living paycheck to paycheckby December 10th, 2024?",20,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any U.S. state government announce new measures to support households earning over $150,000 who are living paycheck to paycheckby December 10th, 2024?",20,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any U.S. state government announce new measures to support households earning over $150,000 who are living paycheck to paycheckby December 10th, 2024?",20,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any U.S. state government announce new measures to support households earning over $150,000 who are living paycheck to paycheckby December 10th, 2024?",20,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?",21,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?",21,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?",21,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?",21,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?",22,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?",22,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?",22,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?",22,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?",23,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?",23,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?",23,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?",23,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",24,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",24,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",24,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",24,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any mainstream U.S. news outlet publish a major story based on the leaked Trump campaign emails by December 10th, 2024?",25,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any mainstream U.S. news outlet publish a major story based on the leaked Trump campaign emails by December 10th, 2024?",25,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any mainstream U.S. news outlet publish a major story based on the leaked Trump campaign emails by December 10th, 2024?",25,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any mainstream U.S. news outlet publish a major story based on the leaked Trump campaign emails by December 10th, 2024?",25,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?",26,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?",26,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?",26,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?",26,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",27,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",27,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",27,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",27,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -Will Yuki Tsunoda score higher than Daniel Ricciardo in the 2024 Formula 1 Driver World Championship?,28,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -Will Yuki Tsunoda score higher than Daniel Ricciardo in the 2024 Formula 1 Driver World Championship?,28,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -Will Yuki Tsunoda score higher than Daniel Ricciardo in the 2024 Formula 1 Driver World Championship?,28,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -Will Yuki Tsunoda score higher than Daniel Ricciardo in the 2024 Formula 1 Driver World Championship?,28,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",29,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",29,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",29,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",29,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?",30,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?",30,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?",30,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?",30,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the United States issue new sanctions specifically targeting Russian entities involved in Syrian military operations before December 10th, 2024?",31,no,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the United States issue new sanctions specifically targeting Russian entities involved in Syrian military operations before December 10th, 2024?",31,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the United States issue new sanctions specifically targeting Russian entities involved in Syrian military operations before December 10th, 2024?",31,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the United States issue new sanctions specifically targeting Russian entities involved in Syrian military operations before December 10th, 2024?",31,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?",32,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?",32,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?",32,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?",32,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?",33,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?",33,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?",33,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?",33,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Romania's Social Democratic Party (PSD) form a governing coalition with the centrist Save Romania Union (USR) before December 9th, 2024?",34,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Romania's Social Democratic Party (PSD) form a governing coalition with the centrist Save Romania Union (USR) before December 9th, 2024?",34,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Romania's Social Democratic Party (PSD) form a governing coalition with the centrist Save Romania Union (USR) before December 9th, 2024?",34,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Romania's Social Democratic Party (PSD) form a governing coalition with the centrist Save Romania Union (USR) before December 9th, 2024?",34,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?",35,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?",35,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?",35,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?",35,no,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?",36,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?",36,no,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?",36,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?",36,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",37,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",37,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",37,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",37,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?",38,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?",38,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?",38,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?",38,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the Pentagon release any additional reports or information regarding extraterrestrial life by December 29, 2024?",39,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will the Pentagon release any additional reports or information regarding extraterrestrial life by December 29, 2024?",39,no,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the Pentagon release any additional reports or information regarding extraterrestrial life by December 29, 2024?",39,no,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will the Pentagon release any additional reports or information regarding extraterrestrial life by December 29, 2024?",39,no,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will at least 100,000 Americans die of H5N1 by the end of 2024?",40,yes,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67,0.4,0.6,0.8,0.67 -"Will at least 100,000 Americans die of H5N1 by the end of 2024?",40,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will at least 100,000 Americans die of H5N1 by the end of 2024?",40,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 -"Will at least 100,000 Americans die of H5N1 by the end of 2024?",40,yes,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67,0.6,0.4,0.8,0.67 diff --git a/trader_old/data/markets_test2.csv b/trader_old/data/markets_test2.csv deleted file mode 100644 index 18a39a851..000000000 --- a/trader_old/data/markets_test2.csv +++ /dev/null @@ -1,161 +0,0 @@ -question,question_id,answer,p_yes_prediction-online,p_no_prediction-online,confidence_prediction-online,info_utility_prediction-online,p_yes_prediction-offline,p_no_prediction-offline,confidence_prediction-offline,info_utility_prediction-offline,p_yes_claude-prediction-offline,p_no_claude-prediction-offline,confidence_claude-prediction-offline,info_utility_claude-prediction-offline,p_yes_claude-prediction-online,p_no_claude-prediction-online,confidence_claude-prediction-online,info_utility_claude-prediction-online,p_yes_prediction-online-sme,p_no_prediction-online-sme,confidence_prediction-online-sme,info_utility_prediction-online-sme,p_yes_prediction-offline-sme,p_no_prediction-offline-sme,confidence_prediction-offline-sme,info_utility_prediction-offline-sme,p_yes_prediction-request-rag,p_no_prediction-request-rag,confidence_prediction-request-rag,info_utility_prediction-request-rag,p_yes_prediction-request-rag-claude,p_no_prediction-request-rag-claude,confidence_prediction-request-rag-claude,info_utility_prediction-request-rag-claude,p_yes_prediction-request-reasoning,p_no_prediction-request-reasoning,confidence_prediction-request-reasoning,info_utility_prediction-request-reasoning,p_yes_prediction-request-reasoning-claude,p_no_prediction-request-reasoning-claude,confidence_prediction-request-reasoning-claude,info_utility_prediction-request-reasoning-claude,p_yes_prediction-url-cot-claude,p_no_prediction-url-cot-claude,confidence_prediction-url-cot-claude,info_utility_prediction-url-cot-claude,p_yes_superforcaster,p_no_superforcaster,confidence_superforcaster,info_utility_superforcaster -"Will the number of migrant arrivals in the Canary Islands exceed 45,000 by December 10th, 2024?",1,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the number of migrant arrivals in the Canary Islands exceed 45,000 by December 10th, 2024?",1,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the number of migrant arrivals in the Canary Islands exceed 45,000 by December 10th, 2024?",1,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the number of migrant arrivals in the Canary Islands exceed 45,000 by December 10th, 2024?",1,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?",2,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?",2,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?",2,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?",2,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any U.S. state government announce new measures to support households earning over $150,000 who are living paycheck to paycheckby December 10th, 2024?",3,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any U.S. state government announce new measures to support households earning over $150,000 who are living paycheck to paycheckby December 10th, 2024?",3,no,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any U.S. state government announce new measures to support households earning over $150,000 who are living paycheck to paycheckby December 10th, 2024?",3,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any U.S. state government announce new measures to support households earning over $150,000 who are living paycheck to paycheckby December 10th, 2024?",3,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the US unemployment rate be above 4% in December 19th, 2024?",4,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the US unemployment rate be above 4% in December 19th, 2024?",4,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the US unemployment rate be above 4% in December 19th, 2024?",4,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the US unemployment rate be above 4% in December 19th, 2024?",4,no,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?",5,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?",5,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?",5,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?",5,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will at least 100,000 Americans die of H5N1 by the end of 2024?",6,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will at least 100,000 Americans die of H5N1 by the end of 2024?",6,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will at least 100,000 Americans die of H5N1 by the end of 2024?",6,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will at least 100,000 Americans die of H5N1 by the end of 2024?",6,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any European country publicly announce a policy change to attract more American immigrants by December 24th, 2024?",7,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any European country publicly announce a policy change to attract more American immigrants by December 24th, 2024?",7,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any European country publicly announce a policy change to attract more American immigrants by December 24th, 2024?",7,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any European country publicly announce a policy change to attract more American immigrants by December 24th, 2024?",7,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?",8,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?",8,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?",8,no,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?",8,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?",9,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?",9,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?",9,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?",9,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -Will Yuki Tsunoda score higher than Daniel Ricciardo in the 2024 Formula 1 Driver World Championship?,10,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -Will Yuki Tsunoda score higher than Daniel Ricciardo in the 2024 Formula 1 Driver World Championship?,10,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -Will Yuki Tsunoda score higher than Daniel Ricciardo in the 2024 Formula 1 Driver World Championship?,10,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -Will Yuki Tsunoda score higher than Daniel Ricciardo in the 2024 Formula 1 Driver World Championship?,10,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?",11,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?",11,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?",11,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?",11,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",12,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",12,no,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",12,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?",12,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?",13,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?",13,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?",13,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?",13,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",14,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",14,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",14,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Israel conduct another airstrike on Iranian territory by December 30, 2024?",14,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?",15,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?",15,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?",15,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?",15,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?",16,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?",16,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?",16,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?",16,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?",17,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?",17,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?",17,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?",17,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?",18,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?",18,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?",18,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?",18,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?",19,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?",19,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?",19,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?",19,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",20,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",20,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",20,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?",20,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?",21,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?",21,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?",21,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?",21,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Banijay UK announce any findings from their investigation into the allegations against Gregg Wallace before December 8th, 2024?",22,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Banijay UK announce any findings from their investigation into the allegations against Gregg Wallace before December 8th, 2024?",22,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Banijay UK announce any findings from their investigation into the allegations against Gregg Wallace before December 8th, 2024?",22,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Banijay UK announce any findings from their investigation into the allegations against Gregg Wallace before December 8th, 2024?",22,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?",23,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?",23,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?",23,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?",23,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any mainstream U.S. news outlet publish a major story based on the leaked Trump campaign emails by December 10th, 2024?",24,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any mainstream U.S. news outlet publish a major story based on the leaked Trump campaign emails by December 10th, 2024?",24,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any mainstream U.S. news outlet publish a major story based on the leaked Trump campaign emails by December 10th, 2024?",24,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any mainstream U.S. news outlet publish a major story based on the leaked Trump campaign emails by December 10th, 2024?",24,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?",25,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?",25,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?",25,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?",25,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Romania's Social Democratic Party (PSD) form a governing coalition with the centrist Save Romania Union (USR) before December 9th, 2024?",26,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Romania's Social Democratic Party (PSD) form a governing coalition with the centrist Save Romania Union (USR) before December 9th, 2024?",26,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Romania's Social Democratic Party (PSD) form a governing coalition with the centrist Save Romania Union (USR) before December 9th, 2024?",26,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Romania's Social Democratic Party (PSD) form a governing coalition with the centrist Save Romania Union (USR) before December 9th, 2024?",26,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -Will Red Bull win the World Constructors’ Championship in the 2024 F1 Season?,27,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -Will Red Bull win the World Constructors’ Championship in the 2024 F1 Season?,27,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -Will Red Bull win the World Constructors’ Championship in the 2024 F1 Season?,27,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -Will Red Bull win the World Constructors’ Championship in the 2024 F1 Season?,27,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -Will Sydney Nicole Gifford announce any changes to her content creation strategy as a result of the lawsuit with Alyssa Sheil by the end of 2024?,28,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -Will Sydney Nicole Gifford announce any changes to her content creation strategy as a result of the lawsuit with Alyssa Sheil by the end of 2024?,28,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -Will Sydney Nicole Gifford announce any changes to her content creation strategy as a result of the lawsuit with Alyssa Sheil by the end of 2024?,28,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -Will Sydney Nicole Gifford announce any changes to her content creation strategy as a result of the lawsuit with Alyssa Sheil by the end of 2024?,28,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Pentagon release any additional reports or information regarding extraterrestrial life by December 29, 2024?",29,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Pentagon release any additional reports or information regarding extraterrestrial life by December 29, 2024?",29,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Pentagon release any additional reports or information regarding extraterrestrial life by December 29, 2024?",29,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Pentagon release any additional reports or information regarding extraterrestrial life by December 29, 2024?",29,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the United States issue new sanctions specifically targeting Russian entities involved in Syrian military operations before December 10th, 2024?",30,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the United States issue new sanctions specifically targeting Russian entities involved in Syrian military operations before December 10th, 2024?",30,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the United States issue new sanctions specifically targeting Russian entities involved in Syrian military operations before December 10th, 2024?",30,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the United States issue new sanctions specifically targeting Russian entities involved in Syrian military operations before December 10th, 2024?",30,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?",31,no,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?",31,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?",31,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?",31,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?",32,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?",32,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?",32,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?",32,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",33,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",33,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",33,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?",33,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",34,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",34,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",34,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?",34,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?",35,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?",35,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?",35,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?",35,no,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?",36,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?",36,no,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?",36,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?",36,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?",37,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?",37,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?",37,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?",37,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?",38,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?",38,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?",38,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?",38,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",39,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",39,no,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",39,no,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any Democratic senator join the DOGE Caucus before December 10th, 2024?",39,no,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?",40,yes,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7,0.2,0.8,0.8,0.7 -"Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?",40,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?",40,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 -"Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?",40,yes,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7,0.8,0.2,0.8,0.7 diff --git a/trader_old/data/multi_bets.json b/trader_old/data/multi_bets.json deleted file mode 100644 index 069228678..000000000 --- a/trader_old/data/multi_bets.json +++ /dev/null @@ -1 +0,0 @@ -[{"id": "1", "market": "omen_subgraph", "title": "Will the number of migrant arrivals in the Canary Islands exceed 45,000 by December 10th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735899608, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8633220090882252800, 5675750123844294656], "outcomeTokenMarginalPrices": [0.39665678512650127, 0.6033432148734987], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.848850653077751, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "2", "market": "omen_subgraph", "title": "Will Turkey publicly announce any new military support for the rebel forces in northern Syria before December 10th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735899608, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6267008863867803648, 7818721987535009792], "outcomeTokenMarginalPrices": [0.5550810298747355, 0.4449189701252644], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.957395468779674, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "3", "market": "omen_subgraph", "title": "Will a new study confirming the link between visceral fat and tau protein accumulation be published by December 30, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735899608, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7666931617497741312, 6391083479624426496], "outcomeTokenMarginalPrices": [0.4546220384222487, 0.5453779615777513], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.971112160781623, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "4", "market": "omen_subgraph", "title": "Will the United Nations Security Council hold an emergency session regarding the Iran-Israel conflict before December 30, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735899608, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6570607380123761664, 7457453651579627520], "outcomeTokenMarginalPrices": [0.531609723876008, 0.468390276123992], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.9859975500905085, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "5", "market": "omen_subgraph", "title": "Will the number of Google searches for 'move abroad' in the U.S. show a sustained increase over the next month compared to the previous year by December 30, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735899608, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6571832734648601600, 7456063168141489152], "outcomeTokenMarginalPrices": [0.5315168589651788, 0.46848314103482125], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.986079785529932, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "6", "market": "omen_subgraph", "title": "Will @firstuserhere coauthor a publication in AIstats, AAAI, ICLR or JMLR by December 24th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735899608, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6378949290519954432, 7681515837227475968], "outcomeTokenMarginalPrices": [0.5463201798401743, 0.45367982015982566], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.969897447176428, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "7", "market": "omen_subgraph", "title": "Will any Democratic senator join the DOGE Caucus before December 10th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735899608, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7026778687256635392, 6973323364924471296], "outcomeTokenMarginalPrices": [0.49809089526158723, 0.5019091047384128], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.999948974281396, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "8", "market": "omen_subgraph", "title": "Will any major polling organization release a poll showing a significant shift in support for Trump among young male voters by December 30, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735899608, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6509705534478785536, 7527222197758488576], "outcomeTokenMarginalPrices": [0.536244279470887, 0.46375572052911307], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.9815847078084445, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "9", "market": "omen_subgraph", "title": "Will Gregg Wallace issue a public apology specifically addressing the new allegations against him by December 9th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735899608, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6611892565061325824, 7410888715725150208], "outcomeTokenMarginalPrices": [0.5284892181752339, 0.471510781824766], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.988627864735803, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "10", "market": "omen_subgraph", "title": "Will Red Bull win the World Constructors\u2019 Championship in the 2024 F1 Season?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735899608, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7543259508676806656, 6495865606060169216], "outcomeTokenMarginalPrices": [0.46269732287244947, 0.5373026771275504], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.980491960793813, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "11", "market": "omen_subgraph", "title": "Will any European country publicly announce a policy change to attract more American immigrants by December 24th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736418008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8245212024748660736, 5942842931500439552], "outcomeTokenMarginalPrices": [0.418862412770887, 0.581137587229113], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.907218804987509, "prediction_response": {"p_yes": 0.8, "p_no": 0.2, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 0, "potential_net_profit": 971787863640511616, "processed_timestamp": 1735925762, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "12", "market": "omen_subgraph", "title": "Will any international humanitarian organization announce a new aid package for civilians affected by the fighting in Aleppo before December 8th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736418008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7718021398376549376, 6348777422450127872], "outcomeTokenMarginalPrices": [0.45133064767020126, 0.5486693523297987], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.966759192923521, "prediction_response": {"p_yes": 0.2, "p_no": 0.8, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 6348777422450127872, "potential_net_profit": 426020787553410304, "processed_timestamp": 1735925731, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "13", "market": "omen_subgraph", "title": "Will the Department of Homeland Security announce a restructuring plan by December 30, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736418008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8247178618240060416, 5941425821871740928], "outcomeTokenMarginalPrices": [0.4187463148296017, 0.5812536851703983], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.906951308259023, "prediction_response": {"p_yes": 0.2, "p_no": 0.8, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 5941425821871740928, "potential_net_profit": 328048612871034112, "processed_timestamp": 1735925768, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "14", "market": "omen_subgraph", "title": "Will the US unemployment rate be above 4% in December 19th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736418008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7447751901935623168, 6579166525037603840], "outcomeTokenMarginalPrices": [0.4690386245054451, 0.5309613754945549], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.986566615483394, "prediction_response": {"p_yes": 0.8, "p_no": 0.2, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 0, "potential_net_profit": 724722646047528192, "processed_timestamp": 1735925719, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "15", "market": "omen_subgraph", "title": "Will any major influencer platform (such as TikTok or Instagram) update their copyright policies in response to the Alyssa Sheil and Sydney Nicole Gifford lawsuit by December 30, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736418008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7770115198421651456, 6306212810069199872], "outcomeTokenMarginalPrices": [0.4480012689577344, 0.5519987310422656], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.962042937681357, "prediction_response": {"p_yes": 0.8, "p_no": 0.2, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 0, "potential_net_profit": 821565199502022144, "processed_timestamp": 1735925737, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "16", "market": "omen_subgraph", "title": "Will Banijay UK announce any findings from their investigation into the allegations against Gregg Wallace before December 8th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736418008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6829378464124429312, 7174884252996530176], "outcomeTokenMarginalPrices": [0.5123357364772121, 0.4876642635227879], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.9978692901976025, "prediction_response": {"p_yes": 0.2, "p_no": 0.8, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 7174884252996530176, "potential_net_profit": 645973737617396608, "processed_timestamp": 1735925712, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "17", "market": "omen_subgraph", "title": "Will Sydney Nicole Gifford announce any changes to her content creation strategy as a result of the lawsuit with Alyssa Sheil by the end of 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736418008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7998003560152404992, 6126528905804374016], "outcomeTokenMarginalPrices": [0.43375091675215816, 0.5662490832478418], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.938282752806261, "prediction_response": {"p_yes": 0.2, "p_no": 0.8, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 6126528905804374016, "potential_net_profit": 371689360964149248, "processed_timestamp": 1735925749, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "18", "market": "omen_subgraph", "title": "Will Joe Rogan publicly announce his endorsement of Trump's 2024 presidential campaign before by December 8th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736418008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7580636800397400064, 6463836916369778688], "outcomeTokenMarginalPrices": [0.460240593326957, 0.5397594066730431], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.977833557622128, "prediction_response": {"p_yes": 0.2, "p_no": 0.8, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 6463836916369778688, "potential_net_profit": 454964614039744512, "processed_timestamp": 1735925725, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "19", "market": "omen_subgraph", "title": "Will the U.S. government issue any public statement or advisory regarding the Hot Topic data breach before December 8th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736418008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6094847400418020352, 8039577823825300480], "outcomeTokenMarginalPrices": [0.5687941105688431, 0.4312058894311569], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.933426612347187, "prediction_response": {"p_yes": 0.2, "p_no": 0.8, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 8039577823825300480, "potential_net_profit": 905663715607609472, "processed_timestamp": 1735925755, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "20", "market": "omen_subgraph", "title": "Will any U.S. state government announce new measures to support households earning over $150,000 who are living paycheck to paycheckby December 10th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736418008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7993723958564144128, 6129808866805242880], "outcomeTokenMarginalPrices": [0.43401385068433995, 0.56598614931566], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.938773833128178, "prediction_response": {"p_yes": 0.8, "p_no": 0.2, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 0, "potential_net_profit": 891181025173133184, "processed_timestamp": 1735925743, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "21", "market": "omen_subgraph", "title": "Will the Romanian government announce any new economic measures to address the budget deficit by December 9th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735986008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7458548042053495808, 6569643276911744000], "outcomeTokenMarginalPrices": [0.4683171998110688, 0.5316828001889313], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.985932667421646, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "22", "market": "omen_subgraph", "title": "Will the FBI release a public statement detailing their findings on the Iranian hackers' activities related to the Trump campaign by December 24th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735986008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8368947813424408576, 5854977363032469504], "outcomeTokenMarginalPrices": [0.41162880782890343, 0.5883711921710966], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.889800022444395, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "23", "market": "omen_subgraph", "title": "Will the U.S. Department of Labor release a report detailing a decline in wage growth for households earning over $150,000 by December 30, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735986008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8580576054979482624, 5710572307271177216], "outcomeTokenMarginalPrices": [0.3995880640603636, 0.6004119359396364], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.8573915486639265, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "24", "market": "omen_subgraph", "title": "Will Pierre Gasly beat Esteban Ocon in the Drivers Championship by December 10th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735986008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7383788583787232256, 6636159668437760000], "outcomeTokenMarginalPrices": [0.47333695881399485, 0.5266630411860052], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.9900400655506845, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "25", "market": "omen_subgraph", "title": "Will any mainstream U.S. news outlet publish a major story based on the leaked Trump campaign emails by December 10th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735986008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6426342389079583744, 7624866064289807360], "outcomeTokenMarginalPrices": [0.5426484198561166, 0.45735158014388344], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.974489085776835, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "26", "market": "omen_subgraph", "title": "Will any state in the U.S. introduce legislation targeting obesity reduction specifically to combat Alzheimer's by December 30, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735986008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7892560022631787520, 6208378505769142272], "outcomeTokenMarginalPrices": [0.4402812261938981, 0.5597187738061019], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.949892009146526, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "27", "market": "omen_subgraph", "title": "Will Snowflake announce any new security measures or updates in response to the breach before December 8th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735986008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7032701968118840320, 6967450095586360320], "outcomeTokenMarginalPrices": [0.4976696012930587, 0.5023303987069413], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.999923968973225, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "28", "market": "omen_subgraph", "title": "Will Yuki Tsunoda score higher than Daniel Ricciardo in the 2024 Formula 1 Driver World Championship?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735986008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6893515824709148672, 7108129036908014592], "outcomeTokenMarginalPrices": [0.507663857151069, 0.492336142848931], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.999177665807558, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "29", "market": "omen_subgraph", "title": "Will the Iranian government issue another public denial regarding the hacking allegations against them before December 7th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735986008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7123359089690985472, 6878777186863065088], "outcomeTokenMarginalPrices": [0.4912662647328514, 0.5087337352671486], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.99893202468659, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "30", "market": "omen_subgraph", "title": "Will the COP29 summit in Baku result in any new international agreement specifically addressing the Caspian Sea environmental crisis by December 7th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1735986008, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8402435860724189184, 5831642253771013120], "outcomeTokenMarginalPrices": [0.4096958163965947, 0.5903041836034053], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.884885639358841, "prediction_response": {"p_yes": 0.5, "p_no": 0.5, "confidence": 0.5, "info_utility": 0.5}, "position_liquidity": 0, "potential_net_profit": 0, "processed_timestamp": 0, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "31", "market": "omen_subgraph", "title": "Will the United States issue new sanctions specifically targeting Russian entities involved in Syrian military operations before December 10th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736504408, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6347983720511538176, 7718986399046947840], "outcomeTokenMarginalPrices": [0.5487312714423552, 0.45126872855764477], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.966674356103338, "prediction_response": {"p_yes": 0.2, "p_no": 0.8, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 7718986399046947840, "potential_net_profit": 805756624046302080, "processed_timestamp": 1735925792, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "32", "market": "omen_subgraph", "title": "Will any new pharmaceutical treatment targeting visceral fat reduction be approved by the FDA before December 30, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736504408, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7843818870114099200, 6246957102323708928], "outcomeTokenMarginalPrices": [0.4433366277728805, 0.5566633722271195], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.954904413475341, "prediction_response": {"p_yes": 0.8, "p_no": 0.2, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 0, "potential_net_profit": 844089579934160640, "processed_timestamp": 1735925805, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "33", "market": "omen_subgraph", "title": "Will the Constitutional Democratic Party of Japan (CDPJ) announce a formal coalition with any other opposition party by December 30, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736504408, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7603583397009488896, 6444329922030162944], "outcomeTokenMarginalPrices": [0.45873929997104457, 0.5412607000289554], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.97612504963118, "prediction_response": {"p_yes": 0.8, "p_no": 0.2, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 0, "potential_net_profit": 770870143732002176, "processed_timestamp": 1735925780, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "34", "market": "omen_subgraph", "title": "Will Romania's Social Democratic Party (PSD) form a governing coalition with the centrist Save Romania Union (USR) before December 9th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736504408, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6382785525064408064, 7676899029049789440], "outcomeTokenMarginalPrices": [0.5460221386548354, 0.4539778613451646], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.970284405941588, "prediction_response": {"p_yes": 0.2, "p_no": 0.8, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 7676899029049789440, "potential_net_profit": 792977306970668032, "processed_timestamp": 1735925786, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "35", "market": "omen_subgraph", "title": "Will Lewis Hamilton finish ahead of George Russell in the WDC by December 8th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736504408, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8951406991179005952, 5473999791126257664], "outcomeTokenMarginalPrices": [0.3794693538792173, 0.6205306461207827], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.793569254505212, "prediction_response": {"p_yes": 0.2, "p_no": 0.8, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 5473999791126257664, "potential_net_profit": 224628169768441280, "processed_timestamp": 1735925705, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "36", "market": "omen_subgraph", "title": "Will any other major airline file a lawsuit against CrowdStrike related to the July 19 incident before December 31, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736504408, "outcomeSlotCount": 2, "outcomeTokenAmounts": [7777211499434802176, 6300458718855853056], "outcomeTokenMarginalPrices": [0.4475498162096363, 0.5524501837903637], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.961379154391031, "prediction_response": {"p_yes": 0.2, "p_no": 0.8, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 6300458718855853056, "potential_net_profit": 413923841973792000, "processed_timestamp": 1735925799, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "37", "market": "omen_subgraph", "title": "Will Israel conduct another airstrike on Iranian territory by December 30, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736504408, "outcomeSlotCount": 2, "outcomeTokenAmounts": [6713006125431115776, 7299263412612062208], "outcomeTokenMarginalPrices": [0.5209194265636007, 0.4790805734363993], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.993870602755031, "prediction_response": {"p_yes": 0.8, "p_no": 0.2, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 0, "potential_net_profit": 519417904210692608, "processed_timestamp": 1735925774, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "38", "market": "omen_subgraph", "title": "Will Apple release a HomePod powered with Apple Intelligence by December 28th, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736504408, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8936278530007503872, 5483266869476018176], "outcomeTokenMarginalPrices": [0.38026627869089535, 0.6197337213091048], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.7963307639025965, "prediction_response": {"p_yes": 0.8, "p_no": 0.2, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 0, "potential_net_profit": 1206437383283768320, "processed_timestamp": 1735925699, "queue_status": 1, "investments": {"Yes": [], "No": []}}, {"id": "39", "market": "omen_subgraph", "title": "Will the Pentagon release any additional reports or information regarding extraterrestrial life by December 29, 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736504408, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8137309462365664256, 6021646371767063552], "outcomeTokenMarginalPrices": [0.4252888731562249, 0.5747111268437751], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.921414343545958, "prediction_response": {"p_yes": 0.2, "p_no": 0.8, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 6021646371767063552, "potential_net_profit": 346706446996115072, "processed_timestamp": 1735925811, "queue_status": 2, "investments": {"Yes": [], "No": []}}, {"id": "40", "market": "omen_subgraph", "title": "Will at least 100,000 Americans die of H5N1 by the end of 2024?", "collateralToken": "0xe91d153e0b41518a2ce8dd3d7944fa863463a97d", "creator": "0x89c5cc945dd550bcffb72fe42bff002429f46fec", "fee": 10000000000000000, "openingTimestamp": 1736504408, "outcomeSlotCount": 2, "outcomeTokenAmounts": [8930011344563093504, 5487115089706233856], "outcomeTokenMarginalPrices": [0.3805970014012938, 0.6194029985987062], "outcomes": ["Yes", "No"], "scaledLiquidityMeasure": 6.7974710804405, "prediction_response": {"p_yes": 0.8, "p_no": 0.2, "confidence": 0.8, "info_utility": 0.7}, "position_liquidity": 0, "potential_net_profit": 1203725933858184832, "processed_timestamp": 1735925817, "queue_status": 2, "investments": {"Yes": [], "No": []}}] \ No newline at end of file diff --git a/trader_old/data/policy_store.json b/trader_old/data/policy_store.json deleted file mode 100644 index ed0e725b3..000000000 --- a/trader_old/data/policy_store.json +++ /dev/null @@ -1 +0,0 @@ -{"accuracy_store": {"claude-prediction-offline": {"accuracy": 57.380457380457386, "pending": 110, "requests": 481}, "claude-prediction-online": {"accuracy": 61.137440758293835, "pending": 0, "requests": 1055}, "prediction-offline": {"accuracy": 67.39834303627407, "pending": 213, "requests": 4466}, "prediction-offline-sme": {"accuracy": 67.203125, "pending": 11, "requests": 64}, "prediction-online": {"accuracy": 66.00632244467862, "pending": 26, "requests": 9490}, "prediction-online-sme": {"accuracy": 65.67408823931157, "pending": 11, "requests": 14642}, "prediction-request-rag": {"accuracy": 63.58231140839836, "pending": 0, "requests": 2691}, "prediction-request-rag-claude": {"accuracy": 65.64351103931072, "pending": 0, "requests": 7428}, "prediction-request-reasoning": {"accuracy": 67.11374625834677, "pending": 1570, "requests": 17372}, "prediction-request-reasoning-claude": {"accuracy": 66.72064777327935, "pending": 0, "requests": 2470}, "prediction-url-cot-claude": {"accuracy": 61.904761904761905, "pending": 0, "requests": 1596}}, "eps": 0.1, "updated_ts": 1732095874, "weighted_accuracy": {"claude-prediction-offline": 0.5731026698142933, "claude-prediction-online": 0.6103536859706571, "prediction-offline": 0.6725913681009724, "prediction-offline-sme": 0.6703320894919184, "prediction-online": 0.6592139883562407, "prediction-online-sme": 0.6563261234196577, "prediction-request-rag": 0.6346874770676403, "prediction-request-rag-claude": 0.6554635569636367, "prediction-request-reasoning": 0.6706711741029258, "prediction-request-reasoning-claude": 0.6657429380782109, "prediction-url-cot-claude": 0.6179929719207252}} \ No newline at end of file diff --git a/trader_old/data/policy_store_multi_bet_failure_adjusting.json b/trader_old/data/policy_store_multi_bet_failure_adjusting.json deleted file mode 100644 index d4dc9d253..000000000 --- a/trader_old/data/policy_store_multi_bet_failure_adjusting.json +++ /dev/null @@ -1 +0,0 @@ -{"accuracy_store": {"claude-prediction-offline": {"accuracy": 57.0309917355372, "pending": -3, "requests": 484}, "claude-prediction-online": {"accuracy": 60.96691871455576, "pending": -3, "requests": 1058}, "prediction-offline": {"accuracy": 66.93951523237716, "pending": -6, "requests": 4497}, "prediction-offline-sme": {"accuracy": 63.30882352941177, "pending": -3, "requests": 68}, "prediction-online": {"accuracy": 65.95830262188062, "pending": -5, "requests": 9497}, "prediction-online-sme": {"accuracy": 65.64752867285638, "pending": -4, "requests": 14648}, "prediction-request-rag": {"accuracy": 63.46624629080119, "pending": -3, "requests": 2696}, "prediction-request-rag-claude": {"accuracy": 65.60002690703621, "pending": -5, "requests": 7433}, "prediction-request-reasoning": {"accuracy": 66.55790855642444, "pending": -25, "requests": 17519}, "prediction-request-reasoning-claude": {"accuracy": 66.6143896523848, "pending": -4, "requests": 2474}, "prediction-url-cot-claude": {"accuracy": 61.71392879450344, "pending": -3, "requests": 1601}, "superforcaster": {"accuracy": 1.0, "pending": -4, "requests": 4}}, "consecutive_failures": {"claude-prediction-offline": {"n_failures": 3, "timestamp": 1735921729}, "claude-prediction-online": {"n_failures": 3, "timestamp": 1735921704}, "prediction-offline": {"n_failures": 7, "timestamp": 1735921910}, "prediction-offline-sme": {"n_failures": 3, "timestamp": 1735921649}, "prediction-online": {"n_failures": 0, "timestamp": 1735925421}, "prediction-online-sme": {"n_failures": 0, "timestamp": 1735925686}, "prediction-request-rag": {"n_failures": 0, "timestamp": 1735925587}, "prediction-request-rag-claude": {"n_failures": 5, "timestamp": 1735921841}, "prediction-request-reasoning": {"n_failures": 0, "timestamp": 1735925816}, "prediction-request-reasoning-claude": {"n_failures": 4, "timestamp": 1735921661}, "prediction-url-cot-claude": {"n_failures": 0, "timestamp": 1735925593}, "superforcaster": {"n_failures": 4, "timestamp": 1735921767}}, "consecutive_failures_threshold": 2, "eps": 0.1, "quarantine_duration": 18000, "updated_ts": 1735920991, "weighted_accuracy": {"claude-prediction-offline": 0.5696527207994426, "claude-prediction-online": 0.6086681927373647, "prediction-offline": 0.66807803913214, "prediction-offline-sme": 0.6317762072590968, "prediction-online": 0.6587627902179048, "prediction-online-sme": 0.6560976220360418, "prediction-request-rag": 0.6335449872245215, "prediction-request-rag-claude": 0.6550504654224211, "prediction-request-reasoning": 0.6653425328432643, "prediction-request-reasoning-claude": 0.66469705199124, "prediction-url-cot-claude": 0.6161077512252101, "superforcaster": 0.01485212484033692}} \ No newline at end of file diff --git a/trader_old/data/utilized_tools.json b/trader_old/data/utilized_tools.json deleted file mode 100644 index 6f38a7ed4..000000000 --- a/trader_old/data/utilized_tools.json +++ /dev/null @@ -1 +0,0 @@ -{"0x6042b69a6fc11be884faa666d5dc9355f03a8e272d55c2bb44c8ed15a81fd524": "prediction-offline", "0x8751bb5472052acb793e7d4264910b6037fe9db8e568627a81025715f27e2e49": "prediction-offline", "0x98a8b36b475a41c4b93897fb98482ea5cfad8e5d5dee6dd273bcc315e1d05118": "prediction-offline", "0xc2b6f1b6e3aeb67abcbe1b8681315717c88609ac4b8e3bc5317eda8778236d30": "prediction-offline"} \ No newline at end of file diff --git a/trader_old/vendor/jhehemann/customs/__init__.py b/trader_old/vendor/jhehemann/customs/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_old/vendor/jhehemann/customs/kelly_criterion/__init__.py b/trader_old/vendor/jhehemann/customs/kelly_criterion/__init__.py deleted file mode 100644 index f562b286a..000000000 --- a/trader_old/vendor/jhehemann/customs/kelly_criterion/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the kelly criterion strategy.""" diff --git a/trader_old/vendor/jhehemann/customs/kelly_criterion/component.yaml b/trader_old/vendor/jhehemann/customs/kelly_criterion/component.yaml deleted file mode 100644 index 216c7bd70..000000000 --- a/trader_old/vendor/jhehemann/customs/kelly_criterion/component.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: kelly_criterion -author: jhehemann -version: 0.1.0 -type: custom -description: The kelly criterion trading strategy. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeiatntqojmmkgwtqubfzp2zf4viusno2vkf7dfy4b343hmymhtf72y - kelly_criterion.py: bafybeiaeazylun25iol746juwtgc4qeuj2rlrtyqhudztpacyybbsgglcy -fingerprint_ignore_patterns: [] -entry_point: kelly_criterion.py -callable: run -dependencies: {} diff --git a/trader_old/vendor/jhehemann/customs/kelly_criterion/kelly_criterion.py b/trader_old/vendor/jhehemann/customs/kelly_criterion/kelly_criterion.py deleted file mode 100644 index 1c7a9b3cb..000000000 --- a/trader_old/vendor/jhehemann/customs/kelly_criterion/kelly_criterion.py +++ /dev/null @@ -1,161 +0,0 @@ -# -*- 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 the kelly criterion strategy.""" - -from typing import Dict, Any, List, Union - -REQUIRED_FIELDS = frozenset( - { - # the fraction of the calculated kelly bet amount to use for placing the bet - "bet_kelly_fraction", - "bankroll", - "win_probability", - "confidence", - "selected_type_tokens_in_pool", - "other_tokens_in_pool", - "bet_fee", - "floor_balance", - } -) -OPTIONAL_FIELDS = frozenset({"max_bet"}) -ALL_FIELDS = REQUIRED_FIELDS.union(OPTIONAL_FIELDS) -DEFAULT_MAX_BET = 8e17 - - -def check_missing_fields(kwargs: Dict[str, Any]) -> List[str]: - """Check for missing fields and return them, if any.""" - missing = [] - for field in REQUIRED_FIELDS: - if kwargs.get(field, None) is None: - missing.append(field) - return missing - - -def remove_irrelevant_fields(kwargs: Dict[str, Any]) -> Dict[str, Any]: - """Remove the irrelevant fields from the given kwargs.""" - return {key: value for key, value in kwargs.items() if key in ALL_FIELDS} - - -def calculate_kelly_bet_amount( - x: int, y: int, p: float, c: float, b: int, f: float -) -> int: - """Calculate the Kelly bet amount.""" - if b == 0: - return 0 - numerator = ( - -4 * x**2 * y - + b * y**2 * p * c * f - + 2 * b * x * y * p * c * f - + b * x**2 * p * c * f - - 2 * b * y**2 * f - - 2 * b * x * y * f - + ( - ( - 4 * x**2 * y - - b * y**2 * p * c * f - - 2 * b * x * y * p * c * f - - b * x**2 * p * c * f - + 2 * b * y**2 * f - + 2 * b * x * y * f - ) - ** 2 - - ( - 4 - * (x**2 * f - y**2 * f) - * ( - -4 * b * x * y**2 * p * c - - 4 * b * x**2 * y * p * c - + 4 * b * x * y**2 - ) - ) - ) - ** (1 / 2) - ) - denominator = 2 * (x**2 * f - y**2 * f) - if denominator == 0: - return 0 - kelly_bet_amount = numerator / denominator - return int(kelly_bet_amount) - - -def wei_to_native(wei: int) -> float: - """Convert WEI to native token.""" - return wei / 10**18 - - -def get_bet_amount_kelly( # pylint: disable=too-many-arguments - bet_kelly_fraction: float, - bankroll: int, - win_probability: float, - confidence: float, - selected_type_tokens_in_pool: int, - other_tokens_in_pool: int, - bet_fee: int, - floor_balance: int, - max_bet: int = DEFAULT_MAX_BET, -) -> Dict[str, Union[int, List[str]]]: - """Calculate the Kelly bet amount.""" - # keep `floor_balance` xDAI in the bankroll - bankroll_adj = bankroll - floor_balance - bankroll_adj = min(bankroll_adj, max_bet) - bankroll_adj_xdai = wei_to_native(bankroll_adj) - info = [f"Adjusted bankroll: {bankroll_adj_xdai} xDAI."] - error = [] - if bankroll_adj <= 0: - error.append( - f"Bankroll ({bankroll_adj}) is less than the floor balance ({floor_balance})." - ) - error.append("Set bet amount to 0.") - error.append("Top up safe with DAI or wait for redeeming.") - return {"bet_amount": 0, "info": info, "error": error} - - fee_fraction = 1 - wei_to_native(bet_fee) - info.append(f"Fee fraction: {fee_fraction}") - kelly_bet_amount = calculate_kelly_bet_amount( - selected_type_tokens_in_pool, - other_tokens_in_pool, - win_probability, - confidence, - bankroll_adj, - fee_fraction, - ) - if kelly_bet_amount < 0: - info.append( - f"Invalid value for kelly bet amount: {kelly_bet_amount}\nSet bet amount to 0." - ) - return {"bet_amount": 0, "info": info, "error": error} - - info.append(f"Kelly bet amount: {wei_to_native(kelly_bet_amount)} xDAI") - info.append(f"Bet kelly fraction: {bet_kelly_fraction}") - adj_kelly_bet_amount = int(kelly_bet_amount * bet_kelly_fraction) - info.append( - f"Adjusted Kelly bet amount: {wei_to_native(adj_kelly_bet_amount)} xDAI" - ) - return {"bet_amount": adj_kelly_bet_amount, "info": info, "error": error} - - -def run(*_args, **kwargs) -> Dict[str, Union[int, List[str]]]: - """Run the strategy.""" - missing = check_missing_fields(kwargs) - if len(missing) > 0: - return {"error": [f"Required kwargs {missing} were not provided."]} - - kwargs = remove_irrelevant_fields(kwargs) - return get_bet_amount_kelly(**kwargs) diff --git a/trader_old/vendor/open_aea/protocols/__init__.py b/trader_old/vendor/open_aea/protocols/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_old/vendor/open_aea/protocols/signing/README.md b/trader_old/vendor/open_aea/protocols/signing/README.md deleted file mode 100644 index d010fe5b6..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Signing Protocol - -## Description - -This is a protocol for communication between a skill and a decision maker. - -## Specification - -```yaml ---- -name: signing -author: open_aea -version: 1.0.0 -description: A protocol for communication between skills and decision maker. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: open_aea/signing:1.0.0 -speech_acts: - sign_transaction: - terms: ct:Terms - raw_transaction: ct:RawTransaction - sign_message: - terms: ct:Terms - raw_message: ct:RawMessage - signed_transaction: - signed_transaction: ct:SignedTransaction - signed_message: - signed_message: ct:SignedMessage - error: - error_code: ct:ErrorCode -... ---- -ct:ErrorCode: | - enum ErrorCodeEnum { - UNSUCCESSFUL_MESSAGE_SIGNING = 0; - UNSUCCESSFUL_TRANSACTION_SIGNING = 1; - } - ErrorCodeEnum error_code = 1; -ct:RawMessage: | - bytes raw_message = 1; -ct:RawTransaction: | - bytes raw_transaction = 1; -ct:SignedMessage: | - bytes signed_message = 1; -ct:SignedTransaction: | - bytes signed_transaction = 1; -ct:Terms: | - bytes terms = 1; -... ---- -initiation: [sign_transaction, sign_message] -reply: - sign_transaction: [signed_transaction, error] - sign_message: [signed_message, error] - signed_transaction: [] - signed_message: [] - error: [] -termination: [signed_transaction, signed_message, error] -roles: {skill, decision_maker} -end_states: [successful, failed] -keep_terminal_state_dialogues: false -... -``` - -## Links diff --git a/trader_old/vendor/open_aea/protocols/signing/__init__.py b/trader_old/vendor/open_aea/protocols/signing/__init__.py deleted file mode 100644 index f202d9656..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 open_aea -# -# 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 the support resources for the signing protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.open_aea.protocols.signing.message import SigningMessage -from packages.open_aea.protocols.signing.serialization import SigningSerializer - - -SigningMessage.serializer = SigningSerializer diff --git a/trader_old/vendor/open_aea/protocols/signing/custom_types.py b/trader_old/vendor/open_aea/protocols/signing/custom_types.py deleted file mode 100644 index 121631b44..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/custom_types.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2020 open_aea -# -# 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 class representations corresponding to every custom type in the protocol specification.""" - -from enum import Enum -from typing import Any - -from aea.helpers.transaction.base import RawMessage as BaseRawMessage -from aea.helpers.transaction.base import RawTransaction as BaseRawTransaction -from aea.helpers.transaction.base import SignedMessage as BaseSignedMessage -from aea.helpers.transaction.base import SignedTransaction as BaseSignedTransaction -from aea.helpers.transaction.base import Terms as BaseTerms - - -class ErrorCode(Enum): - """This class represents an instance of ErrorCode.""" - - UNSUCCESSFUL_MESSAGE_SIGNING = 0 - UNSUCCESSFUL_TRANSACTION_SIGNING = 1 - - @staticmethod - def encode(error_code_protobuf_object: Any, error_code_object: "ErrorCode") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the error_code_protobuf_object argument is matched with the instance of this class in the 'error_code_object' argument. - - :param error_code_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param error_code_object: an instance of this class to be encoded in the protocol buffer object. - """ - error_code_protobuf_object.error_code = error_code_object.value - - @classmethod - def decode(cls, error_code_protobuf_object: Any) -> "ErrorCode": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'error_code_protobuf_object' argument. - - :param error_code_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'error_code_protobuf_object' argument. - """ - enum_value_from_pb2 = error_code_protobuf_object.error_code - return ErrorCode(enum_value_from_pb2) - - -RawMessage = BaseRawMessage -RawTransaction = BaseRawTransaction -SignedMessage = BaseSignedMessage -SignedTransaction = BaseSignedTransaction -Terms = BaseTerms diff --git a/trader_old/vendor/open_aea/protocols/signing/dialogues.py b/trader_old/vendor/open_aea/protocols/signing/dialogues.py deleted file mode 100644 index 49fc21248..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/dialogues.py +++ /dev/null @@ -1,136 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 open_aea -# -# 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 the classes required for signing dialogue management. - -- SigningDialogue: The dialogue class maintains state of a dialogue and manages it. -- SigningDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.open_aea.protocols.signing.message import SigningMessage - - -class SigningDialogue(Dialogue): - """The signing dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - SigningMessage.Performative.SIGN_TRANSACTION, - SigningMessage.Performative.SIGN_MESSAGE, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - SigningMessage.Performative.SIGNED_TRANSACTION, - SigningMessage.Performative.SIGNED_MESSAGE, - SigningMessage.Performative.ERROR, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - SigningMessage.Performative.ERROR: frozenset(), - SigningMessage.Performative.SIGN_MESSAGE: frozenset( - { - SigningMessage.Performative.SIGNED_MESSAGE, - SigningMessage.Performative.ERROR, - } - ), - SigningMessage.Performative.SIGN_TRANSACTION: frozenset( - { - SigningMessage.Performative.SIGNED_TRANSACTION, - SigningMessage.Performative.ERROR, - } - ), - SigningMessage.Performative.SIGNED_MESSAGE: frozenset(), - SigningMessage.Performative.SIGNED_TRANSACTION: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a signing dialogue.""" - - DECISION_MAKER = "decision_maker" - SKILL = "skill" - - class EndState(Dialogue.EndState): - """This class defines the end states of a signing dialogue.""" - - SUCCESSFUL = 0 - FAILED = 1 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[SigningMessage] = SigningMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class SigningDialogues(Dialogues, ABC): - """This class keeps track of all signing dialogues.""" - - END_STATES = frozenset( - {SigningDialogue.EndState.SUCCESSFUL, SigningDialogue.EndState.FAILED} - ) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[SigningDialogue] = SigningDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=SigningMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_old/vendor/open_aea/protocols/signing/message.py b/trader_old/vendor/open_aea/protocols/signing/message.py deleted file mode 100644 index c11b7ea24..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/message.py +++ /dev/null @@ -1,319 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 open_aea -# -# 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 signing's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - -from packages.open_aea.protocols.signing.custom_types import ( - ErrorCode as CustomErrorCode, -) -from packages.open_aea.protocols.signing.custom_types import ( - RawMessage as CustomRawMessage, -) -from packages.open_aea.protocols.signing.custom_types import ( - RawTransaction as CustomRawTransaction, -) -from packages.open_aea.protocols.signing.custom_types import ( - SignedMessage as CustomSignedMessage, -) -from packages.open_aea.protocols.signing.custom_types import ( - SignedTransaction as CustomSignedTransaction, -) -from packages.open_aea.protocols.signing.custom_types import Terms as CustomTerms - - -_default_logger = logging.getLogger("aea.packages.open_aea.protocols.signing.message") - -DEFAULT_BODY_SIZE = 4 - - -class SigningMessage(Message): - """A protocol for communication between skills and decision maker.""" - - protocol_id = PublicId.from_str("open_aea/signing:1.0.0") - protocol_specification_id = PublicId.from_str("open_aea/signing:1.0.0") - - ErrorCode = CustomErrorCode - - RawMessage = CustomRawMessage - - RawTransaction = CustomRawTransaction - - SignedMessage = CustomSignedMessage - - SignedTransaction = CustomSignedTransaction - - Terms = CustomTerms - - class Performative(Message.Performative): - """Performatives for the signing protocol.""" - - ERROR = "error" - SIGN_MESSAGE = "sign_message" - SIGN_TRANSACTION = "sign_transaction" - SIGNED_MESSAGE = "signed_message" - SIGNED_TRANSACTION = "signed_transaction" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = { - "error", - "sign_message", - "sign_transaction", - "signed_message", - "signed_transaction", - } - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "dialogue_reference", - "error_code", - "message_id", - "performative", - "raw_message", - "raw_transaction", - "signed_message", - "signed_transaction", - "target", - "terms", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of SigningMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=SigningMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(SigningMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def error_code(self) -> CustomErrorCode: - """Get the 'error_code' content from the message.""" - enforce(self.is_set("error_code"), "'error_code' content is not set.") - return cast(CustomErrorCode, self.get("error_code")) - - @property - def raw_message(self) -> CustomRawMessage: - """Get the 'raw_message' content from the message.""" - enforce(self.is_set("raw_message"), "'raw_message' content is not set.") - return cast(CustomRawMessage, self.get("raw_message")) - - @property - def raw_transaction(self) -> CustomRawTransaction: - """Get the 'raw_transaction' content from the message.""" - enforce(self.is_set("raw_transaction"), "'raw_transaction' content is not set.") - return cast(CustomRawTransaction, self.get("raw_transaction")) - - @property - def signed_message(self) -> CustomSignedMessage: - """Get the 'signed_message' content from the message.""" - enforce(self.is_set("signed_message"), "'signed_message' content is not set.") - return cast(CustomSignedMessage, self.get("signed_message")) - - @property - def signed_transaction(self) -> CustomSignedTransaction: - """Get the 'signed_transaction' content from the message.""" - enforce( - self.is_set("signed_transaction"), - "'signed_transaction' content is not set.", - ) - return cast(CustomSignedTransaction, self.get("signed_transaction")) - - @property - def terms(self) -> CustomTerms: - """Get the 'terms' content from the message.""" - enforce(self.is_set("terms"), "'terms' content is not set.") - return cast(CustomTerms, self.get("terms")) - - def _is_consistent(self) -> bool: - """Check that the message follows the signing protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, SigningMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == SigningMessage.Performative.SIGN_TRANSACTION: - expected_nb_of_contents = 2 - enforce( - isinstance(self.terms, CustomTerms), - "Invalid type for content 'terms'. Expected 'Terms'. Found '{}'.".format( - type(self.terms) - ), - ) - enforce( - isinstance(self.raw_transaction, CustomRawTransaction), - "Invalid type for content 'raw_transaction'. Expected 'RawTransaction'. Found '{}'.".format( - type(self.raw_transaction) - ), - ) - elif self.performative == SigningMessage.Performative.SIGN_MESSAGE: - expected_nb_of_contents = 2 - enforce( - isinstance(self.terms, CustomTerms), - "Invalid type for content 'terms'. Expected 'Terms'. Found '{}'.".format( - type(self.terms) - ), - ) - enforce( - isinstance(self.raw_message, CustomRawMessage), - "Invalid type for content 'raw_message'. Expected 'RawMessage'. Found '{}'.".format( - type(self.raw_message) - ), - ) - elif self.performative == SigningMessage.Performative.SIGNED_TRANSACTION: - expected_nb_of_contents = 1 - enforce( - isinstance(self.signed_transaction, CustomSignedTransaction), - "Invalid type for content 'signed_transaction'. Expected 'SignedTransaction'. Found '{}'.".format( - type(self.signed_transaction) - ), - ) - elif self.performative == SigningMessage.Performative.SIGNED_MESSAGE: - expected_nb_of_contents = 1 - enforce( - isinstance(self.signed_message, CustomSignedMessage), - "Invalid type for content 'signed_message'. Expected 'SignedMessage'. Found '{}'.".format( - type(self.signed_message) - ), - ) - elif self.performative == SigningMessage.Performative.ERROR: - expected_nb_of_contents = 1 - enforce( - isinstance(self.error_code, CustomErrorCode), - "Invalid type for content 'error_code'. Expected 'ErrorCode'. Found '{}'.".format( - type(self.error_code) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_old/vendor/open_aea/protocols/signing/protocol.yaml b/trader_old/vendor/open_aea/protocols/signing/protocol.yaml deleted file mode 100644 index 67aa31c87..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/protocol.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: signing -author: open_aea -version: 1.0.0 -protocol_specification_id: open_aea/signing:1.0.0 -type: protocol -description: A protocol for communication between skills and decision maker. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeictzqfrs3zlpmirbelejsenkupesqh7nkjncbopkmamk7dkersmrm - __init__.py: bafybeiarl4y6yah6cypjp2jqvlcpexpkt6zcgtcs67a6wsur7ncqa6u7d4 - custom_types.py: bafybeicbmroddjj6xvtoi6k6d2mt7iqr3uwxvhwt3ecpy5ze52ffc6i7bq - dialogues.py: bafybeiblb6pmkl3rluy27rn5525yvmkitcdpkb2a52byn2l7jsafsnnye4 - message.py: bafybeibwldxym64enuo55bzlhb64i34e4hnncstyj2tpnei5gcyrrww3h4 - serialization.py: bafybeialbbd7zxf6e2jekr6lev5gznux5wf3ivbiqsangwznkjyozfep2a - signing.proto: bafybeigbzr6x5wdmqzc7eanlz5xmvaoiwb4kwozgg3cugq63b7esicusra - signing_pb2.py: bafybeig5sfgd3zkclg4fwfpkq7mfh2vtv27jjgpmlzrnk2ti2po5ciysiq - tests/__init__.py: bafybeiaraxpv2z6r4e5rgmvnvdfv5rlrjdwbhqyjocxm2z2wkzpluezdey - tests/test_signing.py: bafybeifaiu6jzymbxhglisc57taub3igt5ftvs6c37s3ddonk7hxr2ni7i - tests/test_signing_dialogues.py: bafybeiewiya7lfnq4uiw3g2apa5mrxnzsy6lsu2xrbd5ljrm43rszrue7m - tests/test_signing_messages.py: bafybeiaiq6nx5v3tihclumgqpl32aqq7lr6vecqhifdefqze7inba67x6m -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_old/vendor/open_aea/protocols/signing/serialization.py b/trader_old/vendor/open_aea/protocols/signing/serialization.py deleted file mode 100644 index 5526c6bbf..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/serialization.py +++ /dev/null @@ -1,162 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 open_aea -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for signing protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.open_aea.protocols.signing import signing_pb2 # type: ignore -from packages.open_aea.protocols.signing.custom_types import ( # type: ignore - ErrorCode, - RawMessage, - RawTransaction, - SignedMessage, - SignedTransaction, - Terms, -) -from packages.open_aea.protocols.signing.message import SigningMessage # type: ignore - - -class SigningSerializer(Serializer): - """Serialization for the 'signing' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'Signing' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(SigningMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - signing_msg = signing_pb2.SigningMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == SigningMessage.Performative.SIGN_TRANSACTION: - performative = signing_pb2.SigningMessage.Sign_Transaction_Performative() # type: ignore - terms = msg.terms - Terms.encode(performative.terms, terms) - raw_transaction = msg.raw_transaction - RawTransaction.encode(performative.raw_transaction, raw_transaction) - signing_msg.sign_transaction.CopyFrom(performative) - elif performative_id == SigningMessage.Performative.SIGN_MESSAGE: - performative = signing_pb2.SigningMessage.Sign_Message_Performative() # type: ignore - terms = msg.terms - Terms.encode(performative.terms, terms) - raw_message = msg.raw_message - RawMessage.encode(performative.raw_message, raw_message) - signing_msg.sign_message.CopyFrom(performative) - elif performative_id == SigningMessage.Performative.SIGNED_TRANSACTION: - performative = signing_pb2.SigningMessage.Signed_Transaction_Performative() # type: ignore - signed_transaction = msg.signed_transaction - SignedTransaction.encode( - performative.signed_transaction, signed_transaction - ) - signing_msg.signed_transaction.CopyFrom(performative) - elif performative_id == SigningMessage.Performative.SIGNED_MESSAGE: - performative = signing_pb2.SigningMessage.Signed_Message_Performative() # type: ignore - signed_message = msg.signed_message - SignedMessage.encode(performative.signed_message, signed_message) - signing_msg.signed_message.CopyFrom(performative) - elif performative_id == SigningMessage.Performative.ERROR: - performative = signing_pb2.SigningMessage.Error_Performative() # type: ignore - error_code = msg.error_code - ErrorCode.encode(performative.error_code, error_code) - signing_msg.error.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = signing_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'Signing' message. - - :param obj: the bytes object. - :return: the 'Signing' message. - """ - message_pb = ProtobufMessage() - signing_pb = signing_pb2.SigningMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - signing_pb.ParseFromString(message_pb.dialogue_message.content) - performative = signing_pb.WhichOneof("performative") - performative_id = SigningMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == SigningMessage.Performative.SIGN_TRANSACTION: - pb2_terms = signing_pb.sign_transaction.terms - terms = Terms.decode(pb2_terms) - performative_content["terms"] = terms - pb2_raw_transaction = signing_pb.sign_transaction.raw_transaction - raw_transaction = RawTransaction.decode(pb2_raw_transaction) - performative_content["raw_transaction"] = raw_transaction - elif performative_id == SigningMessage.Performative.SIGN_MESSAGE: - pb2_terms = signing_pb.sign_message.terms - terms = Terms.decode(pb2_terms) - performative_content["terms"] = terms - pb2_raw_message = signing_pb.sign_message.raw_message - raw_message = RawMessage.decode(pb2_raw_message) - performative_content["raw_message"] = raw_message - elif performative_id == SigningMessage.Performative.SIGNED_TRANSACTION: - pb2_signed_transaction = signing_pb.signed_transaction.signed_transaction - signed_transaction = SignedTransaction.decode(pb2_signed_transaction) - performative_content["signed_transaction"] = signed_transaction - elif performative_id == SigningMessage.Performative.SIGNED_MESSAGE: - pb2_signed_message = signing_pb.signed_message.signed_message - signed_message = SignedMessage.decode(pb2_signed_message) - performative_content["signed_message"] = signed_message - elif performative_id == SigningMessage.Performative.ERROR: - pb2_error_code = signing_pb.error.error_code - error_code = ErrorCode.decode(pb2_error_code) - performative_content["error_code"] = error_code - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return SigningMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_old/vendor/open_aea/protocols/signing/signing.proto b/trader_old/vendor/open_aea/protocols/signing/signing.proto deleted file mode 100644 index 57dc09d17..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/signing.proto +++ /dev/null @@ -1,68 +0,0 @@ -syntax = "proto3"; - -package aea.open_aea.signing.v1_0_0; - -message SigningMessage{ - - // Custom Types - message ErrorCode{ - enum ErrorCodeEnum { - UNSUCCESSFUL_MESSAGE_SIGNING = 0; - UNSUCCESSFUL_TRANSACTION_SIGNING = 1; - } - ErrorCodeEnum error_code = 1; - } - - message RawMessage{ - bytes raw_message = 1; - } - - message RawTransaction{ - bytes raw_transaction = 1; - } - - message SignedMessage{ - bytes signed_message = 1; - } - - message SignedTransaction{ - bytes signed_transaction = 1; - } - - message Terms{ - bytes terms = 1; - } - - - // Performatives and contents - message Sign_Transaction_Performative{ - Terms terms = 1; - RawTransaction raw_transaction = 2; - } - - message Sign_Message_Performative{ - Terms terms = 1; - RawMessage raw_message = 2; - } - - message Signed_Transaction_Performative{ - SignedTransaction signed_transaction = 1; - } - - message Signed_Message_Performative{ - SignedMessage signed_message = 1; - } - - message Error_Performative{ - ErrorCode error_code = 1; - } - - - oneof performative{ - Error_Performative error = 5; - Sign_Message_Performative sign_message = 6; - Sign_Transaction_Performative sign_transaction = 7; - Signed_Message_Performative signed_message = 8; - Signed_Transaction_Performative signed_transaction = 9; - } -} diff --git a/trader_old/vendor/open_aea/protocols/signing/signing_pb2.py b/trader_old/vendor/open_aea/protocols/signing/signing_pb2.py deleted file mode 100644 index f0d03c3a9..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/signing_pb2.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: signing.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\rsigning.proto\x12\x1b\x61\x65\x61.open_aea.signing.v1_0_0"\xbc\x0c\n\x0eSigningMessage\x12O\n\x05\x65rror\x18\x05 \x01(\x0b\x32>.aea.open_aea.signing.v1_0_0.SigningMessage.Error_PerformativeH\x00\x12]\n\x0csign_message\x18\x06 \x01(\x0b\x32\x45.aea.open_aea.signing.v1_0_0.SigningMessage.Sign_Message_PerformativeH\x00\x12\x65\n\x10sign_transaction\x18\x07 \x01(\x0b\x32I.aea.open_aea.signing.v1_0_0.SigningMessage.Sign_Transaction_PerformativeH\x00\x12\x61\n\x0esigned_message\x18\x08 \x01(\x0b\x32G.aea.open_aea.signing.v1_0_0.SigningMessage.Signed_Message_PerformativeH\x00\x12i\n\x12signed_transaction\x18\t \x01(\x0b\x32K.aea.open_aea.signing.v1_0_0.SigningMessage.Signed_Transaction_PerformativeH\x00\x1a\xbd\x01\n\tErrorCode\x12W\n\nerror_code\x18\x01 \x01(\x0e\x32\x43.aea.open_aea.signing.v1_0_0.SigningMessage.ErrorCode.ErrorCodeEnum"W\n\rErrorCodeEnum\x12 \n\x1cUNSUCCESSFUL_MESSAGE_SIGNING\x10\x00\x12$\n UNSUCCESSFUL_TRANSACTION_SIGNING\x10\x01\x1a!\n\nRawMessage\x12\x13\n\x0braw_message\x18\x01 \x01(\x0c\x1a)\n\x0eRawTransaction\x12\x17\n\x0fraw_transaction\x18\x01 \x01(\x0c\x1a\'\n\rSignedMessage\x12\x16\n\x0esigned_message\x18\x01 \x01(\x0c\x1a/\n\x11SignedTransaction\x12\x1a\n\x12signed_transaction\x18\x01 \x01(\x0c\x1a\x16\n\x05Terms\x12\r\n\x05terms\x18\x01 \x01(\x0c\x1a\xb6\x01\n\x1dSign_Transaction_Performative\x12@\n\x05terms\x18\x01 \x01(\x0b\x32\x31.aea.open_aea.signing.v1_0_0.SigningMessage.Terms\x12S\n\x0fraw_transaction\x18\x02 \x01(\x0b\x32:.aea.open_aea.signing.v1_0_0.SigningMessage.RawTransaction\x1a\xaa\x01\n\x19Sign_Message_Performative\x12@\n\x05terms\x18\x01 \x01(\x0b\x32\x31.aea.open_aea.signing.v1_0_0.SigningMessage.Terms\x12K\n\x0braw_message\x18\x02 \x01(\x0b\x32\x36.aea.open_aea.signing.v1_0_0.SigningMessage.RawMessage\x1a|\n\x1fSigned_Transaction_Performative\x12Y\n\x12signed_transaction\x18\x01 \x01(\x0b\x32=.aea.open_aea.signing.v1_0_0.SigningMessage.SignedTransaction\x1ap\n\x1bSigned_Message_Performative\x12Q\n\x0esigned_message\x18\x01 \x01(\x0b\x32\x39.aea.open_aea.signing.v1_0_0.SigningMessage.SignedMessage\x1a_\n\x12\x45rror_Performative\x12I\n\nerror_code\x18\x01 \x01(\x0b\x32\x35.aea.open_aea.signing.v1_0_0.SigningMessage.ErrorCodeB\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "signing_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals["_SIGNINGMESSAGE"]._serialized_start = 47 - _globals["_SIGNINGMESSAGE"]._serialized_end = 1643 - _globals["_SIGNINGMESSAGE_ERRORCODE"]._serialized_start = 551 - _globals["_SIGNINGMESSAGE_ERRORCODE"]._serialized_end = 740 - _globals["_SIGNINGMESSAGE_ERRORCODE_ERRORCODEENUM"]._serialized_start = 653 - _globals["_SIGNINGMESSAGE_ERRORCODE_ERRORCODEENUM"]._serialized_end = 740 - _globals["_SIGNINGMESSAGE_RAWMESSAGE"]._serialized_start = 742 - _globals["_SIGNINGMESSAGE_RAWMESSAGE"]._serialized_end = 775 - _globals["_SIGNINGMESSAGE_RAWTRANSACTION"]._serialized_start = 777 - _globals["_SIGNINGMESSAGE_RAWTRANSACTION"]._serialized_end = 818 - _globals["_SIGNINGMESSAGE_SIGNEDMESSAGE"]._serialized_start = 820 - _globals["_SIGNINGMESSAGE_SIGNEDMESSAGE"]._serialized_end = 859 - _globals["_SIGNINGMESSAGE_SIGNEDTRANSACTION"]._serialized_start = 861 - _globals["_SIGNINGMESSAGE_SIGNEDTRANSACTION"]._serialized_end = 908 - _globals["_SIGNINGMESSAGE_TERMS"]._serialized_start = 910 - _globals["_SIGNINGMESSAGE_TERMS"]._serialized_end = 932 - _globals["_SIGNINGMESSAGE_SIGN_TRANSACTION_PERFORMATIVE"]._serialized_start = 935 - _globals["_SIGNINGMESSAGE_SIGN_TRANSACTION_PERFORMATIVE"]._serialized_end = 1117 - _globals["_SIGNINGMESSAGE_SIGN_MESSAGE_PERFORMATIVE"]._serialized_start = 1120 - _globals["_SIGNINGMESSAGE_SIGN_MESSAGE_PERFORMATIVE"]._serialized_end = 1290 - _globals["_SIGNINGMESSAGE_SIGNED_TRANSACTION_PERFORMATIVE"]._serialized_start = 1292 - _globals["_SIGNINGMESSAGE_SIGNED_TRANSACTION_PERFORMATIVE"]._serialized_end = 1416 - _globals["_SIGNINGMESSAGE_SIGNED_MESSAGE_PERFORMATIVE"]._serialized_start = 1418 - _globals["_SIGNINGMESSAGE_SIGNED_MESSAGE_PERFORMATIVE"]._serialized_end = 1530 - _globals["_SIGNINGMESSAGE_ERROR_PERFORMATIVE"]._serialized_start = 1532 - _globals["_SIGNINGMESSAGE_ERROR_PERFORMATIVE"]._serialized_end = 1627 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/open_aea/protocols/signing/tests/__init__.py b/trader_old/vendor/open_aea/protocols/signing/tests/__init__.py deleted file mode 100644 index 1ca32bbc0..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 package contains the tests of the signing protocol package.""" diff --git a/trader_old/vendor/open_aea/protocols/signing/tests/test_signing.py b/trader_old/vendor/open_aea/protocols/signing/tests/test_signing.py deleted file mode 100644 index 5866ade42..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/tests/test_signing.py +++ /dev/null @@ -1,144 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 Valory AG -# Copyright 2018-2019 Fetch.AI Limited -# -# 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 tests for transaction.""" -# pylint: skip-file - -from typing import List, Type - -from aea_ledger_cosmos import CosmosCrypto - -from aea.helpers.transaction.base import ( - RawMessage, - RawTransaction, - SignedMessage, - SignedTransaction, - Terms, -) -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import Dialogues -from aea.test_tools.test_protocol import ( - BaseProtocolDialoguesTestCase, - BaseProtocolMessagesTestCase, -) - -from packages.open_aea.protocols.signing.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.open_aea.protocols.signing.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.open_aea.protocols.signing.message import SigningMessage - - -class TestMessages(BaseProtocolMessagesTestCase): - """Base class to test message construction for the protocol.""" - - MESSAGE_CLASS = SigningMessage - - ledger_id = CosmosCrypto.identifier - terms = Terms( - ledger_id=ledger_id, - sender_address="address1", - counterparty_address="address2", - amount_by_currency_id={"FET": -2}, - quantities_by_good_id={"good_id": 10}, - is_sender_payable_tx_fee=True, - nonce="transaction nonce", - ) - - def build_messages(self) -> List[SigningMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - SigningMessage( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - terms=self.terms, - raw_transaction=RawTransaction(self.ledger_id, {"tx": "transaction"}), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGN_MESSAGE, - terms=self.terms, - raw_message=RawMessage(self.ledger_id, b"message"), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGNED_TRANSACTION, - message_id=2, - target=1, - signed_transaction=SignedTransaction( - self.ledger_id, {"sig": "signature"} - ), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGNED_MESSAGE, - message_id=2, - target=1, - signed_message=SignedMessage(self.ledger_id, "message"), - ), - SigningMessage( - performative=SigningMessage.Performative.ERROR, - message_id=2, - target=1, - error_code=SigningMessage.ErrorCode.UNSUCCESSFUL_MESSAGE_SIGNING, - ), - ] - - def build_inconsistent(self) -> List[SigningMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - SigningMessage( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - terms=self.terms, - ), - SigningMessage( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - raw_transaction=RawTransaction(self.ledger_id, {"tx": "transaction"}), - ), - SigningMessage( - performative=SigningMessage.Performative.ERROR, - message_id=2, - target=1, - ), - ] - - -class TestDialogues(BaseProtocolDialoguesTestCase): - """Test dialogues.""" - - MESSAGE_CLASS: Type[Message] = SigningMessage - DIALOGUE_CLASS: Type[BaseDialogue] = BaseSigningDialogue - DIALOGUES_CLASS: Type[Dialogues] = BaseSigningDialogues - ROLE_FOR_THE_FIRST_MESSAGE = BaseSigningDialogue.Role.SKILL - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - terms=Terms( - ledger_id="ledger_id", - sender_address="address1", - counterparty_address="address2", - amount_by_currency_id={"FET": -2}, - quantities_by_good_id={"good_id": 10}, - is_sender_payable_tx_fee=True, - nonce="transaction nonce", - ), - raw_transaction=RawTransaction("ledger_id", {"tx": "transaction"}), - ) diff --git a/trader_old/vendor/open_aea/protocols/signing/tests/test_signing_dialogues.py b/trader_old/vendor/open_aea/protocols/signing/tests/test_signing_dialogues.py deleted file mode 100644 index 06b7a1fc9..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/tests/test_signing_dialogues.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 open_aea -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for signing protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.open_aea.protocols.signing.custom_types import RawTransaction, Terms -from packages.open_aea.protocols.signing.dialogues import ( - SigningDialogue, - SigningDialogues, -) -from packages.open_aea.protocols.signing.message import SigningMessage - - -class TestDialoguesSigning(BaseProtocolDialoguesTestCase): - """Test for the 'signing' protocol dialogues.""" - - MESSAGE_CLASS = SigningMessage - - DIALOGUE_CLASS = SigningDialogue - - DIALOGUES_CLASS = SigningDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = SigningDialogue.Role.DECISION_MAKER # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - terms=Terms( - ledger_id="ledger_id", - sender_address="address1", - counterparty_address="address2", - amount_by_currency_id={"FET": -2}, - quantities_by_good_id={"good_id": 10}, - is_sender_payable_tx_fee=True, - nonce="transaction nonce", - ), - raw_transaction=RawTransaction("ledger_id", {"tx": "transaction"}), - ) diff --git a/trader_old/vendor/open_aea/protocols/signing/tests/test_signing_messages.py b/trader_old/vendor/open_aea/protocols/signing/tests/test_signing_messages.py deleted file mode 100644 index cc352270c..000000000 --- a/trader_old/vendor/open_aea/protocols/signing/tests/test_signing_messages.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 open_aea -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for signing protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea_ledger_cosmos import CosmosCrypto - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.open_aea.protocols.signing.custom_types import ( - ErrorCode, - RawMessage, - RawTransaction, - SignedMessage, - SignedTransaction, - Terms, -) -from packages.open_aea.protocols.signing.message import SigningMessage - - -class TestMessageSigning(BaseProtocolMessagesTestCase): - """Test for the 'signing' protocol message.""" - - MESSAGE_CLASS = SigningMessage - ledger_id = CosmosCrypto.identifier - terms = Terms( - ledger_id=ledger_id, - sender_address="address1", - counterparty_address="address2", - amount_by_currency_id={"FET": -2}, - quantities_by_good_id={"good_id": 10}, - is_sender_payable_tx_fee=True, - nonce="transaction nonce", - ) - - def build_messages(self) -> List[SigningMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - SigningMessage( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - terms=self.terms, - raw_transaction=RawTransaction(self.ledger_id, {"tx": "transaction"}), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGN_MESSAGE, - terms=self.terms, - raw_message=RawMessage(self.ledger_id, b"message"), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGNED_TRANSACTION, - signed_transaction=SignedTransaction( - self.ledger_id, {"sig": "signature"} - ), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGNED_MESSAGE, - signed_message=SignedMessage(self.ledger_id, "message"), - ), - SigningMessage( - performative=SigningMessage.Performative.ERROR, - error_code=ErrorCode.UNSUCCESSFUL_MESSAGE_SIGNING, - ), - ] - - def build_inconsistent(self) -> List[SigningMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - SigningMessage( - performative=SigningMessage.Performative.SIGN_TRANSACTION, - # skip content: terms - raw_transaction=RawTransaction(self.ledger_id, {"tx": "transaction"}), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGN_MESSAGE, - # skip content: terms - raw_message=RawMessage(self.ledger_id, b"message"), - ), - SigningMessage( - performative=SigningMessage.Performative.SIGNED_TRANSACTION, - # skip content: signed_transaction - ), - SigningMessage( - performative=SigningMessage.Performative.SIGNED_MESSAGE, - # skip content: signed_message - ), - SigningMessage( - performative=SigningMessage.Performative.ERROR, - # skip content: error_code - ), - ] diff --git a/trader_old/vendor/valory/connections/__init__.py b/trader_old/vendor/valory/connections/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_old/vendor/valory/connections/abci/Makefile b/trader_old/vendor/valory/connections/abci/Makefile deleted file mode 100644 index ac874c59d..000000000 --- a/trader_old/vendor/valory/connections/abci/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# Origin -version_branch = v0.34.19 -tendermint = https://raw.githubusercontent.com/tendermint/tendermint/$(version_branch) - -# Outputs -tmabci = protos/tendermint/abci/types.proto -tmtypes = protos/tendermint/types/types.proto -tmpubkey = protos/tendermint/crypto/keys.proto -tmproof = protos/tendermint/crypto/proof.proto -tmparams = protos/tendermint/types/params.proto -tmversions = protos/tendermint/version/types.proto -tmvalidator = protos/tendermint/types/validator.proto - -# You *only* need to run this to rebuild protobufs from the tendermint source -update-proto: - curl $(tendermint)/proto/tendermint/abci/types.proto > $(tmabci) - curl $(tendermint)/proto/tendermint/crypto/keys.proto > $(tmpubkey) - curl $(tendermint)/proto/tendermint/crypto/proof.proto > $(tmproof) - curl $(tendermint)/proto/tendermint/types/params.proto > $(tmparams) - curl $(tendermint)/proto/tendermint/types/types.proto > $(tmtypes) - curl $(tendermint)/proto/tendermint/types/validator.proto > $(tmvalidator) - curl $(tendermint)/proto/tendermint/version/types.proto > $(tmversions) - curl $(tendermint)/version/version.go | grep -F -eTMVersionDefault -eABCISemVer > version.txt - python scripts/genproto.py diff --git a/trader_old/vendor/valory/connections/abci/__init__.py b/trader_old/vendor/valory/connections/abci/__init__.py deleted file mode 100644 index 106a84724..000000000 --- a/trader_old/vendor/valory/connections/abci/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Abci connection.""" # pragma: nocover diff --git a/trader_old/vendor/valory/connections/abci/check_dependencies.py b/trader_old/vendor/valory/connections/abci/check_dependencies.py deleted file mode 100644 index d2336f3c2..000000000 --- a/trader_old/vendor/valory/connections/abci/check_dependencies.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ -"""Check dependencies.""" -import re -import shutil -import subprocess # nosec -from itertools import islice -from typing import Iterable, List, Pattern, Tuple - - -ERROR_MESSAGE_TEMPLATE_BINARY_NOT_FOUND = ( - "'{command}' is required by the " - "abci connection, but it is not installed, " - "or it is not accessible from the system path." -) -ERROR_MESSAGE_TEMPLATE_VERSION_TOO_LOW = ( - "The installed version of '{command}' " - "is too low: expected at least {lower_bound}; " - "found {actual_version}." -) - -# for the purposes of this script, -# a version is a tuple of integers: (major, minor, patch) -VERSION = Tuple[int, int, int] -MINIMUM_TENDERMINT_VERSION: VERSION = (0, 34, 19) - - -def nth(iterable: Iterable, index: int, default: int = 0) -> int: - """Returns the item at position 'index' or a default value""" - return next(islice(iterable, index, None), default) - - -def get_version(*args: int) -> VERSION: - """ - Get the version from a list of arguments. - - Set to '0' if there are not enough arguments. - - :param args: positional arguments - :return: the version - """ - major = nth(args, 0, 0) - minor = nth(args, 1, 0) - patch = nth(args, 2, 0) - return major, minor, patch - - -def version_to_string(version: VERSION) -> str: - """ - Transform version to string. - - :param version: the version. - :return: the string representation. - """ - return ".".join(map(str, version)) - - -def print_ok_message( - binary_name: str, actual_version: VERSION, version_lower_bound: VERSION -) -> None: # pragma: nocover - """ - Print OK message. - - :param binary_name: the binary binary_name. - :param actual_version: the actual version. - :param version_lower_bound: the version lower bound. - """ - print( - f"check '{binary_name}'>={version_to_string(version_lower_bound)}, " - f"found {version_to_string(actual_version)}" - ) - - -def check_binary( - binary_name: str, - args: List[str], - version_regex: Pattern, - version_lower_bound: VERSION, - only_warning: bool = False, -) -> None: # pragma: nocover - """ - Check a binary is accessible from the terminal. - - It breaks down in: - 1) check if the binary is reachable from the system path; - 2) check that the version number is higher or equal than the minimum required version. - - :param binary_name: the name of the binary. - :param args: the arguments to provide to the binary to retrieve the version. - :param version_regex: the regex used to extract the version from the output. - :param version_lower_bound: the minimum required version. - :param only_warning: if True, don't raise error but print a warning message - """ - path = shutil.which(binary_name) - if not path: - message = ERROR_MESSAGE_TEMPLATE_BINARY_NOT_FOUND.format(command=binary_name) - if only_warning: - print("Warning: ", message) - return - raise ValueError(message) - - version_getter_command = [binary_name, *args] - stdout = subprocess.check_output(version_getter_command).decode("utf-8") # nosec - version_match = version_regex.search(stdout) - if version_match is None: - print( - f"Warning: cannot parse '{binary_name}' version " - f"from command: {version_getter_command}. stdout: {stdout}" - ) - return - actual_version: VERSION = get_version(*map(int, version_match.groups(default="0"))) - if actual_version < version_lower_bound: - message = ERROR_MESSAGE_TEMPLATE_VERSION_TOO_LOW.format( - command=binary_name, - lower_bound=version_to_string(version_lower_bound), - actual_version=version_to_string(actual_version), - ) - if only_warning: - print(f"Warning: {message}") - return - raise ValueError(message) - - print_ok_message(binary_name, actual_version, version_lower_bound) - - -def check_versions() -> None: # pragma: nocover - """Check versions.""" - check_binary( - "tendermint", - ["version"], - re.compile(r"([0-9]+)\.([0-9]+)\.([0-9]+)"), - MINIMUM_TENDERMINT_VERSION, - only_warning=True, - ) - - -def main() -> None: # pragma: nocover - """The main entrypoint of the script.""" - check_versions() - - -if __name__ == "__main__": - main() # pragma: nocover diff --git a/trader_old/vendor/valory/connections/abci/connection.py b/trader_old/vendor/valory/connections/abci/connection.py deleted file mode 100644 index 2eec8de9f..000000000 --- a/trader_old/vendor/valory/connections/abci/connection.py +++ /dev/null @@ -1,1497 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ -"""Connection to interact with an ABCI server.""" -import asyncio -import json -import logging -import os -import platform -import signal -import subprocess # nosec -import sys -from asyncio import AbstractEventLoop, AbstractServer, CancelledError, Task -from io import BytesIO -from logging import Logger -from pathlib import Path -from threading import Event, Thread -from typing import Any, Dict, List, Optional, Tuple, Union, cast - -import grpc -from aea.configurations.base import PublicId -from aea.connections.base import Connection, ConnectionStates -from aea.exceptions import enforce -from aea.mail.base import Envelope -from aea.protocols.dialogue.base import DialogueLabel -from google.protobuf.message import DecodeError - -from packages.valory.connections.abci.dialogues import AbciDialogues -from packages.valory.connections.abci.tendermint.abci import ( # type: ignore - types_pb2_grpc, -) -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - Request, - RequestApplySnapshotChunk, - RequestBeginBlock, - RequestCheckTx, - RequestCommit, - RequestDeliverTx, - RequestEcho, - RequestEndBlock, - RequestFlush, - RequestInfo, - RequestInitChain, - RequestListSnapshots, - RequestLoadSnapshotChunk, - RequestOfferSnapshot, - RequestQuery, - RequestSetOption, - Response, - ResponseApplySnapshotChunk, - ResponseBeginBlock, - ResponseCheckTx, - ResponseCommit, - ResponseDeliverTx, - ResponseEcho, - ResponseEndBlock, - ResponseFlush, - ResponseInfo, - ResponseInitChain, - ResponseListSnapshots, - ResponseLoadSnapshotChunk, - ResponseOfferSnapshot, - ResponseQuery, - ResponseSetOption, -) -from packages.valory.connections.abci.tendermint_decoder import ( - _TendermintProtocolDecoder, -) -from packages.valory.connections.abci.tendermint_encoder import ( - _TendermintProtocolEncoder, -) -from packages.valory.protocols.abci import AbciMessage - - -PUBLIC_ID = PublicId.from_str("valory/abci:0.1.0") - - -_TCP = "tcp://" -ENCODING = "utf-8" -LOCALHOST = "127.0.0.1" -DEFAULT_ABCI_PORT = 26658 -DEFAULT_P2P_PORT = 26656 -DEFAULT_RPC_PORT = 26657 -DEFAULT_LISTEN_ADDRESS = "0.0.0.0" # nosec -DEFAULT_P2P_LISTEN_ADDRESS = f"{_TCP}{DEFAULT_LISTEN_ADDRESS}:{DEFAULT_P2P_PORT}" -DEFAULT_RPC_LISTEN_ADDRESS = f"{_TCP}{LOCALHOST}:{DEFAULT_RPC_PORT}" -MAX_READ_IN_BYTES = 2**20 # Max we'll consume on a read stream (1 MiB) -MAX_VARINT_BYTES = 10 # Max size of varint we support -DEFAULT_TENDERMINT_LOG_FILE = "tendermint.log" - - -class DecodeVarintError(Exception): - """This exception is raised when an error occurs while decoding a varint.""" - - -class EncodeVarintError(Exception): - """This exception is raised when an error occurs while encoding a varint.""" - - -class TooLargeVarint(Exception): - """This exception is raised when a message with varint exceeding the max size is received.""" - - def __init__(self, received_size: int, max_size: int = MAX_READ_IN_BYTES): - """ - Initialize the exception object. - - :param received_size: the received size. - :param max_size: the maximum amount the connection supports. - """ - super().__init__( - f"The max message size is {max_size}, received message with varint {received_size}." - ) - self.received_size = received_size - self.max_size = max_size - - -class ShortBufferLengthError(Exception): - """This exception is raised when the buffer length is shorter than expected.""" - - def __init__(self, expected_length: int, data: bytes): - """ - Initialize the exception object. - - :param expected_length: the expected length to be read - :param data: the data actually read - """ - super().__init__( - f"expected bytes of length {expected_length}, got bytes of length {len(data)}" - ) - self.expected_length = expected_length - self.data = data - - -class _TendermintABCISerializer: - """(stateless) utility class to encode/decode messages for the communication with Tendermint.""" - - @classmethod - def encode_varint(cls, number: int) -> bytes: - """Encode a number in varint coding.""" - - if not 0 <= number < 1 << 64: - log_msg = "Expecting uint64 from Protobuf" - raise EncodeVarintError(f"{log_msg}: {number}") - - number <<= 1 # Shift to int64 - buf = b"" - while True: - towrite = number & 0x7F - number >>= 7 - if number: - buf += bytes((towrite | 0x80,)) - else: - buf += bytes((towrite,)) - break - return buf - - @classmethod - async def decode_varint( - cls, buffer: asyncio.StreamReader, max_length: int = MAX_VARINT_BYTES - ) -> int: - """ - Decode a number from its varint coding. - - :param buffer: the buffer to read from. - :param max_length: the max number of bytes that can be read. - :return: the decoded int. - - :raise: DecodeVarintError if the varint could not be decoded. - :raise: EOFError if EOF byte is read and the process of decoding a varint has not started. - """ - enforce(max_length >= 1, "max bytes must be at least one") - nb_read_bytes = 0 - shift = 0 - result = 0 - success = False - byte = await cls._read_one(buffer) - while byte is not None and nb_read_bytes <= max_length: - nb_read_bytes += 1 - result |= (byte & 0x7F) << shift - shift += 7 - if not byte & 0x80: - success = True - break - byte = await cls._read_one(buffer) - # byte is None when EOF is reached - if byte is None and nb_read_bytes == 0: - raise EOFError() - if not success: - raise DecodeVarintError("could not decode varint") - return result >> 1 - - @classmethod - async def _read_one(cls, buffer: asyncio.StreamReader) -> Optional[int]: - """ - Read one byte to decode a varint. - - :param buffer: the buffer to read from. - :return: the next character, or None if EOF is reached. - """ - character = await buffer.read(1) - if character == b"": - return None - return ord(character) - - @classmethod - def write_message(cls, message: Response) -> bytes: - """Write a message in a buffer.""" - buffer = BytesIO(b"") - protobuf_bytes = message.SerializeToString() - encoded = cls.encode_varint(len(protobuf_bytes)) - buffer.write(encoded) - buffer.write(protobuf_bytes) - return buffer.getvalue() - - -class VarintMessageReader: # pylint: disable=too-few-public-methods - """Varint message reader.""" - - def __init__(self, reader: asyncio.StreamReader) -> None: - """Initialize the reader.""" - self._reader = reader - - async def read_next_message(self) -> bytes: - """Read next message.""" - varint = await _TendermintABCISerializer.decode_varint(self._reader) - if varint > MAX_READ_IN_BYTES: - raise TooLargeVarint(received_size=varint, max_size=MAX_READ_IN_BYTES) - message_bytes = await self.read_until(varint) - if len(message_bytes) < varint: - raise ShortBufferLengthError(varint, message_bytes) - return message_bytes - - async def read_until(self, n: int) -> bytes: - """Wait until n bytes are read from the stream.""" - result = BytesIO(b"") - read_bytes = 0 - while read_bytes < n: - data = await self._reader.read(n - read_bytes) - result.write(data) - read_bytes += len(data) - return result.getvalue() - - -class ABCIApplicationServicer(types_pb2_grpc.ABCIApplicationServicer): - """Implements the gRPC servicer (handler)""" - - # pylint: disable=invalid-overridden-method, no-member - - def __init__( - self, request_queue: asyncio.Queue, dialogues: AbciDialogues, target_skill: str - ): - """ - Initializes the abci handler. - - :param request_queue: queue holding translated abci messages. - :param dialogues: dialogues - :param target_skill: target skill of messages - """ - super().__init__() - self._request_queue = request_queue - self._dialogues = dialogues - self._target_skill = target_skill - self._response_queues: Dict[str, asyncio.Queue] = { - AbciMessage.Performative.RESPONSE_ECHO: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_FLUSH: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_INFO: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_SET_OPTION: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_DELIVER_TX: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_CHECK_TX: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_QUERY: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_COMMIT: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_INIT_CHAIN: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_BEGIN_BLOCK: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_END_BLOCK: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK: asyncio.Queue(), - AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK: asyncio.Queue(), - } - - async def send(self, envelope: Envelope) -> Response: - """ - Returns response to the waiting request - - :param: envelope: Envelope to be returned - """ - message = cast(AbciMessage, envelope.message) - dialogue = self._dialogues.update(message) - if dialogue is None: # pragma: nocover - logging.warning(f"Could not create dialogue for message={message}") - return - - await self._response_queues[message.performative].put(envelope) - - async def Echo( - self, request: RequestEcho, context: grpc.ServicerContext - ) -> ResponseEcho: - """ - Handles "Echo" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(echo=request) - message, _ = _TendermintProtocolDecoder.request_echo( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_ECHO - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_echo(message) - context.set_code(grpc.StatusCode.OK) - - return response.echo - - async def Flush( - self, request: RequestFlush, context: grpc.ServicerContext - ) -> ResponseFlush: # pragma: no cover - """ - Handles "Flush" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(flush=request) - message, _ = _TendermintProtocolDecoder.request_flush( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_FLUSH - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_flush(message) - context.set_code(grpc.StatusCode.OK) - - return response.flush - - async def Info( - self, request: RequestInfo, context: grpc.ServicerContext - ) -> ResponseInfo: - """ - Handles "Info" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(info=request) - message, _ = _TendermintProtocolDecoder.request_info( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_INFO - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_info(message) - context.set_code(grpc.StatusCode.OK) - - return response.info - - async def SetOption( - self, request: RequestSetOption, context: grpc.ServicerContext - ) -> ResponseSetOption: # pragma: no cover - """ - Handles "SetOption" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(set_option=request) - message, _ = _TendermintProtocolDecoder.request_set_option( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_SET_OPTION - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_set_option(message) - context.set_code(grpc.StatusCode.OK) - - return response.set_option - - async def DeliverTx( - self, request: RequestDeliverTx, context: grpc.ServicerContext - ) -> ResponseDeliverTx: - """ - Handles "DeliverTx" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(deliver_tx=request) - message, _ = _TendermintProtocolDecoder.request_deliver_tx( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_DELIVER_TX - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_deliver_tx(message) - context.set_code(grpc.StatusCode.OK) - - return response.deliver_tx - - async def CheckTx( - self, request: RequestCheckTx, context: grpc.ServicerContext - ) -> ResponseCheckTx: - """ - Handles "CheckTx" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(check_tx=request) - message, _ = _TendermintProtocolDecoder.request_check_tx( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_CHECK_TX - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_check_tx(message) - context.set_code(grpc.StatusCode.OK) - - return response.check_tx - - async def Query( - self, request: RequestQuery, context: grpc.ServicerContext - ) -> ResponseQuery: - """ - Handles "Query" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(query=request) - message, _ = _TendermintProtocolDecoder.request_query( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_QUERY - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_query(message) - context.set_code(grpc.StatusCode.OK) - - return response.query - - async def Commit( - self, request: RequestCommit, context: grpc.ServicerContext - ) -> ResponseCommit: - """ - Handles "Commit" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(commit=request) - message, _ = _TendermintProtocolDecoder.request_commit( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_COMMIT - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_commit(message) - context.set_code(grpc.StatusCode.OK) - - return response.commit - - async def InitChain( - self, request: RequestInitChain, context: grpc.ServicerContext - ) -> ResponseInitChain: - """ - Handles "InitChain" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(init_chain=request) - message, _ = _TendermintProtocolDecoder.request_init_chain( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_INIT_CHAIN - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_init_chain(message) - context.set_code(grpc.StatusCode.OK) - - return response.init_chain - - async def BeginBlock( - self, request: RequestBeginBlock, context: grpc.ServicerContext - ) -> ResponseBeginBlock: - """ - Handles "BeginBlock" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(begin_block=request) - message, _ = _TendermintProtocolDecoder.request_begin_block( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_BEGIN_BLOCK - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_begin_block(message) - context.set_code(grpc.StatusCode.OK) - - return response.begin_block - - async def EndBlock( - self, request: RequestEndBlock, context: grpc.ServicerContext - ) -> ResponseEndBlock: - """ - Handles "EndBlock" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(end_block=request) - message, _ = _TendermintProtocolDecoder.request_end_block( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_END_BLOCK - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_end_block(message) - context.set_code(grpc.StatusCode.OK) - - return response.end_block - - async def ListSnapshots( - self, request: RequestListSnapshots, context: grpc.ServicerContext - ) -> ResponseListSnapshots: # pragma: no cover - """ - Handles "ListSnapshots" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(list_snapshots=request) - message, _ = _TendermintProtocolDecoder.request_list_snapshots( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_list_snapshots(message) - context.set_code(grpc.StatusCode.OK) - - return response.list_snapshots - - async def OfferSnapshot( - self, request: RequestOfferSnapshot, context: grpc.ServicerContext - ) -> ResponseOfferSnapshot: # pragma: no cover - """ - Handles "OfferSnapshot" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(offer_snapshot=request) - message, _ = _TendermintProtocolDecoder.request_offer_snapshot( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_offer_snapshot(message) - context.set_code(grpc.StatusCode.OK) - - return response.list_snapshots - - async def LoadSnapshotChunk( - self, request: RequestLoadSnapshotChunk, context: grpc.ServicerContext - ) -> ResponseLoadSnapshotChunk: # pragma: no cover - """ - Handles "LoadSnapshotChunk" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(load_snapshot_chunk=request) - message, _ = _TendermintProtocolDecoder.request_load_snapshot_chunk( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_load_snapshot_chunk(message) - context.set_code(grpc.StatusCode.OK) - - return response.load_snapshot_chunk - - async def ApplySnapshotChunk( - self, request: RequestApplySnapshotChunk, context: grpc.ServicerContext - ) -> ResponseApplySnapshotChunk: # pragma: no cover - """ - Handles "ApplySnapshotChunk" gRPC requests - - :param: request: The request from the Tendermint node - :param: context: The request context - :return: the Echo response - """ - packed_req = Request(apply_snapshot_chunk=request) - message, _ = _TendermintProtocolDecoder.request_apply_snapshot_chunk( - packed_req, self._dialogues, self._target_skill - ) - envelope = Envelope(to=message.to, sender=message.sender, message=message) - - await self._request_queue.put(envelope) - message = cast( - AbciMessage, - ( - await self._response_queues[ - AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK - ].get() - ).message, - ) - - response = _TendermintProtocolEncoder.response_apply_snapshot_chunk(message) - context.set_code(grpc.StatusCode.OK) - - return response.apply_snapshot_chunk - - -class GrpcServerChannel: # pylint: disable=too-many-instance-attributes - """gRPC server channel to handle incoming communication from the Tendermint node.""" - - def __init__( - self, - target_skill_id: PublicId, - address: str, - port: int, - logger: Optional[Logger] = None, - ): - """ - Initialize the gRPC server. - - :param target_skill_id: the public id of the target skill. - :param address: the listen address. - :param port: the port to listen from. - :param logger: the logger. - """ - self.target_skill_id = target_skill_id - self.address = address - self.port = port - self.logger = logger - - # channel state - self._loop: Optional[AbstractEventLoop] = None - self._dialogues = AbciDialogues(connection_id=PUBLIC_ID) - self._is_stopped: bool = True - self.queue: Optional[asyncio.Queue] = None - self._server: Optional[grpc.Server] = None - self._server_task: Optional[Task] = None - self._servicer: Optional[ABCIApplicationServicer] = None - - @property - def is_stopped(self) -> bool: - """Check that the channel is stopped.""" - return self._is_stopped - - async def _start_server(self) -> None: - """Start the gRPC server.""" - self.logger = cast(Logger, self.logger) - self.queue = cast(asyncio.Queue, self.queue) - self.logger.info("Starting gRPC server") - server = grpc.aio.server() - self._servicer = ABCIApplicationServicer( - self.queue, self._dialogues, str(self.target_skill_id) - ) - types_pb2_grpc.add_ABCIApplicationServicer_to_server(self._servicer, server) - server.add_insecure_port(f"[::]:{self.port}") - self._server = server - await self._server.start() - await self._server.wait_for_termination() - - async def connect(self, loop: AbstractEventLoop) -> None: - """ - Connect. - - :param loop: asyncio event loop - """ - if not self._is_stopped: # pragma: nocover - return - self._loop = loop - self._is_stopped = False - self.queue = asyncio.Queue() - - asyncio.create_task(self._start_server()) - - async def disconnect(self) -> None: - """Disconnect the channel""" - if self.is_stopped: # pragma: nocover - return - self._is_stopped = True - self._server = cast(grpc.Server, self._server) - await self._server.stop(0) - - self.queue = None - self._server = None - - async def get_message(self) -> Envelope: - """Get a message from the queue.""" - return await cast(asyncio.Queue, self.queue).get() - - async def send(self, envelope: Envelope) -> None: - """Send a message.""" - self._servicer = cast(ABCIApplicationServicer, self._servicer) - await self._servicer.send(envelope) - - -class TcpServerChannel: # pylint: disable=too-many-instance-attributes - """TCP server channel to handle incoming communication from the Tendermint node.""" - - def __init__( - self, - target_skill_id: PublicId, - address: str, - port: int, - logger: Optional[Logger] = None, - ): - """ - Initialize the TCP server. - - :param target_skill_id: the public id of the target skill. - :param address: the listen address. - :param port: the port to listen from. - :param logger: the logger. - """ - self.target_skill_id = target_skill_id - self.address = address - self.port = port - self.logger = logger or logging.getLogger() - - # channel state - self._loop: Optional[AbstractEventLoop] = None - self._dialogues = AbciDialogues(connection_id=PUBLIC_ID) - self._is_stopped: bool = True - self.queue: Optional[asyncio.Queue] = None - self._server: Optional[AbstractServer] = None - self._server_task: Optional[Task] = None - # a single Tendermint opens four concurrent connections: - # https://docs.tendermint.com/master/spec/abci/apps.html - # this dictionary keeps track of the reader-writer stream pair - # by socket name (ip address and port) - self._streams_by_socket: Dict[ - str, Tuple[asyncio.StreamReader, asyncio.StreamWriter] - ] = {} - # this dictionary associates requests to socket name - # such that responses are sent to the right receiver - self._request_id_to_socket: Dict[DialogueLabel, str] = {} - - @property - def is_stopped(self) -> bool: - """Check that the channel is stopped.""" - return self._is_stopped - - async def connect(self, loop: AbstractEventLoop) -> None: - """ - Connect. - - Upon TCP Channel connection, start the TCP Server asynchronously. - - :param loop: asyncio event loop - """ - if not self._is_stopped: # pragma: nocover - return - self._loop = loop - self._is_stopped = False - self.queue = asyncio.Queue() - self._server = await asyncio.start_server( - self.receive_messages, host=self.address, port=self.port - ) - - async def disconnect(self) -> None: - """Disconnect the channel""" - if self.is_stopped: # pragma: nocover - return - self._is_stopped = True - self._server = cast(AbstractServer, self._server) - self._server.close() - await self._server.wait_closed() - - self.queue = None - self._server = None - self._streams_by_socket = {} - self._request_id_to_socket = {} - - async def receive_messages( - self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter - ) -> None: - """Receive incoming messages.""" - self.logger = cast(Logger, self.logger) - self.queue = cast(asyncio.Queue, self.queue) - ip_address, socket, *_ = writer.get_extra_info("peername") - peer_name = f"{ip_address}:{socket}" - self._streams_by_socket[peer_name] = (reader, writer) - self.logger.debug(f"Connection with Tendermint @ {peer_name}") - - varint_message_reader = VarintMessageReader(reader) - while not self.is_stopped: - try: - message_bytes = await varint_message_reader.read_next_message() - if len(message_bytes) == 0: - self.logger.error( - f"Tendermint node {peer_name} closed connection." - ) # pragma: nocover - # break to the _stop if the connection stops - break # pragma: nocover - self.logger.debug( - f"Received {len(message_bytes)} bytes from connection {peer_name}" - ) - message = Request() - message.ParseFromString(message_bytes) - except ( - DecodeVarintError, - DecodeError, - ) as e: # pragma: nocover - self.logger.error( - f"an error occurred while reading a message: " - f"{type(e).__name__}: {e}. " - f"The message will be ignored." - ) - if reader.at_eof(): - self.logger.info("connection at EOF, stop receiving loop.") - return - continue - except TooLargeVarint as e: # pragma: nocover - self.logger.error( - f"A message exceeding the configured max size was received. " - f"{type(e).__name__}: {e} " - f"Closing the connection to the node." - ) - await self.disconnect() - return - except EOFError: - self.logger.info("connection at EOF, stop receiving loop.") - return - except CancelledError: # pragma: nocover - self.logger.debug(f"Read task for peer {peer_name} cancelled.") - return - await self._handle_message(message, peer_name) - - async def _handle_message(self, message: Request, peer_name: str) -> None: - """Handle a single message from a peer.""" - try: - req_type = message.WhichOneof("value") - result = _TendermintProtocolDecoder.process( - message, self._dialogues, str(self.target_skill_id) - ) - if result is not None: - request, dialogue = result - # associate request to peer, so we remember who to reply to - self._request_id_to_socket[ - dialogue.incomplete_dialogue_label - ] = peer_name - envelope = Envelope( - to=request.to, sender=request.sender, message=request - ) - await cast(asyncio.Queue, self.queue).put(envelope) - else: # pragma: nocover - self.logger.warning(f"Decoded request {req_type} was not a match.") - except Exception as e: # pylint: disable=broad-except # pragma: no cover - self.logger.error(f"Unhandled exception {type(e).__name__}: {e}") - - async def get_message(self) -> Envelope: - """Get a message from the queue.""" - return await cast(asyncio.Queue, self.queue).get() - - async def send(self, envelope: Envelope) -> None: - """Send a message.""" - self.logger = cast(Logger, self.logger) - message = cast(AbciMessage, envelope.message) - dialogue = self._dialogues.update(message) - if dialogue is None: # pragma: nocover - self.logger.warning(f"Could not create dialogue for message={message}") - return - - # we only deal with atomic request-response cycles, so it is safe to remove the reference - peer_name = self._request_id_to_socket.pop(dialogue.incomplete_dialogue_label) - _reader, writer = self._streams_by_socket[peer_name] - protobuf_message = _TendermintProtocolEncoder.process(message) - data = _TendermintABCISerializer.write_message(protobuf_message) - self.logger.debug(f"Writing {len(data)} bytes") - writer.write(data) - - -class StoppableThread( - Thread, -): - """Thread class with a stop() method.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialise the thread.""" - super().__init__(*args, **kwargs) - self._stop_event = Event() - - def stop(self) -> None: - """Set the stop event.""" - self._stop_event.set() - - def stopped(self) -> bool: - """Check if the thread is stopped.""" - return self._stop_event.is_set() - - -class TendermintParams: # pylint: disable=too-few-public-methods - """Tendermint node parameters.""" - - def __init__( # pylint: disable=too-many-arguments - self, - proxy_app: str, - rpc_laddr: str = DEFAULT_RPC_LISTEN_ADDRESS, - p2p_laddr: str = DEFAULT_P2P_LISTEN_ADDRESS, - p2p_seeds: Optional[List[str]] = None, - consensus_create_empty_blocks: bool = True, - home: Optional[str] = None, - use_grpc: bool = False, - ): - """ - Initialize the parameters to the Tendermint node. - - :param proxy_app: ABCI address. - :param rpc_laddr: RPC address. - :param p2p_laddr: P2P address. - :param p2p_seeds: P2P seeds. - :param consensus_create_empty_blocks: if true, Tendermint node creates empty blocks. - :param home: Tendermint's home directory. - :param use_grpc: Whether to use a gRPC server, or TCP - """ - - self.proxy_app = proxy_app - self.rpc_laddr = rpc_laddr - self.p2p_laddr = p2p_laddr - self.p2p_seeds = p2p_seeds - self.consensus_create_empty_blocks = consensus_create_empty_blocks - self.home = home - self.use_grpc = use_grpc - - def __str__(self) -> str: - """Get the string representation.""" - return ( - f"{self.__class__.__name__}(" - f" proxy_app={self.proxy_app},\n" - f" rpc_laddr={self.rpc_laddr},\n" - f" p2p_laddr={self.p2p_laddr},\n" - f" p2p_seeds={self.p2p_seeds},\n" - f" consensus_create_empty_blocks={self.consensus_create_empty_blocks},\n" - f" home={self.home},\n" - ")" - ) - - def build_node_command(self, debug: bool = False) -> List[str]: - """Build the 'node' command.""" - p2p_seeds = ",".join(self.p2p_seeds) if self.p2p_seeds else "" - cmd = [ - "tendermint", - "node", - f"--proxy_app={self.proxy_app}", - f"--rpc.laddr={self.rpc_laddr}", - f"--p2p.laddr={self.p2p_laddr}", - f"--p2p.seeds={p2p_seeds}", - f"--consensus.create_empty_blocks={str(self.consensus_create_empty_blocks).lower()}", - f"--abci={'grpc' if self.use_grpc else 'socket'}", - ] - if debug: - cmd.append("--log_level=debug") - if self.home is not None: # pragma: nocover - cmd += ["--home", self.home] - return cmd - - @staticmethod - def get_node_command_kwargs() -> Dict: - """Get the node command kwargs""" - kwargs = { - "bufsize": 1, - "universal_newlines": True, - "stdout": subprocess.PIPE, - "stderr": subprocess.STDOUT, - } - if platform.system() == "Windows": # pragma: nocover - kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP # type: ignore - else: - kwargs["preexec_fn"] = os.setsid # type: ignore - return kwargs - - -class TendermintNode: - """A class to manage a Tendermint node.""" - - def __init__( - self, - params: TendermintParams, - logger: Optional[Logger] = None, - write_to_log: bool = False, - ): - """ - Initialize a Tendermint node. - - :param params: the parameters. - :param logger: the logger. - :param write_to_log: Write to log file. - """ - self.params = params - self._process: Optional[subprocess.Popen] = None - self._monitoring: Optional[StoppableThread] = None - self._stopping = False - self.logger = logger or logging.getLogger() - self.log_file = os.environ.get("LOG_FILE", DEFAULT_TENDERMINT_LOG_FILE) - self.write_to_log = write_to_log - - def _build_init_command(self) -> List[str]: - """Build the 'init' command.""" - cmd = [ - "tendermint", - "init", - ] - if self.params.home is not None: # pragma: nocover - cmd += ["--home", self.params.home] - return cmd - - def init(self) -> None: - """Initialize Tendermint node.""" - cmd = self._build_init_command() - subprocess.call(cmd) # nosec - - def _monitor_tendermint_process( - self, - ) -> None: - """Check server status.""" - if self._monitoring is None: - raise ValueError("Monitoring is not running") - self.log("Monitoring thread started\n") - while not self._monitoring.stopped(): - try: - if self._process is not None and self._process.stdout is not None: - line = self._process.stdout.readline() - self.log(line) - for trigger in [ - # this occurs when we lose connection from the tm side - "RPC HTTP server stopped", - # whenever the node is stopped because of a closed connection - # from on any of the tendermint modules (abci, p2p, rpc, etc) - # we restart the node - "Stopping abci.socketClient for error: read message: EOF", - ]: - if self._monitoring.stopped(): - break - if line.find(trigger) >= 0: - self._stop_tm_process() - # we can only reach this step if monitoring was activated - # so we make sure that after reset the monitoring continues - self._start_tm_process() - self.log( - f"Restarted the HTTP RPC server, as a connection was dropped with message:\n\t\t {line}\n" - ) - except Exception as e: # pylint: disable=broad-except - self.log(f"Error!: {str(e)}") - self.log("Monitoring thread terminated\n") - - def _start_tm_process(self, debug: bool = False) -> None: - """Start a Tendermint node process.""" - if self._process is not None or self._stopping: # pragma: nocover - return - cmd = self.params.build_node_command(debug) - kwargs = self.params.get_node_command_kwargs() - self.log(f"Starting Tendermint: {cmd}\n") - self._process = ( - subprocess.Popen( # nosec # pylint: disable=consider-using-with,W1509 - cmd, **kwargs - ) - ) - self.log("Tendermint process started\n") - - def _start_monitoring_thread(self) -> None: - """Start a monitoring thread.""" - self._monitoring = StoppableThread(target=self._monitor_tendermint_process) - self._monitoring.start() - - def start(self, debug: bool = False) -> None: - """Start a Tendermint node process.""" - self._start_tm_process(debug) - self._start_monitoring_thread() - - def _stop_tm_process(self) -> None: - """Stop a Tendermint node process.""" - if self._process is None or self._stopping: - return - - self._stopping = True - if platform.system() == "Windows": - self._win_stop_tm() - else: - # this will raise an exception if the process - # is not terminated within the specified timeout - self._unix_stop_tm() - - self._stopping = False - self._process = None - self.log("Tendermint process stopped\n") - - def _win_stop_tm(self) -> None: - """Stop a Tendermint node process on Windows.""" - os.kill(self._process.pid, signal.CTRL_C_EVENT) # type: ignore # pylint: disable=no-member - try: - self._process.wait(timeout=5) # type: ignore - except subprocess.TimeoutExpired: # nosec - os.kill(self._process.pid, signal.CTRL_BREAK_EVENT) # type: ignore # pylint: disable=no-member - - def _unix_stop_tm(self) -> None: - """Stop a Tendermint node process on Unix.""" - self._process.send_signal(signal.SIGTERM) # type: ignore - try: - self._process.wait(timeout=5) # type: ignore - except subprocess.TimeoutExpired: # nosec - self.log("Tendermint process did not stop gracefully\n") - - # if the process is still running poll will return None - poll = self._process.poll() # type: ignore - if poll is not None: - return - - self._process.terminate() # type: ignore - self._process.wait(3) # type: ignore - - def _stop_monitoring_thread(self) -> None: - """Stop a monitoring process.""" - if self._monitoring is not None: - self._monitoring.stop() # set stop event - self._monitoring.join() - - def stop(self) -> None: - """Stop a Tendermint node process.""" - self._stop_tm_process() - self._stop_monitoring_thread() - - @staticmethod - def _write_to_console(line: str) -> None: - """Write line to console.""" - sys.stdout.write(str(line)) - sys.stdout.flush() - - def _write_to_file(self, line: str) -> None: - """Write line to console.""" - with open(self.log_file, "a", encoding=ENCODING) as file: - file.write(line) - - def log(self, line: str) -> None: - """Open and write a line to the log file.""" - self._write_to_console(line=line) - if self.write_to_log: - self._write_to_file(line=line) - - def prune_blocks(self) -> int: - """Prune blocks from the Tendermint state""" - return subprocess.call( # nosec: - ["tendermint", "--home", str(self.params.home), "unsafe-reset-all"] - ) - - def reset_genesis_file( - self, genesis_time: str, initial_height: str, period_count: str - ) -> None: - """Reset genesis file.""" - - genesis_file = Path(str(self.params.home), "config", "genesis.json") - genesis_config = json.loads(genesis_file.read_text(encoding=ENCODING)) - genesis_config["genesis_time"] = genesis_time - genesis_config["initial_height"] = initial_height - # chain id should be max 50 chars. - # this means that the app would theoretically break when a 40-digit period is reached - genesis_config["chain_id"] = f"autonolas-{period_count}" - genesis_file.write_text(json.dumps(genesis_config, indent=2), encoding=ENCODING) - - -class ABCIServerConnection(Connection): # pylint: disable=too-many-instance-attributes - """ABCI server.""" - - connection_id = PUBLIC_ID - params: Optional[TendermintParams] = None - node: Optional[TendermintNode] = None - channel: Optional[Union[TcpServerChannel, GrpcServerChannel]] = None - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize the connection. - - :param kwargs: keyword arguments passed to component base - """ - super().__init__(**kwargs) # pragma: no cover - - self._process_connection_params() - self._process_tendermint_params() - - if self.use_grpc: - self.channel = GrpcServerChannel( - self.target_skill_id, - address=self.host, - port=self.port, - logger=self.logger, - ) - else: - self.channel = TcpServerChannel( - self.target_skill_id, - address=self.host, - port=self.port, - logger=self.logger, - ) - - def _process_connection_params(self) -> None: - """ - Process the connection parameters. - - The parameters to process are: - - host - - port - - target_skill_id - """ - self.host = cast(str, self.configuration.config.get("host")) - self.port = cast(int, self.configuration.config.get("port")) - target_skill_id_string = cast( - Optional[str], self.configuration.config.get("target_skill_id") - ) - - if ( - self.host is None or self.port is None or target_skill_id_string is None - ): # pragma: no cover - raise ValueError("host and port and target_skill_id must be set!") - target_skill_id = PublicId.try_from_str(target_skill_id_string) - if target_skill_id is None: # pragma: no cover - raise ValueError("Provided target_skill_id is not a valid public id.") - self.target_skill_id = target_skill_id - - def _process_tendermint_params(self) -> None: - """ - Process the Tendermint parameters. - - In particular, if use_tendermint is False, do nothing. - Else, process the following parameters: - - rpc_laddr: the listening address for RPC communication - - p2p_laddr: the listening address for P2P communication - - p2p_seeds: a comma-separated list of IP addresses and ports - """ - self.use_tendermint = cast( - bool, self.configuration.config.get("use_tendermint") - ) - self.use_grpc = cast(bool, self.configuration.config.get("use_grpc", False)) - - if not self.use_tendermint: - return - tendermint_config = self.configuration.config.get("tendermint_config", {}) - rpc_laddr = cast( - str, tendermint_config.get("rpc_laddr", DEFAULT_RPC_LISTEN_ADDRESS) - ) - p2p_laddr = cast( - str, tendermint_config.get("p2p_laddr", DEFAULT_P2P_LISTEN_ADDRESS) - ) - p2p_seeds = cast(List[str], tendermint_config.get("p2p_seeds", [])) - home = cast(Optional[str], tendermint_config.get("home", None)) - consensus_create_empty_blocks = cast( - bool, tendermint_config.get("consensus_create_empty_blocks", True) - ) - proxy_app = f"{_TCP}{self.host}:{self.port}" - self.params = TendermintParams( - proxy_app, - rpc_laddr, - p2p_laddr, - p2p_seeds, - consensus_create_empty_blocks, - home, - self.use_grpc, - ) - self.logger.debug(f"Tendermint parameters: {self.params}") - self.node = TendermintNode(self.params, self.logger) - - def _ensure_connected(self) -> None: - """Ensure that the connection and the channel are ready.""" - super()._ensure_connected() - - self.channel = cast(Union[TcpServerChannel, GrpcServerChannel], self.channel) - if self.channel.is_stopped: - raise ConnectionError("The channel is stopped.") - - async def connect(self) -> None: - """ - Set up the connection. - - In the implementation, remember to update 'connection_status' accordingly. - """ - if self.is_connected: # pragma: no cover - return - - self.state = ConnectionStates.connecting - self.channel = cast(Union[TcpServerChannel, GrpcServerChannel], self.channel) - if self.use_tendermint: - self.node = cast(TendermintNode, self.node) - self.node.init() - self.node.start() - self.channel.logger = self.logger - await self.channel.connect(loop=self.loop) - if self.channel.is_stopped: # pragma: no cover - self.state = ConnectionStates.disconnected - return - self.state = ConnectionStates.connected - - async def disconnect(self) -> None: - """ - Tear down the connection. - - In the implementation, remember to update 'connection_status' accordingly. - """ - if self.is_disconnected: # pragma: no cover - return - - self.state = ConnectionStates.disconnecting - self.channel = cast(Union[TcpServerChannel, GrpcServerChannel], self.channel) - await self.channel.disconnect() - if self.use_tendermint: - self.node = cast(TendermintNode, self.node) - self.node.stop() - self.state = ConnectionStates.disconnected - - async def send(self, envelope: Envelope) -> None: - """ - Send an envelope. - - :param envelope: the envelope to send. - """ - self._ensure_connected() - self.channel = cast(Union[TcpServerChannel, GrpcServerChannel], self.channel) - await self.channel.send(envelope) - - async def receive(self, *args: Any, **kwargs: Any) -> Optional[Envelope]: - """ - Receive an envelope. Blocking. - - :param args: arguments to receive - :param kwargs: keyword arguments to receive - :return: the envelope received, if present. # noqa: DAR202 - """ - self._ensure_connected() - self.channel = cast(Union[TcpServerChannel, GrpcServerChannel], self.channel) - try: - message = await self.channel.get_message() - return message - except CancelledError: # pragma: no cover - return None diff --git a/trader_old/vendor/valory/connections/abci/connection.yaml b/trader_old/vendor/valory/connections/abci/connection.yaml deleted file mode 100644 index 81e50c09f..000000000 --- a/trader_old/vendor/valory/connections/abci/connection.yaml +++ /dev/null @@ -1,84 +0,0 @@ -name: abci -author: valory -version: 0.1.0 -type: connection -description: connection to wrap communication with an ABCI server. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - Makefile: bafybeibdgarch56r46dfy7x7fouj52nbjpjs4fgtrd3prgtwelowyjan5i - __init__.py: bafybeic2m6f6j42cbfxz3jcwhju2dcbbdcw6xyc7mslq7uk2hwe6ctcugi - check_dependencies.py: bafybeihmhemryyl2iacwwrqebr7us7wx4otvwbdbtckwkl5kxqopidyzwm - connection.py: bafybeidirftkcxgvof3p3zecpxcvn4mska4hyxczgu2sa2imetn6r7xrla - dialogues.py: bafybeibpdsphu5vqjpieczrb3ulhqfcq4l73qnx6j3zhbz4dpunwegboxq - gogoproto/__init__.py: bafybeifmpcbkrpygdt7uvhpq6gaxgskofpczxktoalp2cwyouay46drcke - gogoproto/gogo_pb2.py: bafybeifdutphcruyva7lcngujrcmfsaycyodyfjbgwcrxthiouotl4fxpu - protos/gogoproto/gogo.proto: bafybeieg7yu62cx25ssjgvjnsc2alececsgush6l5adpxuscaf6ksh6dou - protos/tendermint/abci/types.proto: bafybeigimbf3rrfavl2o2jakr5c6dfm652lzxsddcmho7w5ytxo33sgrm4 - protos/tendermint/crypto/keys.proto: bafybeiar5g76sw7wgiyvaczpfgmw2bqkuillti7lnibmmmenz5zdofm6xe - protos/tendermint/crypto/proof.proto: bafybeibunrccs4vfxakjh4vulifko3dd7gl2mmwey42hsqlwsod4xxml6i - protos/tendermint/types/params.proto: bafybeihmrq4mbifdsai3i3yefuqyucsxeuqavhl5ljyofnwueip43w7lqu - protos/tendermint/types/types.proto: bafybeify5f2ja6semnrvtrberwn2pwhr3bvso6dtteif757bdrhnc3djsu - protos/tendermint/types/validator.proto: bafybeihejcuz3m5gm37sscly4azzdc72gng4kcnd7pwlxkjuhabw6yh7jm - protos/tendermint/version/types.proto: bafybeidqxroep4axnt6y6dhdu7et5abmktsswtwajvm32uot5q4wziefnq - readme.md: bafybeierlmc7t4dwpgc3sgmn5m5l3r4fwnwzbf6agna3igndsogk3iqlv4 - scripts/genproto.py: bafybeicfgwktvlrzqwfbvbld6bor3qd2rcfcgmk5rzfcfl6oj3jrr2mequ - tendermint/__init__.py: bafybeifayxyjcebekkn62sucyupfcuwzlj57kuiwafynpw4nrbocqxe6ya - tendermint/abci/types_pb2.py: bafybeidvvklivlllwprj2rh6un45apg773muyjrsq5momcihi2abxioqsi - tendermint/abci/types_pb2_grpc.py: bafybeihmecy4uas7itftoaslrqvrjb3m2jewojuzxvie7pjzsrw5exnu6u - tendermint/crypto/keys_pb2.py: bafybeiamkizmrn7txfboyrqqdara7n6ix5pbfh4evc3xedeva65snmlfhe - tendermint/crypto/proof_pb2.py: bafybeie7zueijrsuzldcol7dkcd2udupbof6nm73zm6zzkkin6teauan2m - tendermint/types/params_pb2.py: bafybeifblynzqqhyuvwjzgz33izwi5fl6fqabyiuwspasdlkw32xhltxq4 - tendermint/types/types_pb2.py: bafybeiad3gl7a3o4aewrcxfg5qpmjgtpeobcvb5knjxofwo7jjiimeb4m4 - tendermint/types/validator_pb2.py: bafybeibdhuvir43t4he337ajwe6sk7suhzxgdxyk2i6neoonoxfjqtqd6q - tendermint/version/types_pb2.py: bafybeib7ucwdh2oqbprdjskfofjkidf3odpj34zwicckkze6esx2zlsdaq - tendermint_decoder.py: bafybeig3teywhof2vztwaiqj36nx5bv6fysxzmu7i5ewqxa2w7rdf3wa7i - tendermint_encoder.py: bafybeibpnofkac6jizpbezlo7rdsbijloovsuz5rjysshjrims7x44wxv4 - tests/__init__.py: bafybeiaca7l7u423yejqpbbkyvrkrhog2zqpmtbvrga6bjou3yogj4bina - tests/helper.py: bafybeidahgf7lfoachhqliysh6uxc3prjl3yweicay4tkjsqwkxt67lphu - tests/test_abci.py: bafybeia4pw67do72gzc66kz23yzllnspbzqrtd5c5muqxhol27ipjjscxa - tests/test_abci_fuzz.py: bafybeiddeye3fbgefihbgdhqwwuv3dlseo6d5kt3jpixpq45bewm5dep2u - tests/test_abci_spec.py: bafybeifacnizp2mryyb2j64iugnxn5rhtx7xr4emwbw5xcke6le6utpwhu - tests/test_fuzz/__init__.py: bafybeiggaobawdxpx2j637ldmacq7r7tnyeygukmjuayodj3vytdyqsjze - tests/test_fuzz/base.py: bafybeifcv7r4dk7dfw726r3dy42s6mozb5yk4mmhml5i3hpu653odax7bq - tests/test_fuzz/mock_node/__init__.py: bafybeibt3bm4l3wethryy564mzcbhqmnztsbko4c5bt5ila5ghq2e7vz7u - tests/test_fuzz/mock_node/channels/__init__.py: bafybeifjjnlxtqd4pz76aq6w642n5d6pa635ehkhjxgzyjidakza27adja - tests/test_fuzz/mock_node/channels/base.py: bafybeicsirvtetuxnophhibjlzeos4bwtchhxr76v4k4ajsht6vrsqb5ni - tests/test_fuzz/mock_node/channels/grpc_channel.py: bafybeidita6lkds4urwrt3jwpou22js7ngruoof7kynuhkultdytx5taua - tests/test_fuzz/mock_node/channels/tcp_channel.py: bafybeiehlihhp7itiypkilugorwa2rytz2fm3awkm7vhti5p2v7fcvvajq - tests/test_fuzz/mock_node/node.py: bafybeiakzuvng5elaws6mv246o2nrjitdvjr7j5ltrhxscpezybbsyzh3i - tests/test_fuzz/test_fuzz.py: bafybeihfsayqmhajvhthvirxicd4swpe32u2gohe7sq5ixjuygico6wzge - tests/test_tendermint_decoder.py: bafybeihogt3aopyln5newihm3rbiqimoc4aw6za2cngplnjnwatv6nakea - tests/test_tendermint_encoder.py: bafybeigpun2ybwr5tu7b52his3b5apyrlmdytlgofcszbctsmmabo3sjg4 - version.txt: bafybeifjb44fd7qve2ku62ythui6z4mvd4k7qkjomlcdnl3ymb3bnq6xee -fingerprint_ignore_patterns: [] -build_entrypoint: check_dependencies.py -connections: [] -protocols: -- valory/abci:0.1.0:bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u -class_name: ABCIServerConnection -config: - host: 127.0.0.1 - port: 26658 - target_skill_id: null - tendermint_config: - p2p_laddr: tcp://0.0.0.0:26656 - p2p_seeds: [] - rpc_laddr: tcp://127.0.0.1:26657 - home: null - consensus_create_empty_blocks: true - use_grpc: false - use_tendermint: true -excluded_protocols: [] -restricted_to_protocols: [] -dependencies: - grpcio: - version: ==1.53.0 - hypothesis: - version: ==6.21.6 - open-aea-test-autonomy: - version: ==0.14.14.post1 - protobuf: - version: <4.25.0,>=4.21.6 -is_abstract: false -cert_requests: [] diff --git a/trader_old/vendor/valory/connections/abci/dialogues.py b/trader_old/vendor/valory/connections/abci/dialogues.py deleted file mode 100644 index 9fc60a3ac..000000000 --- a/trader_old/vendor/valory/connections/abci/dialogues.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ -"""Dialogues classes for the ABCI connection.""" - -from typing import Any - -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue - -from packages.valory.protocols.abci.dialogues import AbciDialogue as BaseAbciDialogue -from packages.valory.protocols.abci.dialogues import AbciDialogues as BaseAbciDialogues - - -AbciDialogue = BaseAbciDialogue - - -class AbciDialogues(BaseAbciDialogues): - """The dialogues class keeps track of all ABCI dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.CLIENT - - BaseAbciDialogues.__init__( - self, - self_address=str(kwargs.pop("connection_id")), - role_from_first_message=role_from_first_message, - dialogue_class=AbciDialogue, - ) diff --git a/trader_old/vendor/valory/connections/abci/gogoproto/__init__.py b/trader_old/vendor/valory/connections/abci/gogoproto/__init__.py deleted file mode 100644 index a2b9f1c4a..000000000 --- a/trader_old/vendor/valory/connections/abci/gogoproto/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the Protobuf Python modules for Gogoproto.""" # pragma: nocover diff --git a/trader_old/vendor/valory/connections/abci/gogoproto/gogo_pb2.py b/trader_old/vendor/valory/connections/abci/gogoproto/gogo_pb2.py deleted file mode 100644 index e02509ae4..000000000 --- a/trader_old/vendor/valory/connections/abci/gogoproto/gogo_pb2.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: gogoproto/gogo.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x14gogoproto/gogo.proto\x12\tgogoproto\x1a google/protobuf/descriptor.proto:;\n\x13goproto_enum_prefix\x12\x1c.google.protobuf.EnumOptions\x18\xb1\xe4\x03 \x01(\x08:=\n\x15goproto_enum_stringer\x12\x1c.google.protobuf.EnumOptions\x18\xc5\xe4\x03 \x01(\x08:5\n\renum_stringer\x12\x1c.google.protobuf.EnumOptions\x18\xc6\xe4\x03 \x01(\x08:7\n\x0f\x65num_customname\x12\x1c.google.protobuf.EnumOptions\x18\xc7\xe4\x03 \x01(\t:0\n\x08\x65numdecl\x12\x1c.google.protobuf.EnumOptions\x18\xc8\xe4\x03 \x01(\x08:A\n\x14\x65numvalue_customname\x12!.google.protobuf.EnumValueOptions\x18\xd1\x83\x04 \x01(\t:;\n\x13goproto_getters_all\x12\x1c.google.protobuf.FileOptions\x18\x99\xec\x03 \x01(\x08:?\n\x17goproto_enum_prefix_all\x12\x1c.google.protobuf.FileOptions\x18\x9a\xec\x03 \x01(\x08:<\n\x14goproto_stringer_all\x12\x1c.google.protobuf.FileOptions\x18\x9b\xec\x03 \x01(\x08:9\n\x11verbose_equal_all\x12\x1c.google.protobuf.FileOptions\x18\x9c\xec\x03 \x01(\x08:0\n\x08\x66\x61\x63\x65_all\x12\x1c.google.protobuf.FileOptions\x18\x9d\xec\x03 \x01(\x08:4\n\x0cgostring_all\x12\x1c.google.protobuf.FileOptions\x18\x9e\xec\x03 \x01(\x08:4\n\x0cpopulate_all\x12\x1c.google.protobuf.FileOptions\x18\x9f\xec\x03 \x01(\x08:4\n\x0cstringer_all\x12\x1c.google.protobuf.FileOptions\x18\xa0\xec\x03 \x01(\x08:3\n\x0bonlyone_all\x12\x1c.google.protobuf.FileOptions\x18\xa1\xec\x03 \x01(\x08:1\n\tequal_all\x12\x1c.google.protobuf.FileOptions\x18\xa5\xec\x03 \x01(\x08:7\n\x0f\x64\x65scription_all\x12\x1c.google.protobuf.FileOptions\x18\xa6\xec\x03 \x01(\x08:3\n\x0btestgen_all\x12\x1c.google.protobuf.FileOptions\x18\xa7\xec\x03 \x01(\x08:4\n\x0c\x62\x65nchgen_all\x12\x1c.google.protobuf.FileOptions\x18\xa8\xec\x03 \x01(\x08:5\n\rmarshaler_all\x12\x1c.google.protobuf.FileOptions\x18\xa9\xec\x03 \x01(\x08:7\n\x0funmarshaler_all\x12\x1c.google.protobuf.FileOptions\x18\xaa\xec\x03 \x01(\x08:<\n\x14stable_marshaler_all\x12\x1c.google.protobuf.FileOptions\x18\xab\xec\x03 \x01(\x08:1\n\tsizer_all\x12\x1c.google.protobuf.FileOptions\x18\xac\xec\x03 \x01(\x08:A\n\x19goproto_enum_stringer_all\x12\x1c.google.protobuf.FileOptions\x18\xad\xec\x03 \x01(\x08:9\n\x11\x65num_stringer_all\x12\x1c.google.protobuf.FileOptions\x18\xae\xec\x03 \x01(\x08:<\n\x14unsafe_marshaler_all\x12\x1c.google.protobuf.FileOptions\x18\xaf\xec\x03 \x01(\x08:>\n\x16unsafe_unmarshaler_all\x12\x1c.google.protobuf.FileOptions\x18\xb0\xec\x03 \x01(\x08:B\n\x1agoproto_extensions_map_all\x12\x1c.google.protobuf.FileOptions\x18\xb1\xec\x03 \x01(\x08:@\n\x18goproto_unrecognized_all\x12\x1c.google.protobuf.FileOptions\x18\xb2\xec\x03 \x01(\x08:8\n\x10gogoproto_import\x12\x1c.google.protobuf.FileOptions\x18\xb3\xec\x03 \x01(\x08:6\n\x0eprotosizer_all\x12\x1c.google.protobuf.FileOptions\x18\xb4\xec\x03 \x01(\x08:3\n\x0b\x63ompare_all\x12\x1c.google.protobuf.FileOptions\x18\xb5\xec\x03 \x01(\x08:4\n\x0ctypedecl_all\x12\x1c.google.protobuf.FileOptions\x18\xb6\xec\x03 \x01(\x08:4\n\x0c\x65numdecl_all\x12\x1c.google.protobuf.FileOptions\x18\xb7\xec\x03 \x01(\x08:<\n\x14goproto_registration\x12\x1c.google.protobuf.FileOptions\x18\xb8\xec\x03 \x01(\x08:7\n\x0fmessagename_all\x12\x1c.google.protobuf.FileOptions\x18\xb9\xec\x03 \x01(\x08:=\n\x15goproto_sizecache_all\x12\x1c.google.protobuf.FileOptions\x18\xba\xec\x03 \x01(\x08:;\n\x13goproto_unkeyed_all\x12\x1c.google.protobuf.FileOptions\x18\xbb\xec\x03 \x01(\x08::\n\x0fgoproto_getters\x12\x1f.google.protobuf.MessageOptions\x18\x81\xf4\x03 \x01(\x08:;\n\x10goproto_stringer\x12\x1f.google.protobuf.MessageOptions\x18\x83\xf4\x03 \x01(\x08:8\n\rverbose_equal\x12\x1f.google.protobuf.MessageOptions\x18\x84\xf4\x03 \x01(\x08:/\n\x04\x66\x61\x63\x65\x12\x1f.google.protobuf.MessageOptions\x18\x85\xf4\x03 \x01(\x08:3\n\x08gostring\x12\x1f.google.protobuf.MessageOptions\x18\x86\xf4\x03 \x01(\x08:3\n\x08populate\x12\x1f.google.protobuf.MessageOptions\x18\x87\xf4\x03 \x01(\x08:3\n\x08stringer\x12\x1f.google.protobuf.MessageOptions\x18\xc0\x8b\x04 \x01(\x08:2\n\x07onlyone\x12\x1f.google.protobuf.MessageOptions\x18\x89\xf4\x03 \x01(\x08:0\n\x05\x65qual\x12\x1f.google.protobuf.MessageOptions\x18\x8d\xf4\x03 \x01(\x08:6\n\x0b\x64\x65scription\x12\x1f.google.protobuf.MessageOptions\x18\x8e\xf4\x03 \x01(\x08:2\n\x07testgen\x12\x1f.google.protobuf.MessageOptions\x18\x8f\xf4\x03 \x01(\x08:3\n\x08\x62\x65nchgen\x12\x1f.google.protobuf.MessageOptions\x18\x90\xf4\x03 \x01(\x08:4\n\tmarshaler\x12\x1f.google.protobuf.MessageOptions\x18\x91\xf4\x03 \x01(\x08:6\n\x0bunmarshaler\x12\x1f.google.protobuf.MessageOptions\x18\x92\xf4\x03 \x01(\x08:;\n\x10stable_marshaler\x12\x1f.google.protobuf.MessageOptions\x18\x93\xf4\x03 \x01(\x08:0\n\x05sizer\x12\x1f.google.protobuf.MessageOptions\x18\x94\xf4\x03 \x01(\x08:;\n\x10unsafe_marshaler\x12\x1f.google.protobuf.MessageOptions\x18\x97\xf4\x03 \x01(\x08:=\n\x12unsafe_unmarshaler\x12\x1f.google.protobuf.MessageOptions\x18\x98\xf4\x03 \x01(\x08:A\n\x16goproto_extensions_map\x12\x1f.google.protobuf.MessageOptions\x18\x99\xf4\x03 \x01(\x08:?\n\x14goproto_unrecognized\x12\x1f.google.protobuf.MessageOptions\x18\x9a\xf4\x03 \x01(\x08:5\n\nprotosizer\x12\x1f.google.protobuf.MessageOptions\x18\x9c\xf4\x03 \x01(\x08:2\n\x07\x63ompare\x12\x1f.google.protobuf.MessageOptions\x18\x9d\xf4\x03 \x01(\x08:3\n\x08typedecl\x12\x1f.google.protobuf.MessageOptions\x18\x9e\xf4\x03 \x01(\x08:6\n\x0bmessagename\x12\x1f.google.protobuf.MessageOptions\x18\xa1\xf4\x03 \x01(\x08:<\n\x11goproto_sizecache\x12\x1f.google.protobuf.MessageOptions\x18\xa2\xf4\x03 \x01(\x08::\n\x0fgoproto_unkeyed\x12\x1f.google.protobuf.MessageOptions\x18\xa3\xf4\x03 \x01(\x08:1\n\x08nullable\x12\x1d.google.protobuf.FieldOptions\x18\xe9\xfb\x03 \x01(\x08:.\n\x05\x65mbed\x12\x1d.google.protobuf.FieldOptions\x18\xea\xfb\x03 \x01(\x08:3\n\ncustomtype\x12\x1d.google.protobuf.FieldOptions\x18\xeb\xfb\x03 \x01(\t:3\n\ncustomname\x12\x1d.google.protobuf.FieldOptions\x18\xec\xfb\x03 \x01(\t:0\n\x07jsontag\x12\x1d.google.protobuf.FieldOptions\x18\xed\xfb\x03 \x01(\t:1\n\x08moretags\x12\x1d.google.protobuf.FieldOptions\x18\xee\xfb\x03 \x01(\t:1\n\x08\x63\x61sttype\x12\x1d.google.protobuf.FieldOptions\x18\xef\xfb\x03 \x01(\t:0\n\x07\x63\x61stkey\x12\x1d.google.protobuf.FieldOptions\x18\xf0\xfb\x03 \x01(\t:2\n\tcastvalue\x12\x1d.google.protobuf.FieldOptions\x18\xf1\xfb\x03 \x01(\t:0\n\x07stdtime\x12\x1d.google.protobuf.FieldOptions\x18\xf2\xfb\x03 \x01(\x08:4\n\x0bstdduration\x12\x1d.google.protobuf.FieldOptions\x18\xf3\xfb\x03 \x01(\x08:3\n\nwktpointer\x12\x1d.google.protobuf.FieldOptions\x18\xf4\xfb\x03 \x01(\x08\x42\x45\n\x13\x63om.google.protobufB\nGoGoProtosZ"github.com/gogo/protobuf/gogoproto' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "gogoproto.gogo_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b'\n\023com.google.protobufB\nGoGoProtosZ"github.com/gogo/protobuf/gogoproto' - ) -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/connections/abci/protos/gogoproto/gogo.proto b/trader_old/vendor/valory/connections/abci/protos/gogoproto/gogo.proto deleted file mode 100644 index b80c85653..000000000 --- a/trader_old/vendor/valory/connections/abci/protos/gogoproto/gogo.proto +++ /dev/null @@ -1,144 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto2"; -package gogoproto; - -import "google/protobuf/descriptor.proto"; - -option java_package = "com.google.protobuf"; -option java_outer_classname = "GoGoProtos"; -option go_package = "github.com/gogo/protobuf/gogoproto"; - -extend google.protobuf.EnumOptions { - optional bool goproto_enum_prefix = 62001; - optional bool goproto_enum_stringer = 62021; - optional bool enum_stringer = 62022; - optional string enum_customname = 62023; - optional bool enumdecl = 62024; -} - -extend google.protobuf.EnumValueOptions { - optional string enumvalue_customname = 66001; -} - -extend google.protobuf.FileOptions { - optional bool goproto_getters_all = 63001; - optional bool goproto_enum_prefix_all = 63002; - optional bool goproto_stringer_all = 63003; - optional bool verbose_equal_all = 63004; - optional bool face_all = 63005; - optional bool gostring_all = 63006; - optional bool populate_all = 63007; - optional bool stringer_all = 63008; - optional bool onlyone_all = 63009; - - optional bool equal_all = 63013; - optional bool description_all = 63014; - optional bool testgen_all = 63015; - optional bool benchgen_all = 63016; - optional bool marshaler_all = 63017; - optional bool unmarshaler_all = 63018; - optional bool stable_marshaler_all = 63019; - - optional bool sizer_all = 63020; - - optional bool goproto_enum_stringer_all = 63021; - optional bool enum_stringer_all = 63022; - - optional bool unsafe_marshaler_all = 63023; - optional bool unsafe_unmarshaler_all = 63024; - - optional bool goproto_extensions_map_all = 63025; - optional bool goproto_unrecognized_all = 63026; - optional bool gogoproto_import = 63027; - optional bool protosizer_all = 63028; - optional bool compare_all = 63029; - optional bool typedecl_all = 63030; - optional bool enumdecl_all = 63031; - - optional bool goproto_registration = 63032; - optional bool messagename_all = 63033; - - optional bool goproto_sizecache_all = 63034; - optional bool goproto_unkeyed_all = 63035; -} - -extend google.protobuf.MessageOptions { - optional bool goproto_getters = 64001; - optional bool goproto_stringer = 64003; - optional bool verbose_equal = 64004; - optional bool face = 64005; - optional bool gostring = 64006; - optional bool populate = 64007; - optional bool stringer = 67008; - optional bool onlyone = 64009; - - optional bool equal = 64013; - optional bool description = 64014; - optional bool testgen = 64015; - optional bool benchgen = 64016; - optional bool marshaler = 64017; - optional bool unmarshaler = 64018; - optional bool stable_marshaler = 64019; - - optional bool sizer = 64020; - - optional bool unsafe_marshaler = 64023; - optional bool unsafe_unmarshaler = 64024; - - optional bool goproto_extensions_map = 64025; - optional bool goproto_unrecognized = 64026; - - optional bool protosizer = 64028; - optional bool compare = 64029; - - optional bool typedecl = 64030; - - optional bool messagename = 64033; - - optional bool goproto_sizecache = 64034; - optional bool goproto_unkeyed = 64035; -} - -extend google.protobuf.FieldOptions { - optional bool nullable = 65001; - optional bool embed = 65002; - optional string customtype = 65003; - optional string customname = 65004; - optional string jsontag = 65005; - optional string moretags = 65006; - optional string casttype = 65007; - optional string castkey = 65008; - optional string castvalue = 65009; - - optional bool stdtime = 65010; - optional bool stdduration = 65011; - optional bool wktpointer = 65012; - -} diff --git a/trader_old/vendor/valory/connections/abci/protos/tendermint/abci/types.proto b/trader_old/vendor/valory/connections/abci/protos/tendermint/abci/types.proto deleted file mode 100644 index 8e3a90936..000000000 --- a/trader_old/vendor/valory/connections/abci/protos/tendermint/abci/types.proto +++ /dev/null @@ -1,407 +0,0 @@ -syntax = "proto3"; -package tendermint.abci; - -option go_package = "github.com/tendermint/tendermint/abci/types"; - -// For more information on gogo.proto, see: -// https://github.com/gogo/protobuf/blob/master/extensions.md -import "tendermint/crypto/proof.proto"; -import "tendermint/types/types.proto"; -import "tendermint/crypto/keys.proto"; -import "tendermint/types/params.proto"; -import "google/protobuf/timestamp.proto"; -import "gogoproto/gogo.proto"; - -// This file is copied from http://github.com/tendermint/abci -// NOTE: When using custom types, mind the warnings. -// https://github.com/gogo/protobuf/blob/master/custom_types.md#warnings-and-issues - -//---------------------------------------- -// Request types - -message Request { - oneof value { - RequestEcho echo = 1; - RequestFlush flush = 2; - RequestInfo info = 3; - RequestSetOption set_option = 4; - RequestInitChain init_chain = 5; - RequestQuery query = 6; - RequestBeginBlock begin_block = 7; - RequestCheckTx check_tx = 8; - RequestDeliverTx deliver_tx = 9; - RequestEndBlock end_block = 10; - RequestCommit commit = 11; - RequestListSnapshots list_snapshots = 12; - RequestOfferSnapshot offer_snapshot = 13; - RequestLoadSnapshotChunk load_snapshot_chunk = 14; - RequestApplySnapshotChunk apply_snapshot_chunk = 15; - } -} - -message RequestEcho { - string message = 1; -} - -message RequestFlush {} - -message RequestInfo { - string version = 1; - uint64 block_version = 2; - uint64 p2p_version = 3; -} - -// nondeterministic -message RequestSetOption { - string key = 1; - string value = 2; -} - -message RequestInitChain { - google.protobuf.Timestamp time = 1 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - string chain_id = 2; - ConsensusParams consensus_params = 3; - repeated ValidatorUpdate validators = 4 [(gogoproto.nullable) = false]; - bytes app_state_bytes = 5; - int64 initial_height = 6; -} - -message RequestQuery { - bytes data = 1; - string path = 2; - int64 height = 3; - bool prove = 4; -} - -message RequestBeginBlock { - bytes hash = 1; - tendermint.types.Header header = 2 [(gogoproto.nullable) = false]; - LastCommitInfo last_commit_info = 3 [(gogoproto.nullable) = false]; - repeated Evidence byzantine_validators = 4 [(gogoproto.nullable) = false]; -} - -enum CheckTxType { - NEW = 0 [(gogoproto.enumvalue_customname) = "New"]; - RECHECK = 1 [(gogoproto.enumvalue_customname) = "Recheck"]; -} - -message RequestCheckTx { - bytes tx = 1; - CheckTxType type = 2; -} - -message RequestDeliverTx { - bytes tx = 1; -} - -message RequestEndBlock { - int64 height = 1; -} - -message RequestCommit {} - -// lists available snapshots -message RequestListSnapshots { -} - -// offers a snapshot to the application -message RequestOfferSnapshot { - Snapshot snapshot = 1; // snapshot offered by peers - bytes app_hash = 2; // light client-verified app hash for snapshot height -} - -// loads a snapshot chunk -message RequestLoadSnapshotChunk { - uint64 height = 1; - uint32 format = 2; - uint32 chunk = 3; -} - -// Applies a snapshot chunk -message RequestApplySnapshotChunk { - uint32 index = 1; - bytes chunk = 2; - string sender = 3; -} - -//---------------------------------------- -// Response types - -message Response { - oneof value { - ResponseException exception = 1; - ResponseEcho echo = 2; - ResponseFlush flush = 3; - ResponseInfo info = 4; - ResponseSetOption set_option = 5; - ResponseInitChain init_chain = 6; - ResponseQuery query = 7; - ResponseBeginBlock begin_block = 8; - ResponseCheckTx check_tx = 9; - ResponseDeliverTx deliver_tx = 10; - ResponseEndBlock end_block = 11; - ResponseCommit commit = 12; - ResponseListSnapshots list_snapshots = 13; - ResponseOfferSnapshot offer_snapshot = 14; - ResponseLoadSnapshotChunk load_snapshot_chunk = 15; - ResponseApplySnapshotChunk apply_snapshot_chunk = 16; - } -} - -// nondeterministic -message ResponseException { - string error = 1; -} - -message ResponseEcho { - string message = 1; -} - -message ResponseFlush {} - -message ResponseInfo { - string data = 1; - - string version = 2; - uint64 app_version = 3; - - int64 last_block_height = 4; - bytes last_block_app_hash = 5; -} - -// nondeterministic -message ResponseSetOption { - uint32 code = 1; - // bytes data = 2; - string log = 3; - string info = 4; -} - -message ResponseInitChain { - ConsensusParams consensus_params = 1; - repeated ValidatorUpdate validators = 2 [(gogoproto.nullable) = false]; - bytes app_hash = 3; -} - -message ResponseQuery { - uint32 code = 1; - // bytes data = 2; // use "value" instead. - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 index = 5; - bytes key = 6; - bytes value = 7; - tendermint.crypto.ProofOps proof_ops = 8; - int64 height = 9; - string codespace = 10; -} - -message ResponseBeginBlock { - repeated Event events = 1 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; -} - -message ResponseCheckTx { - uint32 code = 1; - bytes data = 2; - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 gas_wanted = 5 [json_name = "gas_wanted"]; - int64 gas_used = 6 [json_name = "gas_used"]; - repeated Event events = 7 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; - string codespace = 8; -} - -message ResponseDeliverTx { - uint32 code = 1; - bytes data = 2; - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 gas_wanted = 5 [json_name = "gas_wanted"]; - int64 gas_used = 6 [json_name = "gas_used"]; - repeated Event events = 7 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; // nondeterministic - string codespace = 8; -} - -message ResponseEndBlock { - repeated ValidatorUpdate validator_updates = 1 - [(gogoproto.nullable) = false]; - ConsensusParams consensus_param_updates = 2; - repeated Event events = 3 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; -} - -message ResponseCommit { - // reserve 1 - bytes data = 2; - int64 retain_height = 3; -} - -message ResponseListSnapshots { - repeated Snapshot snapshots = 1; -} - -message ResponseOfferSnapshot { - Result result = 1; - - enum Result { - UNKNOWN = 0; // Unknown result, abort all snapshot restoration - ACCEPT = 1; // Snapshot accepted, apply chunks - ABORT = 2; // Abort all snapshot restoration - REJECT = 3; // Reject this specific snapshot, try others - REJECT_FORMAT = 4; // Reject all snapshots of this format, try others - REJECT_SENDER = 5; // Reject all snapshots from the sender(s), try others - } -} - -message ResponseLoadSnapshotChunk { - bytes chunk = 1; -} - -message ResponseApplySnapshotChunk { - Result result = 1; - repeated uint32 refetch_chunks = 2; // Chunks to refetch and reapply - repeated string reject_senders = 3; // Chunk senders to reject and ban - - enum Result { - UNKNOWN = 0; // Unknown result, abort all snapshot restoration - ACCEPT = 1; // Chunk successfully accepted - ABORT = 2; // Abort all snapshot restoration - RETRY = 3; // Retry chunk (combine with refetch and reject) - RETRY_SNAPSHOT = 4; // Retry snapshot (combine with refetch and reject) - REJECT_SNAPSHOT = 5; // Reject this snapshot, try others - } -} - -//---------------------------------------- -// Misc. - -// ConsensusParams contains all consensus-relevant parameters -// that can be adjusted by the abci app -message ConsensusParams { - BlockParams block = 1; - tendermint.types.EvidenceParams evidence = 2; - tendermint.types.ValidatorParams validator = 3; - tendermint.types.VersionParams version = 4; -} - -// BlockParams contains limits on the block size. -message BlockParams { - // Note: must be greater than 0 - int64 max_bytes = 1; - // Note: must be greater or equal to -1 - int64 max_gas = 2; -} - -message LastCommitInfo { - int32 round = 1; - repeated VoteInfo votes = 2 [(gogoproto.nullable) = false]; -} - -// Event allows application developers to attach additional information to -// ResponseBeginBlock, ResponseEndBlock, ResponseCheckTx and ResponseDeliverTx. -// Later, transactions may be queried using these events. -message Event { - string type = 1; - repeated EventAttribute attributes = 2 [ - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "attributes,omitempty" - ]; -} - -// EventAttribute is a single key-value pair, associated with an event. -message EventAttribute { - bytes key = 1; - bytes value = 2; - bool index = 3; // nondeterministic -} - -// TxResult contains results of executing the transaction. -// -// One usage is indexing transaction results. -message TxResult { - int64 height = 1; - uint32 index = 2; - bytes tx = 3; - ResponseDeliverTx result = 4 [(gogoproto.nullable) = false]; -} - -//---------------------------------------- -// Blockchain Types - -// Validator -message Validator { - bytes address = 1; // The first 20 bytes of SHA256(public key) - // PubKey pub_key = 2 [(gogoproto.nullable)=false]; - int64 power = 3; // The voting power -} - -// ValidatorUpdate -message ValidatorUpdate { - tendermint.crypto.PublicKey pub_key = 1 [(gogoproto.nullable) = false]; - int64 power = 2; -} - -// VoteInfo -message VoteInfo { - Validator validator = 1 [(gogoproto.nullable) = false]; - bool signed_last_block = 2; -} - -enum EvidenceType { - UNKNOWN = 0; - DUPLICATE_VOTE = 1; - LIGHT_CLIENT_ATTACK = 2; -} - -message Evidence { - EvidenceType type = 1; - // The offending validator - Validator validator = 2 [(gogoproto.nullable) = false]; - // The height when the offense occurred - int64 height = 3; - // The corresponding time where the offense occurred - google.protobuf.Timestamp time = 4 [ - (gogoproto.nullable) = false, - (gogoproto.stdtime) = true - ]; - // Total voting power of the validator set in case the ABCI application does - // not store historical validators. - // https://github.com/tendermint/tendermint/issues/4581 - int64 total_voting_power = 5; -} - -//---------------------------------------- -// State Sync Types - -message Snapshot { - uint64 height = 1; // The height at which the snapshot was taken - uint32 format = 2; // The application-specific snapshot format - uint32 chunks = 3; // Number of chunks in the snapshot - bytes hash = 4; // Arbitrary snapshot hash, equal only if identical - bytes metadata = 5; // Arbitrary application metadata -} - -//---------------------------------------- -// Service Definition - -service ABCIApplication { - rpc Echo(RequestEcho) returns (ResponseEcho); - rpc Flush(RequestFlush) returns (ResponseFlush); - rpc Info(RequestInfo) returns (ResponseInfo); - rpc SetOption(RequestSetOption) returns (ResponseSetOption); - rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx); - rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); - rpc Query(RequestQuery) returns (ResponseQuery); - rpc Commit(RequestCommit) returns (ResponseCommit); - rpc InitChain(RequestInitChain) returns (ResponseInitChain); - rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock); - rpc EndBlock(RequestEndBlock) returns (ResponseEndBlock); - rpc ListSnapshots(RequestListSnapshots) returns (ResponseListSnapshots); - rpc OfferSnapshot(RequestOfferSnapshot) returns (ResponseOfferSnapshot); - rpc LoadSnapshotChunk(RequestLoadSnapshotChunk) returns (ResponseLoadSnapshotChunk); - rpc ApplySnapshotChunk(RequestApplySnapshotChunk) returns (ResponseApplySnapshotChunk); -} diff --git a/trader_old/vendor/valory/connections/abci/protos/tendermint/crypto/keys.proto b/trader_old/vendor/valory/connections/abci/protos/tendermint/crypto/keys.proto deleted file mode 100644 index 16fd7adf3..000000000 --- a/trader_old/vendor/valory/connections/abci/protos/tendermint/crypto/keys.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; -package tendermint.crypto; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; - -import "gogoproto/gogo.proto"; - -// PublicKey defines the keys available for use with Tendermint Validators -message PublicKey { - option (gogoproto.compare) = true; - option (gogoproto.equal) = true; - - oneof sum { - bytes ed25519 = 1; - bytes secp256k1 = 2; - } -} diff --git a/trader_old/vendor/valory/connections/abci/protos/tendermint/crypto/proof.proto b/trader_old/vendor/valory/connections/abci/protos/tendermint/crypto/proof.proto deleted file mode 100644 index 975df7685..000000000 --- a/trader_old/vendor/valory/connections/abci/protos/tendermint/crypto/proof.proto +++ /dev/null @@ -1,41 +0,0 @@ -syntax = "proto3"; -package tendermint.crypto; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; - -import "gogoproto/gogo.proto"; - -message Proof { - int64 total = 1; - int64 index = 2; - bytes leaf_hash = 3; - repeated bytes aunts = 4; -} - -message ValueOp { - // Encoded in ProofOp.Key. - bytes key = 1; - - // To encode in ProofOp.Data - Proof proof = 2; -} - -message DominoOp { - string key = 1; - string input = 2; - string output = 3; -} - -// ProofOp defines an operation used for calculating Merkle root -// The data could be arbitrary format, providing nessecary data -// for example neighbouring node hash -message ProofOp { - string type = 1; - bytes key = 2; - bytes data = 3; -} - -// ProofOps is Merkle proof defined by the list of ProofOps -message ProofOps { - repeated ProofOp ops = 1 [(gogoproto.nullable) = false]; -} diff --git a/trader_old/vendor/valory/connections/abci/protos/tendermint/types/params.proto b/trader_old/vendor/valory/connections/abci/protos/tendermint/types/params.proto deleted file mode 100644 index 0de7d846f..000000000 --- a/trader_old/vendor/valory/connections/abci/protos/tendermint/types/params.proto +++ /dev/null @@ -1,80 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/duration.proto"; - -option (gogoproto.equal_all) = true; - -// ConsensusParams contains consensus critical parameters that determine the -// validity of blocks. -message ConsensusParams { - BlockParams block = 1 [(gogoproto.nullable) = false]; - EvidenceParams evidence = 2 [(gogoproto.nullable) = false]; - ValidatorParams validator = 3 [(gogoproto.nullable) = false]; - VersionParams version = 4 [(gogoproto.nullable) = false]; -} - -// BlockParams contains limits on the block size. -message BlockParams { - // Max block size, in bytes. - // Note: must be greater than 0 - int64 max_bytes = 1; - // Max gas per block. - // Note: must be greater or equal to -1 - int64 max_gas = 2; - // Minimum time increment between consecutive blocks (in milliseconds) If the - // block header timestamp is ahead of the system clock, decrease this value. - // - // Not exposed to the application. - int64 time_iota_ms = 3; -} - -// EvidenceParams determine how we handle evidence of malfeasance. -message EvidenceParams { - // Max age of evidence, in blocks. - // - // The basic formula for calculating this is: MaxAgeDuration / {average block - // time}. - int64 max_age_num_blocks = 1; - - // Max age of evidence, in time. - // - // It should correspond with an app's "unbonding period" or other similar - // mechanism for handling [Nothing-At-Stake - // attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed). - google.protobuf.Duration max_age_duration = 2 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - - // This sets the maximum size of total evidence in bytes that can be committed in a single block. - // and should fall comfortably under the max block bytes. - // Default is 1048576 or 1MB - int64 max_bytes = 3; -} - -// ValidatorParams restrict the public key types validators can use. -// NOTE: uses ABCI pubkey naming, not Amino names. -message ValidatorParams { - option (gogoproto.populate) = true; - option (gogoproto.equal) = true; - - repeated string pub_key_types = 1; -} - -// VersionParams contains the ABCI application version. -message VersionParams { - option (gogoproto.populate) = true; - option (gogoproto.equal) = true; - - uint64 app_version = 1; -} - -// HashedParams is a subset of ConsensusParams. -// -// It is hashed into the Header.ConsensusHash. -message HashedParams { - int64 block_max_bytes = 1; - int64 block_max_gas = 2; -} diff --git a/trader_old/vendor/valory/connections/abci/protos/tendermint/types/types.proto b/trader_old/vendor/valory/connections/abci/protos/tendermint/types/types.proto deleted file mode 100644 index 7f7ea74ca..000000000 --- a/trader_old/vendor/valory/connections/abci/protos/tendermint/types/types.proto +++ /dev/null @@ -1,157 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; -import "tendermint/crypto/proof.proto"; -import "tendermint/version/types.proto"; -import "tendermint/types/validator.proto"; - -// BlockIdFlag indicates which BlcokID the signature is for -enum BlockIDFlag { - option (gogoproto.goproto_enum_stringer) = true; - option (gogoproto.goproto_enum_prefix) = false; - - BLOCK_ID_FLAG_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "BlockIDFlagUnknown"]; - BLOCK_ID_FLAG_ABSENT = 1 [(gogoproto.enumvalue_customname) = "BlockIDFlagAbsent"]; - BLOCK_ID_FLAG_COMMIT = 2 [(gogoproto.enumvalue_customname) = "BlockIDFlagCommit"]; - BLOCK_ID_FLAG_NIL = 3 [(gogoproto.enumvalue_customname) = "BlockIDFlagNil"]; -} - -// SignedMsgType is a type of signed message in the consensus. -enum SignedMsgType { - option (gogoproto.goproto_enum_stringer) = true; - option (gogoproto.goproto_enum_prefix) = false; - - SIGNED_MSG_TYPE_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "UnknownType"]; - // Votes - SIGNED_MSG_TYPE_PREVOTE = 1 [(gogoproto.enumvalue_customname) = "PrevoteType"]; - SIGNED_MSG_TYPE_PRECOMMIT = 2 [(gogoproto.enumvalue_customname) = "PrecommitType"]; - - // Proposals - SIGNED_MSG_TYPE_PROPOSAL = 32 [(gogoproto.enumvalue_customname) = "ProposalType"]; -} - -// PartsetHeader -message PartSetHeader { - uint32 total = 1; - bytes hash = 2; -} - -message Part { - uint32 index = 1; - bytes bytes = 2; - tendermint.crypto.Proof proof = 3 [(gogoproto.nullable) = false]; -} - -// BlockID -message BlockID { - bytes hash = 1; - PartSetHeader part_set_header = 2 [(gogoproto.nullable) = false]; -} - -// -------------------------------- - -// Header defines the structure of a Tendermint block header. -message Header { - // basic block info - tendermint.version.Consensus version = 1 [(gogoproto.nullable) = false]; - string chain_id = 2 [(gogoproto.customname) = "ChainID"]; - int64 height = 3; - google.protobuf.Timestamp time = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - - // prev block info - BlockID last_block_id = 5 [(gogoproto.nullable) = false]; - - // hashes of block data - bytes last_commit_hash = 6; // commit from validators from the last block - bytes data_hash = 7; // transactions - - // hashes from the app output from the prev block - bytes validators_hash = 8; // validators for the current block - bytes next_validators_hash = 9; // validators for the next block - bytes consensus_hash = 10; // consensus params for current block - bytes app_hash = 11; // state after txs from the previous block - bytes last_results_hash = 12; // root hash of all results from the txs from the previous block - - // consensus info - bytes evidence_hash = 13; // evidence included in the block - bytes proposer_address = 14; // original proposer of the block -} - -// Data contains the set of transactions included in the block -message Data { - // Txs that will be applied by state @ block.Height+1. - // NOTE: not all txs here are valid. We're just agreeing on the order first. - // This means that block.AppHash does not include these txs. - repeated bytes txs = 1; -} - -// Vote represents a prevote, precommit, or commit vote from validators for -// consensus. -message Vote { - SignedMsgType type = 1; - int64 height = 2; - int32 round = 3; - BlockID block_id = 4 - [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; // zero if vote is nil. - google.protobuf.Timestamp timestamp = 5 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes validator_address = 6; - int32 validator_index = 7; - bytes signature = 8; -} - -// Commit contains the evidence that a block was committed by a set of validators. -message Commit { - int64 height = 1; - int32 round = 2; - BlockID block_id = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; - repeated CommitSig signatures = 4 [(gogoproto.nullable) = false]; -} - -// CommitSig is a part of the Vote included in a Commit. -message CommitSig { - BlockIDFlag block_id_flag = 1; - bytes validator_address = 2; - google.protobuf.Timestamp timestamp = 3 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes signature = 4; -} - -message Proposal { - SignedMsgType type = 1; - int64 height = 2; - int32 round = 3; - int32 pol_round = 4; - BlockID block_id = 5 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; - google.protobuf.Timestamp timestamp = 6 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes signature = 7; -} - -message SignedHeader { - Header header = 1; - Commit commit = 2; -} - -message LightBlock { - SignedHeader signed_header = 1; - tendermint.types.ValidatorSet validator_set = 2; -} - -message BlockMeta { - BlockID block_id = 1 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; - int64 block_size = 2; - Header header = 3 [(gogoproto.nullable) = false]; - int64 num_txs = 4; -} - -// TxProof represents a Merkle proof of the presence of a transaction in the Merkle tree. -message TxProof { - bytes root_hash = 1; - bytes data = 2; - tendermint.crypto.Proof proof = 3; -} diff --git a/trader_old/vendor/valory/connections/abci/protos/tendermint/types/validator.proto b/trader_old/vendor/valory/connections/abci/protos/tendermint/types/validator.proto deleted file mode 100644 index 49860b96d..000000000 --- a/trader_old/vendor/valory/connections/abci/protos/tendermint/types/validator.proto +++ /dev/null @@ -1,25 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "tendermint/crypto/keys.proto"; - -message ValidatorSet { - repeated Validator validators = 1; - Validator proposer = 2; - int64 total_voting_power = 3; -} - -message Validator { - bytes address = 1; - tendermint.crypto.PublicKey pub_key = 2 [(gogoproto.nullable) = false]; - int64 voting_power = 3; - int64 proposer_priority = 4; -} - -message SimpleValidator { - tendermint.crypto.PublicKey pub_key = 1; - int64 voting_power = 2; -} diff --git a/trader_old/vendor/valory/connections/abci/protos/tendermint/version/types.proto b/trader_old/vendor/valory/connections/abci/protos/tendermint/version/types.proto deleted file mode 100644 index 6061868bd..000000000 --- a/trader_old/vendor/valory/connections/abci/protos/tendermint/version/types.proto +++ /dev/null @@ -1,24 +0,0 @@ -syntax = "proto3"; -package tendermint.version; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/version"; - -import "gogoproto/gogo.proto"; - -// App includes the protocol and software version for the application. -// This information is included in ResponseInfo. The App.Protocol can be -// updated in ResponseEndBlock. -message App { - uint64 protocol = 1; - string software = 2; -} - -// Consensus captures the consensus rules for processing a block in the blockchain, -// including all blockchain data structures and the rules of the application's -// state transition machine. -message Consensus { - option (gogoproto.equal) = true; - - uint64 block = 1; - uint64 app = 2; -} diff --git a/trader_old/vendor/valory/connections/abci/readme.md b/trader_old/vendor/valory/connections/abci/readme.md deleted file mode 100644 index c8f120b2f..000000000 --- a/trader_old/vendor/valory/connections/abci/readme.md +++ /dev/null @@ -1,8 +0,0 @@ -# ABCI connection - -This package implements an AEA connection that wraps -the HTTP requests that can be done to an ABCI server. - -## Usage - -Configure the fields `host` and `port` to the ABCI server you want to interact with. diff --git a/trader_old/vendor/valory/connections/abci/scripts/genproto.py b/trader_old/vendor/valory/connections/abci/scripts/genproto.py deleted file mode 100644 index d85dba5fc..000000000 --- a/trader_old/vendor/valory/connections/abci/scripts/genproto.py +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -""" -Update Python modules from Tendermint Protobuf files. - -NOTE: This code is adapted from the google protobuf Python library. Specifically from the setup.py file. -""" - -import os -import re -import subprocess # nosec -import sys -from distutils.spawn import find_executable -from pathlib import Path -from typing import cast - - -PACKAGE_IMPORT_PATH_PREFIX = "packages.valory.connections.abci" - - -def _find_protoc() -> str: - """Find protoc binary.""" - if "PROTOC" in os.environ and os.path.exists(os.environ["PROTOC"]): - protoc_bin = os.environ["PROTOC"] - elif os.path.exists("../src/protoc"): - protoc_bin = "../src/protoc" - elif os.path.exists("../src/protoc.exe"): - protoc_bin = "../src/protoc.exe" - elif os.path.exists("../vsprojects/Debug/protoc.exe"): - protoc_bin = "../vsprojects/Debug/protoc.exe" - elif os.path.exists("../vsprojects/Release/protoc.exe"): - protoc_bin = "../vsprojects/Release/protoc.exe" - else: - which_protoc = find_executable("protoc") - if which_protoc is None: - raise ValueError("cannot find 'protoc' binary on the system.") - protoc_bin = which_protoc - return cast(str, protoc_bin) - - -protoc = _find_protoc() - - -def generate_proto(source: str) -> None: - """ - Generate a protobuf file. - - Invokes the Protocol Compiler to generate a _pb2.py from the given - .proto file. Does nothing if the output already exists and is newer than - the input. - - :param source: path to the source. - """ - - if not os.path.exists(source): - return - - output = source.replace(".proto", "_pb2.py").replace("./protos/", "./") - - if not os.path.exists(output) or ( - os.path.exists(source) and os.path.getmtime(source) > os.path.getmtime(output) - ): - print("Generating %s..." % output) - - if not os.path.exists(source): - sys.stderr.write("Can't find required file: %s\n" % source) - sys.exit(-1) - - if protoc is None: - sys.stderr.write("protoc is not installed!\n") - sys.exit(-1) - - protoc_cross_platform = protoc.replace("/", os.path.sep) - protoc_command = [ - protoc_cross_platform, - "-I./protos", - "-I.", - "--python_out=.", - source, - ] - if subprocess.call(protoc_command) != 0: # nosec - sys.exit(-1) - - # prepend to all imports statement the AEA package import prefix path - output_path = Path(output) - output_content = output_path.read_text() - output_content = re.sub( - "from tendermint", - f"from {PACKAGE_IMPORT_PATH_PREFIX}.tendermint", - output_content, - ) - output_content = re.sub( - "from gogoproto", - f"from {PACKAGE_IMPORT_PATH_PREFIX}.gogoproto", - output_content, - ) - output_path.write_text(output_content) - - -if __name__ == "__main__": - # Build all the protobuf files and put into their directory - generate_proto("./protos/gogoproto/gogo.proto") - generate_proto("./protos/tendermint/crypto/keys.proto") - generate_proto("./protos/tendermint/crypto/proof.proto") - generate_proto("./protos/tendermint/types/params.proto") - generate_proto("./protos/tendermint/types/types.proto") - generate_proto("./protos/tendermint/types/validator.proto") - generate_proto("./protos/tendermint/version/types.proto") - generate_proto("./protos/tendermint/abci/types.proto") diff --git a/trader_old/vendor/valory/connections/abci/tendermint/__init__.py b/trader_old/vendor/valory/connections/abci/tendermint/__init__.py deleted file mode 100644 index 3c34ec6d0..000000000 --- a/trader_old/vendor/valory/connections/abci/tendermint/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the Protobuf Python modules for the Tendermint-ABCI messages.""" # pragma: nocover diff --git a/trader_old/vendor/valory/connections/abci/tendermint/abci/types_pb2.py b/trader_old/vendor/valory/connections/abci/tendermint/abci/types_pb2.py deleted file mode 100644 index 6f94ff4ba..000000000 --- a/trader_old/vendor/valory/connections/abci/tendermint/abci/types_pb2.py +++ /dev/null @@ -1,211 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/abci/types.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) -from packages.valory.connections.abci.tendermint.crypto import ( - keys_pb2 as tendermint_dot_crypto_dot_keys__pb2, -) -from packages.valory.connections.abci.tendermint.crypto import ( - proof_pb2 as tendermint_dot_crypto_dot_proof__pb2, -) -from packages.valory.connections.abci.tendermint.types import ( - params_pb2 as tendermint_dot_types_dot_params__pb2, -) -from packages.valory.connections.abci.tendermint.types import ( - types_pb2 as tendermint_dot_types_dot_types__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1btendermint/abci/types.proto\x12\x0ftendermint.abci\x1a\x1dtendermint/crypto/proof.proto\x1a\x1ctendermint/types/types.proto\x1a\x1ctendermint/crypto/keys.proto\x1a\x1dtendermint/types/params.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x14gogoproto/gogo.proto"\xea\x06\n\x07Request\x12,\n\x04\x65\x63ho\x18\x01 \x01(\x0b\x32\x1c.tendermint.abci.RequestEchoH\x00\x12.\n\x05\x66lush\x18\x02 \x01(\x0b\x32\x1d.tendermint.abci.RequestFlushH\x00\x12,\n\x04info\x18\x03 \x01(\x0b\x32\x1c.tendermint.abci.RequestInfoH\x00\x12\x37\n\nset_option\x18\x04 \x01(\x0b\x32!.tendermint.abci.RequestSetOptionH\x00\x12\x37\n\ninit_chain\x18\x05 \x01(\x0b\x32!.tendermint.abci.RequestInitChainH\x00\x12.\n\x05query\x18\x06 \x01(\x0b\x32\x1d.tendermint.abci.RequestQueryH\x00\x12\x39\n\x0b\x62\x65gin_block\x18\x07 \x01(\x0b\x32".tendermint.abci.RequestBeginBlockH\x00\x12\x33\n\x08\x63heck_tx\x18\x08 \x01(\x0b\x32\x1f.tendermint.abci.RequestCheckTxH\x00\x12\x37\n\ndeliver_tx\x18\t \x01(\x0b\x32!.tendermint.abci.RequestDeliverTxH\x00\x12\x35\n\tend_block\x18\n \x01(\x0b\x32 .tendermint.abci.RequestEndBlockH\x00\x12\x30\n\x06\x63ommit\x18\x0b \x01(\x0b\x32\x1e.tendermint.abci.RequestCommitH\x00\x12?\n\x0elist_snapshots\x18\x0c \x01(\x0b\x32%.tendermint.abci.RequestListSnapshotsH\x00\x12?\n\x0eoffer_snapshot\x18\r \x01(\x0b\x32%.tendermint.abci.RequestOfferSnapshotH\x00\x12H\n\x13load_snapshot_chunk\x18\x0e \x01(\x0b\x32).tendermint.abci.RequestLoadSnapshotChunkH\x00\x12J\n\x14\x61pply_snapshot_chunk\x18\x0f \x01(\x0b\x32*.tendermint.abci.RequestApplySnapshotChunkH\x00\x42\x07\n\x05value"\x1e\n\x0bRequestEcho\x12\x0f\n\x07message\x18\x01 \x01(\t"\x0e\n\x0cRequestFlush"J\n\x0bRequestInfo\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x15\n\rblock_version\x18\x02 \x01(\x04\x12\x13\n\x0bp2p_version\x18\x03 \x01(\x04".\n\x10RequestSetOption\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t"\x81\x02\n\x10RequestInitChain\x12\x32\n\x04time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x08\xc8\xde\x1f\x00\x90\xdf\x1f\x01\x12\x10\n\x08\x63hain_id\x18\x02 \x01(\t\x12:\n\x10\x63onsensus_params\x18\x03 \x01(\x0b\x32 .tendermint.abci.ConsensusParams\x12:\n\nvalidators\x18\x04 \x03(\x0b\x32 .tendermint.abci.ValidatorUpdateB\x04\xc8\xde\x1f\x00\x12\x17\n\x0f\x61pp_state_bytes\x18\x05 \x01(\x0c\x12\x16\n\x0einitial_height\x18\x06 \x01(\x03"I\n\x0cRequestQuery\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x12\x0c\n\x04path\x18\x02 \x01(\t\x12\x0e\n\x06height\x18\x03 \x01(\x03\x12\r\n\x05prove\x18\x04 \x01(\x08"\xd1\x01\n\x11RequestBeginBlock\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12.\n\x06header\x18\x02 \x01(\x0b\x32\x18.tendermint.types.HeaderB\x04\xc8\xde\x1f\x00\x12?\n\x10last_commit_info\x18\x03 \x01(\x0b\x32\x1f.tendermint.abci.LastCommitInfoB\x04\xc8\xde\x1f\x00\x12=\n\x14\x62yzantine_validators\x18\x04 \x03(\x0b\x32\x19.tendermint.abci.EvidenceB\x04\xc8\xde\x1f\x00"H\n\x0eRequestCheckTx\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12*\n\x04type\x18\x02 \x01(\x0e\x32\x1c.tendermint.abci.CheckTxType"\x1e\n\x10RequestDeliverTx\x12\n\n\x02tx\x18\x01 \x01(\x0c"!\n\x0fRequestEndBlock\x12\x0e\n\x06height\x18\x01 \x01(\x03"\x0f\n\rRequestCommit"\x16\n\x14RequestListSnapshots"U\n\x14RequestOfferSnapshot\x12+\n\x08snapshot\x18\x01 \x01(\x0b\x32\x19.tendermint.abci.Snapshot\x12\x10\n\x08\x61pp_hash\x18\x02 \x01(\x0c"I\n\x18RequestLoadSnapshotChunk\x12\x0e\n\x06height\x18\x01 \x01(\x04\x12\x0e\n\x06\x66ormat\x18\x02 \x01(\r\x12\r\n\x05\x63hunk\x18\x03 \x01(\r"I\n\x19RequestApplySnapshotChunk\x12\r\n\x05index\x18\x01 \x01(\r\x12\r\n\x05\x63hunk\x18\x02 \x01(\x0c\x12\x0e\n\x06sender\x18\x03 \x01(\t"\xb3\x07\n\x08Response\x12\x37\n\texception\x18\x01 \x01(\x0b\x32".tendermint.abci.ResponseExceptionH\x00\x12-\n\x04\x65\x63ho\x18\x02 \x01(\x0b\x32\x1d.tendermint.abci.ResponseEchoH\x00\x12/\n\x05\x66lush\x18\x03 \x01(\x0b\x32\x1e.tendermint.abci.ResponseFlushH\x00\x12-\n\x04info\x18\x04 \x01(\x0b\x32\x1d.tendermint.abci.ResponseInfoH\x00\x12\x38\n\nset_option\x18\x05 \x01(\x0b\x32".tendermint.abci.ResponseSetOptionH\x00\x12\x38\n\ninit_chain\x18\x06 \x01(\x0b\x32".tendermint.abci.ResponseInitChainH\x00\x12/\n\x05query\x18\x07 \x01(\x0b\x32\x1e.tendermint.abci.ResponseQueryH\x00\x12:\n\x0b\x62\x65gin_block\x18\x08 \x01(\x0b\x32#.tendermint.abci.ResponseBeginBlockH\x00\x12\x34\n\x08\x63heck_tx\x18\t \x01(\x0b\x32 .tendermint.abci.ResponseCheckTxH\x00\x12\x38\n\ndeliver_tx\x18\n \x01(\x0b\x32".tendermint.abci.ResponseDeliverTxH\x00\x12\x36\n\tend_block\x18\x0b \x01(\x0b\x32!.tendermint.abci.ResponseEndBlockH\x00\x12\x31\n\x06\x63ommit\x18\x0c \x01(\x0b\x32\x1f.tendermint.abci.ResponseCommitH\x00\x12@\n\x0elist_snapshots\x18\r \x01(\x0b\x32&.tendermint.abci.ResponseListSnapshotsH\x00\x12@\n\x0eoffer_snapshot\x18\x0e \x01(\x0b\x32&.tendermint.abci.ResponseOfferSnapshotH\x00\x12I\n\x13load_snapshot_chunk\x18\x0f \x01(\x0b\x32*.tendermint.abci.ResponseLoadSnapshotChunkH\x00\x12K\n\x14\x61pply_snapshot_chunk\x18\x10 \x01(\x0b\x32+.tendermint.abci.ResponseApplySnapshotChunkH\x00\x42\x07\n\x05value""\n\x11ResponseException\x12\r\n\x05\x65rror\x18\x01 \x01(\t"\x1f\n\x0cResponseEcho\x12\x0f\n\x07message\x18\x01 \x01(\t"\x0f\n\rResponseFlush"z\n\x0cResponseInfo\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12\x13\n\x0b\x61pp_version\x18\x03 \x01(\x04\x12\x19\n\x11last_block_height\x18\x04 \x01(\x03\x12\x1b\n\x13last_block_app_hash\x18\x05 \x01(\x0c"<\n\x11ResponseSetOption\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0b\n\x03log\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t"\x9d\x01\n\x11ResponseInitChain\x12:\n\x10\x63onsensus_params\x18\x01 \x01(\x0b\x32 .tendermint.abci.ConsensusParams\x12:\n\nvalidators\x18\x02 \x03(\x0b\x32 .tendermint.abci.ValidatorUpdateB\x04\xc8\xde\x1f\x00\x12\x10\n\x08\x61pp_hash\x18\x03 \x01(\x0c"\xb6\x01\n\rResponseQuery\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0b\n\x03log\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t\x12\r\n\x05index\x18\x05 \x01(\x03\x12\x0b\n\x03key\x18\x06 \x01(\x0c\x12\r\n\x05value\x18\x07 \x01(\x0c\x12.\n\tproof_ops\x18\x08 \x01(\x0b\x32\x1b.tendermint.crypto.ProofOps\x12\x0e\n\x06height\x18\t \x01(\x03\x12\x11\n\tcodespace\x18\n \x01(\t"V\n\x12ResponseBeginBlock\x12@\n\x06\x65vents\x18\x01 \x03(\x0b\x32\x16.tendermint.abci.EventB\x18\xc8\xde\x1f\x00\xea\xde\x1f\x10\x65vents,omitempty"\xd9\x01\n\x0fResponseCheckTx\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x0b\n\x03log\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t\x12\x1e\n\ngas_wanted\x18\x05 \x01(\x03R\ngas_wanted\x12\x1a\n\x08gas_used\x18\x06 \x01(\x03R\x08gas_used\x12@\n\x06\x65vents\x18\x07 \x03(\x0b\x32\x16.tendermint.abci.EventB\x18\xc8\xde\x1f\x00\xea\xde\x1f\x10\x65vents,omitempty\x12\x11\n\tcodespace\x18\x08 \x01(\t"\xdb\x01\n\x11ResponseDeliverTx\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x0b\n\x03log\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t\x12\x1e\n\ngas_wanted\x18\x05 \x01(\x03R\ngas_wanted\x12\x1a\n\x08gas_used\x18\x06 \x01(\x03R\x08gas_used\x12@\n\x06\x65vents\x18\x07 \x03(\x0b\x32\x16.tendermint.abci.EventB\x18\xc8\xde\x1f\x00\xea\xde\x1f\x10\x65vents,omitempty\x12\x11\n\tcodespace\x18\x08 \x01(\t"\xda\x01\n\x10ResponseEndBlock\x12\x41\n\x11validator_updates\x18\x01 \x03(\x0b\x32 .tendermint.abci.ValidatorUpdateB\x04\xc8\xde\x1f\x00\x12\x41\n\x17\x63onsensus_param_updates\x18\x02 \x01(\x0b\x32 .tendermint.abci.ConsensusParams\x12@\n\x06\x65vents\x18\x03 \x03(\x0b\x32\x16.tendermint.abci.EventB\x18\xc8\xde\x1f\x00\xea\xde\x1f\x10\x65vents,omitempty"5\n\x0eResponseCommit\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x15\n\rretain_height\x18\x03 \x01(\x03"E\n\x15ResponseListSnapshots\x12,\n\tsnapshots\x18\x01 \x03(\x0b\x32\x19.tendermint.abci.Snapshot"\xb6\x01\n\x15ResponseOfferSnapshot\x12=\n\x06result\x18\x01 \x01(\x0e\x32-.tendermint.abci.ResponseOfferSnapshot.Result"^\n\x06Result\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x41\x43\x43\x45PT\x10\x01\x12\t\n\x05\x41\x42ORT\x10\x02\x12\n\n\x06REJECT\x10\x03\x12\x11\n\rREJECT_FORMAT\x10\x04\x12\x11\n\rREJECT_SENDER\x10\x05"*\n\x19ResponseLoadSnapshotChunk\x12\r\n\x05\x63hunk\x18\x01 \x01(\x0c"\xf2\x01\n\x1aResponseApplySnapshotChunk\x12\x42\n\x06result\x18\x01 \x01(\x0e\x32\x32.tendermint.abci.ResponseApplySnapshotChunk.Result\x12\x16\n\x0erefetch_chunks\x18\x02 \x03(\r\x12\x16\n\x0ereject_senders\x18\x03 \x03(\t"`\n\x06Result\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x41\x43\x43\x45PT\x10\x01\x12\t\n\x05\x41\x42ORT\x10\x02\x12\t\n\x05RETRY\x10\x03\x12\x12\n\x0eRETRY_SNAPSHOT\x10\x04\x12\x13\n\x0fREJECT_SNAPSHOT\x10\x05"\xda\x01\n\x0f\x43onsensusParams\x12+\n\x05\x62lock\x18\x01 \x01(\x0b\x32\x1c.tendermint.abci.BlockParams\x12\x32\n\x08\x65vidence\x18\x02 \x01(\x0b\x32 .tendermint.types.EvidenceParams\x12\x34\n\tvalidator\x18\x03 \x01(\x0b\x32!.tendermint.types.ValidatorParams\x12\x30\n\x07version\x18\x04 \x01(\x0b\x32\x1f.tendermint.types.VersionParams"1\n\x0b\x42lockParams\x12\x11\n\tmax_bytes\x18\x01 \x01(\x03\x12\x0f\n\x07max_gas\x18\x02 \x01(\x03"O\n\x0eLastCommitInfo\x12\r\n\x05round\x18\x01 \x01(\x05\x12.\n\x05votes\x18\x02 \x03(\x0b\x32\x19.tendermint.abci.VoteInfoB\x04\xc8\xde\x1f\x00"h\n\x05\x45vent\x12\x0c\n\x04type\x18\x01 \x01(\t\x12Q\n\nattributes\x18\x02 \x03(\x0b\x32\x1f.tendermint.abci.EventAttributeB\x1c\xc8\xde\x1f\x00\xea\xde\x1f\x14\x61ttributes,omitempty";\n\x0e\x45ventAttribute\x12\x0b\n\x03key\x18\x01 \x01(\x0c\x12\r\n\x05value\x18\x02 \x01(\x0c\x12\r\n\x05index\x18\x03 \x01(\x08"o\n\x08TxResult\x12\x0e\n\x06height\x18\x01 \x01(\x03\x12\r\n\x05index\x18\x02 \x01(\r\x12\n\n\x02tx\x18\x03 \x01(\x0c\x12\x38\n\x06result\x18\x04 \x01(\x0b\x32".tendermint.abci.ResponseDeliverTxB\x04\xc8\xde\x1f\x00"+\n\tValidator\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0c\x12\r\n\x05power\x18\x03 \x01(\x03"U\n\x0fValidatorUpdate\x12\x33\n\x07pub_key\x18\x01 \x01(\x0b\x32\x1c.tendermint.crypto.PublicKeyB\x04\xc8\xde\x1f\x00\x12\r\n\x05power\x18\x02 \x01(\x03"Z\n\x08VoteInfo\x12\x33\n\tvalidator\x18\x01 \x01(\x0b\x32\x1a.tendermint.abci.ValidatorB\x04\xc8\xde\x1f\x00\x12\x19\n\x11signed_last_block\x18\x02 \x01(\x08"\xcc\x01\n\x08\x45vidence\x12+\n\x04type\x18\x01 \x01(\x0e\x32\x1d.tendermint.abci.EvidenceType\x12\x33\n\tvalidator\x18\x02 \x01(\x0b\x32\x1a.tendermint.abci.ValidatorB\x04\xc8\xde\x1f\x00\x12\x0e\n\x06height\x18\x03 \x01(\x03\x12\x32\n\x04time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x08\xc8\xde\x1f\x00\x90\xdf\x1f\x01\x12\x1a\n\x12total_voting_power\x18\x05 \x01(\x03"Z\n\x08Snapshot\x12\x0e\n\x06height\x18\x01 \x01(\x04\x12\x0e\n\x06\x66ormat\x18\x02 \x01(\r\x12\x0e\n\x06\x63hunks\x18\x03 \x01(\r\x12\x0c\n\x04hash\x18\x04 \x01(\x0c\x12\x10\n\x08metadata\x18\x05 \x01(\x0c*9\n\x0b\x43heckTxType\x12\x10\n\x03NEW\x10\x00\x1a\x07\x8a\x9d \x03New\x12\x18\n\x07RECHECK\x10\x01\x1a\x0b\x8a\x9d \x07Recheck*H\n\x0c\x45videnceType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x12\n\x0e\x44UPLICATE_VOTE\x10\x01\x12\x17\n\x13LIGHT_CLIENT_ATTACK\x10\x02\x32\x83\n\n\x0f\x41\x42\x43IApplication\x12\x43\n\x04\x45\x63ho\x12\x1c.tendermint.abci.RequestEcho\x1a\x1d.tendermint.abci.ResponseEcho\x12\x46\n\x05\x46lush\x12\x1d.tendermint.abci.RequestFlush\x1a\x1e.tendermint.abci.ResponseFlush\x12\x43\n\x04Info\x12\x1c.tendermint.abci.RequestInfo\x1a\x1d.tendermint.abci.ResponseInfo\x12R\n\tSetOption\x12!.tendermint.abci.RequestSetOption\x1a".tendermint.abci.ResponseSetOption\x12R\n\tDeliverTx\x12!.tendermint.abci.RequestDeliverTx\x1a".tendermint.abci.ResponseDeliverTx\x12L\n\x07\x43heckTx\x12\x1f.tendermint.abci.RequestCheckTx\x1a .tendermint.abci.ResponseCheckTx\x12\x46\n\x05Query\x12\x1d.tendermint.abci.RequestQuery\x1a\x1e.tendermint.abci.ResponseQuery\x12I\n\x06\x43ommit\x12\x1e.tendermint.abci.RequestCommit\x1a\x1f.tendermint.abci.ResponseCommit\x12R\n\tInitChain\x12!.tendermint.abci.RequestInitChain\x1a".tendermint.abci.ResponseInitChain\x12U\n\nBeginBlock\x12".tendermint.abci.RequestBeginBlock\x1a#.tendermint.abci.ResponseBeginBlock\x12O\n\x08\x45ndBlock\x12 .tendermint.abci.RequestEndBlock\x1a!.tendermint.abci.ResponseEndBlock\x12^\n\rListSnapshots\x12%.tendermint.abci.RequestListSnapshots\x1a&.tendermint.abci.ResponseListSnapshots\x12^\n\rOfferSnapshot\x12%.tendermint.abci.RequestOfferSnapshot\x1a&.tendermint.abci.ResponseOfferSnapshot\x12j\n\x11LoadSnapshotChunk\x12).tendermint.abci.RequestLoadSnapshotChunk\x1a*.tendermint.abci.ResponseLoadSnapshotChunk\x12m\n\x12\x41pplySnapshotChunk\x12*.tendermint.abci.RequestApplySnapshotChunk\x1a+.tendermint.abci.ResponseApplySnapshotChunkB-Z+github.com/tendermint/tendermint/abci/typesb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.abci.types_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b"Z+github.com/tendermint/tendermint/abci/types" - _CHECKTXTYPE.values_by_name["NEW"]._options = None - _CHECKTXTYPE.values_by_name["NEW"]._serialized_options = b"\212\235 \003New" - _CHECKTXTYPE.values_by_name["RECHECK"]._options = None - _CHECKTXTYPE.values_by_name["RECHECK"]._serialized_options = b"\212\235 \007Recheck" - _REQUESTINITCHAIN.fields_by_name["time"]._options = None - _REQUESTINITCHAIN.fields_by_name[ - "time" - ]._serialized_options = b"\310\336\037\000\220\337\037\001" - _REQUESTINITCHAIN.fields_by_name["validators"]._options = None - _REQUESTINITCHAIN.fields_by_name[ - "validators" - ]._serialized_options = b"\310\336\037\000" - _REQUESTBEGINBLOCK.fields_by_name["header"]._options = None - _REQUESTBEGINBLOCK.fields_by_name[ - "header" - ]._serialized_options = b"\310\336\037\000" - _REQUESTBEGINBLOCK.fields_by_name["last_commit_info"]._options = None - _REQUESTBEGINBLOCK.fields_by_name[ - "last_commit_info" - ]._serialized_options = b"\310\336\037\000" - _REQUESTBEGINBLOCK.fields_by_name["byzantine_validators"]._options = None - _REQUESTBEGINBLOCK.fields_by_name[ - "byzantine_validators" - ]._serialized_options = b"\310\336\037\000" - _RESPONSEINITCHAIN.fields_by_name["validators"]._options = None - _RESPONSEINITCHAIN.fields_by_name[ - "validators" - ]._serialized_options = b"\310\336\037\000" - _RESPONSEBEGINBLOCK.fields_by_name["events"]._options = None - _RESPONSEBEGINBLOCK.fields_by_name[ - "events" - ]._serialized_options = b"\310\336\037\000\352\336\037\020events,omitempty" - _RESPONSECHECKTX.fields_by_name["events"]._options = None - _RESPONSECHECKTX.fields_by_name[ - "events" - ]._serialized_options = b"\310\336\037\000\352\336\037\020events,omitempty" - _RESPONSEDELIVERTX.fields_by_name["events"]._options = None - _RESPONSEDELIVERTX.fields_by_name[ - "events" - ]._serialized_options = b"\310\336\037\000\352\336\037\020events,omitempty" - _RESPONSEENDBLOCK.fields_by_name["validator_updates"]._options = None - _RESPONSEENDBLOCK.fields_by_name[ - "validator_updates" - ]._serialized_options = b"\310\336\037\000" - _RESPONSEENDBLOCK.fields_by_name["events"]._options = None - _RESPONSEENDBLOCK.fields_by_name[ - "events" - ]._serialized_options = b"\310\336\037\000\352\336\037\020events,omitempty" - _LASTCOMMITINFO.fields_by_name["votes"]._options = None - _LASTCOMMITINFO.fields_by_name["votes"]._serialized_options = b"\310\336\037\000" - _EVENT.fields_by_name["attributes"]._options = None - _EVENT.fields_by_name[ - "attributes" - ]._serialized_options = b"\310\336\037\000\352\336\037\024attributes,omitempty" - _TXRESULT.fields_by_name["result"]._options = None - _TXRESULT.fields_by_name["result"]._serialized_options = b"\310\336\037\000" - _VALIDATORUPDATE.fields_by_name["pub_key"]._options = None - _VALIDATORUPDATE.fields_by_name["pub_key"]._serialized_options = b"\310\336\037\000" - _VOTEINFO.fields_by_name["validator"]._options = None - _VOTEINFO.fields_by_name["validator"]._serialized_options = b"\310\336\037\000" - _EVIDENCE.fields_by_name["validator"]._options = None - _EVIDENCE.fields_by_name["validator"]._serialized_options = b"\310\336\037\000" - _EVIDENCE.fields_by_name["time"]._options = None - _EVIDENCE.fields_by_name[ - "time" - ]._serialized_options = b"\310\336\037\000\220\337\037\001" - _globals["_CHECKTXTYPE"]._serialized_start = 6314 - _globals["_CHECKTXTYPE"]._serialized_end = 6371 - _globals["_EVIDENCETYPE"]._serialized_start = 6373 - _globals["_EVIDENCETYPE"]._serialized_end = 6445 - _globals["_REQUEST"]._serialized_start = 226 - _globals["_REQUEST"]._serialized_end = 1100 - _globals["_REQUESTECHO"]._serialized_start = 1102 - _globals["_REQUESTECHO"]._serialized_end = 1132 - _globals["_REQUESTFLUSH"]._serialized_start = 1134 - _globals["_REQUESTFLUSH"]._serialized_end = 1148 - _globals["_REQUESTINFO"]._serialized_start = 1150 - _globals["_REQUESTINFO"]._serialized_end = 1224 - _globals["_REQUESTSETOPTION"]._serialized_start = 1226 - _globals["_REQUESTSETOPTION"]._serialized_end = 1272 - _globals["_REQUESTINITCHAIN"]._serialized_start = 1275 - _globals["_REQUESTINITCHAIN"]._serialized_end = 1532 - _globals["_REQUESTQUERY"]._serialized_start = 1534 - _globals["_REQUESTQUERY"]._serialized_end = 1607 - _globals["_REQUESTBEGINBLOCK"]._serialized_start = 1610 - _globals["_REQUESTBEGINBLOCK"]._serialized_end = 1819 - _globals["_REQUESTCHECKTX"]._serialized_start = 1821 - _globals["_REQUESTCHECKTX"]._serialized_end = 1893 - _globals["_REQUESTDELIVERTX"]._serialized_start = 1895 - _globals["_REQUESTDELIVERTX"]._serialized_end = 1925 - _globals["_REQUESTENDBLOCK"]._serialized_start = 1927 - _globals["_REQUESTENDBLOCK"]._serialized_end = 1960 - _globals["_REQUESTCOMMIT"]._serialized_start = 1962 - _globals["_REQUESTCOMMIT"]._serialized_end = 1977 - _globals["_REQUESTLISTSNAPSHOTS"]._serialized_start = 1979 - _globals["_REQUESTLISTSNAPSHOTS"]._serialized_end = 2001 - _globals["_REQUESTOFFERSNAPSHOT"]._serialized_start = 2003 - _globals["_REQUESTOFFERSNAPSHOT"]._serialized_end = 2088 - _globals["_REQUESTLOADSNAPSHOTCHUNK"]._serialized_start = 2090 - _globals["_REQUESTLOADSNAPSHOTCHUNK"]._serialized_end = 2163 - _globals["_REQUESTAPPLYSNAPSHOTCHUNK"]._serialized_start = 2165 - _globals["_REQUESTAPPLYSNAPSHOTCHUNK"]._serialized_end = 2238 - _globals["_RESPONSE"]._serialized_start = 2241 - _globals["_RESPONSE"]._serialized_end = 3188 - _globals["_RESPONSEEXCEPTION"]._serialized_start = 3190 - _globals["_RESPONSEEXCEPTION"]._serialized_end = 3224 - _globals["_RESPONSEECHO"]._serialized_start = 3226 - _globals["_RESPONSEECHO"]._serialized_end = 3257 - _globals["_RESPONSEFLUSH"]._serialized_start = 3259 - _globals["_RESPONSEFLUSH"]._serialized_end = 3274 - _globals["_RESPONSEINFO"]._serialized_start = 3276 - _globals["_RESPONSEINFO"]._serialized_end = 3398 - _globals["_RESPONSESETOPTION"]._serialized_start = 3400 - _globals["_RESPONSESETOPTION"]._serialized_end = 3460 - _globals["_RESPONSEINITCHAIN"]._serialized_start = 3463 - _globals["_RESPONSEINITCHAIN"]._serialized_end = 3620 - _globals["_RESPONSEQUERY"]._serialized_start = 3623 - _globals["_RESPONSEQUERY"]._serialized_end = 3805 - _globals["_RESPONSEBEGINBLOCK"]._serialized_start = 3807 - _globals["_RESPONSEBEGINBLOCK"]._serialized_end = 3893 - _globals["_RESPONSECHECKTX"]._serialized_start = 3896 - _globals["_RESPONSECHECKTX"]._serialized_end = 4113 - _globals["_RESPONSEDELIVERTX"]._serialized_start = 4116 - _globals["_RESPONSEDELIVERTX"]._serialized_end = 4335 - _globals["_RESPONSEENDBLOCK"]._serialized_start = 4338 - _globals["_RESPONSEENDBLOCK"]._serialized_end = 4556 - _globals["_RESPONSECOMMIT"]._serialized_start = 4558 - _globals["_RESPONSECOMMIT"]._serialized_end = 4611 - _globals["_RESPONSELISTSNAPSHOTS"]._serialized_start = 4613 - _globals["_RESPONSELISTSNAPSHOTS"]._serialized_end = 4682 - _globals["_RESPONSEOFFERSNAPSHOT"]._serialized_start = 4685 - _globals["_RESPONSEOFFERSNAPSHOT"]._serialized_end = 4867 - _globals["_RESPONSEOFFERSNAPSHOT_RESULT"]._serialized_start = 4773 - _globals["_RESPONSEOFFERSNAPSHOT_RESULT"]._serialized_end = 4867 - _globals["_RESPONSELOADSNAPSHOTCHUNK"]._serialized_start = 4869 - _globals["_RESPONSELOADSNAPSHOTCHUNK"]._serialized_end = 4911 - _globals["_RESPONSEAPPLYSNAPSHOTCHUNK"]._serialized_start = 4914 - _globals["_RESPONSEAPPLYSNAPSHOTCHUNK"]._serialized_end = 5156 - _globals["_RESPONSEAPPLYSNAPSHOTCHUNK_RESULT"]._serialized_start = 5060 - _globals["_RESPONSEAPPLYSNAPSHOTCHUNK_RESULT"]._serialized_end = 5156 - _globals["_CONSENSUSPARAMS"]._serialized_start = 5159 - _globals["_CONSENSUSPARAMS"]._serialized_end = 5377 - _globals["_BLOCKPARAMS"]._serialized_start = 5379 - _globals["_BLOCKPARAMS"]._serialized_end = 5428 - _globals["_LASTCOMMITINFO"]._serialized_start = 5430 - _globals["_LASTCOMMITINFO"]._serialized_end = 5509 - _globals["_EVENT"]._serialized_start = 5511 - _globals["_EVENT"]._serialized_end = 5615 - _globals["_EVENTATTRIBUTE"]._serialized_start = 5617 - _globals["_EVENTATTRIBUTE"]._serialized_end = 5676 - _globals["_TXRESULT"]._serialized_start = 5678 - _globals["_TXRESULT"]._serialized_end = 5789 - _globals["_VALIDATOR"]._serialized_start = 5791 - _globals["_VALIDATOR"]._serialized_end = 5834 - _globals["_VALIDATORUPDATE"]._serialized_start = 5836 - _globals["_VALIDATORUPDATE"]._serialized_end = 5921 - _globals["_VOTEINFO"]._serialized_start = 5923 - _globals["_VOTEINFO"]._serialized_end = 6013 - _globals["_EVIDENCE"]._serialized_start = 6016 - _globals["_EVIDENCE"]._serialized_end = 6220 - _globals["_SNAPSHOT"]._serialized_start = 6222 - _globals["_SNAPSHOT"]._serialized_end = 6312 - _globals["_ABCIAPPLICATION"]._serialized_start = 6448 - _globals["_ABCIAPPLICATION"]._serialized_end = 7731 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/connections/abci/tendermint/abci/types_pb2_grpc.py b/trader_old/vendor/valory/connections/abci/tendermint/abci/types_pb2_grpc.py deleted file mode 100644 index aec5cfb23..000000000 --- a/trader_old/vendor/valory/connections/abci/tendermint/abci/types_pb2_grpc.py +++ /dev/null @@ -1,719 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from packages.valory.connections.abci.tendermint.abci import ( - types_pb2 as tendermint_dot_abci_dot_types__pb2, -) - - -class ABCIApplicationStub(object): - """---------------------------------------- - Service Definition - - """ - - def __init__(self, channel): - """Constructor. - - :param channel: A grpc.Channel. - """ - self.Echo = channel.unary_unary( - "/tendermint.abci.ABCIApplication/Echo", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestEcho.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseEcho.FromString, - ) - self.Flush = channel.unary_unary( - "/tendermint.abci.ABCIApplication/Flush", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestFlush.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseFlush.FromString, - ) - self.Info = channel.unary_unary( - "/tendermint.abci.ABCIApplication/Info", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestInfo.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseInfo.FromString, - ) - self.SetOption = channel.unary_unary( - "/tendermint.abci.ABCIApplication/SetOption", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestSetOption.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseSetOption.FromString, - ) - self.DeliverTx = channel.unary_unary( - "/tendermint.abci.ABCIApplication/DeliverTx", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestDeliverTx.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseDeliverTx.FromString, - ) - self.CheckTx = channel.unary_unary( - "/tendermint.abci.ABCIApplication/CheckTx", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestCheckTx.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseCheckTx.FromString, - ) - self.Query = channel.unary_unary( - "/tendermint.abci.ABCIApplication/Query", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestQuery.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseQuery.FromString, - ) - self.Commit = channel.unary_unary( - "/tendermint.abci.ABCIApplication/Commit", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestCommit.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseCommit.FromString, - ) - self.InitChain = channel.unary_unary( - "/tendermint.abci.ABCIApplication/InitChain", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestInitChain.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseInitChain.FromString, - ) - self.BeginBlock = channel.unary_unary( - "/tendermint.abci.ABCIApplication/BeginBlock", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestBeginBlock.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseBeginBlock.FromString, - ) - self.EndBlock = channel.unary_unary( - "/tendermint.abci.ABCIApplication/EndBlock", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestEndBlock.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseEndBlock.FromString, - ) - self.ListSnapshots = channel.unary_unary( - "/tendermint.abci.ABCIApplication/ListSnapshots", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestListSnapshots.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseListSnapshots.FromString, - ) - self.OfferSnapshot = channel.unary_unary( - "/tendermint.abci.ABCIApplication/OfferSnapshot", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestOfferSnapshot.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseOfferSnapshot.FromString, - ) - self.LoadSnapshotChunk = channel.unary_unary( - "/tendermint.abci.ABCIApplication/LoadSnapshotChunk", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestLoadSnapshotChunk.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseLoadSnapshotChunk.FromString, - ) - self.ApplySnapshotChunk = channel.unary_unary( - "/tendermint.abci.ABCIApplication/ApplySnapshotChunk", - request_serializer=tendermint_dot_abci_dot_types__pb2.RequestApplySnapshotChunk.SerializeToString, - response_deserializer=tendermint_dot_abci_dot_types__pb2.ResponseApplySnapshotChunk.FromString, - ) - - -class ABCIApplicationServicer(object): - """---------------------------------------- - Service Definition - - """ - - def Echo(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def Flush(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def Info(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def SetOption(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def DeliverTx(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def CheckTx(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def Query(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def Commit(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def InitChain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def BeginBlock(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def EndBlock(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def ListSnapshots(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def OfferSnapshot(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def LoadSnapshotChunk(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def ApplySnapshotChunk(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - -def add_ABCIApplicationServicer_to_server(servicer, server): - rpc_method_handlers = { - "Echo": grpc.unary_unary_rpc_method_handler( - servicer.Echo, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestEcho.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseEcho.SerializeToString, - ), - "Flush": grpc.unary_unary_rpc_method_handler( - servicer.Flush, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestFlush.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseFlush.SerializeToString, - ), - "Info": grpc.unary_unary_rpc_method_handler( - servicer.Info, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestInfo.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseInfo.SerializeToString, - ), - "SetOption": grpc.unary_unary_rpc_method_handler( - servicer.SetOption, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestSetOption.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseSetOption.SerializeToString, - ), - "DeliverTx": grpc.unary_unary_rpc_method_handler( - servicer.DeliverTx, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestDeliverTx.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseDeliverTx.SerializeToString, - ), - "CheckTx": grpc.unary_unary_rpc_method_handler( - servicer.CheckTx, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestCheckTx.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseCheckTx.SerializeToString, - ), - "Query": grpc.unary_unary_rpc_method_handler( - servicer.Query, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestQuery.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseQuery.SerializeToString, - ), - "Commit": grpc.unary_unary_rpc_method_handler( - servicer.Commit, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestCommit.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseCommit.SerializeToString, - ), - "InitChain": grpc.unary_unary_rpc_method_handler( - servicer.InitChain, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestInitChain.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseInitChain.SerializeToString, - ), - "BeginBlock": grpc.unary_unary_rpc_method_handler( - servicer.BeginBlock, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestBeginBlock.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseBeginBlock.SerializeToString, - ), - "EndBlock": grpc.unary_unary_rpc_method_handler( - servicer.EndBlock, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestEndBlock.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseEndBlock.SerializeToString, - ), - "ListSnapshots": grpc.unary_unary_rpc_method_handler( - servicer.ListSnapshots, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestListSnapshots.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseListSnapshots.SerializeToString, - ), - "OfferSnapshot": grpc.unary_unary_rpc_method_handler( - servicer.OfferSnapshot, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestOfferSnapshot.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseOfferSnapshot.SerializeToString, - ), - "LoadSnapshotChunk": grpc.unary_unary_rpc_method_handler( - servicer.LoadSnapshotChunk, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestLoadSnapshotChunk.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseLoadSnapshotChunk.SerializeToString, - ), - "ApplySnapshotChunk": grpc.unary_unary_rpc_method_handler( - servicer.ApplySnapshotChunk, - request_deserializer=tendermint_dot_abci_dot_types__pb2.RequestApplySnapshotChunk.FromString, - response_serializer=tendermint_dot_abci_dot_types__pb2.ResponseApplySnapshotChunk.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - "tendermint.abci.ABCIApplication", rpc_method_handlers - ) - server.add_generic_rpc_handlers((generic_handler,)) - - -# This class is part of an EXPERIMENTAL API. -class ABCIApplication(object): - """---------------------------------------- - Service Definition - - """ - - @staticmethod - def Echo( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/Echo", - tendermint_dot_abci_dot_types__pb2.RequestEcho.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseEcho.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def Flush( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/Flush", - tendermint_dot_abci_dot_types__pb2.RequestFlush.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseFlush.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def Info( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/Info", - tendermint_dot_abci_dot_types__pb2.RequestInfo.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseInfo.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def SetOption( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/SetOption", - tendermint_dot_abci_dot_types__pb2.RequestSetOption.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseSetOption.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def DeliverTx( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/DeliverTx", - tendermint_dot_abci_dot_types__pb2.RequestDeliverTx.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseDeliverTx.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def CheckTx( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/CheckTx", - tendermint_dot_abci_dot_types__pb2.RequestCheckTx.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseCheckTx.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def Query( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/Query", - tendermint_dot_abci_dot_types__pb2.RequestQuery.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseQuery.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def Commit( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/Commit", - tendermint_dot_abci_dot_types__pb2.RequestCommit.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseCommit.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def InitChain( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/InitChain", - tendermint_dot_abci_dot_types__pb2.RequestInitChain.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseInitChain.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def BeginBlock( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/BeginBlock", - tendermint_dot_abci_dot_types__pb2.RequestBeginBlock.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseBeginBlock.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def EndBlock( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/EndBlock", - tendermint_dot_abci_dot_types__pb2.RequestEndBlock.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseEndBlock.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def ListSnapshots( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/ListSnapshots", - tendermint_dot_abci_dot_types__pb2.RequestListSnapshots.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseListSnapshots.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def OfferSnapshot( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/OfferSnapshot", - tendermint_dot_abci_dot_types__pb2.RequestOfferSnapshot.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseOfferSnapshot.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def LoadSnapshotChunk( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/LoadSnapshotChunk", - tendermint_dot_abci_dot_types__pb2.RequestLoadSnapshotChunk.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseLoadSnapshotChunk.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def ApplySnapshotChunk( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/tendermint.abci.ABCIApplication/ApplySnapshotChunk", - tendermint_dot_abci_dot_types__pb2.RequestApplySnapshotChunk.SerializeToString, - tendermint_dot_abci_dot_types__pb2.ResponseApplySnapshotChunk.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) diff --git a/trader_old/vendor/valory/connections/abci/tendermint/crypto/keys_pb2.py b/trader_old/vendor/valory/connections/abci/tendermint/crypto/keys_pb2.py deleted file mode 100644 index dc00b9008..000000000 --- a/trader_old/vendor/valory/connections/abci/tendermint/crypto/keys_pb2.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/crypto/keys.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1ctendermint/crypto/keys.proto\x12\x11tendermint.crypto\x1a\x14gogoproto/gogo.proto"D\n\tPublicKey\x12\x11\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x01 \x01(\x0cH\x00\x12\x13\n\tsecp256k1\x18\x02 \x01(\x0cH\x00:\x08\xe8\xa0\x1f\x01\xe8\xa1\x1f\x01\x42\x05\n\x03sumB:Z8github.com/tendermint/tendermint/proto/tendermint/cryptob\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.crypto.keys_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b"Z8github.com/tendermint/tendermint/proto/tendermint/crypto" - ) - _PUBLICKEY._options = None - _PUBLICKEY._serialized_options = b"\350\240\037\001\350\241\037\001" - _globals["_PUBLICKEY"]._serialized_start = 73 - _globals["_PUBLICKEY"]._serialized_end = 141 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/connections/abci/tendermint/crypto/proof_pb2.py b/trader_old/vendor/valory/connections/abci/tendermint/crypto/proof_pb2.py deleted file mode 100644 index adf30b16e..000000000 --- a/trader_old/vendor/valory/connections/abci/tendermint/crypto/proof_pb2.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/crypto/proof.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1dtendermint/crypto/proof.proto\x12\x11tendermint.crypto\x1a\x14gogoproto/gogo.proto"G\n\x05Proof\x12\r\n\x05total\x18\x01 \x01(\x03\x12\r\n\x05index\x18\x02 \x01(\x03\x12\x11\n\tleaf_hash\x18\x03 \x01(\x0c\x12\r\n\x05\x61unts\x18\x04 \x03(\x0c"?\n\x07ValueOp\x12\x0b\n\x03key\x18\x01 \x01(\x0c\x12\'\n\x05proof\x18\x02 \x01(\x0b\x32\x18.tendermint.crypto.Proof"6\n\x08\x44ominoOp\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05input\x18\x02 \x01(\t\x12\x0e\n\x06output\x18\x03 \x01(\t"2\n\x07ProofOp\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c"9\n\x08ProofOps\x12-\n\x03ops\x18\x01 \x03(\x0b\x32\x1a.tendermint.crypto.ProofOpB\x04\xc8\xde\x1f\x00\x42:Z8github.com/tendermint/tendermint/proto/tendermint/cryptob\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.crypto.proof_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b"Z8github.com/tendermint/tendermint/proto/tendermint/crypto" - ) - _PROOFOPS.fields_by_name["ops"]._options = None - _PROOFOPS.fields_by_name["ops"]._serialized_options = b"\310\336\037\000" - _globals["_PROOF"]._serialized_start = 74 - _globals["_PROOF"]._serialized_end = 145 - _globals["_VALUEOP"]._serialized_start = 147 - _globals["_VALUEOP"]._serialized_end = 210 - _globals["_DOMINOOP"]._serialized_start = 212 - _globals["_DOMINOOP"]._serialized_end = 266 - _globals["_PROOFOP"]._serialized_start = 268 - _globals["_PROOFOP"]._serialized_end = 318 - _globals["_PROOFOPS"]._serialized_start = 320 - _globals["_PROOFOPS"]._serialized_end = 377 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/connections/abci/tendermint/types/params_pb2.py b/trader_old/vendor/valory/connections/abci/tendermint/types/params_pb2.py deleted file mode 100644 index c94e41144..000000000 --- a/trader_old/vendor/valory/connections/abci/tendermint/types/params_pb2.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/types/params.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1dtendermint/types/params.proto\x12\x10tendermint.types\x1a\x14gogoproto/gogo.proto\x1a\x1egoogle/protobuf/duration.proto"\xf3\x01\n\x0f\x43onsensusParams\x12\x32\n\x05\x62lock\x18\x01 \x01(\x0b\x32\x1d.tendermint.types.BlockParamsB\x04\xc8\xde\x1f\x00\x12\x38\n\x08\x65vidence\x18\x02 \x01(\x0b\x32 .tendermint.types.EvidenceParamsB\x04\xc8\xde\x1f\x00\x12:\n\tvalidator\x18\x03 \x01(\x0b\x32!.tendermint.types.ValidatorParamsB\x04\xc8\xde\x1f\x00\x12\x36\n\x07version\x18\x04 \x01(\x0b\x32\x1f.tendermint.types.VersionParamsB\x04\xc8\xde\x1f\x00"G\n\x0b\x42lockParams\x12\x11\n\tmax_bytes\x18\x01 \x01(\x03\x12\x0f\n\x07max_gas\x18\x02 \x01(\x03\x12\x14\n\x0ctime_iota_ms\x18\x03 \x01(\x03"~\n\x0e\x45videnceParams\x12\x1a\n\x12max_age_num_blocks\x18\x01 \x01(\x03\x12=\n\x10max_age_duration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationB\x08\xc8\xde\x1f\x00\x98\xdf\x1f\x01\x12\x11\n\tmax_bytes\x18\x03 \x01(\x03"2\n\x0fValidatorParams\x12\x15\n\rpub_key_types\x18\x01 \x03(\t:\x08\xb8\xa0\x1f\x01\xe8\xa0\x1f\x01".\n\rVersionParams\x12\x13\n\x0b\x61pp_version\x18\x01 \x01(\x04:\x08\xb8\xa0\x1f\x01\xe8\xa0\x1f\x01">\n\x0cHashedParams\x12\x17\n\x0f\x62lock_max_bytes\x18\x01 \x01(\x03\x12\x15\n\rblock_max_gas\x18\x02 \x01(\x03\x42=Z7github.com/tendermint/tendermint/proto/tendermint/types\xa8\xe2\x1e\x01\x62\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.types.params_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b"Z7github.com/tendermint/tendermint/proto/tendermint/types\250\342\036\001" - ) - _CONSENSUSPARAMS.fields_by_name["block"]._options = None - _CONSENSUSPARAMS.fields_by_name["block"]._serialized_options = b"\310\336\037\000" - _CONSENSUSPARAMS.fields_by_name["evidence"]._options = None - _CONSENSUSPARAMS.fields_by_name[ - "evidence" - ]._serialized_options = b"\310\336\037\000" - _CONSENSUSPARAMS.fields_by_name["validator"]._options = None - _CONSENSUSPARAMS.fields_by_name[ - "validator" - ]._serialized_options = b"\310\336\037\000" - _CONSENSUSPARAMS.fields_by_name["version"]._options = None - _CONSENSUSPARAMS.fields_by_name["version"]._serialized_options = b"\310\336\037\000" - _EVIDENCEPARAMS.fields_by_name["max_age_duration"]._options = None - _EVIDENCEPARAMS.fields_by_name[ - "max_age_duration" - ]._serialized_options = b"\310\336\037\000\230\337\037\001" - _VALIDATORPARAMS._options = None - _VALIDATORPARAMS._serialized_options = b"\270\240\037\001\350\240\037\001" - _VERSIONPARAMS._options = None - _VERSIONPARAMS._serialized_options = b"\270\240\037\001\350\240\037\001" - _globals["_CONSENSUSPARAMS"]._serialized_start = 106 - _globals["_CONSENSUSPARAMS"]._serialized_end = 349 - _globals["_BLOCKPARAMS"]._serialized_start = 351 - _globals["_BLOCKPARAMS"]._serialized_end = 422 - _globals["_EVIDENCEPARAMS"]._serialized_start = 424 - _globals["_EVIDENCEPARAMS"]._serialized_end = 550 - _globals["_VALIDATORPARAMS"]._serialized_start = 552 - _globals["_VALIDATORPARAMS"]._serialized_end = 602 - _globals["_VERSIONPARAMS"]._serialized_start = 604 - _globals["_VERSIONPARAMS"]._serialized_end = 650 - _globals["_HASHEDPARAMS"]._serialized_start = 652 - _globals["_HASHEDPARAMS"]._serialized_end = 714 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/connections/abci/tendermint/types/types_pb2.py b/trader_old/vendor/valory/connections/abci/tendermint/types/types_pb2.py deleted file mode 100644 index 1818466ed..000000000 --- a/trader_old/vendor/valory/connections/abci/tendermint/types/types_pb2.py +++ /dev/null @@ -1,158 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/types/types.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) -from packages.valory.connections.abci.tendermint.crypto import ( - proof_pb2 as tendermint_dot_crypto_dot_proof__pb2, -) -from packages.valory.connections.abci.tendermint.types import ( - validator_pb2 as tendermint_dot_types_dot_validator__pb2, -) -from packages.valory.connections.abci.tendermint.version import ( - types_pb2 as tendermint_dot_version_dot_types__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1ctendermint/types/types.proto\x12\x10tendermint.types\x1a\x14gogoproto/gogo.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1dtendermint/crypto/proof.proto\x1a\x1etendermint/version/types.proto\x1a tendermint/types/validator.proto",\n\rPartSetHeader\x12\r\n\x05total\x18\x01 \x01(\r\x12\x0c\n\x04hash\x18\x02 \x01(\x0c"S\n\x04Part\x12\r\n\x05index\x18\x01 \x01(\r\x12\r\n\x05\x62ytes\x18\x02 \x01(\x0c\x12-\n\x05proof\x18\x03 \x01(\x0b\x32\x18.tendermint.crypto.ProofB\x04\xc8\xde\x1f\x00"W\n\x07\x42lockID\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12>\n\x0fpart_set_header\x18\x02 \x01(\x0b\x32\x1f.tendermint.types.PartSetHeaderB\x04\xc8\xde\x1f\x00"\xb3\x03\n\x06Header\x12\x34\n\x07version\x18\x01 \x01(\x0b\x32\x1d.tendermint.version.ConsensusB\x04\xc8\xde\x1f\x00\x12\x1d\n\x08\x63hain_id\x18\x02 \x01(\tB\x0b\xe2\xde\x1f\x07\x43hainID\x12\x0e\n\x06height\x18\x03 \x01(\x03\x12\x32\n\x04time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x08\xc8\xde\x1f\x00\x90\xdf\x1f\x01\x12\x36\n\rlast_block_id\x18\x05 \x01(\x0b\x32\x19.tendermint.types.BlockIDB\x04\xc8\xde\x1f\x00\x12\x18\n\x10last_commit_hash\x18\x06 \x01(\x0c\x12\x11\n\tdata_hash\x18\x07 \x01(\x0c\x12\x17\n\x0fvalidators_hash\x18\x08 \x01(\x0c\x12\x1c\n\x14next_validators_hash\x18\t \x01(\x0c\x12\x16\n\x0e\x63onsensus_hash\x18\n \x01(\x0c\x12\x10\n\x08\x61pp_hash\x18\x0b \x01(\x0c\x12\x19\n\x11last_results_hash\x18\x0c \x01(\x0c\x12\x15\n\revidence_hash\x18\r \x01(\x0c\x12\x18\n\x10proposer_address\x18\x0e \x01(\x0c"\x13\n\x04\x44\x61ta\x12\x0b\n\x03txs\x18\x01 \x03(\x0c"\x92\x02\n\x04Vote\x12-\n\x04type\x18\x01 \x01(\x0e\x32\x1f.tendermint.types.SignedMsgType\x12\x0e\n\x06height\x18\x02 \x01(\x03\x12\r\n\x05round\x18\x03 \x01(\x05\x12<\n\x08\x62lock_id\x18\x04 \x01(\x0b\x32\x19.tendermint.types.BlockIDB\x0f\xc8\xde\x1f\x00\xe2\xde\x1f\x07\x42lockID\x12\x37\n\ttimestamp\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x08\xc8\xde\x1f\x00\x90\xdf\x1f\x01\x12\x19\n\x11validator_address\x18\x06 \x01(\x0c\x12\x17\n\x0fvalidator_index\x18\x07 \x01(\x05\x12\x11\n\tsignature\x18\x08 \x01(\x0c"\x9c\x01\n\x06\x43ommit\x12\x0e\n\x06height\x18\x01 \x01(\x03\x12\r\n\x05round\x18\x02 \x01(\x05\x12<\n\x08\x62lock_id\x18\x03 \x01(\x0b\x32\x19.tendermint.types.BlockIDB\x0f\xc8\xde\x1f\x00\xe2\xde\x1f\x07\x42lockID\x12\x35\n\nsignatures\x18\x04 \x03(\x0b\x32\x1b.tendermint.types.CommitSigB\x04\xc8\xde\x1f\x00"\xa8\x01\n\tCommitSig\x12\x34\n\rblock_id_flag\x18\x01 \x01(\x0e\x32\x1d.tendermint.types.BlockIDFlag\x12\x19\n\x11validator_address\x18\x02 \x01(\x0c\x12\x37\n\ttimestamp\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x08\xc8\xde\x1f\x00\x90\xdf\x1f\x01\x12\x11\n\tsignature\x18\x04 \x01(\x0c"\xf5\x01\n\x08Proposal\x12-\n\x04type\x18\x01 \x01(\x0e\x32\x1f.tendermint.types.SignedMsgType\x12\x0e\n\x06height\x18\x02 \x01(\x03\x12\r\n\x05round\x18\x03 \x01(\x05\x12\x11\n\tpol_round\x18\x04 \x01(\x05\x12<\n\x08\x62lock_id\x18\x05 \x01(\x0b\x32\x19.tendermint.types.BlockIDB\x0f\xc8\xde\x1f\x00\xe2\xde\x1f\x07\x42lockID\x12\x37\n\ttimestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x08\xc8\xde\x1f\x00\x90\xdf\x1f\x01\x12\x11\n\tsignature\x18\x07 \x01(\x0c"b\n\x0cSignedHeader\x12(\n\x06header\x18\x01 \x01(\x0b\x32\x18.tendermint.types.Header\x12(\n\x06\x63ommit\x18\x02 \x01(\x0b\x32\x18.tendermint.types.Commit"z\n\nLightBlock\x12\x35\n\rsigned_header\x18\x01 \x01(\x0b\x32\x1e.tendermint.types.SignedHeader\x12\x35\n\rvalidator_set\x18\x02 \x01(\x0b\x32\x1e.tendermint.types.ValidatorSet"\x9e\x01\n\tBlockMeta\x12<\n\x08\x62lock_id\x18\x01 \x01(\x0b\x32\x19.tendermint.types.BlockIDB\x0f\xc8\xde\x1f\x00\xe2\xde\x1f\x07\x42lockID\x12\x12\n\nblock_size\x18\x02 \x01(\x03\x12.\n\x06header\x18\x03 \x01(\x0b\x32\x18.tendermint.types.HeaderB\x04\xc8\xde\x1f\x00\x12\x0f\n\x07num_txs\x18\x04 \x01(\x03"S\n\x07TxProof\x12\x11\n\troot_hash\x18\x01 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\'\n\x05proof\x18\x03 \x01(\x0b\x32\x18.tendermint.crypto.Proof*\xd7\x01\n\x0b\x42lockIDFlag\x12\x31\n\x15\x42LOCK_ID_FLAG_UNKNOWN\x10\x00\x1a\x16\x8a\x9d \x12\x42lockIDFlagUnknown\x12/\n\x14\x42LOCK_ID_FLAG_ABSENT\x10\x01\x1a\x15\x8a\x9d \x11\x42lockIDFlagAbsent\x12/\n\x14\x42LOCK_ID_FLAG_COMMIT\x10\x02\x1a\x15\x8a\x9d \x11\x42lockIDFlagCommit\x12)\n\x11\x42LOCK_ID_FLAG_NIL\x10\x03\x1a\x12\x8a\x9d \x0e\x42lockIDFlagNil\x1a\x08\x88\xa3\x1e\x00\xa8\xa4\x1e\x01*\xd7\x01\n\rSignedMsgType\x12,\n\x17SIGNED_MSG_TYPE_UNKNOWN\x10\x00\x1a\x0f\x8a\x9d \x0bUnknownType\x12,\n\x17SIGNED_MSG_TYPE_PREVOTE\x10\x01\x1a\x0f\x8a\x9d \x0bPrevoteType\x12\x30\n\x19SIGNED_MSG_TYPE_PRECOMMIT\x10\x02\x1a\x11\x8a\x9d \rPrecommitType\x12.\n\x18SIGNED_MSG_TYPE_PROPOSAL\x10 \x1a\x10\x8a\x9d \x0cProposalType\x1a\x08\x88\xa3\x1e\x00\xa8\xa4\x1e\x01\x42\x39Z7github.com/tendermint/tendermint/proto/tendermint/typesb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.types.types_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b"Z7github.com/tendermint/tendermint/proto/tendermint/types" - ) - _BLOCKIDFLAG._options = None - _BLOCKIDFLAG._serialized_options = b"\210\243\036\000\250\244\036\001" - _BLOCKIDFLAG.values_by_name["BLOCK_ID_FLAG_UNKNOWN"]._options = None - _BLOCKIDFLAG.values_by_name[ - "BLOCK_ID_FLAG_UNKNOWN" - ]._serialized_options = b"\212\235 \022BlockIDFlagUnknown" - _BLOCKIDFLAG.values_by_name["BLOCK_ID_FLAG_ABSENT"]._options = None - _BLOCKIDFLAG.values_by_name[ - "BLOCK_ID_FLAG_ABSENT" - ]._serialized_options = b"\212\235 \021BlockIDFlagAbsent" - _BLOCKIDFLAG.values_by_name["BLOCK_ID_FLAG_COMMIT"]._options = None - _BLOCKIDFLAG.values_by_name[ - "BLOCK_ID_FLAG_COMMIT" - ]._serialized_options = b"\212\235 \021BlockIDFlagCommit" - _BLOCKIDFLAG.values_by_name["BLOCK_ID_FLAG_NIL"]._options = None - _BLOCKIDFLAG.values_by_name[ - "BLOCK_ID_FLAG_NIL" - ]._serialized_options = b"\212\235 \016BlockIDFlagNil" - _SIGNEDMSGTYPE._options = None - _SIGNEDMSGTYPE._serialized_options = b"\210\243\036\000\250\244\036\001" - _SIGNEDMSGTYPE.values_by_name["SIGNED_MSG_TYPE_UNKNOWN"]._options = None - _SIGNEDMSGTYPE.values_by_name[ - "SIGNED_MSG_TYPE_UNKNOWN" - ]._serialized_options = b"\212\235 \013UnknownType" - _SIGNEDMSGTYPE.values_by_name["SIGNED_MSG_TYPE_PREVOTE"]._options = None - _SIGNEDMSGTYPE.values_by_name[ - "SIGNED_MSG_TYPE_PREVOTE" - ]._serialized_options = b"\212\235 \013PrevoteType" - _SIGNEDMSGTYPE.values_by_name["SIGNED_MSG_TYPE_PRECOMMIT"]._options = None - _SIGNEDMSGTYPE.values_by_name[ - "SIGNED_MSG_TYPE_PRECOMMIT" - ]._serialized_options = b"\212\235 \rPrecommitType" - _SIGNEDMSGTYPE.values_by_name["SIGNED_MSG_TYPE_PROPOSAL"]._options = None - _SIGNEDMSGTYPE.values_by_name[ - "SIGNED_MSG_TYPE_PROPOSAL" - ]._serialized_options = b"\212\235 \014ProposalType" - _PART.fields_by_name["proof"]._options = None - _PART.fields_by_name["proof"]._serialized_options = b"\310\336\037\000" - _BLOCKID.fields_by_name["part_set_header"]._options = None - _BLOCKID.fields_by_name["part_set_header"]._serialized_options = b"\310\336\037\000" - _HEADER.fields_by_name["version"]._options = None - _HEADER.fields_by_name["version"]._serialized_options = b"\310\336\037\000" - _HEADER.fields_by_name["chain_id"]._options = None - _HEADER.fields_by_name["chain_id"]._serialized_options = b"\342\336\037\007ChainID" - _HEADER.fields_by_name["time"]._options = None - _HEADER.fields_by_name[ - "time" - ]._serialized_options = b"\310\336\037\000\220\337\037\001" - _HEADER.fields_by_name["last_block_id"]._options = None - _HEADER.fields_by_name["last_block_id"]._serialized_options = b"\310\336\037\000" - _VOTE.fields_by_name["block_id"]._options = None - _VOTE.fields_by_name[ - "block_id" - ]._serialized_options = b"\310\336\037\000\342\336\037\007BlockID" - _VOTE.fields_by_name["timestamp"]._options = None - _VOTE.fields_by_name[ - "timestamp" - ]._serialized_options = b"\310\336\037\000\220\337\037\001" - _COMMIT.fields_by_name["block_id"]._options = None - _COMMIT.fields_by_name[ - "block_id" - ]._serialized_options = b"\310\336\037\000\342\336\037\007BlockID" - _COMMIT.fields_by_name["signatures"]._options = None - _COMMIT.fields_by_name["signatures"]._serialized_options = b"\310\336\037\000" - _COMMITSIG.fields_by_name["timestamp"]._options = None - _COMMITSIG.fields_by_name[ - "timestamp" - ]._serialized_options = b"\310\336\037\000\220\337\037\001" - _PROPOSAL.fields_by_name["block_id"]._options = None - _PROPOSAL.fields_by_name[ - "block_id" - ]._serialized_options = b"\310\336\037\000\342\336\037\007BlockID" - _PROPOSAL.fields_by_name["timestamp"]._options = None - _PROPOSAL.fields_by_name[ - "timestamp" - ]._serialized_options = b"\310\336\037\000\220\337\037\001" - _BLOCKMETA.fields_by_name["block_id"]._options = None - _BLOCKMETA.fields_by_name[ - "block_id" - ]._serialized_options = b"\310\336\037\000\342\336\037\007BlockID" - _BLOCKMETA.fields_by_name["header"]._options = None - _BLOCKMETA.fields_by_name["header"]._serialized_options = b"\310\336\037\000" - _globals["_BLOCKIDFLAG"]._serialized_start = 2207 - _globals["_BLOCKIDFLAG"]._serialized_end = 2422 - _globals["_SIGNEDMSGTYPE"]._serialized_start = 2425 - _globals["_SIGNEDMSGTYPE"]._serialized_end = 2640 - _globals["_PARTSETHEADER"]._serialized_start = 202 - _globals["_PARTSETHEADER"]._serialized_end = 246 - _globals["_PART"]._serialized_start = 248 - _globals["_PART"]._serialized_end = 331 - _globals["_BLOCKID"]._serialized_start = 333 - _globals["_BLOCKID"]._serialized_end = 420 - _globals["_HEADER"]._serialized_start = 423 - _globals["_HEADER"]._serialized_end = 858 - _globals["_DATA"]._serialized_start = 860 - _globals["_DATA"]._serialized_end = 879 - _globals["_VOTE"]._serialized_start = 882 - _globals["_VOTE"]._serialized_end = 1156 - _globals["_COMMIT"]._serialized_start = 1159 - _globals["_COMMIT"]._serialized_end = 1315 - _globals["_COMMITSIG"]._serialized_start = 1318 - _globals["_COMMITSIG"]._serialized_end = 1486 - _globals["_PROPOSAL"]._serialized_start = 1489 - _globals["_PROPOSAL"]._serialized_end = 1734 - _globals["_SIGNEDHEADER"]._serialized_start = 1736 - _globals["_SIGNEDHEADER"]._serialized_end = 1834 - _globals["_LIGHTBLOCK"]._serialized_start = 1836 - _globals["_LIGHTBLOCK"]._serialized_end = 1958 - _globals["_BLOCKMETA"]._serialized_start = 1961 - _globals["_BLOCKMETA"]._serialized_end = 2119 - _globals["_TXPROOF"]._serialized_start = 2121 - _globals["_TXPROOF"]._serialized_end = 2204 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/connections/abci/tendermint/types/validator_pb2.py b/trader_old/vendor/valory/connections/abci/tendermint/types/validator_pb2.py deleted file mode 100644 index 990e243ee..000000000 --- a/trader_old/vendor/valory/connections/abci/tendermint/types/validator_pb2.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/types/validator.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) -from packages.valory.connections.abci.tendermint.crypto import ( - keys_pb2 as tendermint_dot_crypto_dot_keys__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n tendermint/types/validator.proto\x12\x10tendermint.types\x1a\x14gogoproto/gogo.proto\x1a\x1ctendermint/crypto/keys.proto"\x8a\x01\n\x0cValidatorSet\x12/\n\nvalidators\x18\x01 \x03(\x0b\x32\x1b.tendermint.types.Validator\x12-\n\x08proposer\x18\x02 \x01(\x0b\x32\x1b.tendermint.types.Validator\x12\x1a\n\x12total_voting_power\x18\x03 \x01(\x03"\x82\x01\n\tValidator\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0c\x12\x33\n\x07pub_key\x18\x02 \x01(\x0b\x32\x1c.tendermint.crypto.PublicKeyB\x04\xc8\xde\x1f\x00\x12\x14\n\x0cvoting_power\x18\x03 \x01(\x03\x12\x19\n\x11proposer_priority\x18\x04 \x01(\x03"V\n\x0fSimpleValidator\x12-\n\x07pub_key\x18\x01 \x01(\x0b\x32\x1c.tendermint.crypto.PublicKey\x12\x14\n\x0cvoting_power\x18\x02 \x01(\x03\x42\x39Z7github.com/tendermint/tendermint/proto/tendermint/typesb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.types.validator_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b"Z7github.com/tendermint/tendermint/proto/tendermint/types" - ) - _VALIDATOR.fields_by_name["pub_key"]._options = None - _VALIDATOR.fields_by_name["pub_key"]._serialized_options = b"\310\336\037\000" - _globals["_VALIDATORSET"]._serialized_start = 107 - _globals["_VALIDATORSET"]._serialized_end = 245 - _globals["_VALIDATOR"]._serialized_start = 248 - _globals["_VALIDATOR"]._serialized_end = 378 - _globals["_SIMPLEVALIDATOR"]._serialized_start = 380 - _globals["_SIMPLEVALIDATOR"]._serialized_end = 466 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/connections/abci/tendermint/version/types_pb2.py b/trader_old/vendor/valory/connections/abci/tendermint/version/types_pb2.py deleted file mode 100644 index 46fcbdf52..000000000 --- a/trader_old/vendor/valory/connections/abci/tendermint/version/types_pb2.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint/version/types.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from packages.valory.connections.abci.gogoproto import ( - gogo_pb2 as gogoproto_dot_gogo__pb2, -) - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1etendermint/version/types.proto\x12\x12tendermint.version\x1a\x14gogoproto/gogo.proto")\n\x03\x41pp\x12\x10\n\x08protocol\x18\x01 \x01(\x04\x12\x10\n\x08software\x18\x02 \x01(\t"-\n\tConsensus\x12\r\n\x05\x62lock\x18\x01 \x01(\x04\x12\x0b\n\x03\x61pp\x18\x02 \x01(\x04:\x04\xe8\xa0\x1f\x01\x42;Z9github.com/tendermint/tendermint/proto/tendermint/versionb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "tendermint.version.types_pb2", _globals -) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = ( - b"Z9github.com/tendermint/tendermint/proto/tendermint/version" - ) - _CONSENSUS._options = None - _CONSENSUS._serialized_options = b"\350\240\037\001" - _globals["_APP"]._serialized_start = 76 - _globals["_APP"]._serialized_end = 117 - _globals["_CONSENSUS"]._serialized_start = 119 - _globals["_CONSENSUS"]._serialized_end = 164 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/connections/abci/tendermint_decoder.py b/trader_old/vendor/valory/connections/abci/tendermint_decoder.py deleted file mode 100644 index a50a501fa..000000000 --- a/trader_old/vendor/valory/connections/abci/tendermint_decoder.py +++ /dev/null @@ -1,472 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ -"""Decode AEA messages from Tendermint protobuf messages.""" - -# isort: skip_file # noqa - -from typing import Callable, Optional, Tuple, cast - -from aea.exceptions import enforce -from google.protobuf.timestamp_pb2 import ( # pylint: disable=no-name-in-module - Timestamp as TimestampPb, -) - -from packages.valory.connections.abci.dialogues import AbciDialogue, AbciDialogues -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - Evidence as EvidencePb, -) -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - LastCommitInfo as LastCommitInfoPb, -) -from packages.valory.connections.abci.tendermint.abci.types_pb2 import Request # type: ignore -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - Validator as ValidatorPb, -) -from packages.valory.connections.abci.tendermint.types.types_pb2 import ( # type: ignore - Header as HeaderPb, -) -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import ( - BlockID, - CheckTxType, - CheckTxTypeEnum, - ConsensusParams, - Evidence, - Evidences, - Header, - LastCommitInfo, - PartSetHeader, - Snapshot, - Timestamp, - Validator, - ValidatorUpdates, - ValidatorUpdate, -) - - -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore # isort:skip - ConsensusParams as ConsensusParamsPb, -) -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore # isort:skip - ValidatorUpdate as ValidatorUpdatePb, -) - - -from packages.valory.connections.abci.tendermint.types.types_pb2 import ( # type: ignore - BlockID as BlockIDPb, -) - - -class _TendermintProtocolDecoder: - """ - Decoder called by the server to process requests from the TCP connection with Tendermint. - - It translates from Tendermint's ABCI Protobuf messages into the AEA's ABCI protocol messages. - """ - - @classmethod - def process( - cls, message: Request, dialogues: AbciDialogues, counterparty: str - ) -> Optional[Tuple[AbciMessage, AbciDialogue]]: - """Process an ABCI request or response.""" - is_request = isinstance(message, Request) - enforce(is_request, "only Request messages are allowed") - message_type = f"request_{message.WhichOneof('value')}" - handler: Callable[ - [Request, AbciDialogues, str], Optional[Tuple[AbciMessage, AbciDialogue]] - ] = getattr(cls, message_type, cls.no_match) - result = handler(message, dialogues, counterparty) - return result - - @classmethod - def request_echo( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode an echo request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - echo = request.echo - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_ECHO, - counterparty=counterparty, - message=echo.message, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_flush( - cls, _request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a flush request. - - :param _request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_FLUSH, - counterparty=counterparty, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_info( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a info request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - info = request.info - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_INFO, - counterparty=counterparty, - version=info.version, - block_version=info.block_version, - p2p_version=info.p2p_version, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_set_option( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a set_option request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - set_option = request.set_option - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_SET_OPTION, - counterparty=counterparty, - option_key=set_option.key, - option_value=set_option.value, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_init_chain( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a init_chain request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - init_chain = request.init_chain - timestamp = cls._decode_timestamp(init_chain.time) - chain_id = init_chain.chain_id - consensus_params = ( - cls._decode_consensus_params(init_chain.consensus_params) - if init_chain.consensus_params is not None - else None - ) - validators = ValidatorUpdates( - [ - cls._decode_validator_update(validator_update_pb) - for validator_update_pb in list(init_chain.validators) - ] - ) - app_state_bytes = init_chain.app_state_bytes - initial_height = init_chain.initial_height - - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_INIT_CHAIN, - counterparty=counterparty, - time=timestamp, - chain_id=chain_id, - validators=validators, - app_state_bytes=app_state_bytes, - initial_height=initial_height, - ) - if consensus_params is not None: - abci_message.set("consensus_params", consensus_params) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_begin_block( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a begin_block request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - begin_block = request.begin_block - hash_ = begin_block.hash - header = cls._decode_header(begin_block.header) - last_commit_info = cls._decode_last_commit_info(begin_block.last_commit_info) - evidences = [ - cls._decode_evidence(byzantine_validator) - for byzantine_validator in list(begin_block.byzantine_validators) - ] - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_BEGIN_BLOCK, - counterparty=counterparty, - hash=hash_, - header=header, - last_commit_info=last_commit_info, - byzantine_validators=Evidences(evidences), - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_check_tx( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a check_tx request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - check_tx = request.check_tx - transaction = check_tx.tx - check_tx_type = CheckTxType(CheckTxTypeEnum(check_tx.type)) - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_CHECK_TX, - counterparty=counterparty, - tx=transaction, - type=check_tx_type, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_deliver_tx( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a deliver_tx request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - counterparty=counterparty, - tx=request.deliver_tx.tx, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_query( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a query request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_QUERY, - counterparty=counterparty, - query_data=request.query.data, - path=request.query.path, - height=request.query.height, - prove=request.query.prove, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_commit( - cls, _request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode a commit request. - - :param _request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_COMMIT, - counterparty=counterparty, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_end_block( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """ - Decode an end_block request. - - :param request: the request. - :param dialogues: the dialogues object. - :param counterparty: the counterparty. - :return: the AbciMessage request. - """ - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_END_BLOCK, - counterparty=counterparty, - height=request.end_block.height, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_list_snapshots( - cls, _request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """Decode a list_snapshots request.""" - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS, - counterparty=counterparty, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_offer_snapshot( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """Decode a offer_snapshot request.""" - offer_snapshot = request.offer_snapshot - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT, - counterparty=counterparty, - snapshot=Snapshot( - offer_snapshot.snapshot.height, - offer_snapshot.snapshot.format, - offer_snapshot.snapshot.chunks, - offer_snapshot.snapshot.hash, - offer_snapshot.snapshot.metadata, - ), - app_hash=offer_snapshot.app_hash, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_load_snapshot_chunk( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """Decode a load_snapshot_chunk request.""" - load_snapshot_chunk = request.load_snapshot_chunk - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK, - counterparty=counterparty, - height=load_snapshot_chunk.height, - format=load_snapshot_chunk.format, - chunk_index=load_snapshot_chunk.chunk, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def request_apply_snapshot_chunk( - cls, request: Request, dialogues: AbciDialogues, counterparty: str - ) -> Tuple[AbciMessage, AbciDialogue]: - """Decode a apply_snapshot_chunk request.""" - apply_snapshot_chunk = request.apply_snapshot_chunk - abci_message, abci_dialogue = dialogues.create( - performative=AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK, - counterparty=counterparty, - index=apply_snapshot_chunk.index, - chunk=apply_snapshot_chunk.chunk, - chunk_sender=apply_snapshot_chunk.sender, - ) - return cast(AbciMessage, abci_message), cast(AbciDialogue, abci_dialogue) - - @classmethod - def no_match( - cls, _request: Request, _dialogues: AbciDialogues, _counterparty: str - ) -> None: # pragma: nocover - """Handle the case in which the request is not supported.""" - return None - - @classmethod - def _decode_timestamp(cls, timestamp_tendermint_pb: TimestampPb) -> Timestamp: - """Decode a timestamp object.""" - return Timestamp( - timestamp_tendermint_pb.seconds, - timestamp_tendermint_pb.nanos, - ) - - @classmethod - def _decode_consensus_params( - cls, consensus_params_tendermint_pb: ConsensusParamsPb - ) -> ConsensusParams: - """Decode a ConsensusParams object.""" - return ConsensusParams.decode(consensus_params_tendermint_pb) - - @classmethod - def _decode_validator_update( - cls, validator_update_pb: ValidatorUpdatePb - ) -> ValidatorUpdate: - """Decode a ValidatorUpdate object.""" - return ValidatorUpdate.decode(validator_update_pb) - - @classmethod - def _decode_header(cls, header_tendermint_pb: HeaderPb) -> Header: - """Decode a Header object.""" - return Header.decode(header_tendermint_pb) - - @classmethod - def _decode_block_id(cls, block_id_pb: BlockIDPb) -> BlockID: # pragma: nocover - """Decode a Block ID object.""" - part_set_header_pb = block_id_pb.part_set_header - part_set_header = PartSetHeader( - part_set_header_pb.index, part_set_header_pb.bytes - ) - return BlockID(block_id_pb.hash, part_set_header) - - @classmethod - def _decode_last_commit_info( - cls, last_commit_info_tendermint_pb: LastCommitInfoPb - ) -> LastCommitInfo: - """Decode a LastCommitInfo object.""" - return LastCommitInfo.decode(last_commit_info_tendermint_pb) - - @classmethod - def _decode_validator( - cls, validator_pb: ValidatorPb - ) -> Validator: # pragma: nocover - """Decode a Validator object.""" - return Validator(validator_pb.address, validator_pb.power) - - @classmethod - def _decode_evidence(cls, evidence_pb: EvidencePb) -> Evidence: # pragma: nocover - """Decode an Evidence object.""" - return Evidence.decode(evidence_pb) diff --git a/trader_old/vendor/valory/connections/abci/tendermint_encoder.py b/trader_old/vendor/valory/connections/abci/tendermint_encoder.py deleted file mode 100644 index 47b9d1041..000000000 --- a/trader_old/vendor/valory/connections/abci/tendermint_encoder.py +++ /dev/null @@ -1,418 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ -"""Encode AEA messages into Tendermint protobuf messages.""" -# pylint: disable=no-member -from typing import Callable, Optional, Union, cast - -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - ConsensusParams, - Event, - EventAttribute, - Request, - Response, - ResponseApplySnapshotChunk, - ResponseBeginBlock, - ResponseCheckTx, - ResponseCommit, - ResponseDeliverTx, - ResponseEcho, - ResponseEndBlock, - ResponseException, - ResponseFlush, - ResponseInfo, - ResponseInitChain, - ResponseListSnapshots, - ResponseLoadSnapshotChunk, - ResponseOfferSnapshot, - ResponseQuery, - ResponseSetOption, - Snapshot, - ValidatorUpdate, -) -from packages.valory.connections.abci.tendermint.crypto.proof_pb2 import ( # type: ignore - ProofOp, - ProofOps, -) -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import ( - ConsensusParams as CustomConsensusParams, -) -from packages.valory.protocols.abci.custom_types import Event as CustomEvent -from packages.valory.protocols.abci.custom_types import ( - EventAttribute as CustomEventAttribute, -) -from packages.valory.protocols.abci.custom_types import ProofOp as CustomProofOp -from packages.valory.protocols.abci.custom_types import ProofOps as CustomProofOps -from packages.valory.protocols.abci.custom_types import Snapshot as CustomSnapshot -from packages.valory.protocols.abci.custom_types import ( - ValidatorUpdate as CustomValidatorUpdate, -) - - -class _TendermintProtocolEncoder: - """ - Decoder called by the server to process requests *towards* the TCP connection with Tendermint. - - It translates from the AEA's ABCI protocol messages into Tendermint's ABCI Protobuf messages. - """ - - @classmethod - def process(cls, message: AbciMessage) -> Optional[Union[Request, Response]]: - """Encode an AbciMessage object into either Request or Response protobuf objects.""" - # from "(request|response)_type", get 'type' - handler: Callable[[AbciMessage], Union[Request, Response]] = getattr( - cls, message.performative.value, cls.no_match - ) - return handler(message) - - @classmethod - def response_exception(cls, message: AbciMessage) -> Response: - """ - Process the response exception. - - :param message: the response. - :return: the ABCI protobuf object. - """ - exception = ResponseException() - exception.error = message.error - response = Response(exception=exception) - return response - - @classmethod - def response_echo(cls, message: AbciMessage) -> Response: - """ - Process the response echo. - - :param message: the response. - :return: the ABCI protobuf object. - """ - echo = ResponseEcho() - echo.message = message.message - response = Response(echo=echo) - return response - - @classmethod - def response_set_option(cls, message: AbciMessage) -> Response: - """ - Process the response set_option. - - :param message: the response. - :return: the ABCI protobuf object. - """ - set_option = ResponseSetOption() - set_option.code = message.code - set_option.log = message.log - set_option.info = message.info - response = Response(set_option=set_option) - return response - - @classmethod - def response_info(cls, message: AbciMessage) -> Response: - """ - Process the response info. - - :param message: the response. - :return: the ABCI protobuf object. - """ - info = ResponseInfo() - info.data = message.info_data - info.version = message.version - info.app_version = message.app_version - info.last_block_height = message.last_block_height - info.last_block_app_hash = message.last_block_app_hash - response = Response(info=info) - return response - - @classmethod - def response_flush(cls, _message: AbciMessage) -> Response: - """ - Process the response flush. - - :param _message: the response. - :return: the ABCI protobuf object. - """ - response = Response(flush=ResponseFlush()) - return response - - @classmethod - def response_init_chain(cls, message: AbciMessage) -> Response: - """ - Process the response init_chain. - - :param message: the response. - :return: the ABCI protobuf object. - """ - init_chain = ResponseInitChain() - - if message.consensus_params is not None: - consensus_params_pb = cls._encode_consensus_params(message.consensus_params) - init_chain.consensus_params.CopyFrom(consensus_params_pb) - - validators_pb = [ - cls._encode_validator_update(vu) - for vu in list(message.validators.validator_updates) - ] - init_chain.validators.extend(validators_pb) - - init_chain.app_hash = message.app_hash - - response = Response(init_chain=init_chain) - return response - - @classmethod - def response_query(cls, message: AbciMessage) -> Response: - """ - Process the response query. - - :param message: the response. - :return: the ABCI protobuf object. - """ - query = ResponseQuery() - - query.code = message.code - query.log = message.log - query.info = message.info - query.index = message.index - query.key = message.key - query.value = message.value - - proof_ops_pb = cls._encode_proof_ops(message.proof_ops) - query.proof_ops.CopyFrom(proof_ops_pb) - - query.height = message.height - query.codespace = message.codespace - - response = Response(query=query) - return response - - @classmethod - def response_check_tx(cls, message: AbciMessage) -> Response: - """ - Process the response check_tx. - - :param message: the response. - :return: the ABCI protobuf object. - """ - check_tx = ResponseCheckTx() - - check_tx.code = message.code - check_tx.data = message.data - check_tx.log = message.log - check_tx.info = message.info - check_tx.gas_wanted = message.gas_wanted - check_tx.gas_used = message.gas_used - - events_pb = [cls._encode_event(e) for e in message.events.events] - check_tx.events.extend(events_pb) - - check_tx.codespace = message.codespace - - response = Response(check_tx=check_tx) - return response - - @classmethod - def response_deliver_tx(cls, message: AbciMessage) -> Response: - """ - Process the response deliver_tx. - - :param message: the response. - :return: the ABCI protobuf object. - """ - deliver_tx = ResponseDeliverTx() - - deliver_tx.code = message.code - deliver_tx.data = message.data - deliver_tx.log = message.log - deliver_tx.info = message.info - deliver_tx.gas_wanted = message.gas_wanted - deliver_tx.gas_used = message.gas_used - - events_pb = [cls._encode_event(e) for e in message.events.events] - deliver_tx.events.extend(events_pb) - - deliver_tx.codespace = message.codespace - - response = Response(deliver_tx=deliver_tx) - return response - - @classmethod - def response_begin_block(cls, message: AbciMessage) -> Response: - """ - Process the response begin_block. - - :param message: the response. - :return: the ABCI protobuf object. - """ - begin_block = ResponseBeginBlock() - - events_pb = [cls._encode_event(e) for e in message.events.events] - begin_block.events.extend(events_pb) - - response = Response(begin_block=begin_block) - return response - - @classmethod - def response_end_block(cls, message: AbciMessage) -> Response: - """ - Process the response end_block. - - :param message: the response. - :return: the ABCI protobuf object. - """ - end_block = ResponseEndBlock() - - if ( - message.is_set("consensus_param_updates") - and message.consensus_param_updates is not None - ): - consensus_params_updates = cast( - ConsensusParams, message.consensus_param_updates - ) - consensus_params_pb = cls._encode_consensus_params(consensus_params_updates) - end_block.consensus_param_updates.CopyFrom(consensus_params_pb) - - validator_updates_pb = [ - cls._encode_validator_update(vu) - for vu in message.validator_updates.validator_updates - ] - end_block.validator_updates.extend(validator_updates_pb) - - events_pb = [cls._encode_event(e) for e in message.events.events] - end_block.events.extend(events_pb) - - response = Response(end_block=end_block) - return response - - @classmethod - def response_commit(cls, message: AbciMessage) -> Response: - """ - Process the response commit. - - :param message: the response. - :return: the ABCI protobuf object. - """ - commit = ResponseCommit() - commit.data = message.data - commit.retain_height = message.retain_height - return Response(commit=commit) - - @classmethod - def response_list_snapshots(cls, message: AbciMessage) -> Response: - """ - Process the response list_snapshots. - - :param message: the response. - :return: the ABCI protobuf object. - """ - list_snapshots = ResponseListSnapshots() - snapshots_pb = [ - cls._encode_snapshot(snapshot) for snapshot in message.snapshots.snapshots - ] - list_snapshots.snapshots.extend(snapshots_pb) - return Response(list_snapshots=list_snapshots) - - @classmethod - def response_offer_snapshot(cls, message: AbciMessage) -> Response: - """ - Process the response offer_snapshot. - - :param message: the response. - :return: the ABCI protobuf object. - """ - offer_snapshot = ResponseOfferSnapshot() - offer_snapshot.result = message.result.result_type.value - return Response(offer_snapshot=offer_snapshot) - - @classmethod - def response_load_snapshot_chunk(cls, message: AbciMessage) -> Response: - """ - Process the response load_snapshot_chunk. - - :param message: the response. - :return: the ABCI protobuf object. - """ - load_snapshot_chunk = ResponseLoadSnapshotChunk() - load_snapshot_chunk.chunk = message.chunk - return Response(load_snapshot_chunk=load_snapshot_chunk) - - @classmethod - def response_apply_snapshot_chunk(cls, message: AbciMessage) -> Response: - """ - Process the response apply_snapshot_chunk. - - :param message: the response. - :return: the ABCI protobuf object. - """ - apply_snapshot_chunk = ResponseApplySnapshotChunk() - apply_snapshot_chunk.result = message.result.result_type.value - apply_snapshot_chunk.refetch_chunks.extend(message.refetch_chunks) - apply_snapshot_chunk.reject_senders.extend(message.reject_senders) - return Response(apply_snapshot_chunk=apply_snapshot_chunk) - - @classmethod - def no_match(cls, _request: Request) -> None: # pragma: nocover - """No match.""" - return None - - @classmethod - def _encode_consensus_params( - cls, consensus_params: CustomConsensusParams - ) -> ConsensusParams: - consensus_params_pb = ConsensusParams() - CustomConsensusParams.encode(consensus_params_pb, consensus_params) - return consensus_params_pb - - @classmethod - def _encode_validator_update( - cls, validator_update: CustomValidatorUpdate - ) -> ValidatorUpdate: - validator_update_pb = ValidatorUpdate() - CustomValidatorUpdate.encode(validator_update_pb, validator_update) - return validator_update_pb - - @classmethod - def _encode_event(cls, event: CustomEvent) -> Event: - attributes_pb = [] - for attribute in event.attributes: - attribute_pb = EventAttribute() - CustomEventAttribute.encode(attribute_pb, attribute) - attributes_pb.append(attribute_pb) - - event_pb = Event() - event_pb.type = event.type_ - event_pb.attributes.extend(attributes_pb) - return event_pb - - @classmethod - def _encode_proof_ops(cls, proof_ops: CustomProofOps) -> ProofOps: - ops_pb = [] - for proof_op in proof_ops.proof_ops: - proof_op_pb = ProofOp() - CustomProofOp.encode(proof_op_pb, proof_op) - ops_pb.append(proof_op_pb) - - proof_ops_pb = ProofOps() - proof_ops_pb.ops.extend(ops_pb) - return proof_ops_pb - - @classmethod - def _encode_snapshot(cls, snapshot: CustomSnapshot) -> Event: - snapshot_pb = Snapshot() - CustomSnapshot.encode(snapshot_pb, snapshot) - return snapshot_pb diff --git a/trader_old/vendor/valory/connections/abci/tests/__init__.py b/trader_old/vendor/valory/connections/abci/tests/__init__.py deleted file mode 100644 index 0a13f4963..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/abci connection.""" - -from hypothesis import settings - - -CI = "CI" # pragma: nocover - -settings.register_profile(CI, deadline=5000) # pragma: nocover diff --git a/trader_old/vendor/valory/connections/abci/tests/helper.py b/trader_old/vendor/valory/connections/abci/tests/helper.py deleted file mode 100644 index da6e982df..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/helper.py +++ /dev/null @@ -1,533 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Helper functions for checking compliance to ABCI spec""" - -# pylint: skip-file - -import builtins -import functools -import inspect -from enum import Enum -from pathlib import Path -from types import ModuleType -from typing import Any, Dict, List, Tuple, Type, Union - -import yaml -from aea.protocols.generator.common import ( - SPECIFICATION_COMPOSITIONAL_TYPES, - _camel_case_to_snake_case, - _get_sub_types_of_compositional_types, - _to_camel_case, -) -from google.protobuf.descriptor import FieldDescriptor - -from packages.valory.connections.abci.connection import PUBLIC_ID -from packages.valory.connections.abci.connection import ( - _TendermintProtocolDecoder as Decoder, -) -from packages.valory.connections.abci.connection import ( - _TendermintProtocolEncoder as Encoder, -) -from packages.valory.connections.abci.dialogues import AbciDialogues -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - DESCRIPTOR, - Request, - Response, -) -from packages.valory.protocols import abci as valory_abci_protocol -from packages.valory.protocols.abci import AbciMessage, custom_types - - -Node = Dict[str, Any] - -camel_to_snake = _camel_case_to_snake_case -snake_to_camel = _to_camel_case - - -type_mapping = { - v: k[5:].lower() for k, v in vars(FieldDescriptor).items() if k.startswith("TYPE_") -} - -type_to_python = dict.fromkeys(type_mapping.values()) -type_to_python.update( - dict( - double=float, - float=float, - int64=int, - uint64=int, - int32=int, - bool=bool, - string=str, - bytes=bytes, - uint32=int, - ) -) - -TENDERMINT_PRIMITIVES = tuple(type_mapping.values()) -PYTHON_PRIMITIVES = (int, float, bool, str, bytes) - -# simple value strategy -AEA_PRIMITIVES = {str: "sss", bytes: b"bbb", int: 123, float: 3.14, bool: True} -TENDER_PRIMITIVES = dict( - int32=-32, - uint32=32, - int64=-64, - uint64=64, - bool=True, - string="sss", - bytes=b"bbb", - nanos=999, -) -REPEATED_FIELD_SIZE = 3 -USE_NON_ZERO_ENUM: bool = True - - -def is_enum(d_type: Any) -> bool: - """Check if a type is an Enum (not instance!).""" - return isinstance(d_type, type) and issubclass(d_type, Enum) - - -def my_repr(self: Any) -> str: - """Custom __repr__ for Tendermint protobuf objects, which lack it.""" - return f"<{self.__module__}.{type(self).__name__} object at {hex(id(self))}>" - - -def is_typing_list(d_type: Any) -> bool: - """Check if field is repeated.""" - return d_type.__class__.__module__ == "typing" and d_type.__origin__ is list - - -def replace_keys(node: Node, trans: Node) -> None: - """Replace keys in-place""" - for k, v in trans.items(): - if isinstance(v, dict): - replace_keys(node[k], v) - else: - node[v] = node.pop(k) - - -def set_repr(cls: Type) -> Type: - """Set custom __repr__""" - cls.__repr__ = my_repr # type: ignore - return cls - - -def get_aea_classes(module: ModuleType) -> Dict[str, Type]: - """Get AEA custom classes.""" - - def is_locally_defined_class(item: Any) -> bool: - return isinstance(item, type) and item.__module__ == module.__name__ - - return {k: v for k, v in vars(module).items() if is_locally_defined_class(v)} - - -AEA_CUSTOM = get_aea_classes(custom_types) - - -@functools.lru_cache() -def get_protocol_readme_spec() -> Tuple[Any, Any, Any]: - """Test specification used to generate protocol matches ABCI spec""" - - protocol_readme = Path(valory_abci_protocol.__file__).parent / "README.md" - raw_chunks = open(protocol_readme).read().split("```") - assert len(raw_chunks) == 3, "Expecting a single YAML code block" - - yaml_chunks = raw_chunks[1].strip("yaml").split("\n---") - yaml_content = [] - for raw_doc in filter(None, yaml_chunks): - try: - yaml_content.append(yaml.safe_load(raw_doc)) - except yaml.YAMLError as e: - raise e - - protocol, custom, dialogues = yaml_content - assert protocol["name"] == "abci" # sanity check - return protocol, custom, dialogues - - -# 1. Create type tree for the AEA-native ABCI protocol -def _create_aea_custom_type_tree(custom_type: Type) -> Tuple[Type, Node]: - """Create custom type tree for AEA-native ABCI spec""" - - kwarg_types = {} - parameters = inspect.signature(custom_type).parameters - for name, parameter in parameters.items(): - d_type = parameter.annotation - if d_type in PYTHON_PRIMITIVES: - kwarg_types[name] = d_type - elif is_enum(d_type): - kwarg_types[name] = d_type - elif is_typing_list(d_type): # "repeated" - assert len(d_type.__args__) == 1 # check assumption - container, content = d_type.__origin__, d_type.__args__[0] - if content in AEA_CUSTOM.values(): - content = _create_aea_custom_type_tree(content) - kwarg_types[name] = container, content - else: - nested_type = AEA_CUSTOM.get(d_type, d_type) - kwarg_types[name] = _create_aea_custom_type_tree(nested_type) - - return custom_type, kwarg_types - - -def _create_aea_type_tree(field: str) -> Any: - """Create type tree for AEA-native ABCI spec""" - - if any(map(field.startswith, SPECIFICATION_COMPOSITIONAL_TYPES)): - subfields = _get_sub_types_of_compositional_types(field) - if field.startswith("pt:optional"): - return _create_aea_type_tree(*subfields) - elif field.startswith("pt:list"): # repeated - return list, _create_aea_type_tree(*subfields) - raise NotImplementedError(f"field: {field}") - - if field.startswith("ct:"): - custom_type = AEA_CUSTOM[field[3:]] - return _create_aea_custom_type_tree(custom_type) - - primitive = getattr(builtins, field[3:]) - return primitive - - -def create_aea_abci_type_tree( - speech_acts: Dict[str, Dict[str, str]] -) -> Dict[str, Node]: - """Create AEA-native ABCI type tree from the defined speech acts""" - - def _get_message_types(fields: Dict[str, str]) -> Node: - """Get message types for AEA-native ABCI spec""" - return {k: _create_aea_type_tree(v) for k, v in fields.items()} - - return {k: _get_message_types(v) for k, v in speech_acts.items()} - - -# 2. Initialize AEA-native ABCI primitives -def _init_subtree(node: Node) -> Node: - """Initialize subtree of type_tree non-custom objects""" - - def init_repeated(repeated_type: Any) -> Tuple[Any, ...]: - """Repeated fields must be tuples for Tendermint protobuf""" - - if repeated_type in PYTHON_PRIMITIVES: - data = AEA_PRIMITIVES[repeated_type] - return tuple(data for _ in range(REPEATED_FIELD_SIZE)) - elif isinstance(repeated_type, tuple): - cls, kws = repeated_type - return tuple(_init_subtree(kws) for _ in range(REPEATED_FIELD_SIZE)) - raise NotImplementedError(f"Repeated in {name}: {repeated_type}") - - kwargs: Node = {} - for name, d_type in node.items(): - if isinstance(d_type, tuple): - container, content = d_type - if container is list: - kwargs[name] = init_repeated(content) - else: - kwargs[name] = _init_subtree(content) - elif d_type in PYTHON_PRIMITIVES: - kwargs[name] = AEA_PRIMITIVES[d_type] - elif is_enum(d_type): - kwargs[name] = list(d_type)[USE_NON_ZERO_ENUM] - else: - raise NotImplementedError(f"{name}: {d_type}") - - return kwargs - - -def init_type_tree_primitives(type_tree: Node) -> Node: - """ - Initialize the primitive types and size of repeated fields. - - These are the only initialization parameters that can vary; - after this the initialization of custom types is what remains - - This structure allows: - - Comparison of structure and these values with Tendermint translation - - Visual inspection of fields to be sets, also on custom objects - - Randomized testing strategies using e.g. hypothesis - - :param type_tree: mapping from message / field name to type. - :return: mapping from message / field name to initialized primitive. - """ - return {k: _init_subtree(node) for k, node in type_tree.items()} - - -# 3. Initialize AEA-native ABCI protocol messages -def _complete_init(type_node: Node, init_node: Node) -> Node: - """Initialize custom classes and containers""" - - def init_repeated(repeated_type: Any) -> Tuple[Any, ...]: - if not isinstance(content, tuple): - return init_node[key] # already initialized primitives - custom_type, kwargs = repeated_type - return tuple(custom_type(**_complete_init(kwargs, c)) for c in init_node[key]) - - node: Node = {} - for key, d_type in type_node.items(): - if d_type in PYTHON_PRIMITIVES: - node[key] = init_node[key] - elif isinstance(d_type, tuple): - container, content = d_type - if container is list: - node[key] = init_repeated(content) - else: - node[key] = container(**_complete_init(content, init_node[key])) - elif is_enum(d_type): - node[key] = init_node[key] - else: - raise NotImplementedError(f"{key}: {d_type}") - - return node - - -def init_aea_abci_messages(type_tree: Node, init_tree: Node) -> Node: - """ - Create ABCI messages for AEA-native ABCI spec - - We iterate the type_tree and init_tree to finalize the - initialization of custom objects contained in it, and - create an instance of all ABCI messages. - - :param type_tree: mapping from message / field name to type. - :param init_tree: mapping from message / field name to initialized primitive. - :return: mapping from message name to ABCI Message instance - """ - - messages = dict.fromkeys(type_tree) - for key in type_tree: - performative = getattr(AbciMessage.Performative, key.upper()) - kwargs = _complete_init(type_tree[key], init_tree[key]) - messages[key] = AbciMessage(performative, **kwargs) - - return messages - - -class EncodingError(Exception): - """EncodingError AEA- to Tendermint-native ABCI message""" - - -class DecodingError(Exception): - """DecodingError Tendermint- to AEA-native ABCI message""" - - -# 4. Translate AEA-native to Tendermint-native -def encode(message: AbciMessage) -> Response: - """Encode AEA-native ABCI protocol messages to Tendermint-native""" - - try: - return Encoder.process(message) - except Exception as e: - raise EncodingError(f"ABCI message {message}: {e}") - - -def decode(request: Request) -> AbciMessage: - """Decode Tendermint-native ABCI protocol messages to AEA-native""" - - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - try: - message, dialogue = Decoder().process(request, dialogues, "dummy") # type: ignore - return message - except Exception as e: - raise DecodingError(f"Request {request}: {e}") - - -# 5. Build content tree from Tendermint-native ABCI messages -def _get_message_content(message: Any) -> Node: - """Verify Tendermint-native ABCI message""" - - # NOTE: PublicKey objects are an Enum in AEA-native protocol - # but are retrieved as mapping from Tendermint side - - assert message.IsInitialized() - assert not message.FindInitializationErrors() - - # NOTE: ListFields does not retrieve what is empty! - fields = dict(message.DESCRIPTOR.fields_by_name) - enum_types = dict(message.DESCRIPTOR.enum_types_by_name) - oneofs = dict(message.DESCRIPTOR.oneofs_by_name) - - kwargs: Node = {} - for name, descr in fields.items(): - attr = getattr(message, name) - - if descr.enum_type: - enum_type = enum_types.pop(snake_to_camel(name)) - kwargs[name] = (enum_type.values[attr].name, attr) - elif isinstance(attr, PYTHON_PRIMITIVES): - kwargs[name] = attr - elif descr.label == descr.LABEL_REPEATED: - assert isinstance(descr.default_value, list) # attr - assert len(set(map(type, attr))) <= 1, "Expecting single type" - if not attr or isinstance(attr[0], PYTHON_PRIMITIVES): - kwargs[name] = list(attr) - else: - kwargs[name] = [_get_message_content(c) for c in attr] - elif descr.message_type: - kwargs[name] = _get_message_content(attr) - else: - raise NotImplementedError(f"name: {name} {attr}") - - # in the case of oneofs, we assert they were retrieved from fields (PublicKey) - expected = {f.name for oneof in oneofs.values() for f in oneof.fields} - assert all(k in kwargs for k in expected), f"oneofs in {message}" - assert not enum_types, f"assumed max 1 enum per message: {message}" - - return kwargs - - -def get_tendermint_content(envelope: Union[Request, Response]) -> Node: - """ - Get Tendermint-native ABCI message content. - - For all Request / Response instances obtained after encoding, - we retrieve the information present in the message they contain. - - :param envelope: a Tendermint Request / Response object. - :return: mapping structure from message / field name to leaf values - """ - - assert isinstance(envelope, (Request, Response)) - assert envelope.IsInitialized() - assert not envelope.FindInitializationErrors() - assert len(envelope.ListFields()) == 1 - descr, message = envelope.ListFields()[0] - return _get_message_content(message) - - -# compare AEA- and Tendermint-native ABCI protocol input and output -def compare_trees(init_node: Node, tender_node: Node) -> None: - """Compare Initialization and Tendermint tree nodes""" - - # NOTE: PublicKey objects are an Enum in AEA-native protocol - # but are retrieved as mapping from Tendermint side - - if init_node == tender_node: - return - - for k, init_child in init_node.items(): - # translate key to tendermint key - tk = {"type_": "type", "format_": "format", "hash_": "hash"}.get(k, k) - tender_child = tender_node[tk] - - if k == "pub_key": - init_child = {init_child["key_type"].name: init_child["data"]} - - if init_child == tender_child: - continue - elif isinstance(init_child, dict) and isinstance(tender_child, dict): - compare_trees(init_child, tender_child) - - elif isinstance(tender_child, list): - # we use a nested mapping to represent a custom class, - # tendermint doesn't use this for storing repeated fields - if isinstance(init_child, dict): - repeated = list(init_child.values()) - assert len(repeated) == 1 - init_child = repeated[0] - - assert len(init_child) == len(tender_child) - for a, b in zip(init_child, tender_child): - compare_trees(a, b) - - else: - assert len(init_child) == 1, "expecting enum" - enum = set(init_child.values()).pop() - assert (enum.name, enum.value) == tender_node[tk] - - -def _process_message_descriptor(m_descriptor: Any) -> Node: - """Process fields of the message descriptor""" - - node: Node = {} - for name, field in m_descriptor.fields_by_name.items(): - if field.message_type: - cls = set_repr(field.message_type._concrete_class) - node[name] = cls, _process_message_descriptor(cls.DESCRIPTOR) - elif field.enum_type: - names = field.enum_type.values_by_name - numbers = field.enum_type.values_by_number - node[name] = Enum(name, zip(names, numbers)) - else: - node[name] = type_mapping[field.type] - - if field.label == field.LABEL_REPEATED: - node[name] = list, node[name] - - return node - - -def get_tender_type_tree() -> Node: - """Tendermint type tree""" - - descriptor = DESCRIPTOR - tender_type_tree = {} - for msg, msg_descr in descriptor.message_types_by_name.items(): - cls = set_repr(msg_descr._concrete_class) - tender_type_tree[msg] = cls, _process_message_descriptor(msg_descr) - return tender_type_tree - - -def _init_tender_tree(tender_node: Node) -> Node: - """Initialize Tendermint classes""" - - def init_repeated(repeated_type: Any) -> List[Any]: - if isinstance(repeated_type, str): - return [ - TENDER_PRIMITIVES[repeated_type] for _ in range(REPEATED_FIELD_SIZE) - ] - cls, kwargs = repeated_type - return [cls(**_init_tender_tree(kwargs)) for _ in range(REPEATED_FIELD_SIZE)] - - node = {} - for field, d_type in tender_node.items(): - if isinstance(d_type, str): - if field == "nanos": # special - node[field] = TENDER_PRIMITIVES[field] - else: - node[field] = TENDER_PRIMITIVES[d_type] - elif is_enum(d_type): - node[field] = list(d_type)[USE_NON_ZERO_ENUM].value - elif isinstance(d_type, tuple): - container, content = d_type - if container is list: - node[field] = init_repeated(content) - else: - node[field] = container(**_init_tender_tree(content)) - else: - raise NotImplementedError(f"field {field}: {d_type}") - - return node - - -def _build_tendermint_messages(cls: Type, tree: Node) -> List[Union[Request, Response]]: - """Build tendermint messages""" - - return [cls(**{k: v}) for k, v in _init_tender_tree(tree).items()] - - -def init_tendermint_messages(tender_type_tree: Node) -> List[Union[Request, Response]]: - """Initialize tendermint ABCI messages""" - - request_cls, request_tree = tender_type_tree["Request"] - - # construct Tendermint-native messages - messages = _build_tendermint_messages(request_cls, request_tree) - - return messages diff --git a/trader_old/vendor/valory/connections/abci/tests/test_abci.py b/trader_old/vendor/valory/connections/abci/tests/test_abci.py deleted file mode 100644 index e88e917b3..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_abci.py +++ /dev/null @@ -1,661 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/abci connection.""" - -# pylint: skip-file - -import asyncio -import logging -import os -import shutil -import time -from abc import ABC, abstractmethod -from cmath import inf -from contextlib import suppress -from pathlib import Path -from tempfile import TemporaryDirectory -from typing import Any, Callable, Generator, List, NoReturn, cast -from unittest import mock -from unittest.mock import MagicMock - -import docker -import pytest -import requests -from _pytest.fixtures import SubRequest # type: ignore -from aea.configurations.base import ConnectionConfig -from aea.connections.base import ConnectionStates -from aea.identity.base import Identity -from aea.mail.base import Envelope -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea_test_autonomy.configurations import ANY_ADDRESS, HTTP_LOCALHOST -from aea_test_autonomy.docker.base import skip_docker_tests -from aea_test_autonomy.docker.tendermint import TendermintDockerImage -from aea_test_autonomy.fixture_helpers import ( # noqa: F401 - DEFAULT_TENDERMINT_PORT, - abci_host, - abci_port, - tendermint_port, -) -from aea_test_autonomy.helpers.async_utils import ( - AnotherThreadTask, - BaseThreadedAsyncLoop, - wait_for_condition, -) -from docker.models.containers import Container -from hypothesis import database, given, settings -from hypothesis.strategies import integers - -from packages.valory.connections.abci import check_dependencies as dep_utils -from packages.valory.connections.abci.connection import ( - ABCIServerConnection, - DEFAULT_ABCI_PORT, - DEFAULT_LISTEN_ADDRESS, - DecodeVarintError, - EncodeVarintError, - ShortBufferLengthError, - TooLargeVarint, - VarintMessageReader, - _TendermintABCISerializer, -) -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import ( - BlockParams, - ConsensusParams, - Duration, - Event, - EventAttribute, - Events, - EvidenceParams, - ProofOps, - ValidatorParams, - ValidatorUpdates, - VersionParams, -) -from packages.valory.protocols.abci.dialogues import AbciDialogue -from packages.valory.protocols.abci.dialogues import AbciDialogues as BaseAbciDialogues - - -PACKAGE_DIR = Path(__file__).parent.parent - - -@pytest.fixture(scope="session", autouse=True) -def hypothesis_cleanup() -> Generator: - """Fixture to remove hypothesis directory after tests.""" - yield - hypothesis_dir = PACKAGE_DIR / ".hypothesis" - if hypothesis_dir.exists(): - with suppress(OSError, PermissionError): - shutil.rmtree(hypothesis_dir) - - -class AsyncBytesIO: - """Utility class to emulate asyncio.StreamReader.""" - - def __init__(self, data: bytes) -> None: - """Initialize the buffer.""" - self.data = data - - self._pointer: int = 0 - - async def read(self, n: int) -> bytes: - """Read n bytes.""" - new_pointer = self._pointer + n - result = self.data[self._pointer : new_pointer] - self._pointer = new_pointer - return result - - -class ABCIAppTest: - """A dummy ABCI application for testing purposes.""" - - class AbciDialogues(BaseAbciDialogues): - """The dialogues class keeps track of all ABCI dialogues.""" - - def __init__(self, address: str) -> None: - """Initialize dialogues.""" - self.address = address - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.SERVER - - BaseAbciDialogues.__init__( - self, - self_address=self.address, - role_from_first_message=role_from_first_message, - dialogue_class=AbciDialogue, - ) - - def __init__(self, address: str): - """Initialize.""" - self._dialogues = ABCIAppTest.AbciDialogues(address) - - def handle(self, request: AbciMessage) -> AbciMessage: - """Process a request.""" - # check that it is not a response - assert "request" in request.performative.value, "performative is not a Request" - # performative of requests is of the form "request_{request_name}" - request_type = request.performative.value.replace("request_", "") - handler: Callable[[AbciMessage], AbciMessage] = getattr( - self, request_type, self.no_match - ) - return handler(request) - - def _update_dialogues(self, request: AbciMessage) -> AbciDialogue: - """Update dialogues.""" - abci_dialogue = self._dialogues.update(request) - assert abci_dialogue is not None, "cannot update dialogue" - return cast(AbciDialogue, abci_dialogue) - - def echo(self, request: AbciMessage) -> AbciMessage: - """Process echo request""" - - abci_dialogue = self._update_dialogues(request) - reply = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_ECHO, - target_message=request, - message=request.message, - ) - return cast(AbciMessage, reply) - - def info(self, request: AbciMessage) -> AbciMessage: - """Process an info request.""" - abci_dialogue = self._update_dialogues(request) - assert request.performative == AbciMessage.Performative.REQUEST_INFO - info_data = "" - version = request.version - app_version = 0 - last_block_height = 0 - last_block_app_hash = b"" - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_INFO, - info_data=info_data, - version=version, - app_version=app_version, - last_block_height=last_block_height, - last_block_app_hash=last_block_app_hash, - ) - return cast(AbciMessage, response) - - def flush(self, request: AbciMessage) -> AbciMessage: - """Process a flush request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_FLUSH - ) - return cast(AbciMessage, response) - - def init_chain(self, request: AbciMessage) -> AbciMessage: - """Process an init_chain request.""" - abci_dialogue = self._update_dialogues(request) - app_hash = b"" - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_INIT_CHAIN, - validators=request.validators, - app_hash=app_hash, - consensus_params=self._get_test_consensus_params(), - ) - return cast(AbciMessage, response) - - def query(self, request: AbciMessage) -> AbciMessage: - """Process a query request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_QUERY, - code=0, - log="", - info="", - index=0, - key=b"", - value=b"", - proof_ops=ProofOps([]), - height=0, - codespace="", - ) - return cast(AbciMessage, response) - - def check_tx(self, request: AbciMessage) -> AbciMessage: - """Process a check_tx request.""" - abci_dialogue = self._update_dialogues(request) - attributes: List[EventAttribute] = [] - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, - code=0, # OK - data=b"", - log="", - info="", - gas_wanted=0, - gas_used=0, - events=Events([Event(type_="", attributes=attributes)]), - codespace="", - ) - return cast(AbciMessage, response) - - def deliver_tx(self, request: AbciMessage) -> AbciMessage: - """Process a deliver_tx request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, - code=0, # OK - data=b"", - log="", - info="", - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, response) - - def begin_block(self, request: AbciMessage) -> AbciMessage: - """Process a begin_block request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, - events=Events([]), - ) - return cast(AbciMessage, response) - - def end_block(self, request: AbciMessage) -> AbciMessage: - """Process an end_block request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_END_BLOCK, - validator_updates=ValidatorUpdates([]), - events=Events([]), - consensus_param_updates=self._get_test_consensus_params(), - ) - return cast(AbciMessage, response) - - def commit(self, request: AbciMessage) -> AbciMessage: - """Process a commit request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_COMMIT, - data=b"", - retain_height=0, - ) - return cast(AbciMessage, response) - - def set_option(self, request: AbciMessage) -> AbciMessage: - """Process a commit request.""" - abci_dialogue = self._update_dialogues(request) - response = abci_dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_SET_OPTION, - code=0, - log="", - info="", - ) - return cast(AbciMessage, response) - - def no_match(self, request: AbciMessage) -> NoReturn: - """No match.""" - raise Exception( - f"Received request with performative {request.performative.value}, but no handler available" - ) - - def _get_test_consensus_params(self) -> ConsensusParams: - """Get an instance of ConsensusParams for testing purposes.""" - return ConsensusParams( - BlockParams(max_bytes=22020096, max_gas=-1), - EvidenceParams( - max_age_num_blocks=100000, - max_age_duration=Duration(seconds=17280, nanos=0), - max_bytes=50, - ), - ValidatorParams(pub_key_types=["ed25519"]), - VersionParams(app_version=0), - ) - - -class BaseABCITest: - """Base class for ABCI test (mixin).""" - - TARGET_SKILL_ID: str - - def make_app(self) -> ABCIAppTest: - """Make an ABCI app.""" - return ABCIAppTest(self.TARGET_SKILL_ID) - - -def start_tendermint_docker_image(use_grpc: bool) -> Container: - """Start TendermintDockerImage""" - - TendermintDockerImage.use_grpc = use_grpc - client = docker.from_env() - image = TendermintDockerImage(client) - container = image.create() - container.start() - logging.info(f"Setting up image {image.image}...") - success = image.wait() - logging.info(f"TendermintDockerImage running: {success}...") - return container - - -@pytest.mark.integration -class BaseTestABCITendermintIntegration(BaseThreadedAsyncLoop, ABC): - """ - Integration test between ABCI connection and Tendermint node. - - To use this class: - - - inherit from this class, and write test methods; - - overwrite the method "make_app". The app must implement a 'handle(message)' method. - """ - - TARGET_SKILL_ID = "dummy_author/dummy:0.1.0" - ADDRESS = "agent_address" - PUBLIC_KEY = "agent_public_key" - tendermint_port = DEFAULT_TENDERMINT_PORT # noqa: F811 - - @pytest.fixture(autouse=True, params=[False, True]) - def setup_and_teardown(self, request: SubRequest) -> Generator: - """Set up the test.""" - - use_grpc = request.param - logging.info(f"Tendermint abci connection using: {('TCP', 'gRPC')[use_grpc]}") - - self.agent_identity = Identity( - "name", address=self.ADDRESS, public_key=self.PUBLIC_KEY - ) - - self.configuration = ConnectionConfig( - connection_id=ABCIServerConnection.connection_id, - host=DEFAULT_LISTEN_ADDRESS, - port=DEFAULT_ABCI_PORT, - target_skill_id=self.TARGET_SKILL_ID, - use_tendermint=False, # using docker image instead - use_grpc=use_grpc, - ) - - self.connection = ABCIServerConnection( - identity=self.agent_identity, configuration=self.configuration, data_dir="" - ) - self.app = self.make_app() - - self.execute(self.connection.connect()) - - self.stopped = False - self.receiving_task: AnotherThreadTask = self.loop.call( - self.process_incoming_messages() - ) - - # connection must be established, - # unlike TCP, only a single ECHO request is send with gRPC - time.sleep(5) - container = start_tendermint_docker_image(use_grpc=use_grpc) - - # wait until tendermint node synchronized with abci - wait_for_condition(self.health_check, period=5, timeout=1000000) - - yield # execute test - - # teardown - self.stopped = True - self.receiving_task.cancel() - self.execute(self.connection.disconnect()) - container.stop() - container.remove() - - @abstractmethod - def make_app(self) -> Any: - """Make an ABCI app.""" - raise NotImplementedError - - def health_check(self) -> bool: - """Do a health-check.""" - end_point = self.tendermint_url() + "/health" - try: - result = requests.get(end_point).status_code == 200 - except requests.exceptions.ConnectionError: - result = False - logging.debug(f"Health-check result {end_point}: {result}") - return result - - def tendermint_url(self) -> str: - """Get the current Tendermint URL.""" - return f"{HTTP_LOCALHOST}:{self.tendermint_port}" - - async def process_incoming_messages(self) -> None: - """Receive requests and send responses from/to the Tendermint node""" - while not self.stopped: - try: - request_envelope = await self.connection.receive() - except asyncio.CancelledError: - break - assert request_envelope is not None - request_type = cast(Message, request_envelope.message).performative.value - logging.debug(f"Received request {request_type}") - response = self.app.handle(cast(AbciMessage, request_envelope.message)) - if response is not None: - response_envelope = Envelope( - to=request_envelope.sender, - sender=request_envelope.to, - message=response, - ) - await self.connection.send(response_envelope) - else: - logging.warning(f"Response to {request_type} was None.") - - -@skip_docker_tests -class TestNoop(BaseABCITest, BaseTestABCITendermintIntegration): - """Test integration between ABCI connection and Tendermint, without txs.""" - - SECONDS = 5 - - def test_run(self) -> None: - """ - Run the test. - - Sleep for N seconds, check Tendermint is still running, and then stop the test. - """ - time.sleep(self.SECONDS) - assert self.health_check() - - -@skip_docker_tests -class TestQuery(BaseABCITest, BaseTestABCITendermintIntegration): - """Test integration ABCI-Tendermint with a query.""" - - def test_run(self) -> None: - """ - Run the test. - - Send a query request to the Tendermint node, which will trigger - a query request to the ABCI connection. - """ - logging.debug("Send request") - response = requests.get(self.tendermint_url() + "/abci_query") - assert response.status_code == 200 - - -@skip_docker_tests -class TestTransaction(BaseABCITest, BaseTestABCITendermintIntegration): - """Test integration ABCI-Tendermint by sending a transaction.""" - - def test_run(self) -> None: - """ - Run the test. - - Send a query request to the Tendermint node, which will trigger - a query request to the ABCI connection. - """ - logging.debug("Send request") - response = requests.get( - self.tendermint_url() + "/broadcast_tx_commit", params=dict(tx="0x01") - ) - assert response.status_code == 200 - - -@pytest.mark.asyncio -async def test_connection_standalone_tendermint_setup() -> None: - """Test the setup of the connection configured with Tendermint.""" - try: - temp_dir = TemporaryDirectory() - os.environ["LOG_FILE"] = str(Path(temp_dir.name, "log.txt")) - agent_identity = Identity( - "name", address="agent_address", public_key="agent_public_key" - ) - configuration = ConnectionConfig( - connection_id=ABCIServerConnection.connection_id, - host=DEFAULT_LISTEN_ADDRESS, - port=DEFAULT_ABCI_PORT, - target_skill_id="dummy_author/dummy:0.1.0", - use_tendermint=True, - tendermint_config=dict( - rpc_laddr=f"{ANY_ADDRESS}:26657", - p2p_laddr=f"{ANY_ADDRESS}:26656", - p2p_seeds=[], - ), - ) - connection = ABCIServerConnection( - identity=agent_identity, configuration=configuration, data_dir="" - ) - await connection.connect() - await asyncio.sleep(2.0) - await connection.disconnect() - - del os.environ["LOG_FILE"] - finally: - temp_dir.cleanup() - - -def test_ensure_connected_raises_connection_error() -> None: - """Test '_ensure_connected' raises ConnectionError if the channel is not connected.""" - configuration_mock = ConnectionConfig( - connection_id=ABCIServerConnection.connection_id, - target_skill_id="dummy_author/dummy:0.1.0", - host=DEFAULT_LISTEN_ADDRESS, - port=DEFAULT_ABCI_PORT, - use_tendermint=False, - use_grpc=False, - ) - connection = ABCIServerConnection( - identity=MagicMock(), configuration=configuration_mock, data_dir="" - ) - - # simulate connection, but without channel connection - connection.state = ConnectionStates.connected - with pytest.raises(ConnectionError, match="The channel is stopped."): - connection._ensure_connected() - - -def test_encode_varint_method() -> None: - """Test encode_varint (uint64 Protobuf) method""" - hard_zero_encoded = b"\x00" - max_uint32_encoded = b"\xfe\xff\xff\xff\x1f" - max_uint64_encoded = b"\xfe\xff\xff\xff\xff\xff\xff\xff\xff\x03" - assert _TendermintABCISerializer.encode_varint(0) == hard_zero_encoded - assert _TendermintABCISerializer.encode_varint((1 << 32) - 1) == max_uint32_encoded - assert _TendermintABCISerializer.encode_varint((1 << 64) - 1) == max_uint64_encoded - - -@settings(database=database.InMemoryExampleDatabase()) -@given(integers(min_value=0, max_value=(1 << 64) - 1)) -@pytest.mark.asyncio -async def test_encode_decode_varint(value: int) -> None: - """Test that encoding and decoding works.""" - encoder = _TendermintABCISerializer.encode_varint - encoded_value = encoder(value) - reader = asyncio.StreamReader() - reader.feed_data(encoded_value) - decoder = _TendermintABCISerializer.decode_varint - decoded_value = await decoder(reader) - assert decoded_value == value - - -@pytest.mark.parametrize("value", [-1, 1 << 64]) -@pytest.mark.asyncio -async def test_encoding_raises(value: int) -> None: - """Test encoding raises""" - encoder = _TendermintABCISerializer.encode_varint - with pytest.raises(EncodeVarintError): - encoder(value) - - -@pytest.mark.asyncio -async def test_decode_varint_raises_exception_when_failing() -> None: - """Test that decode_varint raises exception when the decoding fails.""" - with pytest.raises(DecodeVarintError, match="could not decode varint"): - # set CONTINUE_BIT so to trigger an exception - b = b"\x80" - reader = AsyncBytesIO(b) - await _TendermintABCISerializer.decode_varint(reader) # type: ignore - - -@pytest.mark.asyncio -async def test_decode_varint_raises_eof_error() -> None: - """Test that decode_varint raises exception when the EOF of the stream is reached.""" - with pytest.raises(EOFError, match=""): - reader = AsyncBytesIO(b"") - await _TendermintABCISerializer.decode_varint(reader) # type: ignore - - -def test_dep_util() -> None: - """Test dependency utils.""" - assert dep_utils.nth([0, 1, 2, 3], 1, -1) == 1 - assert dep_utils.nth([0, 1, 2, 3], 5, -1) == -1 - assert dep_utils.get_version(1, 0, 0) == (1, 0, 0) - assert dep_utils.version_to_string((1, 0, 0)) == "1.0.0" - - -@pytest.mark.asyncio -async def test_varint_message_reader() -> None: - """Test VarintMessageReader""" - - async def read(nb: int) -> bytes: - return b"hello" - - def patch_async_methods(value: Any) -> Callable: - async def decode_varint(*args: Any, **kwargs: Any) -> Any: - return value - - return decode_varint - - stream_reader = MagicMock(read=read) - vmr = VarintMessageReader(stream_reader) - - with mock.patch.object( - _TendermintABCISerializer, "decode_varint", new=patch_async_methods(inf) - ): - with pytest.raises(TooLargeVarint): - await vmr.read_next_message() - - with mock.patch.object( - _TendermintABCISerializer, "decode_varint", new=patch_async_methods(10) - ): - with mock.patch.object(vmr, "read_until", new=patch_async_methods(b"")): - with pytest.raises(ShortBufferLengthError): - await vmr.read_next_message() - - with mock.patch.object( - _TendermintABCISerializer, "decode_varint", new=patch_async_methods(5) - ): - res = await vmr.read_next_message() - assert res == b"hello" diff --git a/trader_old/vendor/valory/connections/abci/tests/test_abci_fuzz.py b/trader_old/vendor/valory/connections/abci/tests/test_abci_fuzz.py deleted file mode 100644 index 9a978b080..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_abci_fuzz.py +++ /dev/null @@ -1,339 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Test random initializations of ABCI Message content""" - -# pylint: skip-file - -from typing import Any, Callable, Dict - -from hypothesis import HealthCheck, given, settings -from hypothesis import strategies as st -from hypothesis.strategies._internal.lazy import SearchStrategy - -from packages.valory.connections.abci.tests.helper import ( - AbciMessage, - PYTHON_PRIMITIVES, - Request, - camel_to_snake, - create_aea_abci_type_tree, - decode, - encode, - get_protocol_readme_spec, - get_tender_type_tree, - get_tendermint_content, - is_enum, - replace_keys, -) - - -KEY_MAPPING = dict( # AEA to Tendermint, one-to-one - request_set_option={"key": "option_key", "value": "option_value"}, - request_query={"data": "query_data"}, - request_load_snapshot_chunk={"chunk": "chunk_index"}, - request_apply_snapshot_chunk={"sender": "chunk_sender"}, - response_info={"data": "info_data"}, -) - - -key_translation = { - "type_": "type", - "format_": "format", - "hash_": "hash", - "round_": "round", - "evidence_params": "evidence", - "validator_params": "validator", - "version_params": "version", - "evidence_type": "type", -} - - -Node = Dict[str, Any] - - -BIT32 = 1 << 31 -BIT64 = 1 << 63 - -STRATEGY_MAP = dict( # TODO: strategy to assert failure - int32=st.integers(min_value=-BIT32, max_value=BIT32 - 1), - uint32=st.integers(min_value=0, max_value=(BIT32 << 1) - 1), - int64=st.integers(min_value=-BIT64, max_value=BIT64 - 1), - uint64=st.integers(min_value=0, max_value=(BIT64 << 1) - 1), - bool=st.booleans(), - string=st.text(), - bytes=st.binary(), - nanos=st.integers(min_value=0, max_value=10**9 - 1), # special case -) - - -# Step 1: retrieve tendermint protobuf type for primitives -def _translate(aea_type_node: Node, tender_type_node: Node) -> Node: - """ - Translate type_node primitive to abci_node specification. - - Create a one-to-one mapping from Tendermint to AEA type tree. - This is necessary because different types of integers are - distinguished in protobuf: int32, uint32, int64, uint64. - As long as the structure is maintained this can be used to - initialize the AEA ABCIMessage instances. - - :param aea_type_node: mapping from message / field name to AEA type. - :param tender_type_node: mapping from message / field name to Tendermint type. - :return: mapping from message / field name to initialized primitive. - """ - - for key, type_child in aea_type_node.items(): - if is_enum(type_child): - continue - if key == "pub_key": - type_child[-1]["data"] = "bytes" - continue - if key == "proof_ops" and "ops" in tender_type_node: - _translate(type_child[-1][-1], tender_type_node["ops"][-1][-1]) - continue - - tender_key = key_translation.get(key, key) - abci_child = tender_type_node[tender_key] - - if isinstance(type_child, str) or type_child in PYTHON_PRIMITIVES: - aea_type_node[key] = abci_child - elif is_enum(abci_child): - continue - elif isinstance(type_child, dict) and isinstance(abci_child, dict): - _translate(type_child, abci_child) - - elif isinstance(type_child, tuple) and isinstance(abci_child, tuple): - cls, d_type = type_child - name, nested = abci_child - if d_type in PYTHON_PRIMITIVES: - aea_type_node[key] = cls, nested - elif isinstance(d_type, dict) and isinstance(nested, dict): - _translate(d_type, nested) - elif isinstance(d_type, tuple): - _translate(d_type[-1], nested[-1]) - else: # extra nested mapping - repeated = list(d_type.values()) - assert len(repeated) == 1 - _translate(repeated[0][-1][-1], nested[-1]) - else: - raise NotImplementedError(f"{key}:\n{type_child}\n{abci_child}") - - return aea_type_node - - -def create_tender_type_tree(aea_type_tree: Node, tender_type_tree: Node) -> Node: - """Create type tree with Tendermint primitives (as string)""" - - aea_with_tender_type_tree = {} - for k, aea_type_node in aea_type_tree.items(): - tender_type_node = tender_type_tree[k][-1] - default_value: Dict[str, str] = {} - replace_keys(tender_type_node, KEY_MAPPING.get(k, default_value)) - aea_with_tender_type_tree[k] = _translate(aea_type_node, tender_type_node) - - return aea_with_tender_type_tree - - -# 3. Create hypothesis strategies -def _init_subtree(node: Any) -> Any: - """Initialize subtree with hypothesis strategies""" - - def init_repeated(repeated_type: Any) -> SearchStrategy: - """Repeated fields must be tuples for Tendermint protobuf""" - if isinstance(repeated_type, str) or repeated_type in PYTHON_PRIMITIVES: - strategy = STRATEGY_MAP[repeated_type] - return st.lists(strategy, min_size=0, max_size=100) - elif isinstance(repeated_type, tuple): - cls, kws = repeated_type - strategy = st.builds(cls, **_init_subtree(kws)) - return st.lists(strategy, min_size=0, max_size=100) - else: - raise NotImplementedError(f"Repeated in {name}: {repeated_type}") - - if isinstance(node, str): - return node - - kwargs: Node = {} - for name, d_type in node.items(): - if isinstance(d_type, str) or d_type in PYTHON_PRIMITIVES: - if name == "nanos": # special case - kwargs[name] = STRATEGY_MAP[name] - else: - kwargs[name] = STRATEGY_MAP[d_type] - elif is_enum(d_type): - kwargs[name] = st.sampled_from(list(d_type)) - elif isinstance(d_type, tuple): - container, content = d_type - if container is list: - kwargs[name] = init_repeated(content) - else: - kwargs[name] = st.builds(container, **_init_subtree(content)) - else: - raise NotImplementedError(f"{name}: {d_type}") - - return kwargs - - -def init_type_tree_hypotheses(type_tree: Node) -> Node: - """ - Initialize the hypothesis strategies - - :param type_tree: mapping from message / field name to type. - :return: mapping from message / field name to initialized primitive. - """ - return {k: _init_subtree(node) for k, node in type_tree.items()} - - -def create_aea_hypotheses() -> Any: - """Create hypotheses for ABCI Messages""" - - aea_protocol, *_ = get_protocol_readme_spec() - speech_acts = aea_protocol["speech_acts"] - - # 1. create type tree from speech acts - aea_type_tree = create_aea_abci_type_tree(speech_acts) - aea_type_tree.pop("dummy") # TODO: known oddity on our side - - # 2. create abci tree from Tendermint type definitions - tender_type_tree = {camel_to_snake(k): v for k, v in get_tender_type_tree().items()} - - # 3. map the primitive types from ABCI spec onto the type tree - aea_with_tender_type_tree = create_tender_type_tree(aea_type_tree, tender_type_tree) - - # 4. initialize with hypothesis - hypo_tree = init_type_tree_hypotheses(aea_with_tender_type_tree) - - # 5. collapse hypo_tree - def collapse(node: Node) -> Node: - for k, v in node.items(): - if isinstance(v, dict): - node[k] = st.fixed_dictionaries(collapse(v)) - return node - - return collapse(hypo_tree) - - -def init_abci_messages(type_tree: Node, init_tree: Node) -> Node: - """Create ABCI messages for AEA-native ABCI spec""" - - messages = dict.fromkeys(type_tree) - for key in type_tree: - performative = getattr(AbciMessage.Performative, key.upper()) - messages[key] = AbciMessage(performative, **init_tree[key]) - - return messages - - -def list_to_tuple(node: Node) -> Node: - """Expecting tuples instead of lists""" - for key, value in node.items(): - if isinstance(value, dict): - list_to_tuple(value) - elif isinstance(value, list): - node[key] = tuple(value) - return node - - -def make_aea_test_method(message_key: str, strategy: Node) -> Callable: - """Dynamically create AEA test""" - - @settings(deadline=5000, suppress_health_check=[HealthCheck.too_slow]) - @given(st.fixed_dictionaries({message_key: strategy})) - def test_method(self: Any, conjecture: Node) -> None: - key = list(conjecture)[0] - performative = getattr(AbciMessage.Performative, key.upper()) - message = AbciMessage(performative, **list_to_tuple(conjecture)[key]) - encoded = encode(message) - if key.startswith("request"): - assert encoded is None - else: - assert get_tendermint_content(encoded) is not None - - return test_method - - -class TestAeaHypotheses: - """Test AEA hypotheses""" - - -aea_hypotheses = create_aea_hypotheses() -for k, v in aea_hypotheses.items(): - setattr(TestAeaHypotheses, f"test_{k}", make_aea_test_method(k, v)) - - -# tendermint fuzzing -def _init_tender_hypo_tree(tender_node: Node) -> Node: - """Initialize Tendermint classes""" - - def init_repeated(repeated_type: Any) -> SearchStrategy: - if isinstance(repeated_type, str): - strategy = STRATEGY_MAP[repeated_type] - return st.lists(strategy, min_size=0, max_size=100) - cls, kwargs = repeated_type - strategy = st.builds(cls, **_init_tender_hypo_tree(kwargs)) - return st.lists(strategy, min_size=0, max_size=100) - - node = {} - for field, d_type in tender_node.items(): - if isinstance(d_type, str): - if field == "nanos": # special - node[field] = STRATEGY_MAP[field] - else: - node[field] = STRATEGY_MAP[d_type] - elif is_enum(d_type): - node[field] = st.sampled_from([f.value for f in d_type]) - elif isinstance(d_type, tuple): - container, content = d_type - if container is list: - node[field] = init_repeated(content) - else: - node[field] = st.builds(container, **_init_tender_hypo_tree(content)) - else: - raise NotImplementedError(f"field {field}: {d_type}") - - return node - - -def create_tendermint_hypotheses() -> Node: - """Create Tendermint hypotheses""" - tender_type_tree = get_tender_type_tree() - _, request_tree = tender_type_tree["Request"] - tender_hypo_tree = _init_tender_hypo_tree(request_tree) - return tender_hypo_tree - - -def make_tendermint_test_method(message_key: str, strategy: Node) -> Callable: - """Dynamically create Tendermint test""" - - @settings(deadline=5000, suppress_health_check=[HealthCheck.too_slow]) - @given(st.fixed_dictionaries({message_key: strategy})) - def test_method(self: Any, conjecture: Node) -> None: - request = Request(**conjecture) - assert decode(request) - - return test_method - - -class TestTendermintHypotheses: - """Test Tendermint hypotheses""" - - -tendermint_hypotheses = create_tendermint_hypotheses() -for k, v in tendermint_hypotheses.items(): - setattr(TestTendermintHypotheses, f"test_{k}", make_tendermint_test_method(k, v)) diff --git a/trader_old/vendor/valory/connections/abci/tests/test_abci_spec.py b/trader_old/vendor/valory/connections/abci/tests/test_abci_spec.py deleted file mode 100644 index d27de0d89..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_abci_spec.py +++ /dev/null @@ -1,220 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests to ensure implementation is on par with ABCI spec""" - -# pylint: skip-file - -import logging -import time -from pathlib import Path -from typing import Any, Dict, Set - -import requests -from aea.protocols.generator.common import ( - SPECIFICATION_COMPOSITIONAL_TYPES, - _get_sub_types_of_compositional_types, -) - -from packages.valory.connections import abci as tendermint_abci -from packages.valory.connections.abci.tests.helper import ( - camel_to_snake, - compare_trees, - create_aea_abci_type_tree, - decode, - encode, - get_protocol_readme_spec, - get_tender_type_tree, - get_tendermint_content, - init_aea_abci_messages, - init_tendermint_messages, - init_type_tree_primitives, - replace_keys, -) - - -Node = Dict[str, Any] - -# constants & utility functions -ENCODING = "utf-8" -VERSION = "v0.34.19" -REPO_PATH = Path(*tendermint_abci.__package__.split(".")).absolute() -PROTO_FILES = list((REPO_PATH / "protos" / "tendermint").glob("**/*.proto")) -URL_PREFIX = f"https://raw.githubusercontent.com/tendermint/tendermint/{VERSION}/proto/tendermint/" - -# to ensure primitives are not initialized to empty default values -NON_DEFAULT_PRIMITIVES = {str: "sss", bytes: b"bbb", int: 123, float: 3.14, bool: True} -REPEATED_FIELD_SIZE = 3 -USE_NON_ZERO_ENUM: bool = True - - -# tests -def test_local_types_file_matches_github(request_attempts: int = 3) -> None: - """Test local file containing ABCI spec matches Tendermint GitHub""" - - different = [] - for file in PROTO_FILES: - url = URL_PREFIX + "/".join(file.parts[-2:]) - response, i = requests.get(url), 0 - while response.status_code != 200 and i < request_attempts: - time.sleep(0.1) - response, i = requests.get(url), i + 1 - if response.status_code != 200: - log_msg = "Failed to retrieve Tendermint proto types from Github" - status_code, reason = response.status_code, response.reason - raise requests.HTTPError(f"{log_msg}: {status_code} ({reason})") - github_data = response.text - local_data = file.read_text(encoding=ENCODING) - if not github_data == local_data: - different.append([file, url]) - - if different: - logging.error("\n".join(" =/= ".join(map(str, x)) for x in different)) - assert not bool(different) - - -def test_all_custom_types_used() -> None: - """ - Test if all custom types are used in speech acts. - - By asserting their usage in the speech acts we can delegate - the verification of their implementation and translation to - another test that addresses this (test_aea_to_tendermint). - """ - - aea_protocol, custom_types, _ = get_protocol_readme_spec() - speech_acts = aea_protocol["speech_acts"] - defined_types = {v for vals in speech_acts.values() for v in vals.values()} - - custom_in_speech: Set[str] = set() - for d_type in defined_types: - if any(map(d_type.startswith, SPECIFICATION_COMPOSITIONAL_TYPES)): - subfields = _get_sub_types_of_compositional_types(d_type) - custom_in_speech.update(s[3:] for s in subfields if s.startswith("ct:")) - elif d_type.startswith("ct:"): - custom_in_speech.add(d_type[3:]) - - assert custom_in_speech == {s[3:] for s in custom_types} - - -def test_defined_dialogues_match_abci_spec() -> None: - """ - Test defined dialogues match ABCI spec. - - It verifies solely that request response pairs match: - - AEA requests match Tendermint requests - - AEA responses match Tendermint responses - - That all requests have a matching response - - That all request, response and the exception are covered - """ - - *_, dialogues = get_protocol_readme_spec() - tender_type_tree = get_tender_type_tree() - - # expected - request_oneof = tender_type_tree["Request"][-1] - request_keys = {camel_to_snake(cls.__name__) for cls, _ in request_oneof.values()} - response_oneof = tender_type_tree["Response"][-1] - response_keys = {camel_to_snake(cls.__name__) for cls, _ in response_oneof.values()} - - # defined - initiation = dialogues["initiation"] - reply = dialogues["reply"] - termination = dialogues["termination"] - - # initiation - assert not request_keys.difference(initiation) - assert set(initiation).difference(request_keys) == {"dummy"} - - # reply - missing_response, alt = set(), "response_exception" - for key in request_keys: - if not set(reply[key]) == {key.replace("request", "response"), alt}: - missing_response.add(key) - assert not missing_response - assert not any(reply[key] for key in response_keys) - - # termination - assert not response_keys.difference(termination) - assert set(termination).difference(response_keys) == {"dummy"} - - -def test_aea_to_tendermint() -> None: - """ - Test translation from AEA-native to Tendermint-native ABCI protocol. - - "repeated" fields are returned as list in python, - but must be passed as tuples to Tendermint protobuf. - """ - - aea_protocol, *_ = get_protocol_readme_spec() - speech_acts = aea_protocol["speech_acts"] - - # 1. create type tree from speech acts - type_tree = create_aea_abci_type_tree(speech_acts) - type_tree.pop("dummy") # TODO: known oddity on our side - - # 2. initialize primitives - init_tree = init_type_tree_primitives(type_tree) - - # 3. create AEA-native ABCI protocol messages - abci_messages = init_aea_abci_messages(type_tree, init_tree) - - # 4. encode to Tendermint-native ABCI protocol - # NOTE: request not implemented in encoder - encoded = {k: encode(v) for k, v in abci_messages.items()} - translated = {k: v for k, v in encoded.items() if v} - untranslated = set(encoded).difference(translated) - assert all(k.startswith("request") for k in untranslated) - - # 5. create Tendermint message content tree - tender_tree = {k: get_tendermint_content(v) for k, v in translated.items()} - - # 6. translate expected differences in attribute / field naming - # these are known difference introduced by translating between protocols - param_keys_trans = {k: f"{k}_params" for k in ["evidence", "validator", "version"]} - tendermint_to_aea = dict( - response_info={"data": "info_data"}, - response_query={"proof_ops": {"ops": "proof_ops"}}, - response_init_chain={"consensus_params": param_keys_trans}, - response_end_block={"consensus_param_updates": param_keys_trans}, - ) - replace_keys(tender_tree, tendermint_to_aea) - - # 7. compare AEA-native message initialization with the information - # retrieved from the Tendermint Response after translation - shared = set(type_tree).intersection(tender_tree) - assert len(shared) == 16 # expected number of matches - for k in shared: - init_node, tender_node = init_tree[k], tender_tree[k] - compare_trees(init_node, tender_node) - - -def test_tendermint_decoding() -> None: - """Test Tendermint ABCI message decoding""" - - # 1. create tendermint type tree - tender_type_tree = get_tender_type_tree() - - # 2. initialize messages - messages = init_tendermint_messages(tender_type_tree) - - # 3. translate to AEA-native ABCI Messages - decoded = list(map(decode, messages)) - assert len(decoded) == 15 # expected number of matches diff --git a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/__init__.py b/trader_old/vendor/valory/connections/abci/tests/test_fuzz/__init__.py deleted file mode 100644 index 49e069946..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 fuzzy tests for the ABCI Connection""" diff --git a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/base.py b/trader_old/vendor/valory/connections/abci/tests/test_fuzz/base.py deleted file mode 100644 index d054f0694..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/base.py +++ /dev/null @@ -1,373 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ -"""Defines the base of the fuzzy tests""" - -# pylint: skip-file - -import logging -import os -from pathlib import Path -from typing import Any, Dict, List, Tuple, Type - -from aea.exceptions import enforce -from aea.test_tools.test_cases import AEATestCaseMany -from hypothesis import given, settings -from hypothesis.strategies import binary, booleans, integers, lists, text, tuples - -from packages.valory.connections.abci.tests import CI -from packages.valory.connections.abci.tests.test_fuzz.mock_node.channels.base import ( - BaseChannel, -) -from packages.valory.connections.abci.tests.test_fuzz.mock_node.node import MockNode - - -running_on_ci = os.getenv(CI) -if running_on_ci: - settings.load_profile(CI) - - -class BaseFuzzyTests(AEATestCaseMany): - """ - Base class for the Fuzzy Tests - """ - - package_registry_src_rel = Path(__file__).parents[5] - - UINT_64_MAX_VALUE = 18446744073709551615 - UINT_64_MIN_VALUE = 0 - INT_64_MAX_VALUE = 9223372036854775807 - INT_64_MIN_VALUE = -9223372036854775808 - - UINT_32_MAX_VALUE = 4294967295 - UINT_32_MIN_VALUE = 0 - INT_32_MAX_VALUE = 2147483647 - INT_32_MIN_VALUE = -2147483648 - - CHANNEL_TYPE: Type[BaseChannel] = BaseChannel - CHANNEL_ARGS: Dict[str, Any] = dict() - IS_LOCAL = True - USE_GRPC = False - - channel: BaseChannel - mock_node: MockNode - agent_package = "valory/test_abci:0.1.0" - agent_name = "test_abci" - agent_process = None - cli_log_options = ["-v", "INFO"] - - AGENT_TIMEOUT_SECONDS = 10 - - @classmethod - def setup_class(cls) -> None: - """Sets up the environment for the tests.""" - - super().setup_class() - cls.fetch_agent(cls.agent_package, cls.agent_name, is_local=cls.IS_LOCAL) - cls.set_agent_context(cls.agent_name) - cls.generate_private_key("ethereum", "ethereum_private_key.txt") - cls.add_private_key("ethereum", "ethereum_private_key.txt") - # issue certificates for libp2p proof of representation - cls.generate_private_key("cosmos", "cosmos_private_key.txt") - cls.add_private_key("cosmos", "cosmos_private_key.txt") - cls.run_cli_command("issue-certificates", cwd=cls._get_cwd()) - - # we are mocking a tendermint node - cls.set_config("vendor.valory.connections.abci.config.use_tendermint", False) - - cls.set_config("vendor.valory.connections.abci.config.use_grpc", cls.USE_GRPC) - - cls.run_install() - cls.agent_process = cls.run_agent() - - enforce( - cls.is_running(cls.agent_process, cls.AGENT_TIMEOUT_SECONDS), - f"The agent was not started in the defined timeout ({cls.AGENT_TIMEOUT_SECONDS}s)", - ) - - enforce(cls.CHANNEL_TYPE is not None, "A channel type must be provided") - - cls.channel = cls.CHANNEL_TYPE(**cls.CHANNEL_ARGS) - cls.mock_node = MockNode(cls.channel) - cls.mock_node.connect() - logging.disable(logging.INFO) - - @classmethod - def teardown_class(cls) -> None: - """Tear down the testing environment.""" - logging.disable(logging.NOTSET) - cls.mock_node.disconnect() - super().teardown_class() - - # flake8: noqa:D102 - @given(message=text()) - def test_echo(self, message: str) -> None: - assert self.mock_node.echo(message) - - @given( - version=text().filter(lambda x: x != ""), - block_version=integers(0, UINT_64_MAX_VALUE), - p2p_version=integers(0, UINT_64_MAX_VALUE), - ) - def test_info(self, version: str, block_version: int, p2p_version: int) -> None: - assert self.mock_node.info(version, block_version, p2p_version) - - def test_flush(self) -> None: - assert self.mock_node.flush() - - @given(key=text(), value=text()) - def test_set_option(self, key: str, value: str) -> None: - assert self.mock_node.set_option(key, value) - - @given(tx=binary()) - def test_deliver_tx(self, tx: bytes) -> None: - assert self.mock_node.deliver_tx(tx) - - @given(tx=binary(), is_new_check=booleans()) - def test_check_tx(self, tx: bytes, is_new_check: bool) -> None: - assert self.mock_node.check_tx(tx, is_new_check) - - @given( - data=binary(), - path=text(), - height=integers(-INT_64_MAX_VALUE, INT_64_MAX_VALUE), - prove=booleans(), - ) - def test_query(self, data: bytes, path: str, height: int, prove: bool) -> None: - assert self.mock_node.query(data, path, height, prove) - - def test_commit(self) -> None: - assert self.mock_node.commit() - - @given( - time_seconds=integers(0, INT_64_MAX_VALUE), - time_nanos=integers(0, 10**9), - chain_id=text(), - block_max_bytes=integers(1, INT_64_MAX_VALUE), - block_max_gas=integers(-1, INT_32_MAX_VALUE), - evidence_max_age_num_blocks=integers(INT_64_MIN_VALUE, INT_64_MAX_VALUE), - evidence_max_age_seconds=integers(0, INT_64_MAX_VALUE), - evidence_max_age_nanos=integers(0, 10**9), - evidence_max_bytes=integers(1, INT_64_MAX_VALUE), - pub_key_types=lists(booleans()), - app_version=integers(0, INT_32_MAX_VALUE), - validator_pub_keys=lists(tuples(binary(), booleans())), - validator_power=lists(integers(0, INT_32_MAX_VALUE)), - app_state_bytes=binary(), - initial_height=integers(0, INT_32_MAX_VALUE), - ) - def test_init_chain( - self, - time_seconds: int, - time_nanos: int, - chain_id: str, - block_max_bytes: int, - block_max_gas: int, - evidence_max_age_num_blocks: int, - evidence_max_age_seconds: int, - evidence_max_age_nanos: int, - evidence_max_bytes: int, - pub_key_types: List[str], - app_version: int, - validator_pub_keys: List[Tuple[bytes, bool]], - validator_power: List[int], - app_state_bytes: bytes, - initial_height: int, - ) -> None: - min_validator_length = min( - validator_power.__len__(), - validator_pub_keys.__len__(), - pub_key_types.__len__(), - ) - - assert self.mock_node.init_chain( - time_seconds, - time_nanos, - chain_id, - block_max_bytes, - block_max_gas, - evidence_max_age_num_blocks, - evidence_max_age_seconds, - evidence_max_age_nanos, - evidence_max_bytes, - ["ed25519" if pk else "secp256k1" for pk in pub_key_types][ - :min_validator_length - ], - app_version, - [ - (pk, "ed25519") if tp else (pk, "secp256k1") - for pk, tp in validator_pub_keys - ][:min_validator_length], - validator_power[:min_validator_length], - app_state_bytes, - initial_height, - ) - - @given( - hash_=binary(), - consen_ver_block=integers(0, UINT_64_MAX_VALUE), - consen_ver_app=integers(0, UINT_64_MAX_VALUE), - chain_id=text(), - height=integers(-INT_64_MAX_VALUE, INT_64_MAX_VALUE), - time_seconds=integers(1, INT_64_MAX_VALUE), - time_nanos=integers(0, 10**9), - last_block_id_hash=binary(), - last_commit_hash=binary(), - data_hash=binary(), - validators_hash=binary(), - next_validators_hash=binary(), - next_validators_part_header_total=integers(0, UINT_32_MAX_VALUE), - next_validators_part_header_hash=binary(), - header_consensus_hash=binary(), - header_app_hash=binary(), - header_last_results_hash=binary(), - header_evidence_hash=binary(), - header_proposer_address=binary(), - last_commit_round=integers(INT_32_MIN_VALUE, INT_32_MAX_VALUE), - last_commit_info_votes=lists( - tuples(binary(), integers(INT_64_MIN_VALUE, INT_64_MAX_VALUE)) - ), - last_commit_info_signed_last_block=lists(booleans()), - evidence_type=lists(integers()), - evidence_validator_address=lists(binary()), - evidence_validator_power=lists(integers(INT_64_MIN_VALUE, INT_64_MAX_VALUE)), - evidence_height=lists(integers(INT_64_MIN_VALUE, INT_64_MAX_VALUE)), - evidence_time_seconds=lists(integers(1, INT_64_MAX_VALUE)), - evidence_time_nanos=lists(integers(0, 10**9)), - evidence_total_voting_power=lists(integers(0, INT_64_MAX_VALUE)), - ) - def test_begin_block( - self, - hash_: bytes, - consen_ver_block: int, - consen_ver_app: int, - chain_id: str, - height: int, - time_seconds: int, - time_nanos: int, - last_block_id_hash: bytes, - last_commit_hash: bytes, - data_hash: bytes, - validators_hash: bytes, - next_validators_hash: bytes, - next_validators_part_header_total: int, - next_validators_part_header_hash: bytes, - header_consensus_hash: bytes, - header_app_hash: bytes, - header_last_results_hash: bytes, - header_evidence_hash: bytes, - header_proposer_address: bytes, - last_commit_round: int, - last_commit_info_votes: List[Tuple[bytes, int]], - last_commit_info_signed_last_block: List[bool], - evidence_type: List[int], - evidence_validator_address: List[bytes], - evidence_validator_power: List[int], - evidence_height: List[int], - evidence_time_seconds: List[int], - evidence_time_nanos: List[int], - evidence_total_voting_power: List[int], - ) -> None: - last_commit_len = min( - last_commit_info_votes.__len__(), - last_commit_info_signed_last_block.__len__(), - ) - evidence_len = min( - evidence_type.__len__(), - evidence_validator_address.__len__(), - evidence_validator_power.__len__(), - evidence_height.__len__(), - evidence_time_seconds.__len__(), - evidence_time_nanos.__len__(), - evidence_total_voting_power.__len__(), - ) - self.mock_node.begin_block( - hash_, - consen_ver_block, - consen_ver_app, - chain_id, - height, - time_seconds, - time_nanos, - last_block_id_hash, - last_commit_hash, - data_hash, - validators_hash, - next_validators_hash, - next_validators_part_header_total, - next_validators_part_header_hash, - header_consensus_hash, - header_app_hash, - header_last_results_hash, - header_evidence_hash, - header_proposer_address, - last_commit_round, - last_commit_info_votes[:last_commit_len], - last_commit_info_signed_last_block[:last_commit_len], - evidence_type[:evidence_len], - evidence_validator_address[:evidence_len], - evidence_validator_power[:evidence_len], - evidence_height[:evidence_len], - evidence_time_seconds[:evidence_len], - evidence_time_nanos[:evidence_len], - evidence_total_voting_power[:evidence_len], - ) - - @given(height=integers(INT_64_MIN_VALUE, INT_64_MAX_VALUE)) - def test_end_block(self, height: int) -> None: - assert self.mock_node.end_block(height) - - def test_list_snapshots(self) -> None: - assert self.mock_node.list_snapshots() - - @given( - height=integers(UINT_64_MIN_VALUE, UINT_64_MAX_VALUE), - format_=integers(UINT_32_MIN_VALUE, UINT_32_MAX_VALUE), - chunks=integers(UINT_32_MIN_VALUE, UINT_32_MAX_VALUE), - hash_=binary(), - metadata=binary(), - app_hash=binary(), - ) - def test_offer_snapshot( - self, - height: int, - format_: int, - chunks: int, - hash_: bytes, - metadata: bytes, - app_hash: bytes, - ) -> None: - assert self.mock_node.offer_snapshot( - height, format_, chunks, hash_, metadata, app_hash - ) - - @given( - height=integers(UINT_64_MIN_VALUE, UINT_64_MAX_VALUE), - format_=integers(UINT_32_MIN_VALUE, UINT_32_MAX_VALUE), - chunk=integers(UINT_32_MIN_VALUE, UINT_32_MAX_VALUE), - ) - def test_load_snapshot_chunk(self, height: int, format_: int, chunk: int) -> None: - assert self.mock_node.load_snapshot_chunk(height, format_, chunk) - - @given( - index=integers(UINT_32_MIN_VALUE, UINT_32_MAX_VALUE), - chunk=binary(), - sender=text(), - ) - def test_apply_snapshot_chunk(self, index: int, chunk: bytes, sender: str) -> None: - assert self.mock_node.apply_snapshot_chunk(index, chunk, sender) diff --git a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/__init__.py b/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/__init__.py deleted file mode 100644 index 226b566c9..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 mocks a Tendermint Node""" diff --git a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/__init__.py b/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/__init__.py deleted file mode 100644 index d1e04f729..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 imlpements the channels for the ABCI <-> Tendermint (Mock) Node communication""" diff --git a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/base.py b/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/base.py deleted file mode 100644 index 5f790294d..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/base.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -# pylint: disable=no-member - -"""BaseChannel for MockNode""" - -from typing import Dict - -import packages.valory.connections.abci.tendermint.abci.types_pb2 as abci_types # type: ignore - - -class BaseChannel: - """Defines the interface for other channels to use""" - - def __init__(self, **kwargs: Dict) -> None: - """Initializes a channel""" - - def connect(self) -> None: - """ - Set up the channel. - - By default, it is a no-op. - """ - - def disconnect(self) -> None: - """ - Tear down the channel. - - By default, it is a no-op. - """ - - def send_info(self, request: abci_types.RequestInfo) -> abci_types.ResponseInfo: # type: ignore - """ - Sends an info request. - - :param: request: RequestInfo pb object - """ - raise NotImplementedError - - def send_echo(self, request: abci_types.RequestEcho) -> abci_types.ResponseEcho: # type: ignore - """ - Sends an echo request. - - :param: request: RequestEcho pb object - """ - raise NotImplementedError - - def send_flush(self, request: abci_types.RequestFlush) -> abci_types.ResponseFlush: # type: ignore - """ - Sends an flush request. - - :param: request: RequestFlush pb object - """ - raise NotImplementedError - - def send_set_option( - self, request: abci_types.RequestSetOption # type: ignore - ) -> abci_types.ResponseSetOption: # type: ignore - """ - Sends an setOption request. - - :param: request: RequestSetOption pb object - """ - raise NotImplementedError - - def send_deliver_tx( - self, request: abci_types.RequestDeliverTx # type: ignore - ) -> abci_types.ResponseDeliverTx: # type: ignore - """ - Sends an deliverTx request. - - :param: request: RequestDeliverTx pb object - """ - raise NotImplementedError - - def send_check_tx( - self, request: abci_types.RequestCheckTx # type: ignore - ) -> abci_types.ResponseCheckTx: # type: ignore - """ - Sends an checkTx request. - - :param: request: RequestCheckTx pb object - """ - raise NotImplementedError - - def send_query(self, request: abci_types.RequestQuery) -> abci_types.ResponseQuery: # type: ignore - """ - Sends an query request. - - :param: request: RequestQuery pb object - """ - raise NotImplementedError - - def send_commit( - self, request: abci_types.RequestCommit # type: ignore - ) -> abci_types.ResponseCommit: # type: ignore - """ - Sends an commit request. - - :param: request: RequestCommit pb object - """ - raise NotImplementedError - - def send_init_chain( - self, request: abci_types.RequestInitChain # type: ignore - ) -> abci_types.ResponseInitChain: # type: ignore - """ - Sends an initChain request. - - :param: request: RequestInitChain pb object - """ - raise NotImplementedError - - def send_begin_block( - self, request: abci_types.RequestBeginBlock # type: ignore - ) -> abci_types.ResponseBeginBlock: # type: ignore - """ - Sends an beginBlock request. - - :param: request: RequestBeginBlock pb object - """ - raise NotImplementedError - - def send_end_block( - self, request: abci_types.RequestEndBlock # type: ignore - ) -> abci_types.ResponseEndBlock: # type: ignore - """ - Sends an endBlock request. - - :param: request: RequestEndBlock pb object - """ - raise NotImplementedError - - def send_list_snapshots( - self, request: abci_types.RequestListSnapshots # type: ignore - ) -> abci_types.ResponseListSnapshots: # type: ignore - """ - Sends an listSnapshots request. - - :param: request: RequestListSnapshots pb object - """ - raise NotImplementedError - - def send_offer_snapshot( - self, request: abci_types.RequestOfferSnapshot # type: ignore - ) -> abci_types.ResponseOfferSnapshot: # type: ignore - """ - Sends an offerSnapshot request. - - :param: request: RequestOfferSnapshot pb object - """ - raise NotImplementedError - - def send_load_snapshot_chunk( - self, request: abci_types.RequestLoadSnapshotChunk # type: ignore - ) -> abci_types.ResponseLoadSnapshotChunk: # type: ignore - """ - Sends an loadSnapshotChunk request. - - :param: request: RequestLoadSnapshotChunk pb object - """ - raise NotImplementedError - - def send_apply_snapshot_chunk( - self, request: abci_types.RequestApplySnapshotChunk # type: ignore - ) -> abci_types.ResponseApplySnapshotChunk: # type: ignore - """ - Sends an applySnapshotChunk request. - - :param: request: RequestApplySnapshotChunk pb object - """ - raise NotImplementedError diff --git a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/grpc_channel.py b/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/grpc_channel.py deleted file mode 100644 index f247815cd..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/grpc_channel.py +++ /dev/null @@ -1,213 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ -"""GrpcChannel for MockNode""" -# pylint: skip-file - -import logging -from typing import Dict - -import grpc - -import packages.valory.connections.abci.tendermint.abci.types_pb2 as abci_types # type: ignore -import packages.valory.connections.abci.tendermint.abci.types_pb2_grpc as tendermint_grpc # type: ignore - -from .base import BaseChannel - - -_default_logger = logging.getLogger(__name__) - -logging.basicConfig() - - -class GrpcChannel(BaseChannel): - """Implements BaseChannel to use gRPC""" - - def __init__(self, **kwargs: Dict) -> None: - """ - Initializes a GrpcChannel - - :param: kwargs: - - host: the host of the ABCI app (localhost by default) - - port: the port of the ABCI app (26658 by default) - """ - super().__init__() - - host = kwargs.get("host", "localhost") - port = kwargs.get("port", 26658) - self.logger = _default_logger - - grpc_channel = grpc.insecure_channel(f"{host}:{port}") - self.grpc_client = tendermint_grpc.ABCIApplicationStub(grpc_channel) - - def send_info(self, request: abci_types.RequestInfo) -> abci_types.ResponseInfo: # type: ignore - """ - Sends an info request. - - :param: request: RequestInfo pb object - :return: ResponseInfo pb object - """ - return self.grpc_client.Info(request) - - def send_echo(self, request: abci_types.RequestEcho) -> abci_types.ResponseEcho: # type: ignore - """ - Sends an echo request. - - :param: request: RequestEcho pb object - :return: ResponseEcho pb object - """ - return self.grpc_client.Echo(request) - - def send_flush(self, request: abci_types.RequestFlush) -> abci_types.ResponseFlush: # type: ignore - """ - Sends an flush request. - - :param: request: RequestFlush pb object - :return: ResponseFlush pb object - """ - return self.grpc_client.Flush(request) - - def send_set_option( - self, request: abci_types.RequestSetOption # type: ignore - ) -> abci_types.ResponseSetOption: # type: ignore - """ - Sends an setOption request. - - :param: request: RequestSetOption pb object - :return: ResponseSetOption pb object - """ - return self.grpc_client.SetOption(request) - - def send_deliver_tx( - self, request: abci_types.RequestDeliverTx # type: ignore - ) -> abci_types.ResponseDeliverTx: # type: ignore - """ - Sends an deliverTx request. - - :param: request: RequestDeliverTx pb object - :return: ResponseDeliverTx pb object - """ - return self.grpc_client.DeliverTx(request) - - def send_check_tx( - self, request: abci_types.RequestCheckTx # type: ignore - ) -> abci_types.ResponseCheckTx: # type: ignore - """ - Sends an checkTx request. - - :param: request: RequestCheckTx pb object - :return: ResponseCheckTx pb object - """ - return self.grpc_client.CheckTx(request) - - def send_query(self, request: abci_types.RequestQuery) -> abci_types.ResponseQuery: # type: ignore - """ - Sends an query request. - - :param: request: RequestQuery pb object - :return: ResponseQuery pb object - """ - return self.grpc_client.Query(request) - - def send_commit( - self, request: abci_types.RequestCommit # type: ignore - ) -> abci_types.ResponseCommit: # type: ignore - """ - Sends an commit request. - - :param: request: RequestCommit pb object - :return: ResponseCommit pb object - """ - return self.grpc_client.Commit(request) - - def send_init_chain( - self, request: abci_types.RequestInitChain # type: ignore - ) -> abci_types.ResponseInitChain: # type: ignore - """ - Sends an initChain request. - - :param: request: RequestInitChain pb object - :return: ResponseInitChain pb object - """ - return self.grpc_client.InitChain(request) - - def send_begin_block( - self, request: abci_types.RequestBeginBlock # type: ignore - ) -> abci_types.ResponseBeginBlock: # type: ignore - """ - Sends an beginBlock request. - - :param: request: RequestBeginBlock pb object - :return: ResponseBeginBlock pb object - """ - return self.grpc_client.BeginBlock(request) - - def send_end_block( - self, request: abci_types.RequestEndBlock # type: ignore - ) -> abci_types.ResponseEndBlock: # type: ignore - """ - Sends an endBlock request. - - :param: request: RequestEndBlock pb object - :return: ResponseEndBlock pb object - """ - return self.grpc_client.EndBlock(request) - - def send_list_snapshots( - self, request: abci_types.RequestListSnapshots # type: ignore - ) -> abci_types.ResponseListSnapshots: # type: ignore - """ - Sends an listSnapshots request. - - :param: request: RequestListSnapshots pb object - :return: ResponseListSnapshots pb object - """ - return self.grpc_client.ListSnapshots(request) - - def send_offer_snapshot( - self, request: abci_types.RequestOfferSnapshot # type: ignore - ) -> abci_types.ResponseOfferSnapshot: # type: ignore - """ - Sends an offerSnapshot request. - - :param: request: RequestOfferSnapshot pb object - :return: ResponseOfferSnapshot pb object - """ - return self.grpc_client.OfferSnapshot(request) - - def send_load_snapshot_chunk( - self, request: abci_types.RequestLoadSnapshotChunk # type: ignore - ) -> abci_types.ResponseLoadSnapshotChunk: # type: ignore - """ - Sends an loadSnapshotChunk request. - - :param: request: RequestLoadSnapshotChunk pb object - :return: ResponseLoadSnapshotChunk pb object - """ - return self.grpc_client.LoadSnapshotChunk(request) - - def send_apply_snapshot_chunk( - self, request: abci_types.RequestApplySnapshotChunk # type: ignore - ) -> abci_types.ResponseApplySnapshotChunk: # type: ignore - """ - Sends an applySnapshotChunk request. - - :param: request: RequestApplySnapshotChunk pb object - :return: ResponseApplySnapshotChunk pb object - """ - return self.grpc_client.ApplySnapshotChunk(request) diff --git a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/tcp_channel.py b/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/tcp_channel.py deleted file mode 100644 index a28cb7ea1..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/channels/tcp_channel.py +++ /dev/null @@ -1,535 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ -"""TcpChannel for MockNode""" -# pylint: skip-file - -import asyncio -import logging -import platform -import socket -from asyncio import AbstractEventLoop -from threading import Thread -from typing import Dict, Optional, cast - -from aea.exceptions import enforce - -import packages.valory.connections.abci.tendermint.abci.types_pb2 as abci_types # type: ignore -from packages.valory.connections.abci.connection import ( - VarintMessageReader, - _TendermintABCISerializer, -) -from packages.valory.connections.abci.tests.test_fuzz.mock_node.channels.base import ( - BaseChannel, -) - - -_default_logger = logging.getLogger(__name__) - -logging.basicConfig() - - -class TcpChannel(BaseChannel): - """Implements BaseChannel to use TCP sockets""" - - MAX_READ_IN_BYTES = 64 * 1024 # Max we'll consume on a read stream - - def __init__(self, **kwargs: Dict) -> None: - """ - Initializes a TcpChannel - - :param: kwargs: - - host: the host of the ABCI app (localhost by default) - - port: the port of the ABCI app (26658 by default) - """ - super().__init__(**kwargs) - - self.host: str = cast(str, kwargs.get("host", "localhost")) - self.port: int = cast(int, kwargs.get("port", 26658)) - self.logger = _default_logger - - # attributes for the channel state - self.loop: Optional[AbstractEventLoop] = None - self.loop_thread: Optional[Thread] = None - self.message_reader: Optional[VarintMessageReader] = None - self.reader: Optional[asyncio.StreamReader] = None - self.writer: Optional[asyncio.StreamWriter] = None - - @property - def is_connected(self) -> bool: - """Check whether the channel is connected.""" - return self.loop_thread is not None - - def connect(self) -> None: - """Set up the channel.""" - if self.is_connected: - return - - if platform.system() == "Windows": - self.loop = cast( - asyncio.AbstractEventLoop, - asyncio.WindowsSelectorEventLoopPolicy().new_event_loop(), # type: ignore # windows only - ) - else: - self.loop = cast(asyncio.AbstractEventLoop, asyncio.new_event_loop()) - self.loop_thread = Thread(target=self._run_loop_in_thread, args=(self.loop,)) - self.loop_thread.start() - - # set up asyncio connection - future = asyncio.run_coroutine_threadsafe( - asyncio.open_connection(self.host, self.port, family=socket.AF_INET), - self.loop, - ) - self.reader, self.writer = future.result() - self.message_reader = VarintMessageReader(self.reader) - - def disconnect(self) -> None: - """Tear down the channel.""" - if not self.is_connected: - return - - cast(asyncio.StreamWriter, self.writer).close() - - loop = cast(AbstractEventLoop, self.loop) - loop.call_soon_threadsafe(loop.stop) - cast(Thread, self.loop_thread).join(5) - - # restore channel state - self.loop = None - self.loop_thread = None - self.message_reader = None - self.reader = None - self.writer = None - - @staticmethod - def _run_loop_in_thread(loop: AbstractEventLoop) -> None: - """Run an asyncio loop in the thread of the caller.""" - asyncio.set_event_loop(loop) - loop.run_forever() - - def _get_response(self) -> abci_types.Response: # type: ignore - """ - Gets the response for a request. - - :return: a pb response object - - It assumes that: - - For every request there's a response. - - Responses are sent in the same order as the reqs. - - """ - future = asyncio.run_coroutine_threadsafe( - cast(VarintMessageReader, self.message_reader).read_next_message(), - cast(AbstractEventLoop, self.loop), - ) - message_bytes = future.result() - message = abci_types.Response() # type: ignore - message.ParseFromString(message_bytes) - return message - - def _send_data(self, data: bytes) -> None: - """Send data over the TCP connection.""" - cast(asyncio.StreamWriter, self.writer).write(data) - future = asyncio.run_coroutine_threadsafe( - cast(asyncio.StreamWriter, self.writer).drain(), - cast(AbstractEventLoop, self.loop), - ) - future.result() - - def send_info(self, request: abci_types.RequestInfo) -> abci_types.ResponseInfo: # type: ignore - """ - Sends an info request. - - :param: request: RequestInfo pb object - :return: ResponseInfo pb object - """ - - message = abci_types.Request() # type: ignore - message.info.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "info", - f"expected response of type info, {response_type} was received", - ) - - return response.info - - def send_echo(self, request: abci_types.RequestEcho) -> abci_types.ResponseEcho: # type: ignore - """ - Sends an echo request. - - :param: request: RequestEcho pb object - :return: ResponseEcho pb object - """ - message = abci_types.Request() # type: ignore - message.echo.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "echo", - f"expected response of type echo, {response_type} was received", - ) - - return response.echo - - def send_flush(self, request: abci_types.RequestFlush) -> abci_types.ResponseFlush: # type: ignore - """ - Sends an flush request. - - :param: request: RequestFlush pb object - :return: ResponseFlush pb object - """ - message = abci_types.Request() # type: ignore - message.flush.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "flush", - f"expected response of type flush, {response_type} was received", - ) - - return response.flush - - def send_set_option( - self, request: abci_types.RequestSetOption # type: ignore - ) -> abci_types.ResponseSetOption: # type: ignore - """ - Sends an setOption request. - - :param: request: RequestSetOption pb object - :return: ResponseSetOption pb object - """ - message = abci_types.Request() # type: ignore - message.set_option.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "set_option", - f"expected response of type set_option, {response_type} was received", - ) - - return response.set_option - - def send_deliver_tx( - self, request: abci_types.RequestDeliverTx # type: ignore - ) -> abci_types.ResponseDeliverTx: # type: ignore - """ - Sends an deliverTx request. - - :param: request: RequestDeliverTx pb object - :return: ResponseDeliverTx pb object - """ - message = abci_types.Request() # type: ignore - message.deliver_tx.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "deliver_tx", - f"expected response of type deliver_tx, {response_type} was received", - ) - - return response.deliver_tx - - def send_check_tx( - self, request: abci_types.RequestCheckTx # type: ignore - ) -> abci_types.ResponseCheckTx: # type: ignore - """ - Sends an checkTx request. - - :param: request: RequestCheckTx pb object - :return: ResponseCheckTx pb object - """ - message = abci_types.Request() # type: ignore - message.check_tx.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "check_tx", - f"expected response of type check_tx, {response_type} was received", - ) - - return response.check_tx - - def send_query(self, request: abci_types.RequestQuery) -> abci_types.ResponseQuery: # type: ignore - """ - Sends an query request. - - :param: request: RequestQuery pb object - :return: ResponseQuery pb object - """ - message = abci_types.Request() # type: ignore - message.query.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "query", - f"expected response of type query, {response_type} was received", - ) - - return response.query - - def send_commit( - self, request: abci_types.RequestCommit # type: ignore - ) -> abci_types.ResponseCommit: # type: ignore - """ - Sends an commit request. - - :param: request: RequestCommit pb object - :return: ResponseCommit pb object - """ - message = abci_types.Request() # type: ignore - message.commit.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "commit", - f"expected response of type commit, {response_type} was received", - ) - - return response.commit - - def send_init_chain( - self, request: abci_types.RequestInitChain # type: ignore - ) -> abci_types.ResponseInitChain: # type: ignore - """ - Sends an initChain request. - - :param: request: RequestInitChain pb object - :return: ResponseInitChain pb object - """ - message = abci_types.Request() # type: ignore - message.init_chain.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "init_chain", - f"expected response of type init_chain, {response_type} was received", - ) - - return response.init_chain - - def send_begin_block( - self, request: abci_types.RequestBeginBlock # type: ignore - ) -> abci_types.ResponseBeginBlock: # type: ignore - """ - Sends an beginBlock request. - - :param: request: RequestBeginBlock pb object - :return: ResponseBeginBlock pb object - """ - message = abci_types.Request() # type: ignore - message.begin_block.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "begin_block", - f"expected response of type begin_block, {response_type} was received", - ) - - return response.begin_block - - def send_end_block( - self, request: abci_types.RequestEndBlock # type: ignore - ) -> abci_types.ResponseEndBlock: # type: ignore - """ - Sends an endBlock request. - - :param: request: RequestEndBlock pb object - :return: ResponseEndBlock pb object - """ - message = abci_types.Request() # type: ignore - message.end_block.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "end_block", - f"expected response of type end_block, {response_type} was received", - ) - - return response.end_block - - def send_list_snapshots( - self, request: abci_types.RequestListSnapshots # type: ignore - ) -> abci_types.ResponseListSnapshots: # type: ignore - """ - Sends an listSnapshots request. - - :param: request: RequestListSnapshots pb object - :return: ResponseListSnapshots pb object - """ - message = abci_types.Request() # type: ignore - message.list_snapshots.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "list_snapshots", - f"expected response of type list_snapshots, {response_type} was received", - ) - - return response.list_snapshots - - def send_offer_snapshot( - self, request: abci_types.RequestOfferSnapshot # type: ignore - ) -> abci_types.ResponseOfferSnapshot: # type: ignore - """ - Sends an offerSnapshot request. - - :param: request: RequestOfferSnapshot pb object - :return: ResponseOfferSnapshot pb object - """ - message = abci_types.Request() # type: ignore - message.offer_snapshot.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "offer_snapshot", - f"expected response of type offer_snapshot, {response_type} was received", - ) - - return response.offer_snapshot - - def send_load_snapshot_chunk( - self, request: abci_types.RequestLoadSnapshotChunk # type: ignore - ) -> abci_types.ResponseLoadSnapshotChunk: # type: ignore - """ - Sends an loadSnapshotChunk request. - - :param: request: RequestLoadSnapshotChunk pb object - :return: ResponseLoadSnapshotChunk pb object - """ - message = abci_types.Request() # type: ignore - message.load_snapshot_chunk.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "load_snapshot_chunk", - f"expected response of type load_snapshot_chunk, {response_type} was received", - ) - - return response.load_snapshot_chunk - - def send_apply_snapshot_chunk( - self, request: abci_types.RequestApplySnapshotChunk # type: ignore - ) -> abci_types.ResponseApplySnapshotChunk: # type: ignore - """ - Sends an applySnapshotChunk request. - - :param: request: RequestApplySnapshotChunk pb object - :return: ResponseApplySnapshotChunk pb object - """ - message = abci_types.Request() # type: ignore - message.apply_snapshot_chunk.CopyFrom(request) - - data = _TendermintABCISerializer.write_message(message) - - self._send_data(data) - - response = self._get_response() - response_type = response.WhichOneof("value") - - enforce( - response_type == "apply_snapshot_chunk", - f"expected response of type apply_snapshot_chunk, {response_type} was received", - ) - - return response.apply_snapshot_chunk diff --git a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/node.py b/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/node.py deleted file mode 100644 index 3c5bb3f87..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/mock_node/node.py +++ /dev/null @@ -1,520 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ -"""Used for mocking a tendermint node""" -# flake8: noqa:D102 -# pylint: skip-file - -import logging -from typing import List, Tuple - -from aea.exceptions import enforce -from google.protobuf import timestamp_pb2 - -import packages.valory.connections.abci.tendermint.abci.types_pb2 as abci_types # type: ignore -import packages.valory.connections.abci.tendermint.crypto.keys_pb2 as keys_types # type: ignore -import packages.valory.connections.abci.tendermint.types.types_pb2 as tendermint_types # type: ignore -import packages.valory.connections.abci.tendermint.version.types_pb2 as version_type # type: ignore -from packages.valory.protocols.abci.custom_types import ( - BlockParams, - ConsensusParams, - Duration, - EvidenceParams, - PublicKey, - Snapshot, - Timestamp, - ValidatorParams, - ValidatorUpdate, - VersionParams, -) - -from .channels.base import BaseChannel - - -_default_logger = logging.getLogger(__name__) - -logging.basicConfig() - - -class MockNode: - """Mocks a Tendermint Node""" - - def __init__(self, channel: BaseChannel) -> None: - self.logger = _default_logger - self.logger.setLevel(logging.DEBUG) - - enforce(channel is not None, "channel is None") - - self.channel = channel - - def connect(self) -> None: - """Connect the node.""" - self.channel.connect() - - def disconnect(self) -> None: - """Disconnect the node.""" - self.channel.disconnect() - - def info(self, version: str, block_version: int, p2p_version: int) -> bool: - request = abci_types.RequestInfo() # type: ignore - request.version = version - request.block_version = block_version - request.p2p_version = p2p_version - - self.logger.info( - f"Calling info with version={version}, block_version={block_version}, p2p_version={p2p_version}" - ) - - response = self.channel.send_info(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def echo(self, message: str) -> bool: - request = abci_types.RequestEcho() # type: ignore - request.message = message - - self.logger.info(f"Calling echo with message={message}") - - response = self.channel.send_echo(request) - - self.logger.info(f"Received response {str(response)}") - return True - - def flush(self) -> bool: - request = abci_types.RequestFlush() # type: ignore - - self.logger.info("Sending flush req") - - response = self.channel.send_flush(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def set_option(self, key: str, value: str) -> bool: - request = abci_types.RequestSetOption() # type: ignore - request.key = key - request.value = value - - self.logger.info(f"Calling set_options with key={key} value={value}") - - response = self.channel.send_set_option(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def deliver_tx(self, tx: bytes) -> bool: - request = abci_types.RequestDeliverTx() # type: ignore - request.tx = tx - - self.logger.info(f"Calling deliver_tx with tx={tx!r}") - - response = self.channel.send_deliver_tx(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def check_tx(self, tx: bytes, is_new_check: bool) -> bool: - request = abci_types.RequestCheckTx() # type: ignore - request.tx = tx - request.type = 1 if is_new_check else 0 - - self.logger.info(f"Calling check_tx with tx={tx!r} and is_new={is_new_check}") - - response = self.channel.send_check_tx(request) - - self.logger.info(f"Received response {str(response)}") - - return response - - def query(self, data: bytes, path: str, height: int, prove: bool) -> bool: - request = abci_types.RequestQuery() # type: ignore - request.data = data - request.path = path - request.height = height - request.prove = prove - - self.logger.info( - f"Calling query with data={data!r} and path={path} height={height} prove={prove}" - ) - - response = self.channel.send_query(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def commit(self) -> bool: - request = abci_types.RequestCommit() # type: ignore - - self.logger.info("Calling commit") - - response = self.channel.send_commit(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def init_chain( - self, - time_seconds: int, - time_nanos: int, - chain_id: str, - block_max_bytes: int, - block_max_gas: int, - evidence_max_age_num_blocks: int, - evidence_max_age_seconds: int, - evidence_max_age_nanos: int, - evidence_max_bytes: int, - pub_key_types: List[str], - app_version: int, - validator_pub_keys: List[Tuple[bytes, str]], - validator_power: List[int], - app_state_bytes: bytes, - initial_height: int, - ) -> bool: - request = abci_types.RequestInitChain() # type: ignore - - timestamp = timestamp_pb2.Timestamp() - Timestamp.encode(timestamp, Timestamp(time_seconds, time_nanos)) - request.time.CopyFrom(timestamp) - - request.chain_id = chain_id - - block_params = BlockParams(block_max_bytes, block_max_gas) - duration = Duration(evidence_max_age_seconds, evidence_max_age_nanos) - evidence_params = EvidenceParams( - evidence_max_age_num_blocks, duration, evidence_max_bytes - ) - validator_params = ValidatorParams(pub_key_types) - version_params = VersionParams(app_version) - consensus_params = abci_types.ConsensusParams() # type: ignore - ConsensusParams.encode( - consensus_params, - ConsensusParams( - block_params, evidence_params, validator_params, version_params - ), - ) - request.consensus_params.CopyFrom(consensus_params) - - enforce( - validator_pub_keys.__len__() == validator_power.__len__(), - "pubkeys should have same length as power", - ) - - pub_keys = [ - PublicKey(bs, PublicKey.PublicKeyType(tp)) for bs, tp in validator_pub_keys - ] - validator_updates = [ - ValidatorUpdate(pk, vp) for pk, vp in zip(pub_keys, validator_power) - ] - validator_updates_pb = [] - - for validator_update_object in validator_updates: - validator_update_protobuf_object = abci_types.ValidatorUpdate() # type: ignore - pub_key = keys_types.PublicKey() # type: ignore - - PublicKey.encode(pub_key, validator_update_object.pub_key) - validator_update_protobuf_object.power = validator_update_object.power - validator_update_protobuf_object.pub_key.CopyFrom(pub_key) - - validator_updates_pb.append(validator_update_protobuf_object) - - request.validators.extend(validator_updates_pb) - - request.app_state_bytes = app_state_bytes - request.initial_height = initial_height - - self.logger.info( - f"""Calling init_chain - time_seconds={time_seconds} - time_nanos={time_nanos} - chain_id={chain_id} - block_max_bytes={block_max_bytes} - block_max_gas={block_max_gas} - evidence_max_age_num_blocks={evidence_max_age_num_blocks} - evidence_max_age_seconds={evidence_max_age_seconds} - evidence_max_age_nanos={evidence_max_age_nanos} - evidence_max_bytes={evidence_max_bytes} - pub_key_types={pub_key_types} - app_version={app_version} - validator_pub_keys={validator_pub_keys} - validator_power={validator_power} - app_state_bytes={app_state_bytes!r} - initial_height={initial_height} - """ - ) - - response = self.channel.send_init_chain(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def begin_block( - self, - hash_: bytes, - consen_ver_block: int, - consen_ver_app: int, - chain_id: str, - height: int, - time_seconds: int, - time_nanos: int, - last_block_id_hash: bytes, - last_commit_hash: bytes, - data_hash: bytes, - validators_hash: bytes, - next_validators_hash: bytes, - next_validators_part_header_total: int, - next_validators_part_header_hash: bytes, - header_consensus_hash: bytes, - header_app_hash: bytes, - header_last_results_hash: bytes, - header_evidence_hash: bytes, - header_proposer_address: bytes, - last_commit_round: int, - last_commit_info_votes: List[Tuple[bytes, int]], - last_commit_info_signed_last_block: List[bool], - evidence_type: List[int], - evidence_validator_address: List[bytes], - evidence_validator_power: List[int], - evidence_height: List[int], - evidence_time_seconds: List[int], - evidence_time_nanos: List[int], - evidence_total_voting_power: List[int], - ) -> bool: - consensus_version = version_type.Consensus() # type: ignore - consensus_version.block = consen_ver_block - consensus_version.app = consen_ver_app - - part_set_header = tendermint_types.PartSetHeader() # type: ignore - part_set_header.total = next_validators_part_header_total - part_set_header.hash = next_validators_part_header_hash - - block_id = tendermint_types.BlockID() # type: ignore - block_id.hash = last_block_id_hash - block_id.part_set_header.CopyFrom(part_set_header) - - time = timestamp_pb2.Timestamp() - time.seconds = time_seconds - time.nanos = time_nanos - - header = tendermint_types.Header() # type: ignore - header.version.CopyFrom(consensus_version) - header.chain_id = chain_id - header.height = height - header.time.CopyFrom(time) - header.last_block_id.CopyFrom(block_id) - header.last_commit_hash = last_commit_hash - header.data_hash = data_hash - header.validators_hash = validators_hash - header.next_validators_hash = next_validators_hash - header.consensus_hash = header_consensus_hash - header.app_hash = header_app_hash - header.last_results_hash = header_last_results_hash - header.evidence_hash = header_evidence_hash - header.proposer_address = header_proposer_address - - enforce( - last_commit_info_signed_last_block.__len__() - == last_commit_info_signed_last_block.__len__(), - "last_commit_info_signed_last_block should have same length last_commit_info_signed_last_block", - ) - - vote_infos = [] - for i in range(last_commit_info_votes.__len__()): - validator = abci_types.Validator() # type: ignore - validator.address = last_commit_info_votes[i][0] - validator.power = last_commit_info_votes[i][1] - - vote_info = abci_types.VoteInfo() # type: ignore - vote_info.validator.CopyFrom(validator) - vote_info.signed_last_block = last_commit_info_signed_last_block[i] - - vote_infos.append(vote_info) - - last_commit_info = abci_types.LastCommitInfo() # type: ignore - last_commit_info.round = last_commit_round - last_commit_info.votes.extend(vote_infos) - - enforce( - { - evidence_validator_address.__len__(), - evidence_validator_power.__len__(), - evidence_height.__len__(), - evidence_time_seconds.__len__(), - evidence_time_nanos.__len__(), - evidence_total_voting_power.__len__(), - evidence_type.__len__(), - }.__len__() - == 1, - "evidence_* lists should have same length", - ) - - evidences = [] - - for i in range(evidence_type.__len__()): - validator = abci_types.Validator() # type: ignore - validator.address = evidence_validator_address[i] - validator.power = evidence_validator_power[i] - - time = timestamp_pb2.Timestamp() - time.seconds = evidence_time_seconds[i] - time.nanos = evidence_time_nanos[i] - - evidence = abci_types.Evidence() # type: ignore - evidence.type = evidence_type[i] % 3 - evidence.height = evidence_height[i] - evidence.total_voting_power = evidence_total_voting_power[i] - evidence.time.CopyFrom(time) - evidence.validator.CopyFrom(validator) - - evidences.append(evidence) - - request = abci_types.RequestBeginBlock() # type: ignore - request.hash = hash_ - request.header.CopyFrom(header) - request.last_commit_info.CopyFrom(last_commit_info) - request.byzantine_validators.extend(evidences) - - self.logger.info( - f""" - Calling begin_block - hash_: {hash_!r} - consen_ver_block={consen_ver_block} - consen_ver_app={consen_ver_app} - chain_id={chain_id} - height={height} - time_seconds={time_seconds}" - time_nanos={time_nanos} - last_block_id_hash={last_block_id_hash!r} - last_commit_hash={last_commit_hash!r} - data_hash={data_hash!r} - validators_hash={validators_hash!r}" - next_validators_hash={next_validators_hash!r} - next_validators_part_header_total={next_validators_part_header_total} - next_validators_part_header_hash={next_validators_part_header_hash!r} - header_consensus_hash={header_consensus_hash!r} - header_app_hash={header_app_hash!r} - header_last_results_hash={header_last_results_hash!r} - header_evidence_hash={header_evidence_hash!r} - header_proposer_address={header_proposer_address!r} - last_commit_round={last_commit_round} - last_commit_info_votes={last_commit_info_votes} - last_commit_info_signed_last_block={last_commit_info_signed_last_block} - evidence_type={evidence_type} - evidence_validator_address={evidence_validator_address} - evidence_validator_power={evidence_validator_power} - evidence_height={evidence_height} - evidence_time_seconds={evidence_time_seconds} - evidence_time_nanos={evidence_time_nanos} - evidence_total_voting_power={evidence_total_voting_power} - """ - ) - - response = self.channel.send_begin_block(request) - - self.logger.info(f"Received response {str(response)}") - - return True - - def end_block(self, height: int) -> bool: - request = abci_types.RequestEndBlock() # type: ignore - request.height = height - - self.logger.info(f"Calling end_block height={height}") - - response = self.channel.send_end_block(request) - - self.logger.info(f"Received response {str(response)}") - - return response - - def list_snapshots(self) -> bool: - request = abci_types.RequestListSnapshots() # type: ignore - - self.logger.info("Calling list snapshots") - - response = self.channel.send_list_snapshots(request) - - self.logger.info(f"Received response {str(response)}") - - return response - - def offer_snapshot( - self, - height: int, - format_: int, - chunks: int, - hash_: bytes, - metadata: bytes, - app_hash: bytes, - ) -> bool: - snapshot = abci_types.Snapshot() # type: ignore - Snapshot.encode(snapshot, Snapshot(height, format_, chunks, hash_, metadata)) - - request = abci_types.RequestOfferSnapshot() # type: ignore - request.snapshot.CopyFrom(snapshot) - request.app_hash = app_hash - - self.logger.info( - f"Calling offer snapshot height={height},format_={format_}," - f"chunks={chunks},hash_={hash_!r},metadata={metadata!r},app_hash={app_hash!r}" - ) - - response = self.channel.send_offer_snapshot(request) - - self.logger.info(f"Received response {str(response)}") - - return response - - def load_snapshot_chunk(self, height: int, format_: int, chunk: int) -> bool: - request = abci_types.RequestLoadSnapshotChunk() # type: ignore - request.height = height - request.format = format_ - request.chunk = chunk - - self.logger.info( - f"Calling load snapshot chunk height={height} format={format_} chunk={chunk}" - ) - - response = self.channel.send_load_snapshot_chunk(request) - - self.logger.info(f"Received response {str(response)}") - - return response - - def apply_snapshot_chunk(self, index: int, chunk: bytes, sender: str) -> bool: - request = abci_types.RequestApplySnapshotChunk() # type: ignore - request.index = index - request.chunk = chunk - request.sender = sender - - self.logger.info( - f"Calling load snapshot chunk index={index} chunk={chunk!r} sender={sender}" - ) - - response = self.channel.send_apply_snapshot_chunk(request) - - self.logger.info(f"Received response {str(response)}") - - return response diff --git a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/test_fuzz.py b/trader_old/vendor/valory/connections/abci/tests/test_fuzz/test_fuzz.py deleted file mode 100644 index 02333a39c..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_fuzz/test_fuzz.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Fuzzy tests for valory/abci connection""" -import os - -from hypothesis import settings - -from packages.valory.connections.abci.tests import CI -from packages.valory.connections.abci.tests.test_fuzz.base import BaseFuzzyTests -from packages.valory.connections.abci.tests.test_fuzz.mock_node.channels.grpc_channel import ( - GrpcChannel, -) -from packages.valory.connections.abci.tests.test_fuzz.mock_node.channels.tcp_channel import ( - TcpChannel, -) - - -running_on_ci = os.getenv(CI) -if running_on_ci: - settings.load_profile(CI) - - -class TestFuzzyGrpc(BaseFuzzyTests): - """Test the connection when gRPC is used""" - - CHANNEL_TYPE = GrpcChannel - USE_GRPC = True - AGENT_TIMEOUT_SECONDS = 30 - - -class TestFuzzyTcp(BaseFuzzyTests): - """Test the connection when TCP is used""" - - CHANNEL_TYPE = TcpChannel - USE_GRPC = False - AGENT_TIMEOUT_SECONDS = 30 diff --git a/trader_old/vendor/valory/connections/abci/tests/test_tendermint_decoder.py b/trader_old/vendor/valory/connections/abci/tests/test_tendermint_decoder.py deleted file mode 100644 index 15285a9d4..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_tendermint_decoder.py +++ /dev/null @@ -1,121 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/abci connection, tendermint_decoder module.""" - -# pylint: skip-file - -from packages.valory.connections.abci.connection import PUBLIC_ID -from packages.valory.connections.abci.dialogues import AbciDialogue, AbciDialogues -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - Request, - RequestApplySnapshotChunk, - RequestEcho, - RequestListSnapshots, - RequestLoadSnapshotChunk, - RequestOfferSnapshot, - RequestSetOption, - Snapshot, -) -from packages.valory.connections.abci.tendermint_decoder import ( - _TendermintProtocolDecoder, -) -from packages.valory.protocols.abci import AbciMessage - - -class TestTendermintProtocolDecoder: - """Test for the Tendermint protocol decoder.""" - - def test_request_echo(self) -> None: - """Test decoding of a request echo.""" - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - request = Request() - echo = RequestEcho() - echo.message = "" - request.echo.CopyFrom(echo) - message, dialogue = _TendermintProtocolDecoder.request_echo( - request, dialogues, "counterparty" - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) - - def test_request_set_option(self) -> None: - """Test decoding of a request set-option.""" - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - request = Request() - set_option = RequestSetOption() - set_option.key = "" - set_option.value = "" - request.set_option.CopyFrom(set_option) - message, dialogue = _TendermintProtocolDecoder.request_set_option( - request, dialogues, "counterparty" - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) - - def test_request_list_snapshots(self) -> None: - """Test decoding of a request list-snapshots.""" - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - request = Request() - list_snapshots = RequestListSnapshots() - request.list_snapshots.CopyFrom(list_snapshots) - message, dialogue = _TendermintProtocolDecoder.request_list_snapshots( - request, dialogues, "counterparty" - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) - - def test_request_offer_snapshot(self) -> None: - """Test decoding of a request offer-snapshot.""" - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - request = Request() - offer_snapshot = RequestOfferSnapshot() - snapshot = Snapshot() - offer_snapshot.snapshot.CopyFrom(snapshot) - offer_snapshot.app_hash = b"" - request.offer_snapshot.CopyFrom(offer_snapshot) - message, dialogue = _TendermintProtocolDecoder.request_offer_snapshot( - request, dialogues, "counterparty" - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) - - def test_request_load_snapshot_chunk(self) -> None: - """Test decoding of a request load-snapshot-chunk.""" - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - request = Request() - load_snapshot_chunk = RequestLoadSnapshotChunk() - request.load_snapshot_chunk.CopyFrom(load_snapshot_chunk) - message, dialogue = _TendermintProtocolDecoder.request_load_snapshot_chunk( - request, dialogues, "counterparty" - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) - - def test_request_apply_snapshot_chunk(self) -> None: - """Test decoding of a request load-snapshot-chunk.""" - dialogues = AbciDialogues(connection_id=PUBLIC_ID) - request = Request() - apply_snapshot_chunk = RequestApplySnapshotChunk() - request.apply_snapshot_chunk.CopyFrom(apply_snapshot_chunk) - message, dialogue = _TendermintProtocolDecoder.request_apply_snapshot_chunk( - request, dialogues, "counterparty" - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) diff --git a/trader_old/vendor/valory/connections/abci/tests/test_tendermint_encoder.py b/trader_old/vendor/valory/connections/abci/tests/test_tendermint_encoder.py deleted file mode 100644 index 51df9d778..000000000 --- a/trader_old/vendor/valory/connections/abci/tests/test_tendermint_encoder.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/abci connection, tendermint_encoder module.""" - -# pylint: skip-file - -from packages.valory.connections.abci.tendermint.abci.types_pb2 import ( # type: ignore - ResponseListSnapshots, -) -from packages.valory.connections.abci.tendermint_encoder import ( - _TendermintProtocolEncoder, -) -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import Result, ResultType, SnapShots -from packages.valory.protocols.abci.custom_types import Snapshot as CustomSnapshot - - -class TestTendermintProtocolEncoder: - """Test for the Tendermint protocol encoder.""" - - def test_response_exception(self) -> None: - """Test decoding of a response exception.""" - expected_error = "error" - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_EXCEPTION, # type: ignore - error=expected_error, - ) - message = _TendermintProtocolEncoder.response_exception(abci_message) - assert message.exception.error == expected_error - - def test_response_echo(self) -> None: - """Test decoding of a response echo.""" - expected_message = "message" - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_ECHO, # type: ignore - message=expected_message, - ) - message = _TendermintProtocolEncoder.response_echo(abci_message) - assert message.echo.message == expected_message - - def test_response_set_option(self) -> None: - """Test decoding of a response set-option.""" - expected_code = 0 - expected_log = "log" - expected_info = "info" - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_SET_OPTION, # type: ignore - code=expected_code, - log=expected_log, - info=expected_info, - ) - message = _TendermintProtocolEncoder.response_set_option(abci_message) - assert message.set_option.code == expected_code - assert message.set_option.log == expected_log - assert message.set_option.info == expected_info - - def test_response_list_snapshots(self) -> None: - """Test decoding of a response list-snapshots.""" - snapshot = CustomSnapshot(0, 0, 0, b"", b"") - snapshots = SnapShots([snapshot]) - - # expected snapshots object - list_snapshots = ResponseListSnapshots() - snapshots_pb = [ - _TendermintProtocolEncoder._encode_snapshot(snapshot) - for snapshot in snapshots.snapshots - ] - list_snapshots.snapshots.extend(snapshots_pb) - - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, # type: ignore - snapshots=snapshots, - ) - message = _TendermintProtocolEncoder.response_list_snapshots(abci_message) - assert message.list_snapshots == list_snapshots - - def test_response_offer_snapshot(self) -> None: - """Test decoding of a response offer-snapshot.""" - expected_result = Result(ResultType.ACCEPT) - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, # type: ignore - result=expected_result, - ) - message = _TendermintProtocolEncoder.response_offer_snapshot(abci_message) - assert message.offer_snapshot.result == expected_result.result_type.value - - def test_response_load_snapshot_chunk(self) -> None: - """Test decoding of a response load-snapshot-chunk.""" - expected_chunk = b"chunk" - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, # type: ignore - chunk=expected_chunk, - ) - message = _TendermintProtocolEncoder.response_load_snapshot_chunk(abci_message) - assert message.load_snapshot_chunk.chunk == expected_chunk - - def test_response_apply_snapshot_chunk(self) -> None: - """Test decoding of a response apply-snapshot-chunk.""" - result = Result(ResultType.ACCEPT) - abci_message = AbciMessage( - performative=AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, # type: ignore - result=result, - refetch_chunks=tuple(), - reject_senders=tuple(), - ) - message = _TendermintProtocolEncoder.response_apply_snapshot_chunk(abci_message) - assert message.apply_snapshot_chunk.result == result.result_type.value diff --git a/trader_old/vendor/valory/connections/abci/version.txt b/trader_old/vendor/valory/connections/abci/version.txt deleted file mode 100644 index a1ed4c348..000000000 --- a/trader_old/vendor/valory/connections/abci/version.txt +++ /dev/null @@ -1,6 +0,0 @@ - TMCoreSemVer = TMVersionDefault - // TMVersionDefault is the used as the fallback version of Tendermint Core - TMVersionDefault = "0.34.19" - // ABCISemVer is the semantic version of the ABCI library - ABCISemVer = "0.17.0" - ABCIVersion = ABCISemVer diff --git a/trader_old/vendor/valory/connections/http_client/README.md b/trader_old/vendor/valory/connections/http_client/README.md deleted file mode 100644 index 376f78401..000000000 --- a/trader_old/vendor/valory/connections/http_client/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# HTTP client connection - -This connection wraps an HTTP client. It consumes messages from the AEA, translates them into HTTP requests, then sends the HTTP response as a message back to the AEA. - -## Usage - -First, add the connection to your AEA project (`aea add connection valory/http_client:0.23.0`). Then, update the `config` in `connection.yaml` by providing a `host` and `port` of the server. diff --git a/trader_old/vendor/valory/connections/http_client/__init__.py b/trader_old/vendor/valory/connections/http_client/__init__.py deleted file mode 100644 index 6c4b07655..000000000 --- a/trader_old/vendor/valory/connections/http_client/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 Valory AG -# Copyright 2018-2020 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Implementation of the HTTP_client connection and channel.""" diff --git a/trader_old/vendor/valory/connections/http_client/connection.py b/trader_old/vendor/valory/connections/http_client/connection.py deleted file mode 100644 index 248f57268..000000000 --- a/trader_old/vendor/valory/connections/http_client/connection.py +++ /dev/null @@ -1,446 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""HTTP client connection and channel.""" - -import asyncio -import email -import logging -import ssl -from asyncio import CancelledError -from asyncio.events import AbstractEventLoop -from asyncio.tasks import Task -from traceback import format_exc -from typing import Any, Optional, Set, Tuple, Union, cast - -import aiohttp -import certifi # pylint: disable=wrong-import-order -from aiohttp import ClientTimeout -from aiohttp.client_reqrep import ClientResponse # pylint: disable=wrong-import-order -from multidict import ( # pylint: disable=wrong-import-order - CIMultiDict, - CIMultiDictProxy, -) - -from aea.common import Address -from aea.configurations.base import PublicId -from aea.connections.base import Connection, ConnectionStates -from aea.exceptions import enforce -from aea.mail.base import Envelope, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue - -from packages.valory.protocols.http.dialogues import HttpDialogue as BaseHttpDialogue -from packages.valory.protocols.http.dialogues import HttpDialogues as BaseHttpDialogues -from packages.valory.protocols.http.message import HttpMessage - - -SUCCESS = 200 -NOT_FOUND = 404 -REQUEST_TIMEOUT = 408 -SERVER_ERROR = 500 -PUBLIC_ID = PublicId.from_str("valory/http_client:0.23.0") - -_default_logger = logging.getLogger("aea.packages.valory.connections.http_client") - -RequestId = str - -ssl_context = ssl.create_default_context(cafile=certifi.where()) - - -def headers_to_string(headers: CIMultiDictProxy) -> str: - """ - Convert headers to string. - - :param headers: dict - - :return: str - """ - msg = email.message.Message() - for name, value in headers.items(): - msg.add_header(name, value) - return msg.as_string() - - -HttpDialogue = BaseHttpDialogue - - -class HttpDialogues(BaseHttpDialogues): - """The dialogues class keeps track of all http dialogues.""" - - def __init__(self) -> None: - """Initialize dialogues.""" - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - # The client connection maintains the dialogue on behalf of the server - return HttpDialogue.Role.SERVER - - BaseHttpDialogues.__init__( - self, - self_address=str(HTTPClientConnection.connection_id), - role_from_first_message=role_from_first_message, - dialogue_class=HttpDialogue, - ) - - -class HTTPClientAsyncChannel: # pylint: disable=too-many-instance-attributes - """A wrapper for a HTTPClient.""" - - DEFAULT_EXCEPTION_CODE = ( - 600 # custom code to indicate there was exception during request - ) - - def __init__( - self, - agent_address: Address, - address: str, - port: int, - timeout: int, - connection_id: PublicId, - ): - """ - Initialize an http client channel. - - :param agent_address: the address of the agent. - :param address: server hostname / IP address. - :param port: server port number. - :param timeout: the time to wait for a response. - :param connection_id: the id of the connection. - """ - self.agent_address = agent_address - self.address = address - self.port = port - self.timeout = timeout - self.connection_id = connection_id - self._dialogues = HttpDialogues() - - self._in_queue = None # type: Optional[asyncio.Queue] # pragma: no cover - self._loop = ( - None - ) # type: Optional[asyncio.AbstractEventLoop] # pragma: no cover - self.is_stopped = True - self._tasks: Set[Task] = set() - - self.logger = _default_logger - self.logger.debug("Initialised the HTTP client channel") - - async def connect(self, loop: AbstractEventLoop) -> None: - """ - Connect channel using loop. - - :param loop: asyncio event loop to use - """ - self._loop = loop - self._in_queue = asyncio.Queue() - self.is_stopped = False - - def _get_message_and_dialogue( - self, envelope: Envelope - ) -> Tuple[HttpMessage, Optional[HttpDialogue]]: - """ - Get a message copy and dialogue related to this message. - - :param envelope: incoming envelope - - :return: Tuple[Message, Optional[Dialogue]] - """ - message = cast(HttpMessage, envelope.message) - dialogue = cast(Optional[HttpDialogue], self._dialogues.update(message)) - return message, dialogue - - async def _http_request_task(self, request_envelope: Envelope) -> None: - """ - Perform http request and send back response. - - :param request_envelope: request envelope - """ - if not self._loop: # pragma: nocover - raise ValueError("Channel is not connected") - - request_http_message, dialogue = self._get_message_and_dialogue( - request_envelope - ) - - if not dialogue: - self.logger.warning( - f"Could not create dialogue for message={request_http_message}" - ) - return - - try: - resp = await asyncio.wait_for( - self._perform_http_request(request_http_message), - timeout=self.timeout, - ) - envelope = self.to_envelope( - request_http_message, - status_code=resp.status, - headers=resp.headers, - status_text=resp.reason, - body=resp._body # pylint: disable=protected-access - if resp._body is not None # pylint: disable=protected-access - else b"", - dialogue=dialogue, - ) - except Exception: # pylint: disable=broad-except - envelope = self.to_envelope( - request_http_message, - status_code=self.DEFAULT_EXCEPTION_CODE, - headers=CIMultiDictProxy(CIMultiDict()), - status_text="HTTPConnection request error.", - body=format_exc().encode("utf-8"), - dialogue=dialogue, - ) - - if self._in_queue is not None: - await self._in_queue.put(envelope) - - async def _perform_http_request( - self, request_http_message: HttpMessage - ) -> ClientResponse: - """ - Perform http request and return response. - - :param request_http_message: HttpMessage with http request constructed. - - :return: aiohttp.ClientResponse - """ - try: - if request_http_message.is_set("headers") and request_http_message.headers: - headers: Optional[dict] = dict( - email.message_from_string(request_http_message.headers).items() - ) - else: - headers = None - session_timeout = ClientTimeout(self.timeout) - async with aiohttp.ClientSession(timeout=session_timeout) as session: - async with session.request( - method=request_http_message.method, - url=request_http_message.url, - headers=headers, - data=request_http_message.body, - ssl=ssl_context, - ) as resp: - await resp.read() - return resp - except Exception as e: # pragma: nocover # pylint: disable=broad-except - self.logger.debug( - f"Exception raised during http call: {request_http_message.method} {request_http_message.url}, {e}" - ) - raise - - def send(self, request_envelope: Envelope) -> None: - """ - Send an envelope with http request data to request. - - Convert an http envelope into an http request. - Send the http request - Wait for and receive its response - Translate the response into a response envelop. - Send the response envelope to the in-queue. - - :param request_envelope: the envelope containing an http request - """ - if self._loop is None or self.is_stopped: - raise ValueError("Can not send a message! Channel is not started!") - - if request_envelope is None: - return - - enforce( - isinstance(request_envelope.message, HttpMessage), - "Message not of type HttpMessage", - ) - - request_http_message = cast(HttpMessage, request_envelope.message) - - if ( - request_http_message.performative != HttpMessage.Performative.REQUEST - ): # pragma: nocover - self.logger.warning( - "The HTTPMessage performative must be a REQUEST. Envelop dropped." - ) - return - - task = self._loop.create_task(self._http_request_task(request_envelope)) - task.add_done_callback(self._task_done_callback) - self._tasks.add(task) - - def _task_done_callback(self, task: Task) -> None: - """ - Handle http request task completed. - - Removes tasks from _tasks. - - :param task: Task completed. - """ - self._tasks.remove(task) - self.logger.debug(f"Task completed: {task}") - - async def get_message(self) -> Optional["Envelope"]: - """ - Get http response from in-queue. - - :return: None or envelope with http response. - """ - if self._in_queue is None: - raise ValueError("Looks like channel is not connected!") - - try: - return await self._in_queue.get() - except CancelledError: # pragma: nocover - return None - - @staticmethod - def to_envelope( - http_request_message: HttpMessage, - status_code: int, - headers: CIMultiDictProxy, - status_text: Optional[Any], - body: bytes, - dialogue: HttpDialogue, - ) -> Envelope: - """ - Convert an HTTP response object (from the 'requests' library) into an Envelope containing an HttpMessage (from the 'http' Protocol). - - :param http_request_message: the message of the http request envelop - :param status_code: the http status code, int - :param headers: dict of http response headers - :param status_text: the http status_text, str - :param body: bytes of http response content - :param dialogue: the http dialogue - - :return: Envelope with http response data. - """ - http_message = dialogue.reply( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_request_message, - status_code=status_code, - headers=headers_to_string(headers), - status_text=status_text, - body=body, - version="", - ) - envelope = Envelope( - to=http_message.to, - sender=http_message.sender, - message=http_message, - ) - return envelope - - async def _cancel_tasks(self) -> None: - """Cancel all requests tasks pending.""" - for task in list(self._tasks): - if task.done(): # pragma: nocover - continue - task.cancel() - - for task in list(self._tasks): - try: - await task - except KeyboardInterrupt: # pragma: nocover - raise - except BaseException: # pragma: nocover # pylint: disable=broad-except - pass # nosec - - async def disconnect(self) -> None: - """Disconnect.""" - if not self.is_stopped: - self.logger.info(f"HTTP Client has shutdown on port: {self.port}.") - self.is_stopped = True - - await self._cancel_tasks() - - -class HTTPClientConnection(Connection): - """Proxy to the functionality of the web client.""" - - DEFAULT_TIMEOUT = 300 # default timeout in seconds - connection_id = PUBLIC_ID - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize a HTTP client connection. - - :param kwargs: keyword arguments - """ - super().__init__(**kwargs) - host = cast(str, self.configuration.config.get("host")) - port = cast(int, self.configuration.config.get("port")) - timeout = int(self.configuration.config.get("timeout", self.DEFAULT_TIMEOUT)) - if host is None or port is None: # pragma: nocover - raise ValueError("host and port must be set!") - self.channel = HTTPClientAsyncChannel( - self.address, - host, - port, - timeout, - connection_id=self.connection_id, - ) - - async def connect(self) -> None: - """Connect to a HTTP server.""" - if self.is_connected: # pragma: nocover - return - - with self._connect_context(): - self.channel.logger = self.logger - await self.channel.connect(self.loop) - - async def disconnect(self) -> None: - """Disconnect from a HTTP server.""" - if self.is_disconnected: - return # pragma: nocover - self.state = ConnectionStates.disconnecting - await self.channel.disconnect() - self.state = ConnectionStates.disconnected - - async def send(self, envelope: "Envelope") -> None: - """ - Send an envelope. - - :param envelope: the envelop - """ - self._ensure_connected() - self.channel.send(envelope) - - async def receive( - self, *args: Any, **kwargs: Any - ) -> Optional[Union["Envelope", None]]: - """ - Receive an envelope. - - :param args: arguments - :param kwargs: keyword arguments - :return: the envelope received, or None. - """ - self._ensure_connected() - try: - return await self.channel.get_message() - except Exception: # pragma: nocover # pylint: disable=broad-except - self.logger.debug("Exception on receive") - return None diff --git a/trader_old/vendor/valory/connections/http_client/connection.yaml b/trader_old/vendor/valory/connections/http_client/connection.yaml deleted file mode 100644 index a4694f248..000000000 --- a/trader_old/vendor/valory/connections/http_client/connection.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: http_client -author: valory -version: 0.23.0 -type: connection -description: The HTTP_client connection that wraps a web-based client connecting to - a RESTful API specification. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeigqhgnqpgi22gfxqvsgbmrjdkrklpgu2m4px6zwb7bhvy3gkkyetu - __init__.py: bafybeieh7rjtg22qukaznxzhadreuxhyfeamj3lcluxtcbfiexktue2nim - connection.py: bafybeiephqitgfzzautuegh2fpp5yezglkri4gj646glu3erokbfgsupzu - tests/__init__.py: bafybeiak7fbussk7n5zl2o4trefz7whvc3ae3k2vrryhb6cettb2qskjau - tests/test_http_client.py: bafybeic4k7g6k4y5axh3pgpz25j7drghqxl5gblczux2sxtms54ududepe -fingerprint_ignore_patterns: [] -connections: [] -protocols: -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -class_name: HTTPClientConnection -config: - host: 127.0.0.1 - port: 8000 - timeout: 300 -excluded_protocols: [] -restricted_to_protocols: -- valory/http:1.0.0 -dependencies: - aiohttp: - version: <4.0.0,>=3.8.5 - certifi: {} - multidict: {} -is_abstract: false diff --git a/trader_old/vendor/valory/connections/http_client/tests/__init__.py b/trader_old/vendor/valory/connections/http_client/tests/__init__.py deleted file mode 100644 index f7c0817d8..000000000 --- a/trader_old/vendor/valory/connections/http_client/tests/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 Valory AG -# Copyright 2018-2020 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/http_client connection.""" diff --git a/trader_old/vendor/valory/connections/http_client/tests/test_http_client.py b/trader_old/vendor/valory/connections/http_client/tests/test_http_client.py deleted file mode 100644 index 85f92b505..000000000 --- a/trader_old/vendor/valory/connections/http_client/tests/test_http_client.py +++ /dev/null @@ -1,362 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ -"""Tests for valory/http_client connection. Adapted from original AEA code.""" -# pylint: skip-file - -import asyncio -import logging -from asyncio import CancelledError -from typing import Any, cast -from unittest.mock import MagicMock, Mock, patch - -import aiohttp -import pytest - -from aea.common import Address -from aea.configurations.base import ConnectionConfig -from aea.identity.base import Identity -from aea.mail.base import Envelope, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.test_tools.constants import UNKNOWN_PROTOCOL_PUBLIC_ID -from aea.test_tools.mocks import AnyStringWith -from aea.test_tools.network import get_host, get_unused_tcp_port - -from packages.valory.connections.http_client.connection import HTTPClientConnection -from packages.valory.protocols.http.dialogues import HttpDialogue -from packages.valory.protocols.http.dialogues import HttpDialogues as BaseHttpDialogues -from packages.valory.protocols.http.message import HttpMessage - - -logger = logging.getLogger(__name__) - - -class _MockRequest: - """Fake request for aiohttp client session.""" - - def __init__(self, response: Mock) -> None: - """Init with mock response.""" - self.response = response - - async def __aenter__(self) -> Mock: - """Enter async context.""" - return self.response - - async def __aexit__(self, *args: Any, **kwargs: Any) -> None: - """Exit async context.""" - return None - - -class HttpDialogues(BaseHttpDialogues): - """The dialogues class keeps track of all http dialogues.""" - - def __init__(self, self_address: Address, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param self_address: the address - :param kwargs: keyword arguments - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return HttpDialogue.Role.CLIENT - - BaseHttpDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - ) - - -@pytest.mark.asyncio -class TestHTTPClientConnect: - """Tests the http client connection's 'connect' functionality.""" - - def setup(self) -> None: - """Initialise the class.""" - self.address = get_host() - self.port = get_unused_tcp_port() - self.agent_identity = Identity( - "name", address="some string", public_key="some public_key" - ) - self.client_skill_id = "some/skill:0.1.0" - configuration = ConnectionConfig( - host=self.address, - port=self.port, - connection_id=HTTPClientConnection.connection_id, - ) - self.http_client_connection = HTTPClientConnection( - configuration=configuration, - data_dir=MagicMock(), - identity=self.agent_identity, - ) - self.connection_address = str(HTTPClientConnection.connection_id) - self.http_dialogs = HttpDialogues(self.client_skill_id) - - @pytest.mark.asyncio - async def test_initialization(self) -> None: - """Test the initialisation of the class.""" - assert self.http_client_connection.address == self.agent_identity.address - - @pytest.mark.asyncio - async def test_connection(self) -> None: - """Test the connect functionality of the http client connection.""" - await self.http_client_connection.connect() - assert self.http_client_connection.is_connected is True - - @pytest.mark.asyncio - async def test_disconnect(self) -> None: - """Test the disconnect functionality of the http client connection.""" - await self.http_client_connection.connect() - assert self.http_client_connection.is_connected is True - - await self.http_client_connection.disconnect() - assert self.http_client_connection.is_connected is False - - @pytest.mark.asyncio - async def test_http_send_error(self) -> None: - """Test request fails and send back result with code 600.""" - await self.http_client_connection.connect() - request_http_message, _ = self.http_dialogs.create( - counterparty=self.connection_address, - performative=HttpMessage.Performative.REQUEST, - method="get", - url="bad url", - headers="", - version="", - body=b"", - ) - request_envelope = Envelope( - to=self.connection_address, - sender=self.client_skill_id, - protocol_specification_id=UNKNOWN_PROTOCOL_PUBLIC_ID, - message=request_http_message, - ) - - connection_response_mock = Mock() - connection_response_mock.status_code = 200 - - await self.http_client_connection.send(envelope=request_envelope) - # TODO: Consider returning the response from the server in order to be able to assert that the message send! - envelope = await asyncio.wait_for( - self.http_client_connection.receive(), timeout=10 - ) - assert envelope - assert isinstance(envelope.message, HttpMessage) - assert envelope.message.status_code == 600 - - await self.http_client_connection.disconnect() - - @pytest.mark.asyncio - async def test_http_client_send_not_connected_error(self) -> None: - """Test connection.send error if not conencted.""" - with pytest.raises(ConnectionError): - await self.http_client_connection.send(Mock()) - - @pytest.mark.asyncio - async def test_http_channel_send_not_connected_error(self) -> None: - """Test channel.send error if not conencted.""" - with pytest.raises(ValueError): - self.http_client_connection.channel.send(Mock()) - - @pytest.mark.asyncio - async def test_send_empty_envelope_skip(self) -> None: - """Test skip on empty envelope request sent.""" - await self.http_client_connection.connect() - with patch.object( - self.http_client_connection.channel, "_http_request_task" - ) as mock: - await self.http_client_connection.send(None) # type: ignore - mock.assert_not_called() - - @pytest.mark.asyncio - async def test_channel_get_message_not_connected(self) -> None: - """Test errro on message get if not connected.""" - with pytest.raises(ValueError): - await self.http_client_connection.channel.get_message() - - @pytest.mark.asyncio - async def test_channel_cancel_tasks_on_disconnect(self) -> None: - """Test requests tasks cancelled on disconnect.""" - await self.http_client_connection.connect() - request_http_message, _ = self.http_dialogs.create( - counterparty=self.connection_address, - performative=HttpMessage.Performative.REQUEST, - method="get", - url="https://not-a-google.com", - headers="Host: https://not-a-google.com", - version="", - body=b"", - ) - request_envelope = Envelope( - to=self.connection_address, - sender=self.client_skill_id, - protocol_specification_id=UNKNOWN_PROTOCOL_PUBLIC_ID, - message=request_http_message, - ) - - connection_response_mock = Mock() - connection_response_mock.status_code = 200 - - response_mock = Mock() - response_mock.status = 200 - response_mock.headers = {"headers": "some header"} - response_mock.reason = "OK" - response_mock._body = b"Some content" - response_mock.read.return_value = asyncio.Future() - - with patch.object( - aiohttp.ClientSession, - "request", - return_value=_MockRequest(response_mock), - ): - await self.http_client_connection.send(envelope=request_envelope) - - assert self.http_client_connection.channel._tasks - task = list(self.http_client_connection.channel._tasks)[0] - assert not task.done() - await self.http_client_connection.disconnect() - - assert not self.http_client_connection.channel._tasks - assert task.done() - with pytest.raises(CancelledError): - await task - - @pytest.mark.asyncio - async def test_http_send_ok(self) -> None: - """Test request is ok cause mocked.""" - await self.http_client_connection.connect() - request_http_message, sending_dialogue = self.http_dialogs.create( - counterparty=self.connection_address, - performative=HttpMessage.Performative.REQUEST, - method="get", - url="https://not-a-google.com", - headers="", - version="", - body=b"", - ) - request_envelope = Envelope( - to=self.connection_address, - sender=self.client_skill_id, - message=request_http_message, - ) - - connection_response_mock = Mock() - connection_response_mock.status_code = 200 - - response_mock = Mock() - response_mock.status = 200 - response_mock.headers = {"headers": "some header"} - response_mock.reason = "OK" - response_mock._body = b"Some content" - response_mock.read.return_value = asyncio.Future() - response_mock.read.return_value.set_result("") - - with patch.object( - aiohttp.ClientSession, - "request", - return_value=_MockRequest(response_mock), - ): - await self.http_client_connection.send(envelope=request_envelope) - # TODO: Consider returning the response from the server in order to be able to assert that the message send! - envelope = await asyncio.wait_for( - self.http_client_connection.receive(), timeout=10 - ) - - assert envelope is not None and envelope.message is not None - message = envelope.message - assert isinstance(message, HttpMessage) - response_dialogue = self.http_dialogs.update(message) - assert message.status_code == response_mock.status, message.body.decode("utf-8") - assert sending_dialogue == response_dialogue - await self.http_client_connection.disconnect() - - @pytest.mark.asyncio - async def test_http_dialogue_construct_fail(self) -> None: - """Test dialogue not properly constructed.""" - await self.http_client_connection.connect() - - incorrect_http_message = HttpMessage( - dialogue_reference=self.http_dialogs.new_self_initiated_dialogue_reference(), - performative=HttpMessage.Performative.RESPONSE, # type: ignore - status_code=500, - headers="", - status_text="", - body=b"", - version="", - ) - incorrect_http_message.to = self.connection_address - incorrect_http_message.sender = self.client_skill_id - - # the incorrect message cannot be sent into a dialogue, so this is omitted. - - envelope = Envelope( - to=incorrect_http_message.to, - sender=incorrect_http_message.sender, - message=incorrect_http_message, - ) - with patch.object( - self.http_client_connection.channel.logger, "warning" - ) as mock_logger: - await self.http_client_connection.channel._http_request_task(envelope) - mock_logger.assert_any_call( - AnyStringWith("Could not create dialogue for message=") - ) - - @pytest.mark.asyncio - async def test_http_send_exception(self) -> None: - """Test request is ok cause mocked.""" - await self.http_client_connection.connect() - request_http_message, sending_dialogue = self.http_dialogs.create( - counterparty=self.connection_address, - performative=HttpMessage.Performative.REQUEST, # type: ignore - method="get", - url="https://not-a-google.com", - headers="Host: https://not-a-google.com", - version="", - body=b"", - ) - request_envelope = Envelope( - to=self.connection_address, - sender=self.client_skill_id, - message=request_http_message, - ) - - with patch.object( - aiohttp.ClientSession, - "request", - side_effect=asyncio.TimeoutError("expected exception"), - ): - await self.http_client_connection.send(envelope=request_envelope) - envelope = await asyncio.wait_for( - self.http_client_connection.receive(), timeout=10 - ) - - assert envelope - message = cast(HttpMessage, envelope.message) - assert message.performative == HttpMessage.Performative.RESPONSE - assert b"expected exception" in message.body diff --git a/trader_old/vendor/valory/connections/http_server/README.md b/trader_old/vendor/valory/connections/http_server/README.md deleted file mode 100644 index a2947c138..000000000 --- a/trader_old/vendor/valory/connections/http_server/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# HTTP server connection - -This connection wraps an HTTP server. It consumes requests from clients, translates them into messages for the AEA, waits for a response message from the AEA, then serves the response to the client. - -## Usage - -First, add the connection to your AEA project (`aea add connection valory/http_server:0.22.0`). Then, update the `config` in `connection.yaml` by providing a `host` and `port` of the server. Optionally, provide a path to an [OpenAPI specification](https://swagger.io/docs/specification/about/) for request validation. \ No newline at end of file diff --git a/trader_old/vendor/valory/connections/http_server/__init__.py b/trader_old/vendor/valory/connections/http_server/__init__.py deleted file mode 100644 index 031e3523f..000000000 --- a/trader_old/vendor/valory/connections/http_server/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2023 Valory AG -# Copyright 2018-2020 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Implementation of the HTTP connection and channel.""" diff --git a/trader_old/vendor/valory/connections/http_server/connection.py b/trader_old/vendor/valory/connections/http_server/connection.py deleted file mode 100644 index 55b38e7bb..000000000 --- a/trader_old/vendor/valory/connections/http_server/connection.py +++ /dev/null @@ -1,645 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2023 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ -"""HTTP server connection, channel, server, and handler.""" -import asyncio -import email -import logging -import ssl -from abc import ABC, abstractmethod -from asyncio import CancelledError -from asyncio.events import AbstractEventLoop -from asyncio.futures import Future -from concurrent.futures._base import CancelledError as FuturesCancelledError -from traceback import format_exc -from typing import Any, Dict, Optional, cast -from urllib.parse import parse_qs, urlparse - -from aiohttp import web -from aiohttp.web_request import BaseRequest -from openapi_core import validate_request -from openapi_core.schema.specs import Spec -from openapi_core.validation.request.datatypes import RequestParameters -from openapi_core.validation.request.validators import RequestValidator -from openapi_spec_validator.exceptions import ( # pylint: disable=wrong-import-order - OpenAPIValidationError, -) -from openapi_spec_validator.schemas import ( # pylint: disable=wrong-import-order - read_yaml_file, -) -from werkzeug.datastructures import ( # pylint: disable=wrong-import-order - ImmutableMultiDict, -) - -from aea.common import Address -from aea.configurations.base import PublicId -from aea.connections.base import Connection, ConnectionStates -from aea.mail.base import Envelope, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.http.dialogues import HttpDialogue -from packages.valory.protocols.http.dialogues import HttpDialogues as BaseHttpDialogues -from packages.valory.protocols.http.message import HttpMessage - - -SUCCESS = 200 -NOT_FOUND = 404 -REQUEST_TIMEOUT = 408 -SERVER_ERROR = 500 - -_default_logger = logging.getLogger("aea.packages.valory.connections.http_server") - -RequestId = DialogueLabel -PUBLIC_ID = PublicId.from_str("valory/http_server:0.22.0") - - -class HttpDialogues(BaseHttpDialogues): - """The dialogues class keeps track of all http dialogues.""" - - def __init__(self, self_address: Address, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param self_address: address of the dialogues maintainer. - :param kwargs: keyword arguments. - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - # The server connection maintains the dialogue on behalf of the client - return HttpDialogue.Role.CLIENT - - BaseHttpDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - **kwargs, - ) - - -def headers_to_string(headers: Dict) -> str: - """ - Convert headers to string. - - :param headers: dict - - :return: str - """ - msg = email.message.Message() - for name, value in headers.items(): - msg.add_header(name, value) - return msg.as_string() - - -class Request: - """Generic request object.""" - - def __init__( - self, - host_url: str, - path: str, - full_url_pattern: str, - method: str, - parameters: RequestParameters, - body: bytes, - mimetype: str, - ) -> None: - """Initialize Request object.""" - self.host_url = host_url - self.path = path - self.full_url_pattern = full_url_pattern - self.method = method - self.parameters = parameters - self.body = body - self.mimetype = mimetype - - @property - def is_id_set(self) -> bool: - """Check if id is set.""" - return self._id is not None - - @property - def id(self) -> RequestId: - """Get the request id.""" - return self._id - - @id.setter - def id(self, request_id: RequestId) -> None: - """Set the request id.""" - self._id = request_id - - @classmethod - async def create(cls, http_request: BaseRequest) -> "Request": - """ - Create a request. - - :param http_request: http_request - :return: a request - """ - method = http_request.method.lower() - parsed_path = urlparse(http_request.path_qs) - url = http_request.url - body = await http_request.read() - mimetype = http_request.content_type - query_params = parse_qs(parsed_path.query, keep_blank_values=True) - parameters = RequestParameters( - query=ImmutableMultiDict(query_params), # type: ignore - header=headers_to_string(dict(http_request.headers)), - path={}, - ) - - request = Request( - host_url=str(url.with_path("/")), - path=parsed_path.path, - full_url_pattern=str(url), - method=method, - parameters=parameters, - body=body, - mimetype=mimetype, - ) - return request - - def to_envelope_and_set_id( - self, - dialogues: HttpDialogues, - target_skill_id: PublicId, - ) -> Envelope: - """ - Process incoming API request by packaging into Envelope and sending it in-queue. - - :param dialogues: the http dialogues - :param target_skill_id: the target skill id - - :return: envelope - """ - url = self.full_url_pattern - http_message, http_dialogue = dialogues.create( - counterparty=str(target_skill_id), - performative=HttpMessage.Performative.REQUEST, - method=self.method, - url=url, - headers=self.parameters.header, - body=self.body if self.body is not None else b"", - version="", - ) - dialogue = cast(HttpDialogue, http_dialogue) - self.id = dialogue.incomplete_dialogue_label - envelope = Envelope( - to=http_message.to, - sender=http_message.sender, - message=http_message, - ) - return envelope - - -class Response(web.Response): - """Generic response object.""" - - @classmethod - def from_message(cls, http_message: HttpMessage) -> "Response": - """ - Turn an envelope into a response. - - :param http_message: the http_message - :return: the response - """ - if http_message.performative == HttpMessage.Performative.RESPONSE: - if http_message.is_set("headers") and http_message.headers: - headers: Optional[dict] = dict( - email.message_from_string(http_message.headers).items() - ) - else: - headers = None - - # if content length header provided, it should correspond to actuyal body length - if headers and "Content-Length" in headers: - headers["Content-Length"] = str(len(http_message.body or "")) - - response = cls( - status=http_message.status_code, - reason=http_message.status_text, - body=http_message.body, - headers=headers, - ) - else: # pragma: nocover - response = cls(status=SERVER_ERROR, text="Server error") - return response - - -class APISpec: - """API Spec class to verify a request against an OpenAPI/Swagger spec.""" - - def __init__( - self, - api_spec_path: Optional[str] = None, - server: Optional[str] = None, - logger: logging.Logger = _default_logger, - ): - """ - Initialize the API spec. - - :param api_spec_path: Directory API path and filename of the API spec YAML source file. - :param server: the server url - :param logger: the logger - """ - self._validator = None # type: Optional[RequestValidator] - self.logger = logger - if api_spec_path is not None: - try: - api_spec_dict = read_yaml_file(api_spec_path) - if server is not None: - api_spec_dict["servers"] = [{"url": server}] - self.api_spec = Spec.create(data=api_spec_dict) - self._validator = RequestValidator(self.api_spec) - except OpenAPIValidationError as e: # pragma: nocover - self.logger.error( - f"API specification YAML source file not correctly formatted: {str(e)}" - ) - except Exception: - self.logger.exception( - "API specification YAML source file not correctly formatted." - ) - raise - - def verify(self, request: Request) -> bool: - """ - Verify a http_method, url and param against the provided API spec. - - :param request: the request object - :return: whether or not the request conforms with the API spec - """ - if self._validator is None: - self.logger.debug("Skipping API verification!") - return True - - try: - validate_request( - spec=self.api_spec, - request=request, - validator=self._validator, - ) - except Exception: # pragma: nocover # pylint: disable=broad-except - self.logger.exception("APISpec verify error") - return False - return True - - -class BaseAsyncChannel(ABC): - """Base asynchronous channel class.""" - - def __init__(self, address: Address, connection_id: PublicId) -> None: - """ - Initialize a channel. - - :param address: the address of the agent. - :param connection_id: public id of connection using this channel. - """ - self._in_queue = None # type: Optional[asyncio.Queue] - self._loop = None # type: Optional[asyncio.AbstractEventLoop] - self.is_stopped = True - self.address = address - self.connection_id = connection_id - - @abstractmethod - async def connect(self, loop: AbstractEventLoop) -> None: - """ - Connect. - - Upon HTTP Channel connection, start the HTTP Server in its own thread. - - :param loop: asyncio event loop - """ - self._loop = loop - self._in_queue = asyncio.Queue() - self.is_stopped = False - - async def get_message(self) -> Optional["Envelope"]: - """ - Get http response from in-queue. - - :return: None or envelope with http response. - """ - if self._in_queue is None: - raise ValueError("Looks like channel is not connected!") - - try: - return await self._in_queue.get() - except CancelledError: # pragma: nocover - return None - - @abstractmethod - def send(self, envelope: Envelope) -> None: - """ - Send the envelope in_queue. - - :param envelope: the envelope - """ - - @abstractmethod - async def disconnect(self) -> None: - """ - Disconnect. - - Shut-off the HTTP Server. - """ - - -class HTTPChannel(BaseAsyncChannel): - """A wrapper for an RESTful API with an internal HTTPServer.""" - - RESPONSE_TIMEOUT = 5.0 - - def __init__( - self, - address: Address, - host: str, - port: int, - target_skill_id: PublicId, - api_spec_path: Optional[str], - connection_id: PublicId, - timeout_window: float = RESPONSE_TIMEOUT, - logger: logging.Logger = _default_logger, - ssl_cert_path: Optional[str] = None, - ssl_key_path: Optional[str] = None, - ): - """ - Initialize a channel and process the initial API specification from the file path (if given). - - :param address: the address of the agent. - :param host: RESTful API hostname / IP address - :param port: RESTful API port number - :param target_skill_id: the skill id which handles the requests - :param api_spec_path: Directory API path and filename of the API spec YAML source file. - :param connection_id: public id of connection using this channel. - :param timeout_window: the timeout (in seconds) for a request to be handled. - :param logger: the logger - :param ssl_cert_path: optional path to ssl certificate - :param ssl_key_path: optional path to ssl key - """ - super().__init__(address=address, connection_id=connection_id) - self.host = host - self.port = port - self.ssl_cert_path = ssl_cert_path - self.ssl_key_path = ssl_key_path - self.target_skill_id = target_skill_id - if self.ssl_cert_path and self.ssl_key_path: - self.server_address = "https://{}:{}".format(self.host, self.port) - else: - self.server_address = "http://{}:{}".format(self.host, self.port) - - self._api_spec = APISpec(api_spec_path, self.server_address, logger) - self.timeout_window = timeout_window - self.http_server: Optional[web.TCPSite] = None - self.pending_requests: Dict[RequestId, Future] = {} - self._dialogues = HttpDialogues(str(HTTPServerConnection.connection_id)) - self.logger = logger - - @property - def api_spec(self) -> APISpec: - """Get the api spec.""" - return self._api_spec - - async def connect(self, loop: AbstractEventLoop) -> None: - """ - Connect. - - Upon HTTP Channel connection, start the HTTP Server in its own thread. - - :param loop: asyncio event loop - """ - if self.is_stopped: - await super().connect(loop) - - try: - await self._start_http_server() - self.logger.info( - "HTTP Server has connected to port: {}.".format(self.port) - ) - except Exception: # pragma: nocover # pylint: disable=broad-except - self.is_stopped = True - self._in_queue = None - self.logger.exception( - "Failed to start server on {}:{}.".format(self.host, self.port) - ) - - async def _http_handler(self, http_request: BaseRequest) -> Response: - """ - Verify the request then send the request to Agent as an envelope. - - :param http_request: the request object - - :return: a tuple of response code and response description - """ - request = await Request.create(http_request) - if self._in_queue is None: # pragma: nocover - raise ValueError("Channel not connected!") - - is_valid_request = self.api_spec.verify(request) - - if not is_valid_request: - self.logger.warning(f"request is not valid: {request}") - return Response(status=NOT_FOUND, reason="Request Not Found") - - try: - # turn request into envelope - envelope = request.to_envelope_and_set_id( - self._dialogues, self.target_skill_id - ) - - self.pending_requests[request.id] = Future() - - # send the envelope to the agent's inbox (via self.in_queue) - await self._in_queue.put(envelope) - # wait for response envelope within given timeout window (self.timeout_window) to appear in dispatch_ready_envelopes - - response_message = await asyncio.wait_for( - self.pending_requests[request.id], - timeout=self.timeout_window, - ) - return Response.from_message(response_message) - - except asyncio.TimeoutError: - self.logger.warning( - f"Request timed out! Request={request} not handled as a result. Ensure requests (protocol_id={HttpMessage.protocol_id}) are handled by a skill!" - ) - return Response(status=REQUEST_TIMEOUT, reason="Request Timeout") - except FuturesCancelledError: - return Response( # pragma: nocover - status=SERVER_ERROR, reason="Server terminated unexpectedly." - ) - except BaseException: # pragma: nocover # pylint: disable=broad-except - self.logger.exception("Error during handling incoming request") - return Response( - status=SERVER_ERROR, reason="Server Error", text=format_exc() - ) - finally: - if request.is_id_set: - self.pending_requests.pop(request.id, None) - - async def _start_http_server(self) -> None: - """Start http server.""" - server = web.Server(self._http_handler) - runner = web.ServerRunner(server) - await runner.setup() - ssl_context = None - if self.ssl_cert_path and self.ssl_key_path: - ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) - ssl_context.load_cert_chain(self.ssl_cert_path, self.ssl_key_path) - self.http_server = web.TCPSite( - runner, self.host, self.port, ssl_context=ssl_context - ) - await self.http_server.start() - - def send(self, envelope: Envelope) -> None: - """ - Send the envelope in_queue. - - :param envelope: the envelope - """ - if self.http_server is None: # pragma: nocover - raise ValueError("Server not connected, call connect first!") - - message = cast(HttpMessage, envelope.message) - dialogue = self._dialogues.update(message) - - if dialogue is None: - self.logger.warning( - "Could not create dialogue for message={}".format(message) - ) - return - - future = self.pending_requests.pop(dialogue.incomplete_dialogue_label, None) - - if not future: - self.logger.warning( - "Dropping message={} for incomplete_dialogue_label={} which has timed out.".format( - message, dialogue.incomplete_dialogue_label - ) - ) - return - if not future.done(): - future.set_result(message) - - async def disconnect(self) -> None: - """ - Disconnect. - - Shut-off the HTTP Server. - """ - if self.http_server is None: # pragma: nocover - raise ValueError("Server not connected, call connect first!") - - if not self.is_stopped: - await self.http_server.stop() - self.logger.info("HTTP Server has shutdown on port: {}.".format(self.port)) - self.is_stopped = True - self._in_queue = None - - -class HTTPServerConnection(Connection): - """Proxy to the functionality of the http server implementing a RESTful API specification.""" - - connection_id = PUBLIC_ID - - def __init__(self, **kwargs: Any) -> None: - """Initialize a HTTP server connection.""" - super().__init__(**kwargs) - host = cast(Optional[str], self.configuration.config.get("host")) - port = cast(Optional[int], self.configuration.config.get("port")) - target_skill_id_ = cast( - Optional[str], self.configuration.config.get("target_skill_id") - ) - if host is None or port is None or target_skill_id_ is None: # pragma: nocover - raise ValueError("host and port and target_skill_id must be set!") - target_skill_id = PublicId.try_from_str(target_skill_id_) - if target_skill_id is None: # pragma: nocover - raise ValueError("Provided target_skill_id is not a valid public id.") - api_spec_path = cast( - Optional[str], self.configuration.config.get("api_spec_path") - ) - ssl_cert_path = cast(Optional[str], self.configuration.config.get("ssl_cert")) - ssl_key_path = cast(Optional[str], self.configuration.config.get("ssl_key")) - - if bool(ssl_cert_path) != bool(ssl_key_path): # pragma: nocover - raise ValueError("Please specify both ssl_cert and ssl_key or neither.") - - self.channel = HTTPChannel( - self.address, - host, - port, - target_skill_id, - api_spec_path, - connection_id=self.connection_id, - logger=self.logger, - ssl_cert_path=ssl_cert_path, - ssl_key_path=ssl_key_path, - ) - - async def connect(self) -> None: - """Connect to the http channel.""" - if self.is_connected: - return - - self.state = ConnectionStates.connecting - self.channel.logger = self.logger - await self.channel.connect(loop=self.loop) - if self.channel.is_stopped: - self.state = ConnectionStates.disconnected - else: - self.state = ConnectionStates.connected - - async def disconnect(self) -> None: - """Disconnect from HTTP channel.""" - if self.is_disconnected: - return - - self.state = ConnectionStates.disconnecting - await self.channel.disconnect() - self.state = ConnectionStates.disconnected - - async def send(self, envelope: "Envelope") -> None: - """ - Send an envelope. - - :param envelope: the envelop - """ - self._ensure_connected() - self.channel.send(envelope) - - async def receive(self, *args: Any, **kwargs: Any) -> Optional["Envelope"]: - """ - Receive an envelope. - - :param args: positional arguments - :param kwargs: keyword arguments - :return: the envelope received, or None. - """ - self._ensure_connected() - try: - return await self.channel.get_message() - except CancelledError: # pragma: no cover - return None diff --git a/trader_old/vendor/valory/connections/http_server/connection.yaml b/trader_old/vendor/valory/connections/http_server/connection.yaml deleted file mode 100644 index d19bee4c5..000000000 --- a/trader_old/vendor/valory/connections/http_server/connection.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: http_server -author: valory -version: 0.22.0 -type: connection -description: The HTTP server connection that wraps http server implementing a RESTful - API specification. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeifepluovb4so2eem34ulpcp4svegb2dqfpmtojtofhfkb3j2xanui - __init__.py: bafybeifykou5sazojmc7hdqnsdp4mncd4zh3xys3mdgdzwks23mvhzu2ga - connection.py: bafybeie42txykvedioambi2dq4nurktilg5v6qleo2iaesc7psmrobdhva - tests/__init__.py: bafybeifqaf7cnc4oczjkbwmv4ahrkbiqxrojwgowej3kbri3skz4lzt43i - tests/data/certs/server.crt: bafybeiev5i3xxkvn36wflf633gkumuxexsw4y2bubwbvl7edrz4igfgv34 - tests/data/certs/server.csr: bafybeicvp7xdl5w3o4bzikkudpduitss3bpp6xqfwlxbw6kabdangohy5u - tests/data/certs/server.key: bafybeiabvpkpqr4fctrbssfal6pviv5otgmu32qyrfpyhcql5wgmlzjtoe - tests/data/petstore_sim.yaml: bafybeiaekkfxljlv57uviz4ug6isdqbzsnuxpsgy3dvhzh22daql3xh2i4 - tests/test_http_server.py: bafybeia2cax2paqaygr6xgzbgmiqepsyjkdx4joi5qukpg6ewnz5yckk7m -fingerprint_ignore_patterns: [] -connections: [] -protocols: -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -class_name: HTTPServerConnection -config: - api_spec_path: null - host: 127.0.0.1 - port: 8000 - ssl_cert: null - ssl_key: null - target_skill_id: null -excluded_protocols: [] -restricted_to_protocols: -- valory/http:1.0.0 -dependencies: - aiohttp: - version: <4.0.0,>=3.8.5 - openapi-core: - version: ==0.15.0 - openapi-spec-validator: - version: <0.5.0,>=0.4.0 - werkzeug: {} - attrs: {} -is_abstract: false diff --git a/trader_old/vendor/valory/connections/http_server/tests/__init__.py b/trader_old/vendor/valory/connections/http_server/tests/__init__.py deleted file mode 100644 index 27614bc9e..000000000 --- a/trader_old/vendor/valory/connections/http_server/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2023 Valory AG -# Copyright 2018-2020 Fetch.AI Limited -# -# 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 the tests of the HTTP Server connection implementation.""" diff --git a/trader_old/vendor/valory/connections/http_server/tests/data/certs/server.crt b/trader_old/vendor/valory/connections/http_server/tests/data/certs/server.crt deleted file mode 100644 index b2ae04f89..000000000 --- a/trader_old/vendor/valory/connections/http_server/tests/data/certs/server.crt +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICsTCCAZkCFGqNcoSHEADDJ5wZBtczunKoFWBVMA0GCSqGSIb3DQEBCwUAMBQx -EjAQBgNVBAMMCWxvY2FsaG9zdDAgFw0yMTA5MDYwOTU2MTVaGA8yMTIxMDgxMzA5 -NTYxNVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAxX8TpWN5cE9oGotbTlEDVst1at0ZgYlgKwCVconrOQ77AhD4 -MyJZ++Poy2i9N1JKYclT9ZrSRtqh+djILaCVeHHgwqFgwpGJuupunv/5o8fX9k1/ -YUs3MQou9STiOLS+B/MK25Fi/LUvr1ZYJzAViekgV1yv7Sn/n2mpQe66ByyNZt3D -Tzid9f3d7FHY6HBkxaoaUxkSIJeHcHy6qUXdiEeoPWBbkp6JjFqKW6mynwnDP4Wc -zGerRtLo69rxtaaES0aboOjA6bk1Ab+4XmSH+Kv6r7CzArLFHJO+ZUU6Pqxd2ehR -L9qicTzOQyN7ygVlBwZWpioOSRzGROgrNhQniQIDAQABMA0GCSqGSIb3DQEBCwUA -A4IBAQBxSEAWtXQUq8qW8XHRcw1loBoxIus1+ajkMX9/pN0SFuNBq8P61TLtMjM1 -G0czcgyXVqjMFtudY+CJa6yn+WWnp6oqDkjcu8Z5SdFfM677pQwF4R1nylb1aLP+ -X+7NxVIs2pHNzYvxRm/OQ1Q6rVWVq3omludCcxHd3+y5kW5enG1Dp2yLXsdatNjj -2DzLF2WNMVXuXmFC9GVZpSsP5qCYD8rfqNvLaV6oxZ+woJ+UX8Q5YlEB1/2LtRBf -x+XiiKXY2h4ZTHGjCO+Pu6FKOxf4JxWoBirCe7WOjfOJUdQYLOk6nT+qSP8iLFaS -/DBRpBw/kJjec5xedh2CZOEC8NLw ------END CERTIFICATE----- diff --git a/trader_old/vendor/valory/connections/http_server/tests/data/certs/server.csr b/trader_old/vendor/valory/connections/http_server/tests/data/certs/server.csr deleted file mode 100644 index b11586e88..000000000 --- a/trader_old/vendor/valory/connections/http_server/tests/data/certs/server.csr +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIICWTCCAUECAQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEAxX8TpWN5cE9oGotbTlEDVst1at0ZgYlgKwCVconr -OQ77AhD4MyJZ++Poy2i9N1JKYclT9ZrSRtqh+djILaCVeHHgwqFgwpGJuupunv/5 -o8fX9k1/YUs3MQou9STiOLS+B/MK25Fi/LUvr1ZYJzAViekgV1yv7Sn/n2mpQe66 -ByyNZt3DTzid9f3d7FHY6HBkxaoaUxkSIJeHcHy6qUXdiEeoPWBbkp6JjFqKW6my -nwnDP4WczGerRtLo69rxtaaES0aboOjA6bk1Ab+4XmSH+Kv6r7CzArLFHJO+ZUU6 -Pqxd2ehRL9qicTzOQyN7ygVlBwZWpioOSRzGROgrNhQniQIDAQABoAAwDQYJKoZI -hvcNAQELBQADggEBAH9MeBQNrb081LoPDk3C/C4zH6BoVtxkQXoPXGv6+wijNju5 -wAUZc26VGdawW3Scqj9kboObi5NwI7o8ZMsOx2V8MT5FjSl79DoAszwww19J48J4 -6qGRPuph3c48Gz1eZCCQscaEG4pYqdL3aS6Jt/HmKkZGIAZvNGwzaBOGTIJTZHSU -9W9gV3RAL1unLgZKYAmKVStFtCOjARbn0wlBOeT2nkqRsckACgxxDNAjDPmKVmUK -x6BSPttFWIVc/FXvkIBpwbxKAlwK9amtko0VGgw3WC7kBq13/ijNeQV/PaqFbSWF -MshUv0YLv0aKVwFN1oRYiDYuwSXyRK5PYW4VNhQ= ------END CERTIFICATE REQUEST----- diff --git a/trader_old/vendor/valory/connections/http_server/tests/data/certs/server.key b/trader_old/vendor/valory/connections/http_server/tests/data/certs/server.key deleted file mode 100644 index a98c11c10..000000000 --- a/trader_old/vendor/valory/connections/http_server/tests/data/certs/server.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAxX8TpWN5cE9oGotbTlEDVst1at0ZgYlgKwCVconrOQ77AhD4 -MyJZ++Poy2i9N1JKYclT9ZrSRtqh+djILaCVeHHgwqFgwpGJuupunv/5o8fX9k1/ -YUs3MQou9STiOLS+B/MK25Fi/LUvr1ZYJzAViekgV1yv7Sn/n2mpQe66ByyNZt3D -Tzid9f3d7FHY6HBkxaoaUxkSIJeHcHy6qUXdiEeoPWBbkp6JjFqKW6mynwnDP4Wc -zGerRtLo69rxtaaES0aboOjA6bk1Ab+4XmSH+Kv6r7CzArLFHJO+ZUU6Pqxd2ehR -L9qicTzOQyN7ygVlBwZWpioOSRzGROgrNhQniQIDAQABAoIBAHao81Tbf4tLKnFI -aYOUiT0M4W9jiH+b2nv7zc8TrpCJv6ZuK7INYaNGPAh61bT3bFl0bU2Tx+NqWQeU -iDFh2myTf0dxToGYj/gOAojlo0gUOl1yEqaSWobMZ4pCrukDL2n3TP6/S4oqEox2 -hGCHM2m4+AWFWu5T3ZIaGefTV1IXEqghj7L+53UI4qksnJDEQ9GT34KnlJhQKZmw -E6St5F2xfXTKq6EWBIC23RNo4kAgDHBTE8MVRZdUEPmipf564NEVtxLFTKUi+tue -GbiagtCWeGeEGZ2uFyr+HWIQUz4qLcMR6hp+hxh2VP3U52/0I5PKngSO0G6IemMD -Hxj6DEECgYEA/A7Vjy9Or7DEIWZcsm44kyl79qUbzAlqDtG2RmOc6DDiWM3jQ/OR -bOW4wNCFxv/KOsoeB7FxP7kKTupwj2u1Y9krAsHifXyFtHilZy9yTo4h8wHy40ae -4B8sP4+xEhppfjoFg5ySdF1BF1prwh34YSlFEkD+Q3Uu4Hr3+Ph8Pk8CgYEAyJXL -TKT3zUUD6BhtJ74jtmwSW7SZx+lgbgzEtAHTwcZZllaTCdBY6H3im5pJ9LettymT -PtSVn2EYVULtJJiT0qm3rqkqDQ8QImdx+T2V/GL9Oo8T1LdYud2J+f7+pEAn9Ud3 -/XL6kZUXm/CpwIGIx3tB09kSsLxCGRnyrdhR3qcCgYEA3TCLWg5yp5ygUIsKV45/ -2SxzWzsCzKeKSZzgrp5lqCCV0MZEZHIOsRhaa+HRM5NuPO73MVsWfYv9Lsluo30q -fYeqxc2s2t/2WSvyQj2RurvhsOWJ5sYnT5grdU+8XJ2O67Uw95DjuHfJUhwIKh2w -xFq6AU3Fkx73VwiyKOqt5OMCgYBiIh7/VWpCy/QYVfL5UaXpNsBYi2f9DSl3Tdni -c05lbCQiUCLJ11vYCtaV6Asspbxgcv+t6pV1Dyy3cfHRSLBxjUTnN63yC5+KJW/2 -T3IUs11Oi/dYx4aqED/TxjRQqW6jKp8CqYD7PqT5TunN29HOPng7K+VgAAqaez5m -XQHY2wKBgErzDsGHH+0XktR7HCZJMmuc/1HnDzfENnfpRIjjlwJF8xn/HymS0OP+ -3AsfN0g60Qutng62wthkzeUheD3UM2nwpmatuP4UXUFGkGcwmCdvzMf/SvyKIjmQ -Mxiu8flSlCWlvP5e+Rrmd3RitOXeCqZLKbywMnlWHHfL33d1LWlf ------END RSA PRIVATE KEY----- diff --git a/trader_old/vendor/valory/connections/http_server/tests/data/petstore_sim.yaml b/trader_old/vendor/valory/connections/http_server/tests/data/petstore_sim.yaml deleted file mode 100644 index dd8ea80ed..000000000 --- a/trader_old/vendor/valory/connections/http_server/tests/data/petstore_sim.yaml +++ /dev/null @@ -1,111 +0,0 @@ -openapi: "3.0.0" -info: - version: 1.0.0 - title: Swagger Petstore - license: - name: MIT -servers: - - url: '' -paths: - /pets: - get: - summary: List all pets - operationId: listPets - tags: - - pets - parameters: - - name: limit - in: query - description: How many items to return at one time (max 100) - required: false - schema: - type: integer - format: int32 - responses: - '200': - description: A paged array of pets - headers: - x-next: - description: A link to the next page of responses - schema: - type: string - content: - application/json: - schema: - $ref: "#/components/schemas/Pets" - default: - description: unexpected error - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - post: - summary: Create a pet - operationId: createPets - tags: - - pets - responses: - '201': - description: Null response - default: - description: unexpected error - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - /pets/{petId}: - get: - summary: Info for a specific pet - operationId: showPetById - tags: - - pets - parameters: - - name: petId - in: path - required: true - description: The id of the pet to retrieve - schema: - type: string - responses: - '200': - description: Expected response to a valid request - content: - application/json: - schema: - $ref: "#/components/schemas/Pet" - default: - description: unexpected error - content: - application/json: - schema: - $ref: "#/components/schemas/Error" -components: - schemas: - Pet: - type: object - required: - - id - - name - properties: - id: - type: integer - format: int64 - name: - type: string - tag: - type: string - Pets: - type: array - items: - $ref: "#/components/schemas/Pet" - Error: - type: object - required: - - code - - message - properties: - code: - type: integer - format: int32 - message: - type: string \ No newline at end of file diff --git a/trader_old/vendor/valory/connections/http_server/tests/test_http_server.py b/trader_old/vendor/valory/connections/http_server/tests/test_http_server.py deleted file mode 100644 index cd08e0d08..000000000 --- a/trader_old/vendor/valory/connections/http_server/tests/test_http_server.py +++ /dev/null @@ -1,597 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2023 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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 the tests of the HTTP Server connection module.""" -# pylint: skip-file - -import asyncio -import logging -import os -import ssl -from pathlib import Path -from traceback import print_exc -from typing import Tuple, cast -from unittest.mock import MagicMock, Mock, patch - -import aiohttp -import pytest -from aiohttp.client_reqrep import ClientResponse - -from aea.common import Address -from aea.configurations.base import ConnectionConfig -from aea.identity.base import Identity -from aea.mail.base import Envelope, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.test_tools.mocks import RegexComparator -from aea.test_tools.network import get_host, get_unused_tcp_port - -from packages.valory.connections.http_server.connection import ( - APISpec, - HTTPServerConnection, - Response, -) -from packages.valory.protocols.http.dialogues import HttpDialogue -from packages.valory.protocols.http.dialogues import HttpDialogues as BaseHttpDialogues -from packages.valory.protocols.http.message import HttpMessage - - -logger = logging.getLogger(__name__) - -DATA_DIR = str(Path(__file__).parent / "data") - - -class HttpDialogues(BaseHttpDialogues): - """The dialogues class keeps track of all http dialogues.""" - - def __init__(self, self_address: Address, **kwargs) -> None: - """ - Initialize dialogues. - - :param self_address: self address - :param kwargs: keyword arguments - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return HttpDialogue.Role.SERVER - - BaseHttpDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - ) - - -@pytest.mark.asyncio -class TestHTTPServer: - """Tests for HTTPServer connection.""" - - async def request(self, method: str, path: str, **kwargs) -> ClientResponse: - """ - Make a http request. - - :param method: HTTP method: GET, POST etc - :param path: path to request on server. full url constructed automatically - :param kwargs: keyword arguments - :return: http response - """ - try: - url = f"http://{self.host}:{self.port}{path}" - async with aiohttp.ClientSession() as session: - async with session.request(method, url, **kwargs) as resp: - await resp.read() - return resp - except Exception: - print_exc() - raise - - def setup(self): - """Initialise the test case.""" - self.identity = Identity("name", address="my_key", public_key="my_public_key") - self.agent_address = self.identity.address - self.host = get_host() - self.port = get_unused_tcp_port() - self.api_spec_path = os.path.join(DATA_DIR, "petstore_sim.yaml") - self.connection_id = HTTPServerConnection.connection_id - self.protocol_id = HttpMessage.protocol_id - self.target_skill_id = "some_author/some_skill:0.1.0" - - self.configuration = ConnectionConfig( - host=self.host, - port=self.port, - target_skill_id=self.target_skill_id, - api_spec_path=self.api_spec_path, - connection_id=HTTPServerConnection.connection_id, - restricted_to_protocols={HttpMessage.protocol_id}, - ) - self.http_connection = HTTPServerConnection( - configuration=self.configuration, - data_dir=MagicMock(), - identity=self.identity, - ) - self.loop = asyncio.get_event_loop() - self.loop.run_until_complete(self.http_connection.connect()) - self.connection_address = str(HTTPServerConnection.connection_id) - self._dialogues = HttpDialogues(self.target_skill_id) - self.original_timeout = self.http_connection.channel.timeout_window - - @pytest.mark.asyncio - async def test_http_connection_disconnect_channel(self): - """Test the disconnect.""" - await self.http_connection.channel.disconnect() - assert self.http_connection.channel.is_stopped - - def _get_message_and_dialogue( - self, envelope: Envelope - ) -> Tuple[HttpMessage, HttpDialogue]: - message = cast(HttpMessage, envelope.message) - dialogue = cast(HttpDialogue, self._dialogues.update(message)) - assert dialogue is not None - return message, dialogue - - @pytest.mark.asyncio - async def test_get_200(self): - """Test send get request w/ 200 response.""" - request_task = self.loop.create_task(self.request("get", "/pets")) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=20) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - message = dialogue.reply( - target_message=incoming_message, - performative=HttpMessage.Performative.RESPONSE, - version=incoming_message.version, - status_code=200, - status_text="Success", - body=b"Response body", - headers="Content-Length: 1", - ) - response_envelope = Envelope( - to=envelope.sender, - sender=envelope.to, - context=envelope.context, - message=message, - ) - await self.http_connection.send(response_envelope) - - response = await asyncio.wait_for( - request_task, - timeout=20, - ) - assert ( - response.status == 200 - and response.reason == "Success" - and await response.text() == "Response body" - and int(response.headers["Content-Length"]) == len("Response body") - ) - - @pytest.mark.asyncio - async def test_header_content_type(self): - """Test send get request w/ 200 response.""" - content_type = "something/unique" - request_task = self.loop.create_task(self.request("get", "/pets")) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=20) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - message = dialogue.reply( - target_message=incoming_message, - performative=HttpMessage.Performative.RESPONSE, - version=incoming_message.version, - headers=f"Content-Type: {content_type}", - status_code=200, - status_text="Success", - body=b"Response body", - ) - response_envelope = Envelope( - to=envelope.sender, - sender=envelope.to, - context=envelope.context, - message=message, - ) - await self.http_connection.send(response_envelope) - - response = await asyncio.wait_for( - request_task, - timeout=20, - ) - assert ( - response.status == 200 - and response.reason == "Success" - and await response.text() == "Response body" - ) - assert response.headers["Content-Type"] == content_type - - @pytest.mark.asyncio - async def test_bad_performative_get_timeout_error(self): - """Test send get request w/ 200 response.""" - self.http_connection.channel.timeout_window = 3 - request_task = self.loop.create_task(self.request("get", "/pets")) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=10) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - incorrect_message = HttpMessage( - performative=HttpMessage.Performative.REQUEST, - dialogue_reference=dialogue.dialogue_label.dialogue_reference, - target=incoming_message.message_id, - message_id=incoming_message.message_id + 1, - method="post", - url="/pets", - version=incoming_message.version, - headers=incoming_message.headers, - body=b"Request body", - ) - incorrect_message.to = incoming_message.sender - - # the incorrect message cannot be sent into a dialogue, so this is omitted. - - response_envelope = Envelope( - to=incorrect_message.to, - sender=envelope.to, - context=envelope.context, - message=incorrect_message, - ) - with patch.object(self.http_connection.logger, "warning") as mock_logger: - await self.http_connection.send(response_envelope) - mock_logger.assert_any_call( - f"Could not create dialogue for message={incorrect_message}" - ) - - response = await asyncio.wait_for(request_task, timeout=10) - - assert ( - response.status == 408 - and response.reason == "Request Timeout" - and await response.text() == "" - ) - - @pytest.mark.asyncio - async def test_late_message_get_timeout_error(self): - """Test send get request w/ 200 response.""" - self.http_connection.channel.timeout_window = 0.2 - request_task = self.loop.create_task(self.request("get", "/pets")) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=10) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - message = dialogue.reply( - target_message=incoming_message, - performative=HttpMessage.Performative.RESPONSE, - version=incoming_message.version, - headers=incoming_message.headers, - status_code=200, - status_text="Success", - body=b"Response body", - ) - response_envelope = Envelope( - to=message.to, - sender=envelope.to, - context=envelope.context, - message=message, - ) - await asyncio.sleep(0.4) - with patch.object(self.http_connection.logger, "warning") as mock_logger: - await self.http_connection.send(response_envelope) - mock_logger.assert_any_call( - RegexComparator( - "Dropping message=.* for incomplete_dialogue_label=.* which has timed out." - ) - ) - - response = await asyncio.wait_for(request_task, timeout=10) - - assert ( - response.status == 408 - and response.reason == "Request Timeout" - and await response.text() == "" - ) - - @pytest.mark.asyncio - async def test_post_201(self): - """Test send get request w/ 200 response.""" - request_task = self.loop.create_task( - self.request( - "post", - "/pets", - ) - ) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=20) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - message = dialogue.reply( - target_message=incoming_message, - performative=HttpMessage.Performative.RESPONSE, - version=incoming_message.version, - status_code=201, - status_text="Created", - body=b"Response body", - ) - response_envelope = Envelope( - to=message.to, - sender=envelope.to, - context=envelope.context, - message=message, - ) - - await self.http_connection.send(response_envelope) - - response = await asyncio.wait_for( - request_task, - timeout=20, - ) - assert ( - response.status == 201 - and response.reason == "Created" - and await response.text() == "Response body" - ) - - @pytest.mark.asyncio - async def test_get_404(self): - """Test send post request w/ 404 response.""" - response = await self.request("get", "/url-non-exists") - - assert ( - response.status == 404 - and response.reason == "Request Not Found" - and await response.text() == "" - ) - - @pytest.mark.asyncio - async def test_post_404(self): - """Test send post request w/ 404 response.""" - response = await self.request("get", "/url-non-exists", data="some data") - - assert ( - response.status == 404 - and response.reason == "Request Not Found" - and await response.text() == "" - ) - - @pytest.mark.asyncio - async def test_get_408(self): - """Test send post request w/ 404 response.""" - await self.http_connection.connect() - self.http_connection.channel.timeout_window = 0.1 - with patch.object( - self.http_connection.channel.logger, "warning" - ) as mock_logger: - response = await self.request("get", "/pets") - mock_logger.assert_any_call( - RegexComparator("Request timed out! Request=.*") - ) - - assert ( - response.status == 408 - and response.reason == "Request Timeout" - and await response.text() == "" - ) - - @pytest.mark.asyncio - async def test_post_408(self): - """Test send post request w/ 404 response.""" - self.http_connection.channel.timeout_window = 0.1 - response = await self.request("post", "/pets", data="somedata") - - assert ( - response.status == 408 - and response.reason == "Request Timeout" - and await response.text() == "" - ) - - @pytest.mark.asyncio - async def test_send_connection_drop(self): - """Test unexpected response.""" - message = HttpMessage( - performative=HttpMessage.Performative.RESPONSE, - dialogue_reference=("", ""), - target=1, - message_id=2, - headers="", - version="", - status_code=200, - status_text="Success", - body=b"", - ) - message.to = str(HTTPServerConnection.connection_id) - message.sender = self.target_skill_id - envelope = Envelope( - to=message.to, - sender=message.sender, - message=message, - ) - await self.http_connection.send(envelope) - - @pytest.mark.asyncio - async def test_get_message_channel_not_connected(self): - """Test error on channel get message if not connected.""" - await self.http_connection.disconnect() - with pytest.raises(ValueError): - await self.http_connection.channel.get_message() - - @pytest.mark.asyncio - async def test_fail_connect(self): - """Test error on server connection.""" - await self.http_connection.disconnect() - - with patch.object( - self.http_connection.channel, - "_start_http_server", - side_effect=Exception("expected"), - ): - await self.http_connection.connect() - assert not self.http_connection.is_connected - - @pytest.mark.asyncio - async def test_server_error_on_send_response(self): - """Test exception raised on response sending to the client.""" - request_task = self.loop.create_task( - self.request( - "post", - "/pets", - ) - ) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=20) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - message = dialogue.reply( - target_message=incoming_message, - performative=HttpMessage.Performative.RESPONSE, - version=incoming_message.version, - headers=incoming_message.headers, - status_code=201, - status_text="Created", - body=b"Response body", - ) - response_envelope = Envelope( - to=message.to, - sender=envelope.to, - context=envelope.context, - message=message, - ) - - with patch.object(Response, "from_message", side_effect=Exception("expected")): - await self.http_connection.send(response_envelope) - response = await asyncio.wait_for( - request_task, - timeout=20, - ) - - assert response and response.status == 500 and response.reason == "Server Error" - - def teardown(self): - """Teardown the test case.""" - self.loop.run_until_complete(self.http_connection.disconnect()) - self.http_connection.channel.timeout_window = self.original_timeout - - -def test_bad_api_spec(): - """Test error on apispec file is invalid.""" - with pytest.raises(FileNotFoundError): - APISpec("not_exist_file") - - -def test_apispec_verify_if_no_validator_set(): - """Test api spec ok if no spec file provided.""" - assert APISpec().verify(Mock()) - - -@pytest.mark.asyncio -class TestHTTPSServer: - """Tests for HTTPServer connection.""" - - async def request(self, method: str, path: str, **kwargs) -> ClientResponse: - """ - Make a http request. - - :param method: HTTP method: GET, POST etc - :param path: path to request on server. full url constructed automatically - :param kwargs: keyword arguments - :return: http response - """ - try: - url = f"https://{self.host}:{self.port}{path}" - sslcontext = ssl.create_default_context(cafile=self.ssl_cert) - async with aiohttp.ClientSession() as session: - async with session.request( - method, url, **kwargs, ssl=sslcontext - ) as resp: - await resp.read() - return resp - except Exception: - print_exc() - raise - - def setup(self): - """Initialise the test case.""" - self.identity = Identity("name", address="my_key", public_key="my_public_key") - self.agent_address = self.identity.address - self.host = "localhost" - self.port = get_unused_tcp_port() - self.api_spec_path = os.path.join(DATA_DIR, "petstore_sim.yaml") - self.connection_id = HTTPServerConnection.connection_id - self.protocol_id = HttpMessage.protocol_id - self.target_skill_id = "some_author/some_skill:0.1.0" - self.ssl_cert = os.path.join(DATA_DIR, "certs", "server.crt") - self.ssl_key = os.path.join(DATA_DIR, "certs", "server.key") - self.configuration = ConnectionConfig( - host=self.host, - port=self.port, - target_skill_id=self.target_skill_id, - api_spec_path=self.api_spec_path, - connection_id=HTTPServerConnection.connection_id, - restricted_to_protocols={HttpMessage.protocol_id}, - ssl_cert=self.ssl_cert, - ssl_key=self.ssl_key, - ) - self.http_connection = HTTPServerConnection( - configuration=self.configuration, - data_dir=MagicMock(), - identity=self.identity, - ) - self.loop = asyncio.get_event_loop() - self.loop.run_until_complete(self.http_connection.connect()) - self.connection_address = str(HTTPServerConnection.connection_id) - self._dialogues = HttpDialogues(self.target_skill_id) - self.original_timeout = self.http_connection.channel.timeout_window - - @pytest.mark.asyncio - async def test_get_200(self): - """Test send get request w/ 200 response.""" - request_task = self.loop.create_task(self.request("get", "/pets")) - envelope = await asyncio.wait_for(self.http_connection.receive(), timeout=20) - assert envelope - incoming_message, dialogue = self._get_message_and_dialogue(envelope) - message = dialogue.reply( - target_message=incoming_message, - performative=HttpMessage.Performative.RESPONSE, - version=incoming_message.version, - status_code=200, - status_text="Success", - body=b"Response body", - ) - response_envelope = Envelope( - to=envelope.sender, - sender=envelope.to, - context=envelope.context, - message=message, - ) - await self.http_connection.send(response_envelope) - - response = await asyncio.wait_for( - request_task, - timeout=20, - ) - - assert ( - response.status == 200 - and response.reason == "Success" - and await response.text() == "Response body" - ) - - def _get_message_and_dialogue( - self, envelope: Envelope - ) -> Tuple[HttpMessage, HttpDialogue]: - message = cast(HttpMessage, envelope.message) - dialogue = cast(HttpDialogue, self._dialogues.update(message)) - assert dialogue is not None - return message, dialogue diff --git a/trader_old/vendor/valory/connections/ipfs/__init__.py b/trader_old/vendor/valory/connections/ipfs/__init__.py deleted file mode 100644 index 54c1c92f4..000000000 --- a/trader_old/vendor/valory/connections/ipfs/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""A connection responsible for uploading and downloading files from IPFS.""" diff --git a/trader_old/vendor/valory/connections/ipfs/connection.py b/trader_old/vendor/valory/connections/ipfs/connection.py deleted file mode 100644 index 03de8b56e..000000000 --- a/trader_old/vendor/valory/connections/ipfs/connection.py +++ /dev/null @@ -1,323 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ -"""A connection responsible for uploading and downloading files from IPFS.""" -import asyncio -import os -import tempfile -from asyncio import Task -from concurrent.futures import Executor -from pathlib import Path -from shutil import rmtree -from typing import Any, Callable, Dict, Optional, cast - -import requests -from aea.configurations.base import PublicId -from aea.connections.base import Connection, ConnectionStates -from aea.mail.base import Envelope -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea_cli_ipfs.exceptions import DownloadError -from aea_cli_ipfs.ipfs_utils import IPFSTool -from ipfshttpclient.exceptions import ErrorResponse - -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.protocols.ipfs.dialogues import IpfsDialogue -from packages.valory.protocols.ipfs.dialogues import IpfsDialogues as BaseIpfsDialogues - - -PUBLIC_ID = PublicId.from_str("valory/ipfs:0.1.0") - - -class IpfsDialogues(BaseIpfsDialogues): - """A class to keep track of IPFS dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return IpfsDialogue.Role.CONNECTION - - BaseIpfsDialogues.__init__( - self, - self_address=str(kwargs.pop("connection_id")), - role_from_first_message=role_from_first_message, - **kwargs, - ) - - -class IpfsConnection(Connection): - """An async connection for sending and receiving files to IPFS.""" - - connection_id = PUBLIC_ID - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize the connection. - - :param kwargs: keyword arguments passed to component base. - """ - super().__init__(**kwargs) # pragma: no cover - ipfs_domain = self.configuration.config.get("ipfs_domain") - self.ipfs_tool: IPFSTool = IPFSTool(ipfs_domain) - self.task_to_request: Dict[asyncio.Future, Envelope] = {} - self.loop_executor: Optional[Executor] = None - self.dialogues = IpfsDialogues(connection_id=PUBLIC_ID) - self._response_envelopes: Optional[asyncio.Queue] = None - - @property - def response_envelopes(self) -> asyncio.Queue: - """Returns the response envelopes queue.""" - if self._response_envelopes is None: - raise ValueError( - "`IPFSConnection.response_envelopes` is not yet initialized. Is the connection setup?" - ) - return self._response_envelopes - - async def connect(self) -> None: - """Set up the connection.""" - self.ipfs_tool.check_ipfs_node_running() - self._response_envelopes = asyncio.Queue() - self.state = ConnectionStates.connected - - async def disconnect(self) -> None: - """Tear down the connection.""" - if self.is_disconnected: # pragma: nocover - return - - self.state = ConnectionStates.disconnecting - - for task in self.task_to_request.keys(): - if not task.cancelled(): # pragma: nocover - task.cancel() - self._response_envelopes = None - - self.state = ConnectionStates.disconnected - - async def send(self, envelope: Envelope) -> None: - """Send an envelope.""" - task = self._handle_envelope(envelope) - task.add_done_callback(self._handle_done_task) - self.task_to_request[task] = envelope - - async def receive(self, *args: Any, **kwargs: Any) -> Optional[Envelope]: - """Receive an envelope.""" - return await self.response_envelopes.get() - - def run_async( - self, func: Callable, *args: Any, timeout: Optional[float] = None - ) -> Task: - """Run a function asynchronously by using threads.""" - ipfs_operation = self.loop.run_in_executor( - self.loop_executor, - func, - *args, - ) - timely_operation = asyncio.wait_for(ipfs_operation, timeout=timeout) - task = self.loop.create_task(timely_operation) - return task - - def _handle_envelope(self, envelope: Envelope) -> Task: - """Handle incoming envelopes by dispatching background tasks.""" - message = cast(IpfsMessage, envelope.message) - performative = message.performative - handler = getattr(self, f"_handle_{performative.value}", None) - if handler is None: - err = f"Performative `{performative.value}` is not supported." - self.logger.error(err) - task = self.run_async(self._handle_error, err) - return task - dialogue = self.dialogues.update(message) - task = self.run_async(handler, message, dialogue) - return task - - def _handle_store_files( - self, message: IpfsMessage, dialogue: BaseDialogue - ) -> IpfsMessage: - """ - Handle a STORE_FILES performative. - - Uploads the provided files to ipfs. - - :param message: The ipfs request. - :returns: the hash of the uploaded files. - """ - files = message.files - if len(files) == 0: - err = "No files were present." - self.logger.error(err) - return self._handle_error(err, dialogue) - if len(files) == 1: - # a single file needs to be stored, - # we don't need to create a dir - path, data = files.popitem() - self.__create_file(path, data) - else: - # multiple files are present, which means that it's a directory - # we begin by checking that they belong to the same directory - dirs = {os.path.dirname(path) for path in files.keys()} - if len(dirs) > 1: - err = f"Received files from different dirs {dirs}. " - self.logger.error(err) - self.logger.info( - "If you want to send multiple files as a single dir, " - "make sure the their path matches to one directory only." - ) - return self._handle_error(err, dialogue) - - # "path" is the directory, it's the same for all the files - path = dirs.pop() - os.makedirs(path, exist_ok=True) - for file_path, data in files.items(): - self.__create_file(file_path, data) - try: - # note that path will be a dir if multiple files - # are being uploaded. - _, hash_, _ = self.ipfs_tool.add(path) - self.logger.debug(f"Successfully stored files with hash: {hash_}.") - except ( - ValueError, - requests.exceptions.ChunkedEncodingError, - ) as e: # pragma: no cover - err = str(e) - self.logger.error(err) - return self._handle_error(err, dialogue) - finally: - self.__remove_filepath(path) - response_message = cast( - IpfsMessage, - dialogue.reply( - performative=IpfsMessage.Performative.IPFS_HASH, - target_message=message, - ipfs_hash=hash_, - ), - ) - return response_message - - def _handle_get_files( - self, message: IpfsMessage, dialogue: BaseDialogue - ) -> IpfsMessage: - """ - Handle GET_FILES performative. - - Downloads and returns the files resulting from the ipfs hash. - - :param message: The ipfs request. - :returns: the downloaded files. - """ - response_body: Dict[str, str] = {} - ipfs_hash = message.ipfs_hash - with tempfile.TemporaryDirectory() as tmp_dir: - try: - self.ipfs_tool.download(ipfs_hash, tmp_dir) - except ( - DownloadError, - PermissionError, - ErrorResponse, - ) as e: - err = str(e) - self.logger.error(err) - return self._handle_error(err, dialogue) - - files = os.listdir(tmp_dir) - if len(files) > 1: - self.logger.warning( - f"Multiple files or dirs found in {tmp_dir}. " - f"The first will be used. " - ) - downloaded_file = files.pop() - files_to_be_read = [downloaded_file] - base_dir = Path(tmp_dir) - if os.path.isdir(base_dir / downloaded_file): - base_dir = base_dir / downloaded_file - files_to_be_read = os.listdir(base_dir) - - for file_path in files_to_be_read: - with open(base_dir / file_path, encoding="utf-8", mode="r") as file: - response_body[file_path] = file.read() - - response_message = cast( - IpfsMessage, - dialogue.reply( - performative=IpfsMessage.Performative.FILES, - files=response_body, - target_message=message, - ), - ) - return response_message - - def _handle_error( # pylint: disable=no-self-use - self, reason: str, dialogue: BaseDialogue - ) -> IpfsMessage: - """Handler for error messages.""" - message = cast( - IpfsMessage, - dialogue.reply( - performative=IpfsMessage.Performative.ERROR, - reason=reason, - ), - ) - return message - - def _handle_done_task(self, task: asyncio.Future) -> None: - """ - Process a done receiving task. - - :param task: the done task. - """ - request = self.task_to_request.pop(task) - response_message: Optional[Message] = task.result() - - response_envelope = None - if response_message is not None: - response_envelope = Envelope( - to=request.sender, - sender=request.to, - message=response_message, - context=request.context, - ) - - # not handling `asyncio.QueueFull` exception, because the maxsize we defined for the Queue is infinite - self.response_envelopes.put_nowait(response_envelope) - - @staticmethod - def __create_file(path: str, data: str) -> None: - """Creates a file in the specified path.""" - with open(path, "w", encoding="utf-8") as f: - f.write(data) - - def __remove_filepath(self, filepath: str) -> None: - """Remove a file or a folder. If filepath is not a file or a folder, an `IPFSInteractionError` is raised.""" - if os.path.isfile(filepath): - os.remove(filepath) - elif os.path.isdir(filepath): - rmtree(filepath) - else: # pragma: no cover - self.logger.error(f"`{filepath}` is not an existing filepath!") diff --git a/trader_old/vendor/valory/connections/ipfs/connection.yaml b/trader_old/vendor/valory/connections/ipfs/connection.yaml deleted file mode 100644 index c29abbec8..000000000 --- a/trader_old/vendor/valory/connections/ipfs/connection.yaml +++ /dev/null @@ -1,31 +0,0 @@ -name: ipfs -author: valory -version: 0.1.0 -type: connection -description: A connection responsible for uploading and downloading files from IPFS. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeiercvjoct4tygo4oif5y4chnst2y7b6mhdgdj3zvoeakstbn4m7g4 - connection.py: bafybeifnjyjqmhlxenw7m4rfnjw2b6mwaevdl3hrcalefptd2tpm5lrbcy - readme.md: bafybeihdrtloo2stz7frhfhtl5m7ewwigdeehnujf6julwj6c5pzr7iefu - tests/__init__.py: bafybeicqjmce5v5ympy2rcryfh644rxrtujvbcuzk7ylmfmzynoh6wujx4 - tests/test_connection.py: bafybeiedbdf5aumheq6cvtyeneoewmm5zslesvtqqx2ix3w2qqmfo3x26q -fingerprint_ignore_patterns: [] -connections: [] -protocols: -- valory/ipfs:0.1.0:bafybeiftxi2qhreewgsc5wevogi7yc5g6hbcbo4uiuaibauhv3nhfcdtvm -class_name: IpfsConnection -config: - ipfs_domain: null -excluded_protocols: [] -restricted_to_protocols: [] -dependencies: - ipfshttpclient: - version: ==0.8.0a2 - open-aea-cli-ipfs: - version: ==1.53.0 - requests: - version: <2.31.2,>=2.28.1 -is_abstract: false -cert_requests: [] diff --git a/trader_old/vendor/valory/connections/ipfs/readme.md b/trader_old/vendor/valory/connections/ipfs/readme.md deleted file mode 100644 index 20788e676..000000000 --- a/trader_old/vendor/valory/connections/ipfs/readme.md +++ /dev/null @@ -1,2 +0,0 @@ -# IPFS Connection -A connection responsible for uploading and downloading files from IPFS. \ No newline at end of file diff --git a/trader_old/vendor/valory/connections/ipfs/tests/__init__.py b/trader_old/vendor/valory/connections/ipfs/tests/__init__.py deleted file mode 100644 index ccb977283..000000000 --- a/trader_old/vendor/valory/connections/ipfs/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for ipfs connection.""" diff --git a/trader_old/vendor/valory/connections/ipfs/tests/test_connection.py b/trader_old/vendor/valory/connections/ipfs/tests/test_connection.py deleted file mode 100644 index 34be5c404..000000000 --- a/trader_old/vendor/valory/connections/ipfs/tests/test_connection.py +++ /dev/null @@ -1,282 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ -# pylint: disable=protected-access,attribute-defined-outside-init - -"""Tests for ipfs connection.""" -import asyncio -import os -import platform -import tempfile -from typing import Dict, List, Optional -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from aea.configurations.base import ConnectionConfig -from aea.connections.base import ConnectionStates -from aea.mail.base import Envelope -from aea_cli_ipfs.exceptions import DownloadError -from aea_cli_ipfs.ipfs_utils import IPFSTool -from aea_test_autonomy.fixture_helpers import ( # noqa: F401; pylint: disable=unused-import - LOCAL_IPFS, - ipfs_daemon, - use_ipfs_daemon, -) - -from packages.valory.connections.ipfs.connection import ( - IpfsConnection, - IpfsDialogues, - PUBLIC_ID, -) -from packages.valory.protocols.ipfs import IpfsMessage - - -ANY_SKILL = "skill/any:0.1.0" - - -@use_ipfs_daemon -class TestIpfsConnection: - """Tests for IpfsConnection""" - - def setup(self) -> None: - """Set up the tests.""" - configuration = ConnectionConfig( - ipfs_domain=LOCAL_IPFS, - connection_id=IpfsConnection.connection_id, - ) - self.connection = IpfsConnection( - configuration=configuration, - data_dir=MagicMock(), - ) - self.dummy_msg = IpfsMessage(performative=IpfsMessage.Performative.GET_FILES) # type: ignore - self.dummy_envelope = Envelope( - to=str(PUBLIC_ID), sender=ANY_SKILL, message=self.dummy_msg - ) - - @pytest.mark.asyncio - async def test_connect(self) -> None: - """Test connect""" - await self.connection.connect() - assert self.connection.response_envelopes is not None - assert self.connection.state == ConnectionStates.connected - - @pytest.mark.asyncio - async def test_disconnect(self) -> None: - """Test disconnect""" - await self.connection.connect() - await self.connection.disconnect() - assert self.connection.state == ConnectionStates.disconnected - with pytest.raises(ValueError): - self.connection.response_envelopes # pylint: disable=pointless-statement - - @pytest.mark.parametrize( - ("performative", "expected_error"), - [ - (IpfsMessage.Performative.GET_FILES, False), - (IpfsMessage.Performative.STORE_FILES, False), - (IpfsMessage.Performative.IPFS_HASH, True), - (IpfsMessage.Performative.FILES, True), - ], - ) - def test_handle_envelope( - self, - performative: IpfsMessage.Performative, - expected_error: bool, - ) -> None: - """Tests for _handle_envelope.""" - dummy_msg = IpfsMessage(performative=performative) - envelope = Envelope(to=str(PUBLIC_ID), sender=ANY_SKILL, message=dummy_msg) - with mock.patch.object( - IpfsConnection, - "run_async", - return_value=MagicMock(), - ), mock.patch.object( - self.connection.logger, - "error", - ) as mock_logger: - self.connection._handle_envelope(envelope) - if expected_error: - mock_logger.assert_called_with( - f"Performative `{performative.value}` is not supported." - ) - - @pytest.mark.asyncio - async def test_send(self) -> None: - """Test send.""" - await self.connection.connect() - with mock.patch.object( - IpfsConnection, - "_handle_envelope", - return_value=MagicMock(add_done_callback=lambda *_: _), - ): - assert len(self.connection.task_to_request) == 0 - await self.connection.send(self.dummy_envelope) - assert len(self.connection.task_to_request) == 1 - - @pytest.mark.asyncio - async def test_receive(self) -> None: - """Tests receive.""" - await self.connection.connect() - expected_envelope = self.dummy_envelope - self.connection.response_envelopes.put_nowait(expected_envelope) - actual_envelope = await self.connection.receive() - - assert expected_envelope == actual_envelope - - @pytest.mark.asyncio - async def test_handle_done_task(self) -> None: - """Test _handle_done_tasks.""" - await self.connection.connect() - assert self.connection.response_envelopes.qsize() == 0 - dummy_task = MagicMock(result=lambda: self.dummy_msg) - dummy_request = MagicMock(to=ANY_SKILL, sender=str(PUBLIC_ID), context=None) - self.connection.task_to_request[dummy_task] = dummy_request - self.connection._handle_done_task(dummy_task) - assert self.connection.response_envelopes.qsize() == 1 - - def test_handle_error(self) -> None: - """Test handle_error.""" - message = self.connection._handle_error( - reason="dummy reason", - dialogue=MagicMock(), - ) - assert message is not None - - @pytest.mark.asyncio - async def test_run_async(self) -> None: - """Test run async.""" - dummy_log = "dummy operation is being performed" - - def dummy_operation() -> None: - """A dummy handler.""" - self.connection.logger.info(dummy_log) - - await self.connection.connect() - with mock.patch.object( - self.connection.logger, - "info", - ) as mock_logger: - task = self.connection.run_async(dummy_operation) - assert task is not None - - # give some time for the task to be scheduled and run - await asyncio.sleep(1) - mock_logger.assert_called_with(dummy_log) - - @pytest.mark.parametrize( - ("files", "expected_log", "log_level"), - [ - ({}, "No files were present.", "error"), - ( - {"dummy_filename": "dummy_content"}, - "Successfully stored files with hash: QmYn1qHyFMDdVxYcwseLBdooLAyc3orNBH8vvj4iPTXd4R.", - "debug", - ), - ( - { - "dummy_dir/dummy_filename1": "dummy_content", - "dummy_dir/dummy_filename2": "dummy_content", - }, - "Successfully stored files with hash: QmRP7wK1NZKwno9CFxQUeFaJip5eaaLBo1v8WFtyECgLCz.", - "debug", - ), - ( - { - "dummy_dir/dummy_dir_nested/dummy_filename1": "dummy_content", - "dummy_dir/dummy_dir_nested/dummy_filename2": "dummy_content", - }, - "Successfully stored files with hash: QmcYhNziJDuwmRVg8TYY5S5fUycuBguM6zxukgMDnVQt8H.", - "debug", - ), - ( - { - "dummy_dir1/dummy_filename1": "dummy_content", - "dummy_dir2/dummy_filename2": "dummy_content", - }, - "If you want to send multiple files as a single dir, " - "make sure the their path matches to one directory only.", - "info", - ), - ], - ) - def test_handle_store_files( - self, files: Dict[str, str], expected_log: str, log_level: str - ) -> None: - """Test _handle_store_files.""" - with mock.patch.object( - self.connection.logger, - log_level, - ) as mock_logger: - message = IpfsMessage( - performative=IpfsMessage.Performative.STORE_FILES, files=files # type: ignore - ) - dialogue = MagicMock() - message = self.connection._handle_store_files(message, dialogue) - assert message is not None - mock_logger.assert_called_with(expected_log) - - @pytest.mark.skipif( - platform.system() == "Windows", - reason="PermissionError: [Errno 13] Permission denied", - ) - @pytest.mark.parametrize( - ("extra_files", "download_side_effect", "is_dir"), - [ - ([], None, False), - (["dummy_unexpected_extra_file"], None, False), - ([], DownloadError, False), - ([], None, True), - ], - ) - def test_handle_get_files( - self, - extra_files: List[str], - download_side_effect: Optional[Exception], - is_dir: bool, - ) -> None: - """Test _handle_get_files""" - with tempfile.NamedTemporaryFile() as tmp_file, mock.patch.object( - os, - "listdir", - ) as mock_listdir, mock.patch.object( - IPFSTool, "download", side_effect=download_side_effect - ): - listdir_value = [extra_files + [tmp_file.name]] - if is_dir: - listdir_value = [["/tmp"]] + listdir_value # nosec - mock_listdir.side_effect = listdir_value - - tmp_file.write(b"dummy_data") - tmp_file.flush() - - _, ipfs_hash, _ = self.connection.ipfs_tool.add(tmp_file.name) - message = IpfsMessage( - performative=IpfsMessage.Performative.GET_FILES, ipfs_hash=ipfs_hash # type: ignore - ) - dialogue = MagicMock() - message = self.connection._handle_get_files(message, dialogue) - assert message is not None - - def test_ipfs_dialogue(self) -> None: # pylint: disable=no-self-use - """Test 'IpfsDialogues' creation.""" - dialogues = IpfsDialogues(connection_id=str(PUBLIC_ID)) - dialogues.create( - counterparty=ANY_SKILL, - performative=IpfsMessage.Performative.GET_FILES, - ) diff --git a/trader_old/vendor/valory/connections/ledger/README.md b/trader_old/vendor/valory/connections/ledger/README.md deleted file mode 100644 index fe01aea2b..000000000 --- a/trader_old/vendor/valory/connections/ledger/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Ledger connection - -The ledger connection wraps the APIs needed to interact with multiple ledgers, including smart contracts deployed on those ledgers. - -The AEA communicates with the ledger connection via the `valory/ledger_api:1.0.0` and `valory/contract_api:1.0.0` protocols. - -The connection uses the ledger APIs registered in the ledger API registry. - -## Usage - -First, add the connection to your AEA project (`aea add connection valory/ledger:0.19.0`). Optionally, update the `ledger_apis` in `config` of `connection.yaml`. diff --git a/trader_old/vendor/valory/connections/ledger/__init__.py b/trader_old/vendor/valory/connections/ledger/__init__.py deleted file mode 100644 index ae0f10868..000000000 --- a/trader_old/vendor/valory/connections/ledger/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Scaffold of a connection.""" diff --git a/trader_old/vendor/valory/connections/ledger/base.py b/trader_old/vendor/valory/connections/ledger/base.py deleted file mode 100644 index e5537187c..000000000 --- a/trader_old/vendor/valory/connections/ledger/base.py +++ /dev/null @@ -1,217 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2023 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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 base classes for the ledger API connection.""" -import asyncio -import inspect -from abc import ABC, abstractmethod -from asyncio import Task -from concurrent.futures._base import Executor -from logging import Logger -from typing import Any, Callable, Dict, Optional, Union - -from aea.crypto.base import LedgerApi -from aea.crypto.registries import Registry, ledger_apis_registry -from aea.exceptions import enforce -from aea.helpers.async_utils import AsyncState -from aea.mail.base import Envelope -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, Dialogues - - -class RequestDispatcher(ABC): - """Base class for a request dispatcher.""" - - def __init__( # pylint: disable=too-many-arguments - self, - logger: Logger, - connection_state: AsyncState, - retry_attempts: int = 120, - retry_timeout: int = 3, - loop: Optional[asyncio.AbstractEventLoop] = None, - executor: Optional[Executor] = None, - api_configs: Optional[Dict[str, Dict[str, str]]] = None, - ): - """ - Initialize the request dispatcher. - - :param retry_attempts: the retry attempts for any api used. - :param retry_timeout: the retry timeout of any api used. - :param logger: the logger. - :param connection_state: connection state. - :param loop: the asyncio loop. - :param executor: an executor. - :param api_configs: api configs. - """ - self.connection_state = connection_state - self.loop = loop if loop is not None else asyncio.get_event_loop() - self.executor = executor - self._api_configs = api_configs - self.logger = logger - self.retry_attempts = retry_attempts - self.retry_timeout = retry_timeout - - def api_config(self, ledger_id: str) -> Dict[str, str]: - """Get api config.""" - config = {} # type: Dict[str, str] - if self._api_configs is not None and ledger_id in self._api_configs: - config = self._api_configs[ledger_id] - return config - - async def run_async( - self, - func: Callable[[Any], Task], - api: LedgerApi, - message: Message, - dialogue: Dialogue, - ) -> Union[Message, Task]: - """ - Run a function in executor. - - :param func: the function to execute. - :param api: the ledger api. - :param message: a Ledger API message. - :param dialogue: a Ledger API dialogue. - :return: the return value of the function. - """ - try: - if inspect.iscoroutinefunction(func): - # If it is a coroutine, no need to run it in an executor - # This can happen if the handler is async. - task = func(api, message, dialogue) # type: ignore - else: - task = self.loop.run_in_executor( # type: ignore - self.executor, func, api, message, dialogue - ) - response = await task - return response - except Exception as exception: # pylint: disable=broad-except - return self.get_error_message(exception, api, message, dialogue) - - async def wait_for( - self, func: Callable, *args: Any, timeout: Optional[float] = None - ) -> Any: - """ - Runs a non-coroutine callable async while enforcing a timeout. - - Warning: This function can be used with non-coroutine callables ONLY! - If you want the same functionality with coroutine callables, use asyncio.wait_for(). - - :param func: the callable (function) to run. - :param args: the function params. - :param timeout: for how long to run the function before cancelling it and raising TimeoutError. - :return: the return value of "func" if it finishes in "timeout", raises a TimeoutError otherwise. - """ - enforce( - not inspect.iscoroutinefunction(func), - 'A coroutine was passed to "RequestDispatcher.wait_for()", ' - '"RequestDispatcher.wait_for()" only works with non-coroutine callables. ' - 'Hint: Look at "asyncio.wait_for()". ', - ) - - # we run the passed function using the default executor - running_func = self.loop.run_in_executor(self.executor, func, *args) - - # func_result will carry the value the function returns - func_result = await asyncio.wait_for(running_func, timeout=timeout) - return func_result - - def set_extra_kwargs( # pylint: disable=no-self-use, unused-argument - 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. - - :param envelope: the envelope. - :return: an awaitable. - """ - if not isinstance(envelope.message, Message): # pragma: nocover - raise ValueError("Ledger connection expects non-serialized messages.") - message = envelope.message - ledger_id = self.get_ledger_id(message) - 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 - f"No dialogue created. Message={message} not valid." - ) - performative = message.performative - handler = self.get_handler(performative) - return self.loop.create_task(self.run_async(handler, api, message, dialogue)) - - def get_handler(self, performative: Any) -> Callable[[Any], Task]: - """ - Get the handler method, given the message performative. - - :param performative: the message performative. - :return: the method that will send the request. - """ - handler = getattr(self, performative.value, None) - if handler is None: - raise Exception("Performative not recognized.") # pragma: nocover - return handler - - @abstractmethod - def get_error_message( - self, - exception: Exception, - api: LedgerApi, - message: Message, - dialogue: Dialogue, - ) -> Message: - """ - Build an error message. - - :param exception: the exception - :param api: the ledger api - :param message: the received message. - :param dialogue: the dialogue. - :return: an error message response. - """ - - @property - @abstractmethod - def dialogues(self) -> Dialogues: - """Get the dialogues.""" - - @property - def ledger_api_registry(self) -> Registry: - """Get the registry.""" - return ledger_apis_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/trader_old/vendor/valory/connections/ledger/connection.py b/trader_old/vendor/valory/connections/ledger/connection.py deleted file mode 100644 index 4221b59cb..000000000 --- a/trader_old/vendor/valory/connections/ledger/connection.py +++ /dev/null @@ -1,193 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2023 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Scaffold connection and channel.""" - -import asyncio -from typing import Any, Dict, Optional - -from aea.configurations.base import PublicId -from aea.connections.base import Connection, ConnectionStates -from aea.mail.base import Envelope -from aea.protocols.base import Message - -from packages.valory.connections.ledger.base import RequestDispatcher -from packages.valory.connections.ledger.contract_dispatcher import ( - ContractApiRequestDispatcher, -) -from packages.valory.connections.ledger.ledger_dispatcher import ( - LedgerApiRequestDispatcher, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.ledger_api import LedgerApiMessage - - -PUBLIC_ID = PublicId.from_str("valory/ledger:0.19.0") - - -class LedgerConnection(Connection): - """Proxy to the functionality of the SDK or API.""" - - connection_id = PUBLIC_ID - TIMEOUT = 3 - MAX_ATTEMPTS = 120 - - def __init__(self, **kwargs: Any): - """Initialize a connection to interact with a ledger APIs.""" - super().__init__(**kwargs) - - self._ledger_dispatcher: Optional[LedgerApiRequestDispatcher] = None - self._contract_dispatcher: Optional[ContractApiRequestDispatcher] = None - self._response_envelopes: Optional[asyncio.Queue] = None - - self.task_to_request: Dict[asyncio.Future, Envelope] = {} - self.api_configs = self.configuration.config.get( - "ledger_apis", {} - ) # type: Dict[str, Dict[str, str]] - self.request_retry_attempts = self.configuration.config.get( - "retry_attempts", self.MAX_ATTEMPTS - ) - self.request_retry_timeout = self.configuration.config.get( - "retry_timeout", self.TIMEOUT - ) - - @property - def response_envelopes(self) -> asyncio.Queue: - """Get the response envelopes. Only intended to be accessed when connected.""" - if self._response_envelopes is None: - raise ValueError( - "`asyncio.Queue` for `_response_envelopes` not set. Is the ledger connection active?" - ) - return self._response_envelopes - - async def connect(self) -> None: - """Set up the connection.""" - - if self.is_connected: # pragma: nocover - return - - self.state = ConnectionStates.connecting - - self._ledger_dispatcher = LedgerApiRequestDispatcher( - self._state, - loop=self.loop, - api_configs=self.api_configs, - logger=self.logger, - retry_attempts=self.request_retry_attempts, - retry_timeout=self.request_retry_timeout, - connection_id=self.connection_id, - ) - self._contract_dispatcher = ContractApiRequestDispatcher( - self._state, - loop=self.loop, - api_configs=self.api_configs, - logger=self.logger, - retry_attempts=self.request_retry_attempts, - retry_timeout=self.request_retry_timeout, - connection_id=self.connection_id, - ) - - self._response_envelopes = asyncio.Queue() - self.state = ConnectionStates.connected - - async def disconnect(self) -> None: - """Tear down the connection.""" - if self.is_disconnected: # pragma: nocover - return - - self.state = ConnectionStates.disconnecting - - for task in self.task_to_request.keys(): - if not task.cancelled(): # pragma: nocover - task.cancel() - self._ledger_dispatcher = None - self._contract_dispatcher = None - self._response_envelopes = None - - self.state = ConnectionStates.disconnected - - async def send(self, envelope: "Envelope") -> None: - """ - Send an envelope. - - :param envelope: the envelope to send. - """ - task = self._schedule_request(envelope) - task.add_done_callback(self._handle_done_task) - self.task_to_request[task] = envelope - - def _schedule_request(self, envelope: Envelope) -> asyncio.Task: - """ - Schedule a ledger API request. - - :param envelope: the message. - :return: task - """ - dispatcher: RequestDispatcher - if ( - envelope.protocol_specification_id - == LedgerApiMessage.protocol_specification_id - ): - if self._ledger_dispatcher is None: # pragma: nocover - raise ValueError("No ledger dispatcher set.") - dispatcher = self._ledger_dispatcher - elif ( - envelope.protocol_specification_id - == ContractApiMessage.protocol_specification_id - ): - if self._contract_dispatcher is None: # pragma: nocover - raise ValueError("No contract dispatcher set.") - dispatcher = self._contract_dispatcher - else: - raise ValueError("Protocol not supported") - - task = dispatcher.dispatch(envelope) - return task - - async def receive(self, *args: Any, **kwargs: Any) -> Optional["Envelope"]: - """ - Receive an envelope. Blocking. - - :param args: the arguments - :param kwargs: the keyword arguments - :return: the envelope received, or None. - """ - return await self.response_envelopes.get() - - def _handle_done_task(self, task: asyncio.Future) -> None: - """ - Process a done receiving task. - - :param task: the done task. - """ - request = self.task_to_request.pop(task) - response_message: Optional[Message] = task.result() - - response_envelope = None - if response_message is not None: - response_envelope = Envelope( - to=request.sender, - sender=request.to, - message=response_message, - context=request.context, - ) - - # not handling `asyncio.QueueFull` exception, because the maxsize we defined for the Queue is infinite - self.response_envelopes.put_nowait(response_envelope) diff --git a/trader_old/vendor/valory/connections/ledger/connection.yaml b/trader_old/vendor/valory/connections/ledger/connection.yaml deleted file mode 100644 index 4c7b71d91..000000000 --- a/trader_old/vendor/valory/connections/ledger/connection.yaml +++ /dev/null @@ -1,115 +0,0 @@ -name: ledger -author: valory -version: 0.19.0 -type: connection -description: A connection to interact with any ledger API and contract API. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeihkgodu7o7v6pfazm7u6orlspsfrae3cyz36yc46x67phfmw3l57e - __init__.py: bafybeia3purd7y4b7tkdt2fcaxkdazos32criq5hx6fhufaislrdefe674 - base.py: bafybeifuoq2oqlcjlgeg2fg5l2ijiylb23v65xghv7u422helief2cjjuy - connection.py: bafybeicydkymhz2feqmihtkiwdfg7pp4pww2elqv4tijuhjcplyvawdk74 - contract_dispatcher.py: bafybeidf2wu3rsp5pm45qwjlievbpmueeaj6hjw3kdyn67xhbocylwg3d4 - ledger_dispatcher.py: bafybeicartiu3mcavtyd3eveonrbak3uaowqzymtaza6gqtoi5msid75ci - tests/__init__.py: bafybeifku7ttsmbj4gfx6dkgjvwypx7v5ysfqlzof6vh4p7gujakjtuwhe - tests/conftest.py: bafybeid7vo7e2m76ey5beeadtbxywxx5ukefd5slwbc362rwmhht6i45ou - tests/test_contract_dispatcher.py: bafybeiag5lnpc7h25w23ash4hk4cowxsy5buxgpr474l3tfewnhf56eqyq - tests/test_ledger.py: bafybeigcedfr3yv3jse3xwrerrgwbelgb56uhgrvdus527d3daekh6dx4m - tests/test_ledger_api.py: bafybeifw5smawex5m2fm6rt4kmunc22kpabalmshh45qb3xnuap33sfgyi -fingerprint_ignore_patterns: [] -connections: [] -protocols: -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -class_name: LedgerConnection -config: - ledger_apis: - ethereum: - address: http://127.0.0.1:8545 - chain_id: 1337 - default_gas_price_strategy: eip1559 - gas_price_strategies: &id001 - gas_station: - gas_price_api_key: null - gas_price_strategy: fast - eip1559: - max_gas_fast: 1500 - fee_history_blocks: 10 - fee_history_percentile: 5 - priority_fee_estimation_trigger: 100 - default_priority_fee: 3 - fallback_estimate: - maxFeePerGas: 20000000000 - maxPriorityFeePerGas: 3000000000 - baseFee: null - priority_fee_increase_boundary: 200 - is_gas_estimation_enabled: true - poa_chain: false - ethereum_flashbots: - 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 - authentication_private_key: null - flashbots_builders: [] - solana: - 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 - 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 - celo: - address: http://127.0.0.1:8545 - chain_id: 42220 - default_gas_price_strategy: eip1559 - gas_price_strategies: *id001 - is_gas_estimation_enabled: true - poa_chain: true - retry_attempts: 240 - retry_timeout: 3 -excluded_protocols: [] -restricted_to_protocols: -- valory/contract_api:1.0.0 -- valory/ledger_api:1.0.0 -dependencies: - pytest-asyncio: {} -is_abstract: false diff --git a/trader_old/vendor/valory/connections/ledger/contract_dispatcher.py b/trader_old/vendor/valory/connections/ledger/contract_dispatcher.py deleted file mode 100644 index dfcb42507..000000000 --- a/trader_old/vendor/valory/connections/ledger/contract_dispatcher.py +++ /dev/null @@ -1,451 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2023 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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 the implementation of the contract API request dispatcher.""" -import inspect -import logging -from collections.abc import Mapping -from typing import Any, Callable, Optional, Union, cast - -from aea.common import JSONLike -from aea.contracts import Contract, contract_registry -from aea.contracts.base import snake_to_camel -from aea.crypto.base import LedgerApi -from aea.crypto.registries import Registry -from aea.exceptions import AEAException, parse_exception -from aea.helpers.transaction.base import RawMessage, RawTransaction, State -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import Dialogues as BaseDialogues - -from packages.valory.connections.ledger.base import RequestDispatcher -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.contract_api.dialogues import ContractApiDialogue -from packages.valory.protocols.contract_api.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) - - -_default_logger = logging.getLogger( - "aea.packages.valory.connections.ledger.contract_dispatcher" -) - - -class ContractApiDialogues(BaseContractApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - # The ledger connection maintains the dialogue on behalf of the ledger - return ContractApiDialogue.Role.LEDGER - - BaseContractApiDialogues.__init__( - self, - self_address=str(kwargs.pop("connection_id")), - role_from_first_message=role_from_first_message, - **kwargs, - ) - - -class ContractApiRequestDispatcher(RequestDispatcher): - """Implement the contract API request dispatcher.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the dispatcher.""" - logger = kwargs.pop("logger", None) - connection_id = kwargs.pop("connection_id") - logger = logger if logger is not None else _default_logger - super().__init__(logger, *args, **kwargs) - self._contract_api_dialogues = ContractApiDialogues(connection_id=connection_id) - - @property - def dialogues(self) -> BaseDialogues: - """Get the dialogues.""" - return self._contract_api_dialogues - - @property - def contract_registry(self) -> Registry[Contract]: - """Get the contract registry.""" - return contract_registry - - def get_ledger_id(self, message: Message) -> str: - """Get the ledger id.""" - if not isinstance(message, ContractApiMessage): # pragma: nocover - raise ValueError("argument is not a ContractApiMessage instance.") - message = cast(ContractApiMessage, message) - return message.ledger_id - - def get_error_message( - self, - exception: Exception, - api: LedgerApi, - message: Message, - dialogue: BaseDialogue, - ) -> ContractApiMessage: - """ - Build an error message. - - :param exception: the exception. - :param api: the Ledger API. - :param message: the request message. - :param dialogue: the Contract API dialogue. - :return: an error message response. - """ - response = cast( - ContractApiMessage, - dialogue.reply( - performative=ContractApiMessage.Performative.ERROR, - target_message=message, - code=500, - message=parse_exception(exception), - data=b"", - ), - ) - return response - - def dispatch_request( - self, - ledger_api: LedgerApi, - message: ContractApiMessage, - dialogue: ContractApiDialogue, - response_builder: Callable[ - [Union[bytes, JSONLike], ContractApiDialogue], ContractApiMessage - ], - ) -> ContractApiMessage: - """ - Dispatch a request to a user-defined contract method. - - :param ledger_api: the ledger apis. - :param message: the contract API request message. - :param dialogue: the contract API dialogue. - :param response_builder: callable that from bytes builds a contract API message. - :return: the response message. - """ - contract = self.contract_registry.make(message.contract_id) - try: - data = self._get_data(ledger_api, message, contract) - response = response_builder(data, dialogue) - except AEAException as exception: - self.logger.debug( - f"Whilst processing the contract api request:\n{message}\nthe following exception occured:\n{str(exception)}" - ) - response = self.get_error_message(exception, ledger_api, message, dialogue) - except ( - Exception # pylint: disable=broad-except # pragma: nocover - ) as exception: - self.logger.debug( - f"Whilst processing the contract api request:\n{message}\nthe following error occured:\n{parse_exception(exception)}" - ) - response = self.get_error_message(exception, ledger_api, message, dialogue) - return response - - def get_state( - self, - ledger_api: LedgerApi, - message: ContractApiMessage, - dialogue: ContractApiDialogue, - ) -> ContractApiMessage: - """ - Send the request 'get_state'. - - :param ledger_api: the API object. - :param message: the Ledger API message - :param dialogue: the contract API dialogue - :return: None - """ - - def build_response( - data: Union[bytes, JSONLike], dialogue: ContractApiDialogue - ) -> ContractApiMessage: - if not isinstance(data, Mapping): - raise ValueError( # pragma: nocover - f"Invalid state type, got={type(data)}, expected={JSONLike}." - ) - return cast( - ContractApiMessage, - dialogue.reply( - performative=ContractApiMessage.Performative.STATE, - state=State(message.ledger_id, data), - ), - ) - - return self.dispatch_request(ledger_api, message, dialogue, build_response) - - def get_deploy_transaction( - self, - ledger_api: LedgerApi, - message: ContractApiMessage, - dialogue: ContractApiDialogue, - ) -> ContractApiMessage: - """ - Send the request 'get_raw_transaction'. - - :param ledger_api: the API object. - :param message: the Ledger API message - :param dialogue: the contract API dialogue - :return: None - """ - - def build_response( - transaction: Union[bytes, JSONLike], dialogue: ContractApiDialogue - ) -> ContractApiMessage: - if not isinstance(transaction, Mapping): - raise ValueError( # pragma: nocover - f"Invalid transaction type, got={type(transaction)}, expected={JSONLike}." - ) - return cast( - ContractApiMessage, - dialogue.reply( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=RawTransaction(message.ledger_id, transaction), - ), - ) - - return self.dispatch_request(ledger_api, message, dialogue, build_response) - - def get_raw_transaction( - self, - ledger_api: LedgerApi, - message: ContractApiMessage, - dialogue: ContractApiDialogue, - ) -> ContractApiMessage: - """ - Send the request 'get_raw_transaction'. - - :param ledger_api: the API object. - :param message: the Ledger API message - :param dialogue: the contract API dialogue - :return: None - """ - - def build_response( - transaction: Union[bytes, JSONLike], dialogue: ContractApiDialogue - ) -> ContractApiMessage: - if isinstance(transaction, bytes): - raise ValueError( # pragma: nocover - f"Invalid transaction type, got={type(transaction)}, expected={JSONLike}." - ) - return cast( - ContractApiMessage, - dialogue.reply( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=RawTransaction(message.ledger_id, transaction), - ), - ) - - return self.dispatch_request(ledger_api, message, dialogue, build_response) - - def get_raw_message( - self, - ledger_api: LedgerApi, - message: ContractApiMessage, - dialogue: ContractApiDialogue, - ) -> ContractApiMessage: - """ - Send the request 'get_raw_message'. - - :param ledger_api: the ledger API object. - :param message: the Ledger API message - :param dialogue: the contract API dialogue - :return: None - """ - - def build_response( - raw_message: Union[bytes, JSONLike], dialogue: ContractApiDialogue - ) -> ContractApiMessage: - if not isinstance(raw_message, bytes): - raise ValueError( # pragma: nocover - f"Invalid message type, got={type(raw_message)}, expected=bytes." - ) - return cast( - ContractApiMessage, - dialogue.reply( - performative=ContractApiMessage.Performative.RAW_MESSAGE, - raw_message=RawMessage(message.ledger_id, raw_message), - ), - ) - - return self.dispatch_request(ledger_api, message, dialogue, build_response) - - def _get_data( - self, - api: LedgerApi, - message: ContractApiMessage, - contract: Contract, - ) -> Union[bytes, JSONLike]: - """Get the data from the contract method, either from the stub or from the callable specified by the message.""" - # first, check if the custom handler for this type of request has been implemented. - data = self._call_stub(api, message, contract) - if data is not None: - return data - - # then, check if there is the handler for the provided callable. - data = self._validate_and_call_callable(api, message, contract) - return data - - @staticmethod - def _call_stub( - ledger_api: LedgerApi, message: ContractApiMessage, contract: Contract - ) -> Optional[Union[bytes, JSONLike]]: - """Try to call stub methods associated to the contract API request performative.""" - try: - method: Callable = getattr(contract, message.performative.value) - if message.performative in [ - ContractApiMessage.Performative.GET_STATE, - ContractApiMessage.Performative.GET_RAW_MESSAGE, - ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ]: - args, kwargs = ( - [ledger_api, message.contract_address], - message.kwargs.body, - ) - elif message.performative in [ # pragma: nocover - ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - ]: - args, kwargs = [ledger_api], message.kwargs.body - else: # pragma: nocover - raise AEAException(f"Unexpected performative: {message.performative}") - data = method(*args, **kwargs) - return data - except (AttributeError, NotImplementedError): - return None - - @staticmethod - def _validate_and_call_callable( - api: LedgerApi, message: ContractApiMessage, contract: Contract - ) -> Union[bytes, JSONLike]: - """ - Validate a Contract callable, given the performative. - - In particular: - - if the performative is either 'get_state' or 'get_raw_transaction', the signature - must accept ledger api as first argument and contract address as second argument, - plus keyword arguments. - - if the performative is either 'get_deploy_transaction' or 'get_raw_message', the signature - must accept ledger api as first argument, plus keyword arguments. - - :param api: the ledger api object. - :param message: the contract api request. - :param contract: the contract instance. - :return: the data generated by the method. - """ - method_to_call: Optional[Callable] = None - try: - method_to_call = getattr(contract, message.callable) - except AttributeError: - _default_logger.info( - f"Contract method {message.callable} not found in the contract package {contract.contract_id}. Checking in the ABI..." - ) - - # Check for the method in the ABI - if not method_to_call: - try: - contract_instance = contract.get_instance(api, message.contract_address) - contract_instance.get_function_by_name(message.callable) - except ValueError: - raise AEAException( - f"Contract method {message.callable} not found in ABI of contract {type(contract)}" - ) - - default_method_call = contract.default_method_call - return default_method_call( # type: ignore - api, - message.contract_address, - snake_to_camel(message.callable), - **message.kwargs.body, - ) - - full_args_spec = inspect.getfullargspec(method_to_call) - if message.performative in [ - ContractApiMessage.Performative.GET_STATE, - ContractApiMessage.Performative.GET_RAW_MESSAGE, - ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ]: - if len(full_args_spec.args) < 2: # pragma: nocover - raise AEAException( - f"Expected two or more positional arguments, got {len(full_args_spec.args)}" - ) - for arg in ["ledger_api", "contract_address"]: # pragma: nocover - if arg not in full_args_spec.args: - raise AEAException( - f"Missing required argument `{arg}` in {method_to_call}" - ) - return method_to_call(api, message.contract_address, **message.kwargs.body) - if message.performative in [ - ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - ]: - if len(full_args_spec.args) < 1: # pragma: nocover - raise AEAException( - f"Expected one or more positional arguments, got {len(full_args_spec.args)}" - ) - if "ledger_api" not in full_args_spec.args: # pragma: nocover - raise AEAException( - f"Missing required argument `ledger_api` in {method_to_call}" - ) - return method_to_call(api, **message.kwargs.body) - 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 = cast(str, kwargs.pop("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 - """ - 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": cast(dict, self._api_configs).copy()} - ) diff --git a/trader_old/vendor/valory/connections/ledger/ledger_dispatcher.py b/trader_old/vendor/valory/connections/ledger/ledger_dispatcher.py deleted file mode 100644 index de927acf7..000000000 --- a/trader_old/vendor/valory/connections/ledger/ledger_dispatcher.py +++ /dev/null @@ -1,474 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2023 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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 the implementation of the ledger API request dispatcher.""" -import asyncio -import logging -from typing import Any, cast - -from aea.common import JSONLike -from aea.connections.base import ConnectionStates -from aea.crypto.base import LedgerApi -from aea.helpers.transaction.base import RawTransaction, State, TransactionDigest -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import Dialogues as BaseDialogues - -from packages.valory.connections.ledger.base import RequestDispatcher -from packages.valory.protocols.ledger_api.custom_types import ( - TransactionDigests, - TransactionReceipt, -) -from packages.valory.protocols.ledger_api.dialogues import LedgerApiDialogue -from packages.valory.protocols.ledger_api.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.protocols.ledger_api.message import LedgerApiMessage - - -_default_logger = logging.getLogger( - "aea.packages.valory.connections.ledger.ledger_dispatcher" -) - - -class LedgerApiDialogues(BaseLedgerApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - # The ledger connection maintains the dialogue on behalf of the ledger - return LedgerApiDialogue.Role.LEDGER - - BaseLedgerApiDialogues.__init__( - self, - self_address=str(kwargs.pop("connection_id")), - role_from_first_message=role_from_first_message, - **kwargs, - ) - - -class LedgerApiRequestDispatcher(RequestDispatcher): - """Implement ledger API request dispatcher.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the dispatcher.""" - logger = kwargs.pop("logger", None) - connection_id = kwargs.pop("connection_id") - logger = logger if logger is not None else _default_logger - super().__init__(logger, *args, **kwargs) - self._ledger_api_dialogues = LedgerApiDialogues(connection_id=connection_id) - - def get_ledger_id(self, message: Message) -> str: - """Get the ledger id from message.""" - if not isinstance(message, LedgerApiMessage): # pragma: nocover - raise ValueError("argument is not a LedgerApiMessage instance.") - message = cast(LedgerApiMessage, message) - if message.performative is LedgerApiMessage.Performative.GET_RAW_TRANSACTION: - ledger_id = message.terms.ledger_id - elif ( - message.performative - is LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION - ): - ledger_id = message.signed_transaction.ledger_id - elif ( - message.performative - is LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS - ): - ledger_id = message.signed_transactions.ledger_id - elif ( - message.performative - is LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT - ): - ledger_id = message.transaction_digest.ledger_id - else: - ledger_id = message.ledger_id - return ledger_id - - @property - def dialogues(self) -> BaseDialogues: - """Get the dialogues.""" - return self._ledger_api_dialogues - - def get_balance( - self, - api: LedgerApi, - message: LedgerApiMessage, - dialogue: LedgerApiDialogue, - ) -> LedgerApiMessage: - """ - Send the request 'get_balance'. - - :param api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - try: - balance = api.get_balance(message.address, raise_on_try=True) - except Exception as e: # pylint: disable=broad-except # pragma: nocover - return self.get_error_message(e, api, message, dialogue) - - if balance is None: - response = self.get_error_message( - ValueError("No balance returned"), api, message, dialogue - ) - else: - response = cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.BALANCE, - target_message=message, - balance=balance, - ledger_id=message.ledger_id, - ), - ) - return response - - def get_state( - self, - api: LedgerApi, - message: LedgerApiMessage, - dialogue: LedgerApiDialogue, - ) -> LedgerApiMessage: - """ - Send the request 'get_state'. - - :param api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - try: - result = api.get_state( - message.callable, - *message.args, - raise_on_try=True, - **message.kwargs.body, - ) - except Exception as e: # pylint: disable=broad-except # pragma: nocover - return self.get_error_message(e, api, message, dialogue) - - if result is None: # pragma: nocover - response = self.get_error_message( - ValueError("Failed to get state"), api, message, dialogue - ) - else: - response = cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.STATE, - target_message=message, - state=State(message.ledger_id, result), - ledger_id=message.ledger_id, - ), - ) - return response - - def get_raw_transaction( - self, - api: LedgerApi, - message: LedgerApiMessage, - dialogue: LedgerApiDialogue, - ) -> LedgerApiMessage: - """ - Send the request 'get_raw_transaction'. - - :param api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - try: - raw_transaction = api.get_transfer_transaction( - sender_address=message.terms.sender_address, - destination_address=message.terms.counterparty_address, - amount=message.terms.sender_payable_amount, - tx_fee=message.terms.fee, - tx_nonce=message.terms.nonce, - raise_on_try=True, - **message.terms.kwargs, - ) - except Exception as e: # pylint: disable=broad-except # pragma: nocover - return self.get_error_message(e, api, message, dialogue) - - if raw_transaction is None: - response = self.get_error_message( - ValueError("No raw transaction returned"), api, message, dialogue - ) - else: - response = cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.RAW_TRANSACTION, - target_message=message, - raw_transaction=RawTransaction( - message.terms.ledger_id, raw_transaction - ), - ), - ) - return response - - async def get_transaction_receipt( - self, - api: LedgerApi, - message: LedgerApiMessage, - dialogue: LedgerApiDialogue, - ) -> LedgerApiMessage: - """ - Send the request 'get_transaction_receipt'. - - NOTE: Under no circumstance can async methods block! - All possible methods that can block here, should be run async. - - :param api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - retry_attempts = ( - self.retry_attempts - if message.retry_attempts is None - else message.retry_attempts - ) - retry_timeout = ( - self.retry_timeout - if message.retry_timeout is None - else message.retry_timeout - ) - - transaction_receipt = None - is_settled = False - attempts = 0 - while ( - not is_settled - and attempts < retry_attempts - and self.connection_state.get() == ConnectionStates.connected - ): - try: - transaction_receipt = await self.wait_for( - lambda: api.get_transaction_receipt( - message.transaction_digest.body, - raise_on_try=True, - ), - timeout=retry_timeout, - ) - except Exception as e: # pylint: disable=broad-except - self.logger.warning(e) - transaction_receipt = None - - if transaction_receipt is not None: - is_settled = api.is_transaction_settled(transaction_receipt) - attempts += 1 - await asyncio.sleep(retry_timeout * attempts) - self.logger.debug( - f"Transaction receipt: {transaction_receipt}, settled: {is_settled}" - ) - - attempts = 0 - transaction = None - while ( - transaction is None - and attempts < retry_attempts - and self.connection_state.get() == ConnectionStates.connected - ): - try: - transaction = await self.wait_for( - lambda: api.get_transaction( - message.transaction_digest.body, - raise_on_try=True, - ), - timeout=retry_timeout, - ) - except Exception as e: # pylint: disable=broad-except - self.logger.warning(e) - transaction = None - - attempts += 1 - await asyncio.sleep(retry_timeout * attempts) - self.logger.debug(f"Transaction: {transaction}") - - if not is_settled: - response = self.get_error_message( - ValueError("Transaction not settled within timeout"), - api, - message, - dialogue, - ) - elif transaction_receipt is None: # pragma: nocover - response = self.get_error_message( - ValueError("No transaction_receipt returned"), api, message, dialogue - ) - elif transaction is None: - response = self.get_error_message( - ValueError("No transaction returned"), api, message, dialogue - ) - else: - response = cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - target_message=message, - transaction_receipt=TransactionReceipt( - message.transaction_digest.ledger_id, - transaction_receipt, - transaction, - ), - ), - ) - return response - - def send_signed_transactions( - self, - api: LedgerApi, - message: LedgerApiMessage, - dialogue: LedgerApiDialogue, - ) -> LedgerApiMessage: - """ - Send the request 'send_signed_transactions'. - - :param api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - try: - signed_transactions = message.signed_transactions.signed_transactions - transaction_digests = api.send_signed_transactions( - signed_transactions, - raise_on_try=True, - **message.kwargs.body, - ) - except Exception as e: # pylint: disable=broad-except # pragma: nocover - return self.get_error_message(e, api, message, dialogue) - - if transaction_digests is None: # pragma: nocover - return self.get_error_message( - ValueError("No transaction_digest returned"), api, message, dialogue - ) - - ledger_id = self.get_ledger_id(message) - return cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGESTS, - target_message=message, - transaction_digests=TransactionDigests(ledger_id, transaction_digests), - ), - ) - - def send_signed_transaction( - self, - api: LedgerApi, - message: LedgerApiMessage, - dialogue: LedgerApiDialogue, - ) -> LedgerApiMessage: - """ - Send the request 'send_signed_tx'. - - :param api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - try: - transaction_digest = api.send_signed_transaction( - message.signed_transaction.body, - raise_on_try=True, - ) - except Exception as e: # pylint: disable=broad-except # pragma: nocover - return self.get_error_message(e, api, message, dialogue) - - if transaction_digest is None: # pragma: nocover - return self.get_error_message( - ValueError("No transaction_digest returned"), api, message, dialogue - ) - - return cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, - target_message=message, - transaction_digest=TransactionDigest( - message.signed_transaction.ledger_id, transaction_digest - ), - ), - ) - - def get_error_message( - self, - exception: Exception, - api: LedgerApi, - message: Message, - dialogue: BaseDialogue, - ) -> LedgerApiMessage: - """ - Build an error message. - - :param exception: the exception. - :param api: the Ledger API. - :param message: the request message. - :param dialogue: the Ledger API dialogue. - :return: an error message response. - """ - message = cast(LedgerApiMessage, message) - dialogue = cast(LedgerApiDialogue, dialogue) - response = cast( - LedgerApiMessage, - dialogue.reply( - performative=LedgerApiMessage.Performative.ERROR, - target_message=message, - code=500, - message=str(exception), - data=b"", - ), - ) - 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 - """ - if not isinstance(message, LedgerApiMessage): # pragma: nocover - raise ValueError("argument is not a LedgerApiMessage instance.") - message = cast(LedgerApiMessage, message) - kwargs = {} - if message.is_set("kwargs"): - # check if kwargs is set - kwargs = cast(JSONLike, message.kwargs.body) - # if the chain id is specified in the message, use it. - # otherwise, use the ledger id. - chain_id = cast(str, kwargs.pop("chain_id", self.get_ledger_id(message))) - return chain_id diff --git a/trader_old/vendor/valory/connections/ledger/tests/__init__.py b/trader_old/vendor/valory/connections/ledger/tests/__init__.py deleted file mode 100644 index 346bbd406..000000000 --- a/trader_old/vendor/valory/connections/ledger/tests/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2023 Valory AG -# Copyright 2018-2020 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/ledger connection.""" diff --git a/trader_old/vendor/valory/connections/ledger/tests/conftest.py b/trader_old/vendor/valory/connections/ledger/tests/conftest.py deleted file mode 100644 index 8f7e518ec..000000000 --- a/trader_old/vendor/valory/connections/ledger/tests/conftest.py +++ /dev/null @@ -1,148 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test confiugurations for the package.""" -# pylint: skip-file - -import logging -from pathlib import Path -from typing import Any, AsyncGenerator, Dict, Generator, cast -from unittest.mock import MagicMock - -import pytest -import pytest_asyncio -from aea_ledger_ethereum import EthereumCrypto -from aea_ledger_ethereum.test_tools.constants import ( - ETHEREUM_TESTNET_CONFIG as _DEFAULT_ETHEREUM_TESTNET_CONFIG, -) -from aea_ledger_ethereum.test_tools.fixture_helpers import ( - DEFAULT_GANACHE_ADDR, - DEFAULT_GANACHE_PORT, -) - -from aea.configurations.base import ComponentType, ContractConfig -from aea.configurations.constants import DEFAULT_LEDGER -from aea.configurations.loader import load_component_configuration -from aea.connections.base import Connection -from aea.contracts.base import Contract, contract_registry -from aea.crypto.ledger_apis import DEFAULT_LEDGER_CONFIGS, LedgerApi -from aea.crypto.registries import ledger_apis_registry, make_crypto -from aea.crypto.wallet import CryptoStore -from aea.identity.base import Identity - - -PACKAGE_DIR = Path(__file__).parent.parent - -DEFAULT_ETHEREUM_TESTNET_CONFIG = { - **_DEFAULT_ETHEREUM_TESTNET_CONFIG, - "default_gas_price_strategy": "eip1559", -} - - -def get_register_contract(directory: Path) -> Contract: - """Get and register the erc1155 contract package.""" - configuration = load_component_configuration(ComponentType.CONTRACT, directory) - configuration._directory = directory # pylint: disable=protected-access - configuration = cast(ContractConfig, configuration) - - if str(configuration.public_id) not in contract_registry.specs: - # load contract into sys modules - Contract.from_config(configuration) - - contract = contract_registry.make(str(configuration.public_id)) - return contract - - -@pytest.fixture() -def ganache_addr() -> str: - """Get the ganache addr""" - return DEFAULT_GANACHE_ADDR - - -@pytest.fixture() -def ganache_port() -> int: - """Get the ganache port""" - return DEFAULT_GANACHE_PORT - - -@pytest.fixture(scope="function") -def ethereum_testnet_config(ganache_addr: str, ganache_port: int) -> Dict: - """Get Ethereum ledger api configurations using Ganache.""" - new_uri = f"{ganache_addr}:{ganache_port}" - new_config = DEFAULT_ETHEREUM_TESTNET_CONFIG.copy() - new_config["address"] = new_uri - return new_config - - -@pytest.fixture(scope="function") -def update_default_ethereum_ledger_api(ethereum_testnet_config: Dict) -> Generator: - """Change temporarily default Ethereum ledger api configurations to interact with local Ganache.""" - old_config = DEFAULT_LEDGER_CONFIGS.pop(EthereumCrypto.identifier) - DEFAULT_LEDGER_CONFIGS[EthereumCrypto.identifier] = ethereum_testnet_config - yield - DEFAULT_LEDGER_CONFIGS.pop(EthereumCrypto.identifier) - DEFAULT_LEDGER_CONFIGS[EthereumCrypto.identifier] = old_config - - -def make_ledger_api_connection( - ethereum_testnet_config: Dict = DEFAULT_ETHEREUM_TESTNET_CONFIG, -) -> Connection: - """Make a connection.""" - crypto = make_crypto(DEFAULT_LEDGER) - identity = Identity("name", crypto.address, crypto.public_key) - crypto_store = CryptoStore() - directory = PACKAGE_DIR - connection = Connection.from_dir( - str(directory), - data_dir=MagicMock(), - identity=identity, - crypto_store=crypto_store, - ) - connection = cast(Connection, connection) - connection._logger = logging.getLogger("packages.valory.connections.ledger") - - # use testnet config - connection.configuration.config.get("ledger_apis", {})[ - "ethereum" - ] = ethereum_testnet_config - - connection.request_retry_attempts = 1 # type: ignore - connection.request_retry_attempts = 2 # type: ignore - return connection - - -@pytest_asyncio.fixture() -async def ledger_apis_connection( - request: Any, ethereum_testnet_config: Dict -) -> AsyncGenerator: - """Make a connection.""" - connection = make_ledger_api_connection(ethereum_testnet_config) - await connection.connect() - yield connection - await connection.disconnect() - - -@pytest.fixture() -def ledger_api( - ethereum_testnet_config: Dict, -) -> Generator[LedgerApi, None, None]: - """Ledger api fixture.""" - ledger_id, config = EthereumCrypto.identifier, ethereum_testnet_config - api = ledger_apis_registry.make(ledger_id, **config) - yield api diff --git a/trader_old/vendor/valory/connections/ledger/tests/test_contract_dispatcher.py b/trader_old/vendor/valory/connections/ledger/tests/test_contract_dispatcher.py deleted file mode 100644 index c5549b73f..000000000 --- a/trader_old/vendor/valory/connections/ledger/tests/test_contract_dispatcher.py +++ /dev/null @@ -1,281 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the tests of the ledger connection module.""" - -from unittest import mock -from unittest.mock import ANY, MagicMock, Mock, patch - -import pytest -from aea_ledger_ethereum import EthereumCrypto - -from aea.common import Address -from aea.crypto.ledger_apis import ETHEREUM_DEFAULT_ADDRESS -from aea.crypto.registries import ledger_apis_registry -from aea.exceptions import AEAException -from aea.helpers.async_utils import AsyncState -from aea.multiplexer import MultiplexerStatus -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue - -from packages.valory.connections.ledger.contract_dispatcher import ( - ContractApiRequestDispatcher, -) - -# pylint: skip-file -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.contract_api.dialogues import ContractApiDialogue -from packages.valory.protocols.contract_api.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) - - -SOME_SKILL_ID = "some/skill:0.1.0" -NON_BLOCKING_TIME = 1 -BLOCKING_TIME = 100 -TOLERANCE = 1 -WAIT_TIME_AMONG_TASKS = 0.1 - - -class ContractApiDialogues(BaseContractApiDialogues): - """This class keeps track of all contract_api dialogues.""" - - def __init__(self, self_address: str) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> Dialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return ContractApiDialogue.Role.AGENT - - BaseContractApiDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - ) - - -def test_validate_and_call_callable() -> None: - """Tests a default method call through ContractApiRequestDispatcher.""" - - dummy_address = "0x0000000000000000000000000000000000000000" - contract_dispatcher = ContractApiRequestDispatcher( - connection_id=Mock(), connection_state=AsyncState() - ) - contract = Mock() - - def getAddress(ledger_api=None, contract_address=None, _addr=None): # type: ignore - return 0 - - contract.getAddress = getAddress - contract.dummy_method = None - contract_instance = Mock() - contract.get_instance.return_value = contract_instance - - ledger_api = ledger_apis_registry.make( - EthereumCrypto.identifier, - address=ETHEREUM_DEFAULT_ADDRESS, - ) - - message = MagicMock() - message.performative = ContractApiMessage.Performative.GET_STATE - message.kwargs.body = {"_addr": dummy_address} - - message.contract_address = dummy_address - - message.callable = "some" - contract.some = None - contract.default_method_call = lambda x, y, z, _addr: 12 - contract.get_state = Mock(side_effect=AttributeError()) - with patch.object( - contract_dispatcher.contract_registry, "make", return_value=contract - ): - assert ( - contract_dispatcher.dispatch_request( - dialogue=Mock(), - ledger_api=ledger_api, - message=message, - response_builder=lambda x, y: 12, # type: ignore - ) - == 12 - ) - - contract.some = Mock(side_effect=AEAException("expected")) - dialogue = Mock() - dialogue.reply = Mock(return_value=1234) - with patch.object( - contract_dispatcher.contract_registry, "make", return_value=contract - ): - assert ( - contract_dispatcher.dispatch_request( - dialogue=dialogue, - ledger_api=ledger_api, - message=message, - response_builder=lambda x, y: 12, # type: ignore - ) - == 1234 - ) - dialogue.reply.assert_called_once_with( - performative=ContractApiMessage.Performative.ERROR, - target_message=ANY, - code=500, - message=ANY, - data=ANY, - ) - - message.callable = "getAddress" - # Call a method present in the ABI but not in the contract package - with mock.patch("web3.contract.contract.ContractFunction.call", return_value=0): - result = ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, contract - ) - assert result == 0 - - # Call an non-existent method - message.callable = "dummy_method" - contract_instance.get_function_by_name = Mock(side_effect=ValueError()) - with pytest.raises( - AEAException, - match=f"Contract method dummy_method not found in ABI of contract {type(contract)}", - ): - ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, contract - ) - - message.performative = None - message.callable = "getAddress" - with pytest.raises(AEAException, match="Unexpected performative:"): - ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, contract - ) - - message.callable = "some_fn" - message.performative = ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION - contract.some_fn = lambda x: None - with pytest.raises(AEAException, match="Missing required argument `ledger_api`"): - ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, contract - ) - - contract.some_fn = lambda: None - with pytest.raises( - AEAException, match="Expected one or more positional arguments, got 0" - ): - ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, contract - ) - - contract.some_fn = lambda ledger_api, _addr: None - ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, contract - ) - - with pytest.raises( - AttributeError, - ): - ContractApiRequestDispatcher._validate_and_call_callable( - ledger_api, message, None # type: ignore - ) - - -def test_build_response_fails_on_bad_data_type() -> None: - """Test internal build_response functions for data type check.""" - dispatcher = ContractApiRequestDispatcher(MagicMock(), connection_id="test_id") - with patch.object( - dispatcher, - "dispatch_request", - lambda x, x1, x2, fn: fn(data=b"some_data", dialogue=MagicMock()), - ), pytest.raises( - ValueError, match=r"Invalid state type, got=, expected=typing.Dict" - ): - dispatcher.get_state(MagicMock(), MagicMock(), MagicMock()) - - with patch.object( - dispatcher, - "dispatch_request", - lambda x, x1, x2, fn: fn(raw_message=12, dialogue=MagicMock()), - ), pytest.raises(ValueError, match=r"Invalid message type"): - dispatcher.get_raw_message(MagicMock(), MagicMock(), MagicMock()) - - with patch.object( - dispatcher, - "dispatch_request", - lambda x, x1, x2, fn: fn(transaction=b"some_data", dialogue=MagicMock()), - ): - with pytest.raises( - ValueError, - match=r"Invalid transaction type, got=, expected=typing.Dict", - ): - dispatcher.get_deploy_transaction(MagicMock(), MagicMock(), MagicMock()) - with pytest.raises( - ValueError, - match=r"Invalid transaction type, got=, expected=typing.Dict", - ): - dispatcher.get_raw_transaction(MagicMock(), MagicMock(), MagicMock()) - - -@pytest.mark.asyncio -async def test_run_async() -> None: - """Test run async error handled.""" - - # for pydocstyle - def _raise(): # type: ignore - raise Exception("Expected") - - contract_api_dialogues = ContractApiDialogues(SOME_SKILL_ID) - request, dialogue = contract_api_dialogues.create( - counterparty="str(ledger_apis_connection.connection_id)", - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ledger_id=EthereumCrypto.identifier, - contract_id=str(SOME_SKILL_ID), - contract_address="test addr", - callable="get_create_batch_transaction", - kwargs=ContractApiMessage.Kwargs( - { - "deployer_address": "test_addr", - "token_ids": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - } - ), - ) - api = None - msg = await ContractApiRequestDispatcher( - MultiplexerStatus(), connection_id="test_id" - ).run_async( - _raise, api, request, dialogue # type: ignore - ) - assert msg.performative == ContractApiMessage.Performative.ERROR # type: ignore - - -@pytest.mark.asyncio -async def test_get_handler() -> None: - """Test failed to get handler.""" - with pytest.raises(Exception, match="Performative not recognized."): - ContractApiRequestDispatcher( - MultiplexerStatus(), connection_id="test_id" - ).get_handler(ContractApiMessage.Performative.ERROR) diff --git a/trader_old/vendor/valory/connections/ledger/tests/test_ledger.py b/trader_old/vendor/valory/connections/ledger/tests/test_ledger.py deleted file mode 100644 index ddfd8e75c..000000000 --- a/trader_old/vendor/valory/connections/ledger/tests/test_ledger.py +++ /dev/null @@ -1,623 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the tests of the ledger connection module.""" - -import asyncio -import logging -import time -from asyncio import Task -from threading import Thread -from typing import Any, Callable, Dict, FrozenSet, Tuple, Type, cast -from unittest import mock - -import pytest -from aea_ledger_ethereum import EthereumCrypto - -from aea.common import Address -from aea.configurations.base import ConnectionConfig -from aea.connections.base import ConnectionStates -from aea.crypto.base import LedgerApi -from aea.exceptions import AEAEnforceError -from aea.helpers.async_utils import AsyncState -from aea.mail.base import Envelope -from aea.multiplexer import Multiplexer -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.connections.ledger.base import RequestDispatcher -from packages.valory.connections.ledger.connection import LedgerConnection, PUBLIC_ID -from packages.valory.connections.ledger.ledger_dispatcher import ( - LedgerApiRequestDispatcher, -) -from packages.valory.connections.ledger.tests.conftest import make_ledger_api_connection - -# pylint: skip-file -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.protocols.ledger_api.custom_types import Kwargs - - -SOME_SKILL_ID = "some/skill:0.1.0" -NON_BLOCKING_TIME = 1 -BLOCKING_TIME = 100 -TOLERANCE = 1 -WAIT_TIME_AMONG_TASKS = 0.1 - - -def dummy_task_wrapper(waiting_time: float, result_message: LedgerApiMessage) -> Task: - """Create a dummy task that simply waits for a given `waiting_time` and returns a given `result_message`.""" - - async def dummy_task(*_: Any) -> LedgerApiMessage: - """Wait for the given `waiting_time` and return the given `result_message`.""" - await asyncio.sleep(waiting_time) - return result_message - - task = asyncio.create_task(dummy_task()) - return task - - -class TestLedgerConnection: - """Test `LedgerConnection` class.""" - - @pytest.mark.asyncio - async def test_not_hanging(self) -> None: - """Test that the connection does not hang and that the tasks cannot get blocked.""" - # create configurations for the test, re bocking and non-blocking tasks' waiting times - assert ( - NON_BLOCKING_TIME + TOLERANCE + WAIT_TIME_AMONG_TASKS < BLOCKING_TIME - ), "`NON_BLOCKING_TIME + TOLERANCE + WAIT_TIME_AMONG_TASKS` should be less than the `BLOCKING_TIME`." - - # setup a dummy ledger connection - ledger_connection = LedgerConnection( - configuration=ConnectionConfig("ledger", "valory", "0.19.0"), - data_dir="test_data_dir", - ) - - # connect() is called by the multiplexer - await ledger_connection.connect() - - # once a connection is ready, `receive()` is called by the multiplexer - receive_task = asyncio.ensure_future(ledger_connection.receive()) - - # create a blocking task lasting `BLOCKING_TIME` secs - blocking_task = dummy_task_wrapper( - BLOCKING_TIME, - LedgerApiMessage( - LedgerApiMessage.Performative.ERROR, - _body={"data": b"blocking_task"}, # type: ignore - ), - ) - blocking_dummy_envelope = Envelope( - to="test_blocking_to", - sender="test_blocking_sender", - message=LedgerApiMessage( - LedgerApiMessage.Performative.ERROR - ), # type: ignore - ) - with mock.patch.object( - LedgerConnection, "_schedule_request", return_value=blocking_task - ): - await ledger_connection.send(blocking_dummy_envelope) - - # create a non-blocking task lasting `NON_BLOCKING_TIME` secs, after `WAIT_TIME_AMONG_TASKS` - await asyncio.sleep(WAIT_TIME_AMONG_TASKS) - normal_task = dummy_task_wrapper( - NON_BLOCKING_TIME, - LedgerApiMessage( - LedgerApiMessage.Performative.ERROR, _body={"data": b"normal_task"} - ), # type: ignore - ) - normal_dummy_envelope = Envelope( - to="test_normal_to", - sender="test_normal_sender", - message=LedgerApiMessage( - LedgerApiMessage.Performative.ERROR - ), # type: ignore - ) - with mock.patch.object( - LedgerConnection, "_schedule_request", return_value=normal_task - ): - await ledger_connection.send(normal_dummy_envelope) - - # sleep for `NON_BLOCKING_TIME + TOLERANCE` - await asyncio.sleep(NON_BLOCKING_TIME + TOLERANCE) - - # the normal task should be finished - assert normal_task.done(), "Normal task should be done at this point." - - # the `receive_task` should be done, and not await for the `blocking_task` - assert receive_task.done(), "Receive task is blocked by blocking task!" - - # the blocking task should not be done - assert not blocking_task.done(), "Blocking task should be still running." - # cancel remaining task before ending test - blocking_task.cancel() - - -class TestRequestDispatcher: - """Test `RequestDispatcher` class.""" - - dispatcher: RequestDispatcher - loop: asyncio.AbstractEventLoop - - def setup(self) -> None: - """Setup test vars.""" - logger = logging.getLogger(type(self).__class__.__name__) - state = AsyncState(ConnectionStates.connected) - self.loop = asyncio.get_event_loop() - self.dispatcher = DummyRequestDispatcher( - logger=logger, connection_state=state, loop=self.loop - ) - - def dummy_func(self, sleep: float) -> bool: - """A dummy function that sleeps and returns True.""" - time.sleep(sleep) - return True - - async def dummy_async_func(self, sleep: float) -> bool: - """A dummy async function that sleeps and returns True.""" - await asyncio.sleep(sleep) - return True - - @pytest.mark.asyncio - async def test_wait_for_happy_path(self) -> None: - """Tests that wait_for works when timeout is bigger than execution time of callable.""" - should_finish_in = 0.5 - tolerance = 0.5 - timeout = should_finish_in + tolerance - - return_value = await self.dispatcher.wait_for( - lambda: self.dummy_func(should_finish_in), timeout=timeout - ) - assert return_value, "dummy_func() should've returned True" - - @pytest.mark.asyncio - async def test_wait_for_raise_excp(self) -> None: - """Tests that wait_for works when timeout is less than execution time of callable.""" - timeout = 0.25 - timeout_increase = 0.5 - should_finish_in = timeout + timeout_increase - - with pytest.raises(asyncio.TimeoutError): - await self.dispatcher.wait_for( - lambda: self.dummy_func(should_finish_in), timeout=timeout - ) - - @pytest.mark.asyncio - async def test_wait_for_coroutine(self) -> None: - """Tests that an error is thrown when a coroutine is passed.""" - should_finish_in = 0.0 # this value is irrelevant to the result of the test - with pytest.raises(AEAEnforceError): - await self.dispatcher.wait_for(self.dummy_async_func, should_finish_in) - - -class DummyLedgerApiMessage(LedgerApiMessage): - """Implement a dummy `LedgerApiMessage`, which contains performatives for the normal and blocking tasks.""" - - class Performative(Message.Performative): - """Performatives for the ledger_api protocol.""" - - NORMAL = "normal" - BLOCKING = "blocking" - GET_NORMAL = "get_normal" - GET_BLOCKING = "get_blocking" - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """Initialise an instance of `DummyLedgerApiMessage`.""" - Message.__init__( - self, - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=DummyLedgerApiMessage.Performative(performative), - **kwargs, - ) - - def _is_consistent(self) -> bool: - """Dummy consistency checks.""" - return True - - -class DummyLedgerApiDialogue(Dialogue): - """Implement a dummy `LedgerApiDialogue`.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - DummyLedgerApiMessage.Performative.GET_NORMAL, - DummyLedgerApiMessage.Performative.GET_BLOCKING, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - DummyLedgerApiMessage.Performative.NORMAL, - DummyLedgerApiMessage.Performative.BLOCKING, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - DummyLedgerApiMessage.Performative.GET_NORMAL: frozenset( - {DummyLedgerApiMessage.Performative.NORMAL} - ), - DummyLedgerApiMessage.Performative.GET_BLOCKING: frozenset( - {DummyLedgerApiMessage.Performative.BLOCKING} - ), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a ledger_api dialogue.""" - - AGENT = "agent" - - class EndState(Dialogue.EndState): - """This class defines the end states of a ledger_api dialogue.""" - - SUCCESSFUL = 0 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[DummyLedgerApiMessage] = DummyLedgerApiMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class DummyLedgerApiDialogues(Dialogues): - """Implement a dummy `LedgerApiDialogues`.""" - - END_STATES = frozenset({DummyLedgerApiDialogue.EndState.SUCCESSFUL}) - - def __init__(self, self_address: Address, **kwargs: Any) -> None: - """Initialize dialogues.""" - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> Dialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message""" - return DummyLedgerApiDialogue.Role.AGENT - - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - role_from_first_message=role_from_first_message, - message_class=DummyLedgerApiMessage, - dialogue_class=DummyLedgerApiDialogue, - ) - - -class DummyRequestDispatcher(RequestDispatcher): - """Implement a dummy request dispatcher.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the dispatcher.""" - super().__init__(*args, **kwargs) - self.block = True - self._ledger_api_dialogues = DummyLedgerApiDialogues( - LedgerConnection.connection_id.__str__() - ) - - @staticmethod - def get_normal( - _api: LedgerApi, - message: DummyLedgerApiMessage, - dialogue: DummyLedgerApiDialogue, - ) -> DummyLedgerApiMessage: - """ - Send the request 'get_normal'. - - :param _api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - time.sleep(NON_BLOCKING_TIME) - - return cast( - DummyLedgerApiMessage, - dialogue.reply( - performative=DummyLedgerApiMessage.Performative.NORMAL, # type: ignore - target_message=message, - data=b"normal_task", - ledger_id=message.ledger_id, - ), - ) - - def get_blocking( - self, - _api: LedgerApi, - message: DummyLedgerApiMessage, - dialogue: DummyLedgerApiDialogue, - ) -> DummyLedgerApiMessage: - """ - Send the request 'get_blocking'. - - :param _api: the API object. - :param message: the Ledger API message - :param dialogue: the Ledger API dialogue - :return: response Ledger API message - """ - while self.block: - time.sleep(0.05) - - return cast( - DummyLedgerApiMessage, - dialogue.reply( - performative=DummyLedgerApiMessage.Performative.BLOCKING, # type: ignore - target_message=message, - data=b"blocking_task", - ledger_id=message.ledger_id, - ), - ) - - @property - def dialogues(self) -> Dialogues: - """Dummy dialogues property.""" - return self._ledger_api_dialogues - - def get_error_message( - self, exception: Exception, api: LedgerApi, message: Message, dialogue: Dialogue - ) -> Message: - """Dummy `get_error_message`.""" - return cast( - DummyLedgerApiMessage, - dialogue.reply( - performative=DummyLedgerApiMessage.Performative.ERROR, # type: ignore - target_message=message, - data=f"{exception}".encode("utf-8"), - ledger_id=cast(DummyLedgerApiMessage, message).ledger_id, - ), - ) - - def get_ledger_id(self, message: Message) -> str: - """Dummy `get_ledger_id`.""" - if not isinstance(message, DummyLedgerApiMessage): # pragma: nocover - raise ValueError("argument is not a `DummyLedgerApiMessage` instance.") - return message.ledger_id - - def get_chain_id(self, message: Message) -> str: - """Extract the chain id from the message.""" - return self.get_ledger_id(message=message) - - -class LedgerConnectionWithDummyDispatcher(LedgerConnection): - """An extended `LedgerConnection` which utilizes the `DummyDispatcher`.""" - - async def connect(self) -> None: - """Set up the connection.""" - if self.is_connected: # pragma: nocover - return - - self.state = ConnectionStates.connecting - - self._ledger_dispatcher = DummyRequestDispatcher( # type: ignore - logger=self.logger, - connection_state=self._state, - loop=self.loop, - api_configs=self.api_configs, - retry_attempts=self.request_retry_attempts, - retry_timeout=self.request_retry_timeout, - ) - - self._response_envelopes = asyncio.Queue() - self.state = ConnectionStates.connected - - -class TestLedgerConnectionWithMultiplexer: - """Test `LedgerConnection` class, using the multiplexer.""" - - running_loop: asyncio.AbstractEventLoop - thread_loop: Thread - multiplexer: Multiplexer - ledger_connection: LedgerConnectionWithDummyDispatcher - make_ledger_connection_callable: Callable = make_ledger_api_connection - ledger_api_dialogues: DummyLedgerApiDialogues - - @classmethod - def setup_class(cls) -> None: - """Setup the test class.""" - # set up a multiplexer with the required ledger connection - cls.running_loop = asyncio.new_event_loop() - cls.thread_loop = Thread(target=cls.running_loop.run_forever) - cls.thread_loop.start() - cls.multiplexer = Multiplexer( - [ - LedgerConnectionWithDummyDispatcher( - configuration=ConnectionConfig("ledger", "valory", "0.19.0"), - data_dir="test_data_dir", - ) - ], - loop=cls.running_loop, - ) - cls.multiplexer.connect() - # the ledger connection's connect() is called by the multiplexer - # once a connection is ready, `receive()` is called by the multiplexer - cls.ledger_connection = cast( - LedgerConnectionWithDummyDispatcher, cls.multiplexer.connections[0] - ) - assert cls.ledger_connection._ledger_dispatcher is not None - cls.ledger_api_dialogues = cast( - DummyLedgerApiDialogues, - cls.ledger_connection._ledger_dispatcher._ledger_api_dialogues, - ) - - @classmethod - def teardown_class(cls) -> None: - """Tear down the multiplexer.""" - cls.ledger_connection._ledger_dispatcher.block = False # type: ignore - if cls.multiplexer.is_connected: - cls.multiplexer.disconnect() - cls.running_loop.call_soon_threadsafe(cls.running_loop.stop) - cls.thread_loop.join() - - def create_ledger_dialogues( - self, blocking: bool = True - ) -> Tuple[DummyLedgerApiMessage, DummyLedgerApiDialogues]: - """Create a dialogue.""" - if blocking: - performative = DummyLedgerApiMessage.Performative.GET_BLOCKING - _callable = "get_blocking" - else: - performative = DummyLedgerApiMessage.Performative.GET_NORMAL - _callable = "get_normal" - - return cast( - Tuple[DummyLedgerApiMessage, DummyLedgerApiDialogues], - self.ledger_api_dialogues.create( - counterparty=str(self.ledger_connection.connection_id), - performative=performative, # type: ignore - ledger_id=EthereumCrypto.identifier, - callable=_callable, - args=(), - kwargs=Kwargs({}), - ), - ) - - @staticmethod - def create_envelope(request: DummyLedgerApiMessage) -> Envelope: - """Create a dummy envelope.""" - return Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - @pytest.mark.asyncio - async def test_not_hanging_with_multiplexer(self) -> None: - """Test that the connection does not hang and that the tasks cannot get blocked, using the multiplexer.""" - # create configurations for the test, re bocking and non-blocking tasks' waiting times - assert ( - NON_BLOCKING_TIME + TOLERANCE + WAIT_TIME_AMONG_TASKS < BLOCKING_TIME - ), "`NON_BLOCKING_TIME + TOLERANCE + WAIT_TIME_AMONG_TASKS` should be less than the `blocking_time`." - assert self.ledger_connection._ledger_dispatcher.block # type: ignore - - # create a blocking task lasting `BLOCKING_TIME` secs - request, _ = self.create_ledger_dialogues() - request._sender = SOME_SKILL_ID - blocking_dummy_envelope = TestLedgerConnectionWithMultiplexer.create_envelope( - request - ) - self.multiplexer.put(blocking_dummy_envelope) - - # create a non-blocking task lasting `NON_BLOCKING_TIME` secs, after `WAIT_TIME_AMONG_TASKS` - await asyncio.sleep(WAIT_TIME_AMONG_TASKS) - - request, _ = self.create_ledger_dialogues(blocking=False) - request._sender = SOME_SKILL_ID - normal_dummy_envelope = TestLedgerConnectionWithMultiplexer.create_envelope( - request - ) - self.multiplexer.put(normal_dummy_envelope) - - # the response envelopes of the ledger connection should be empty - assert ( - self.ledger_connection.response_envelopes.empty() - ), "The response envelopes of the ledger connection should be empty." - # `receive()` should not be done, - # and multiplexer's `_receiving_loop` should be still running and have an empty `in_queue` - assert ( - len(self.multiplexer.in_queue.queue) == 0 - ), "The multiplexer's `in_queue` should not contain anything." - - # sleep for `NON_BLOCKING_TIME + TOLERANCE` - await asyncio.sleep(NON_BLOCKING_TIME + TOLERANCE) - - # `receive()` should be done, - # and multiplexer's `_receiving_loop` should have put the `normal_dummy_envelope` in the `in_queue` - envelope = self.multiplexer.get(block=True) - assert envelope is not None - message = envelope.message - assert isinstance(message, DummyLedgerApiMessage) - assert ( - message.data == b"normal_task" - ), "Normal task should be the first item in the multiplexer's `in_queue`." - assert self.ledger_connection._ledger_dispatcher.block # type: ignore - - -@pytest.mark.asyncio -async def test_request_dispatcher_run_async() -> None: - """Test request dispatcher run async.""" - dispatcher = LedgerApiRequestDispatcher( - logger=mock.Mock(), connection_id=PUBLIC_ID, connection_state=AsyncState() - ) - assert ( - await dispatcher.run_async( - lambda x, y, z: 12, mock.Mock(), mock.Mock(), mock.Mock() # type: ignore - ) - == 12 - ) - - def raise_exc(*args): # type: ignore - raise ValueError("expected") - - dialogue = mock.Mock() - dialogue.reply = mock.Mock(return_value=124) - assert ( - await dispatcher.run_async( - raise_exc, mock.Mock(), mock.Mock(), dialogue=dialogue - ) - == 124 - ) - dialogue.reply.assert_called_once_with( - performative=mock.ANY, - target_message=mock.ANY, - code=500, - message="expected", - data=b"", - ) - - -def test_ledger_connection_exceptions() -> None: - """Test exception.""" - configuration = mock.Mock() - configuration.public_id = LedgerConnection.connection_id - connection = LedgerConnection(data_dir="", configuration=configuration) - with pytest.raises( - ValueError, - match="`asyncio.Queue` for `_response_envelopes` not set. Is the ledger connection active?", - ): - connection.response_envelopes - - envelope = mock.Mock() - envelope.protocol_specification_id = ContractApiMessage.protocol_specification_id - connection._contract_dispatcher = mock.Mock() - connection._contract_dispatcher.dispatch.return_value = 12 - assert connection._schedule_request(envelope) == 12 diff --git a/trader_old/vendor/valory/connections/ledger/tests/test_ledger_api.py b/trader_old/vendor/valory/connections/ledger/tests/test_ledger_api.py deleted file mode 100644 index c7b85f2df..000000000 --- a/trader_old/vendor/valory/connections/ledger/tests/test_ledger_api.py +++ /dev/null @@ -1,682 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2023 Valory AG -# Copyright 2018-2019 Fetch.AI Limited -# -# 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 the tests of the ledger API connection module.""" -# pylint: skip-file - -import asyncio -import logging -import platform -import time -from pathlib import Path -from typing import Any, Dict, List, Optional, cast -from unittest.mock import Mock, patch - -import pytest -from aea_ledger_ethereum import EthereumCrypto -from aea_ledger_ethereum.test_tools.constants import ETHEREUM_PRIVATE_KEY_PATH -from aea_ledger_ethereum.test_tools.fixture_helpers import ( # noqa: F401 pylint: disable=unsed-import - DEFAULT_GANACHE_CHAIN_ID, - ganache, -) -from web3.eth import Eth - -from aea.common import Address -from aea.configurations.data_types import PublicId -from aea.connections.base import Connection, ConnectionStates -from aea.crypto.ledger_apis import LedgerApis -from aea.crypto.registries import make_crypto, make_ledger_api -from aea.helpers.async_utils import AsyncState -from aea.helpers.transaction.base import ( - RawTransaction, - SignedTransaction, - Terms, - TransactionDigest, - TransactionReceipt, -) -from aea.mail.base import Envelope, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue - -from packages.valory.connections.ledger.connection import LedgerConnection -from packages.valory.connections.ledger.ledger_dispatcher import ( - LedgerApiRequestDispatcher, -) -from packages.valory.protocols.ledger_api.custom_types import ( - Kwargs, - SignedTransactions, - TransactionDigests, -) -from packages.valory.protocols.ledger_api.dialogues import LedgerApiDialogue -from packages.valory.protocols.ledger_api.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.protocols.ledger_api.message import LedgerApiMessage - - -SOME_SKILL_ID = "some/skill:0.1.0" -PACKAGE_DIR = Path(__file__).parent.parent - -skip_docker_tests = pytest.mark.skipif( - platform.system() != "Linux", - reason="Docker daemon is not available in Windows and macOS CI containers.", -) -logger = logging.getLogger(__name__) -ledger_ids = pytest.mark.parametrize( - "ledger_id,address", - [ - (EthereumCrypto.identifier, EthereumCrypto(ETHEREUM_PRIVATE_KEY_PATH).address), - ], -) -# TODO: uncomment gas station strategy config after the gasstation API start -gas_strategies = pytest.mark.parametrize( - "gas_strategies", - [ - {"gas_price_strategy": None}, - # {"gas_price_strategy": "gas_station"}, # noqa:E800 - {"gas_price_strategy": "eip1559"}, - { - "max_fee_per_gas": 1_000_000_000, - "max_priority_fee_per_gas": 1_000_000_000, - }, - ], -) - - -class LedgerApiDialogues(BaseLedgerApiDialogues): - """The dialogues class keeps track of all ledger_api dialogues.""" - - def __init__(self, self_address: Address, **kwargs: Any) -> None: - """Initialize dialogues.""" - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message""" - return LedgerApiDialogue.Role.AGENT - - BaseLedgerApiDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - ) - - -@pytest.mark.usefixtures("ganache") -@skip_docker_tests -class TestLedgerDispatcher: - """Tests for ledger dispatcher.""" - - @pytest.mark.asyncio - @ledger_ids - async def test_get_balance( - self, - ledger_id: str, - address: str, - ledger_apis_connection: Connection, - update_default_ethereum_ledger_api: None, - ethereum_testnet_config: Dict, - ) -> None: - """Test get balance method.""" - - config = ethereum_testnet_config - ledger_api_dialogues = LedgerApiDialogues(SOME_SKILL_ID) - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.GET_BALANCE, # type: ignore - ledger_id=ledger_id, - address=address, - ) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_msg = cast(LedgerApiMessage, response.message) - response_dialogue = ledger_api_dialogues.update(response_msg) - assert response_dialogue == ledger_api_dialogue - assert response_msg.performative == LedgerApiMessage.Performative.BALANCE - actual_balance_amount = response_msg.balance - expected_balance_amount = make_ledger_api(ledger_id, **config).get_balance( - address - ) - assert actual_balance_amount == expected_balance_amount - - @pytest.mark.asyncio - @ledger_ids - async def test_get_state( - self, - ledger_id: str, - address: str, - ledger_apis_connection: Connection, - update_default_ethereum_ledger_api: None, - ethereum_testnet_config: Dict, - ) -> None: - """Test get state.""" - - config = ethereum_testnet_config - - if "ethereum" in ledger_id: - callable_name = "get_block" - else: - callable_name = "blocks" - args = ("latest",) - kwargs = Kwargs({}) - - ledger_api_dialogues = LedgerApiDialogues(SOME_SKILL_ID) - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.GET_STATE, # type: ignore - ledger_id=ledger_id, - callable=callable_name, - args=args, - kwargs=kwargs, - ) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_msg = cast(LedgerApiMessage, response.message) - response_dialogue = ledger_api_dialogues.update(response_msg) - assert response_dialogue == ledger_api_dialogue - - assert ( - response_msg.performative == LedgerApiMessage.Performative.STATE - ), response_msg - actual_block = response_msg.state.body - expected_block = make_ledger_api(ledger_id, **config).get_state( - callable_name, *args - ) - assert actual_block == expected_block - - @pytest.mark.asyncio - @gas_strategies - async def test_get_raw_transaction( - self, - gas_strategies: Dict, - ledger_apis_connection: Connection, - update_default_ethereum_ledger_api: None, - ) -> None: - """Test get raw transaction with Ethereum APIs.""" - import aea # noqa # to load registries - - crypto1 = make_crypto( - EthereumCrypto.identifier, private_key_path=ETHEREUM_PRIVATE_KEY_PATH - ) - crypto2 = make_crypto(EthereumCrypto.identifier) - ledger_api_dialogues = LedgerApiDialogues(SOME_SKILL_ID) - - amount = 40000 - fee = 10**7 - - # Create ledger_api dialogue: get raw transaction - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - terms=Terms( - ledger_id=EthereumCrypto.identifier, - sender_address=crypto1.address, - counterparty_address=crypto2.address, - amount_by_currency_id={"ETH": -amount}, - quantities_by_good_id={"some_service_id": 1}, - is_sender_payable_tx_fee=True, - nonce="", - fee_by_currency_id={"ETH": fee}, - chain_id=DEFAULT_GANACHE_CHAIN_ID, - **gas_strategies, - ), - ) - request = cast(LedgerApiMessage, request) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - - # Raw transaction - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_message = cast(LedgerApiMessage, response.message) - assert ( - response_message.performative - == LedgerApiMessage.Performative.RAW_TRANSACTION - ) - response_dialogue = ledger_api_dialogues.update(response_message) - assert response_dialogue == ledger_api_dialogue - assert isinstance(response_message.raw_transaction, RawTransaction) - assert response_message.raw_transaction.ledger_id == request.terms.ledger_id - - @pytest.mark.asyncio - @gas_strategies - async def test_send_signed_transaction_ethereum( - self, gas_strategies: Dict, ledger_apis_connection: LedgerConnection - ) -> None: - """Test send signed transaction with Ethereum APIs.""" - ledger_api_dialogues = LedgerApiDialogues(SOME_SKILL_ID) - - crypto1 = make_crypto( - EthereumCrypto.identifier, private_key_path=ETHEREUM_PRIVATE_KEY_PATH - ) - crypto2 = make_crypto(EthereumCrypto.identifier) - - # First, send a transaction so we can get a digest at the end - amount = 40000 - fee = 10**7 - - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - terms=Terms( - ledger_id=EthereumCrypto.identifier, - sender_address=crypto1.address, - counterparty_address=crypto2.address, - amount_by_currency_id={"ETH": -amount}, - quantities_by_good_id={"some_service_id": 1}, - is_sender_payable_tx_fee=True, - nonce="", - fee_by_currency_id={"ETH": fee}, - chain_id=DEFAULT_GANACHE_CHAIN_ID, - **gas_strategies, - ), - ) - request = cast(LedgerApiMessage, request) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - # Check that we got the correct transaction response - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_message = cast(LedgerApiMessage, response.message) - assert ( - response_message.performative - == LedgerApiMessage.Performative.RAW_TRANSACTION - ) - response_dialogue = ledger_api_dialogues.update(response_message) - assert response_dialogue == ledger_api_dialogue - assert isinstance(response_message.raw_transaction, RawTransaction) - assert response_message.raw_transaction.ledger_id == request.terms.ledger_id - - # Sign the transaction - signed_transaction = crypto1.sign_transaction( - response_message.raw_transaction.body - ) - - # Create new dialogue starting with signed transaction - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, # type: ignore - signed_transaction=SignedTransaction( - EthereumCrypto.identifier, signed_transaction - ), - ) - request = cast(LedgerApiMessage, request) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - - # Transaction digest - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_message = cast(LedgerApiMessage, response.message) - assert ( - response_message.performative != LedgerApiMessage.Performative.ERROR - ), f"Received error: {response_message.message}" - assert ( - response_message.performative - == LedgerApiMessage.Performative.TRANSACTION_DIGEST - ) - response_dialogue = ledger_api_dialogues.update(response_message) - assert response_dialogue == ledger_api_dialogue - assert isinstance(response_message.transaction_digest, TransactionDigest) - assert isinstance(response_message.transaction_digest.body, str) - assert ( - response_message.transaction_digest.ledger_id - == request.signed_transaction.ledger_id - ) - await asyncio.sleep(0.01) - # Create new dialogue starting with GET_TRANSACTION_RECEIPT - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, # type: ignore - transaction_digest=response_message.transaction_digest, - ) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - - # Transaction receipt - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_message = cast(LedgerApiMessage, response.message) - assert ( - response_message.performative - == LedgerApiMessage.Performative.TRANSACTION_RECEIPT - ) - response_dialogue = ledger_api_dialogues.update(response_message) - assert response_dialogue == ledger_api_dialogue - assert isinstance(response_message.transaction_receipt, TransactionReceipt) - assert response_message.transaction_receipt.receipt is not None - assert response_message.transaction_receipt.transaction is not None - assert ( - response_message.transaction_receipt.ledger_id - == request.transaction_digest.ledger_id # type: ignore - ) - assert LedgerApis.is_transaction_settled( - response_message.transaction_receipt.ledger_id, - response_message.transaction_receipt.receipt, - ), "Transaction not settled." - - @pytest.mark.asyncio - async def test_send_signed_transactions( - self, ledger_apis_connection: LedgerConnection - ) -> None: - """Test the send_signed_transactions.""" - ledger_api_dialogues = LedgerApiDialogues(SOME_SKILL_ID) - - # Create new dialogue starting with signed transaction - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS, # type: ignore - signed_transactions=SignedTransactions( - EthereumCrypto.identifier, - [{"raw_transaction": "test_tx"}], - ), - kwargs=LedgerApiMessage.Kwargs({}), - ) - request = cast(LedgerApiMessage, request) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - expected_transaction_digests = ["transaction_digest_1", "transaction_digest_2"] - # create a mock for api.send_signed_transactions - with patch( - "aea_ledger_ethereum.ethereum.EthereumApi.send_signed_transactions" - ) as mock_send_signed_transactions: - # configure the mock to return a specific value - mock_send_signed_transactions.return_value = expected_transaction_digests - - # call the function under test - await ledger_apis_connection.send(envelope) - await asyncio.sleep(0.01) - - # Transaction digest - response = await ledger_apis_connection.receive() - - assert response is not None - assert isinstance(response.message, LedgerApiMessage) - response_message = cast(LedgerApiMessage, response.message) - assert ( - response_message.performative != LedgerApiMessage.Performative.ERROR - ), f"Received error: {response_message.message}" - assert ( - response_message.performative - == LedgerApiMessage.Performative.TRANSACTION_DIGESTS - ) - response_dialogue = ledger_api_dialogues.update(response_message) - assert response_dialogue == ledger_api_dialogue - assert isinstance(response_message.transaction_digests, TransactionDigests) - assert isinstance( - response_message.transaction_digests.transaction_digests, List - ) - assert ( - response_message.transaction_digests.ledger_id - == request.signed_transactions.ledger_id - ) - assert ( - response_message.transaction_digests.transaction_digests - == expected_transaction_digests - ) - - @pytest.mark.asyncio - async def test_unsupported_protocol( - self, ledger_apis_connection: LedgerConnection - ) -> None: - """Test fail on protocol not supported.""" - envelope = Envelope( - to=str(ledger_apis_connection.connection_id), - sender="test/skill:0.1.0", - protocol_specification_id=PublicId.from_str("author/package_name:0.1.0"), - message=b"message", - ) - with pytest.raises(ValueError, match="Protocol not supported"): - ledger_apis_connection._schedule_request(envelope) - - @pytest.mark.asyncio - async def test_no_balance( - self, - ) -> None: - """Test no balance.""" - dispatcher = LedgerApiRequestDispatcher( - AsyncState(), connection_id=LedgerConnection.connection_id - ) - mock_api = Mock() - message = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, # type: ignore - dialogue_reference=dispatcher.dialogues.new_self_initiated_dialogue_reference(), - ledger_id=EthereumCrypto.identifier, - address="test", - ) - message.to = dispatcher.dialogues.self_address - message.sender = "test" - dialogue = cast( - Optional[LedgerApiDialogue], dispatcher.dialogues.update(message) - ) - assert dialogue is not None - - mock_api.get_balance.return_value = None - msg = dispatcher.get_balance(mock_api, message, dialogue) - assert msg.performative == LedgerApiMessage.Performative.ERROR - - @pytest.mark.asyncio - async def test_no_raw_tx( - self, - ) -> None: - """Test no raw tx returned.""" - dispatcher = LedgerApiRequestDispatcher( - AsyncState(), connection_id=LedgerConnection.connection_id - ) - mock_api = Mock() - message = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - dialogue_reference=dispatcher.dialogues.new_self_initiated_dialogue_reference(), - terms=Terms( - ledger_id=EthereumCrypto.identifier, - sender_address="1111", - counterparty_address="22222", - amount_by_currency_id={"ETH": -1}, - quantities_by_good_id={"some_service_id": 1}, - is_sender_payable_tx_fee=True, - nonce="", - fee_by_currency_id={"ETH": 10}, - chain_id=3, - ), - ) - message.to = dispatcher.dialogues.self_address - message.sender = "test" - dialogue = cast( - Optional[LedgerApiDialogue], dispatcher.dialogues.update(message) - ) - assert dialogue is not None - - mock_api.get_transfer_transaction.return_value = None - msg = dispatcher.get_raw_transaction(mock_api, message, dialogue) - assert msg.performative == LedgerApiMessage.Performative.ERROR - - @pytest.mark.asyncio - @pytest.mark.parametrize( - "failing_ledger_method_name", - ("get_transaction_receipt", "is_transaction_settled", "get_transaction"), - ) - @pytest.mark.parametrize("retries", (0, 5, 20)) - @pytest.mark.parametrize("retry_timeout", (0.1,)) - @pytest.mark.parametrize("ledger_raise_error", (True, False)) - async def test_attempts_get_transaction_receipt( - self, - failing_ledger_method_name: str, - retries: int, - retry_timeout: float, - ledger_raise_error: bool, - ) -> None: - """Test retry and sleep.""" - dispatcher = LedgerApiRequestDispatcher( - AsyncState(ConnectionStates.connected), - connection_id=LedgerConnection.connection_id, - ) - mock_api = Mock() - message = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, # type: ignore - dialogue_reference=dispatcher.dialogues.new_self_initiated_dialogue_reference(), - transaction_digest=TransactionDigest("asdad", "sdfdsf"), - ) - message.to = dispatcher.dialogues.self_address - message.sender = "test" - dialogue = dispatcher.dialogues.update(message) - assert dialogue is not None - assert isinstance(dialogue, LedgerApiDialogue) - - mock_api.is_transaction_settled.return_value = ( - True if failing_ledger_method_name == "get_transaction" else False - ) - failing_ledger_method = getattr(mock_api, failing_ledger_method_name) - if ( - ledger_raise_error - and failing_ledger_method_name != "is_transaction_settled" - ): - failing_ledger_method.side_effect = ValueError() - elif failing_ledger_method_name != "is_transaction_settled": - failing_ledger_method.return_value = None - - with patch.object(dispatcher, "retry_attempts", retries): - with patch.object(dispatcher, "retry_timeout", retry_timeout): - msg = await dispatcher.get_transaction_receipt( - mock_api, message, dialogue - ) - - assert ( - msg.performative == LedgerApiMessage.Performative.ERROR - ), "performative should be `ERROR`, please revisit the test's implementation." - times_called = failing_ledger_method.call_count - expected_times = retries - assert times_called == expected_times, "Tried more times than expected!" - - @pytest.mark.asyncio - @ledger_ids - async def test_get_transaction_receipt_node_blocking( - self, - ledger_id: str, - address: str, - ledger_apis_connection: LedgerConnection, - update_default_ethereum_ledger_api: None, - ethereum_testnet_config: Dict, - ) -> None: - """Test retry strategy when the node is blocking.""" - retry_attempts = expected_times_called = 2 - retry_timeout = 0.001 - blocking_duration = 1 - - # the retry strategy's total duration is an arithmetic progression - expected_duration = sum(i * retry_timeout for i in range(retry_attempts)) - assert expected_duration < blocking_duration, ( - "The purpose of this test is to check whether the retry strategy works if a node is blocking." - f"Therefore, the blocking time ({blocking_duration}) must be larger than the expected duration " - f"({expected_duration}) of the retry strategy." - ) - - ledger_api_dialogues = LedgerApiDialogues(SOME_SKILL_ID) - request, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(ledger_apis_connection.connection_id), - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, # type: ignore - ledger_id=ledger_id, - address=address, - transaction_digest=TransactionDigest(ledger_id="ethereum", body="tx_hash"), - ) - envelope = Envelope( - to=request.to, - sender=request.sender, - message=request, - ) - - with patch.object( - ledger_apis_connection._ledger_dispatcher, "retry_attempts", retry_attempts - ), patch.object( - ledger_apis_connection._ledger_dispatcher, "retry_timeout", retry_timeout - ), patch.object( - Eth, - "get_transaction_receipt", - side_effect=lambda *_: time.sleep(blocking_duration), - ) as get_transaction_receipt_mock: - await ledger_apis_connection.send(envelope) - - try: - await asyncio.wait_for( - ledger_apis_connection.receive(), timeout=blocking_duration - ) - except asyncio.exceptions.TimeoutError: - raise AssertionError( - "The retry strategy did not finish before the given `blocking_duration`, " - "which suggests that the ledger api's call was also blocked, " - "and the dispatcher was waiting for its response." - ) - - actual_times_called = get_transaction_receipt_mock.call_count - assert ( - actual_times_called == expected_times_called - ), f"Tried {actual_times_called} times, {expected_times_called} were expected!" diff --git a/trader_old/vendor/valory/connections/p2p_libp2p_client/README.md b/trader_old/vendor/valory/connections/p2p_libp2p_client/README.md deleted file mode 100644 index f2c31c230..000000000 --- a/trader_old/vendor/valory/connections/p2p_libp2p_client/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# P2P Libp2p Client Connection - -A lightweight TCP connection to a libp2p DHT node. - -It allows for using the DHT without having to deploy a node by delegating its communication traffic to an already running DHT node with delegate service enabled. - - -## Usage - -First, add the connection to your AEA project: `aea add connection valory/p2p_libp2p_client:0.1.0`. - -Next, ensure that the connection is properly configured by setting: - -- `nodes` to a list of `uri`s, connection will choose the delegate randomly -- `uri` to the public IP address and port number of the delegate service of a running DHT node, in format `${ip|dns}:${port}` diff --git a/trader_old/vendor/valory/connections/p2p_libp2p_client/__init__.py b/trader_old/vendor/valory/connections/p2p_libp2p_client/__init__.py deleted file mode 100644 index b1456be04..000000000 --- a/trader_old/vendor/valory/connections/p2p_libp2p_client/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 Valory AG -# Copyright 2018-2019 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Implementation of the libp2p client connection.""" diff --git a/trader_old/vendor/valory/connections/p2p_libp2p_client/connection.py b/trader_old/vendor/valory/connections/p2p_libp2p_client/connection.py deleted file mode 100644 index be999f719..000000000 --- a/trader_old/vendor/valory/connections/p2p_libp2p_client/connection.py +++ /dev/null @@ -1,688 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2023 Valory AG -# Copyright 2018-2019 Fetch.AI Limited -# -# 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 the libp2p client connection.""" -# pylint: disable-all -import asyncio -import contextlib -import hashlib -import logging -import random -import ssl -from asyncio import CancelledError -from asyncio.events import AbstractEventLoop -from asyncio.streams import StreamWriter -from pathlib import Path -from typing import Any, Dict, List, Optional - -from asn1crypto import x509 # type: ignore -from ecdsa.curves import SECP256k1 # type: ignore -from ecdsa.keys import BadSignatureError, VerifyingKey # type: ignore -from ecdsa.util import sigdecode_der # type: ignore - -from aea.configurations.base import PublicId -from aea.configurations.constants import DEFAULT_LEDGER -from aea.connections.base import Connection, ConnectionStates -from aea.crypto.registries import make_crypto -from aea.exceptions import enforce -from aea.helpers.acn.agent_record import AgentRecord -from aea.helpers.acn.uri import Uri -from aea.helpers.pipe import IPCChannelClient, TCPSocketChannelClient, TCPSocketProtocol -from aea.mail.base import Envelope - -from packages.valory.protocols.acn import acn_pb2 -from packages.valory.protocols.acn.message import AcnMessage - - -try: - from asyncio.streams import ( # type: ignore # pylint: disable=ungrouped-imports - IncompleteReadError, - ) -except ImportError: # pragma: nocover - from asyncio import IncompleteReadError # pylint: disable=ungrouped-imports - - -_default_logger = logging.getLogger("aea.packages.valory.connections.p2p_libp2p_client") - -PUBLIC_ID = PublicId.from_str("valory/p2p_libp2p_client:0.1.0") - -SUPPORTED_LEDGER_IDS = ["fetchai", "cosmos", "ethereum"] - -POR_DEFAULT_SERVICE_ID = "acn" - -ACN_CURRENT_VERSION = "0.1.0" - - -class NodeClient: - """Client to communicate with node using ipc channel(pipe).""" - - ACN_ACK_TIMEOUT = 5.0 - - def __init__(self, pipe: IPCChannelClient, node_por: AgentRecord) -> None: - """Set node client with pipe.""" - self.pipe = pipe - self._wait_status: Optional[asyncio.Future] = None - self.agent_record = node_por - - async def wait_for_status(self) -> Any: - """Get status.""" - if self._wait_status is None: # pragma: nocover - raise ValueError("waiter for status not set!") - return await asyncio.wait_for(self._wait_status, timeout=self.ACN_ACK_TIMEOUT) - - @staticmethod - def make_acn_envelope_message(envelope: Envelope) -> bytes: - """Make acn message with envelope in.""" - acn_msg = acn_pb2.AcnMessage() # type: ignore - performative = acn_pb2.AcnMessage.Aea_Envelope_Performative() # type: ignore - performative.envelope = envelope.encode() - acn_msg.aea_envelope.CopyFrom(performative) # pylint: disable=no-member - buf = acn_msg.SerializeToString() - return buf - - async def write_acn_status_ok(self) -> None: - """Send acn status ok.""" - acn_msg = acn_pb2.AcnMessage() # type: ignore - performative = acn_pb2.AcnMessage.Status_Performative() # type: ignore - status = AcnMessage.StatusBody( - status_code=AcnMessage.StatusBody.StatusCode.SUCCESS, msgs=[] - ) - AcnMessage.StatusBody.encode( - performative.body, status # pylint: disable=no-member - ) - acn_msg.status.CopyFrom(performative) # pylint: disable=no-member - buf = acn_msg.SerializeToString() - await self._write(buf) - - async def write_acn_status_error( - self, - msg: str, - status_code: AcnMessage.StatusBody.StatusCode = AcnMessage.StatusBody.StatusCode.ERROR_GENERIC, # type: ignore - ) -> None: - """Send acn status error generic.""" - acn_msg = acn_pb2.AcnMessage() # type: ignore - performative = acn_pb2.AcnMessage.Status_Performative() # type: ignore - status = AcnMessage.StatusBody(status_code=status_code, msgs=[msg]) - AcnMessage.StatusBody.encode( - performative.body, status # pylint: disable=no-member - ) - acn_msg.status.CopyFrom(performative) # pylint: disable=no-member - - buf = acn_msg.SerializeToString() - - await self._write(buf) - - async def connect(self) -> bool: - """Connect to node with pipe.""" - return await self.pipe.connect() - - async def send_envelope(self, envelope: Envelope) -> None: - """Send envelope to node.""" - self._wait_status = asyncio.Future() - buf = self.make_acn_envelope_message(envelope) - await self._write(buf) - try: - status = await self.wait_for_status() - if status.code != int(AcnMessage.StatusBody.StatusCode.SUCCESS): # type: ignore # pylint: disable=no-member - raise ValueError( # pragma: nocover - f"failed to send envelope. got error confirmation: {status}" - ) - except asyncio.TimeoutError: # pragma: nocover - if not self._wait_status.done(): # pragma: nocover - self._wait_status.set_exception(Exception("Timeout")) - await asyncio.sleep(0) - raise ValueError("acn status await timeout!") - finally: - self._wait_status = None - - def make_agent_record(self) -> AcnMessage.AgentRecord: # type: ignore - """Make acn agent record.""" - agent_record = AcnMessage.AgentRecord( - address=self.agent_record.address, - public_key=self.agent_record.public_key, - peer_public_key=self.agent_record.representative_public_key, - signature=self.agent_record.signature, - service_id=POR_DEFAULT_SERVICE_ID, - ledger_id=self.agent_record.ledger_id, - ) - return agent_record - - async def read_envelope(self) -> Optional[Envelope]: - """Read envelope from the node.""" - while True: - buf = await self._read() - - if not buf: - return None - - try: - acn_msg = acn_pb2.AcnMessage() # type: ignore - acn_msg.ParseFromString(buf) - - except Exception as e: # pragma: nocover - await self.write_acn_status_error( - f"Failed to parse acn message {e}", - status_code=AcnMessage.StatusBody.StatusCode.ERROR_DECODE, - ) - raise ValueError(f"Error parsing acn message: {e}") from e - - performative = acn_msg.WhichOneof("performative") - if performative == "aea_envelope": # pragma: nocover - aea_envelope = acn_msg.aea_envelope # pylint: disable=no-member - try: - envelope = Envelope.decode(aea_envelope.envelope) - await self.write_acn_status_ok() - return envelope - except Exception as e: - await self.write_acn_status_error( - f"Failed to decode envelope: {e}", - status_code=AcnMessage.StatusBody.StatusCode.ERROR_DECODE, - ) - raise - - elif performative == "status": - if self._wait_status is not None: - self._wait_status.set_result( - acn_msg.status.body # pylint: disable=no-member - ) - else: # pragma: nocover - await self.write_acn_status_error( - f"Bad acn message {performative}", - status_code=AcnMessage.StatusBody.StatusCode.ERROR_UNEXPECTED_PAYLOAD, - ) - - async def _write(self, data: bytes) -> None: - """ - Write to the writer stream. - - :param data: data to write to stream - """ - await self.pipe.write(data) - - async def _read(self) -> Optional[bytes]: - """ - Read from the reader stream. - - :return: bytes - """ - return await self.pipe.read() - - async def register( - self, - ) -> None: - """Register agent on the remote node.""" - agent_record = self.make_agent_record() - acn_msg = acn_pb2.AcnMessage() # type: ignore - performative = acn_pb2.AcnMessage.Register_Performative() # type: ignore - AcnMessage.AgentRecord.encode( - performative.record, agent_record # pylint: disable=no-member - ) - acn_msg.register.CopyFrom(performative) # pylint: disable=no-member - - buf = acn_msg.SerializeToString() - await self._write(buf) - - try: - buf = await asyncio.wait_for(self._read(), timeout=self.ACN_ACK_TIMEOUT) - except ConnectionError as e: # pragma: nocover - raise e - except IncompleteReadError as e: # pragma: no cover - raise e - - if buf is None: # pragma: nocover - raise ConnectionError( - "Error on connection setup. Incoming buffer is empty!" - ) - acn_msg = acn_pb2.AcnMessage() # type: ignore - acn_msg.ParseFromString(buf) - performative = acn_msg.WhichOneof("performative") - if performative != "status": # pragma: nocover - raise Exception(f"Wrong response message from peer: {performative}") - response = acn_msg.status # pylint: disable=no-member - - if response.body.code != int(AcnMessage.StatusBody.StatusCode.SUCCESS): # type: ignore # pylint: disable=no-member - raise Exception( # pragma: nocover - "Registration to peer failed: {}".format( - AcnMessage.StatusBody.StatusCode(response.body.code) # type: ignore # pylint: disable=no-member - ) - ) - - async def close(self) -> None: - """Close client and pipe.""" - await self.pipe.close() - - -class P2PLibp2pClientConnection(Connection): - """ - A libp2p client connection. - - Send and receive envelopes to and from agents on the p2p network without deploying a libp2p node. - Connect to the libp2p node using traffic delegation service. - """ - - connection_id = PUBLIC_ID - - DEFAULT_CONNECT_RETRIES = 3 - DEFAULT_TLS_CONNECTION_SIGNATURE_TIMEOUT = 5.0 - - def __init__(self, **kwargs: Any) -> None: - """Initialize a libp2p client connection.""" - super().__init__(**kwargs) - - self.tls_connection_signature_timeout = self.configuration.config.get( - "tls_connection_signature_timeout", - self.DEFAULT_TLS_CONNECTION_SIGNATURE_TIMEOUT, - ) - self.connect_retries = self.configuration.config.get( - "connect_retries", self.DEFAULT_CONNECT_RETRIES - ) - ledger_id = self.configuration.config.get("ledger_id", DEFAULT_LEDGER) - if ledger_id not in SUPPORTED_LEDGER_IDS: - raise ValueError( # pragma: nocover - "Ledger id '{}' is not supported. Supported ids: '{}'".format( - ledger_id, SUPPORTED_LEDGER_IDS - ) - ) - - key_file: Optional[str] = self.configuration.config.get("tcp_key_file") - nodes: Optional[List[Dict[str, Any]]] = self.configuration.config.get("nodes") - - if nodes is None: - raise ValueError("At least one node should be provided") - nodes = list(nodes) - - nodes_uris = [node.get("uri", None) for node in nodes] - enforce( - len(nodes_uris) == len(nodes) and None not in nodes_uris, - "Delegate 'uri' should be provided for each node", - ) - - nodes_public_keys = [node.get("public_key", None) for node in nodes] - enforce( - len(nodes_public_keys) == len(nodes) and None not in nodes_public_keys, - "Delegate 'public_key' should be provided for each node", - ) - - cert_requests = self.configuration.cert_requests - if cert_requests is None or len(cert_requests) != len(nodes): - raise ValueError( # pragma: nocover - "cert_requests field must be set and contain exactly as many entries as 'nodes'!" - ) - for cert_request in cert_requests: - save_path = cert_request.get_absolute_save_path(Path(self.data_dir)) - if not save_path.is_file(): - raise Exception( # pragma: nocover - f"cert_request 'save_path' field is not a file:\n{save_path}\n" - "Please ensure that 'issue-certificates' command is called beforehand" - ) - - # we cannot use the key from the connection's crypto store as - # the key will be used for TLS tcp connection, whereas the - # connection's crypto store key is used for PoR - if key_file is not None: - key = make_crypto(ledger_id, private_key_path=key_file) - else: - key = make_crypto(ledger_id) - - # client connection id - self.key = key - self.logger.debug("Public key used for TCP: {}".format(key.public_key)) - - # delegate uris - self.delegate_uris = [Uri(node_uri) for node_uri in nodes_uris] - - # delegates PoRs - self.delegate_pors: List[AgentRecord] = [] - for i, cert_request in enumerate(cert_requests): - agent_record = AgentRecord.from_cert_request( - cert_request, self.address, nodes_public_keys[i], self.data_dir - ) - self.delegate_pors.append(agent_record) - - # select a delegate - index = random.randint(0, len(self.delegate_uris) - 1) # nosec - self.node_uri = self.delegate_uris[index] - self.node_por = self.delegate_pors[index] - self.logger.debug("Node to use as delegate: {}".format(self.node_uri)) - - self._in_queue = None # type: Optional[asyncio.Queue] - self._process_messages_task = None # type: Optional[asyncio.Future] - self._node_client: Optional[NodeClient] = None - - self._send_queue: Optional[asyncio.Queue] = None - self._send_task: Optional[asyncio.Task] = None - - async def _send_loop(self) -> None: - """Handle message in the send queue.""" - - if not self._send_queue or not self._node_client: # pragma: nocover - self.logger.error("Send loop not started cause not connected properly.") - return - try: - while self.is_connected: - envelope = await self._send_queue.get() - await self._send_envelope_with_node_client(envelope) - except asyncio.CancelledError: # pylint: disable=try-except-raise - raise # pragma: nocover - except Exception: # pylint: disable=broad-except # pragma: nocover - self.logger.exception( - f"Failed to send an envelope {envelope}. Stop connection." - ) - await asyncio.shield(self.disconnect()) - - async def _send_envelope_with_node_client(self, envelope: Envelope) -> None: - """Send envelope with node client, reconnect and retry on fail.""" - if not self._node_client: # pragma: nocover - raise ValueError("Connection not connected to node!") - - self._ensure_valid_envelope_for_external_comms(envelope) - try: - await self._node_client.send_envelope(envelope) - except Exception: # pylint: disable=broad-except - self.logger.exception( - "Exception raised on message send. Try reconnect and send again." - ) - await self._perform_connection_to_node() - await self._node_client.send_envelope(envelope) - - async def connect(self) -> None: - """Set up the connection.""" - if self.is_connected: # pragma: nocover - return - - with self._connect_context(): - # connect libp2p client - - await self._perform_connection_to_node() - # start receiving msgs - self._in_queue = asyncio.Queue() - self._process_messages_task = asyncio.ensure_future( - self._process_messages(), loop=self.loop - ) - self._send_queue = asyncio.Queue() - self._send_task = self.loop.create_task(self._send_loop()) - - async def _perform_connection_to_node(self) -> None: - """Connect to node with retries.""" - for attempt in range(self.connect_retries): - if self.state not in [ # type: ignore - ConnectionStates.connecting, - ConnectionStates.connected, - ]: - # do nothing if disconnected, or disconnecting - return # pragma: nocover - try: - self.logger.info( - "Connecting to libp2p node {}. Attempt {}".format( - str(self.node_uri), attempt + 1 - ) - ) - pipe = TCPSocketChannelClientTLS( - f"{self.node_uri.host}:{self.node_uri._port}", # pylint: disable=protected-access - "", - server_pub_key=self.node_por.representative_public_key, - verification_signature_wait_timeout=self.tls_connection_signature_timeout, - ) - if not await pipe.connect(): - raise ValueError( - f"Pipe connection error: {pipe.last_exception or ''}" - ) - - self._node_client = NodeClient(pipe, self.node_por) - await self._setup_connection() - - self.logger.info( - "Successfully connected to libp2p node {}".format( - str(self.node_uri) - ) - ) - return - except Exception as e: # pylint: disable=broad-except - if attempt == self.connect_retries - 1: - self.logger.error( - "Connection to libp2p node {} failed: error: {}. It was the last attempt, exception will be raised".format( - str(self.node_uri), str(e) - ) - ) - self.state = ConnectionStates.disconnected - raise - sleep_time = attempt * 2 + 1 - self.logger.error( - "Connection to libp2p node {} failed: error: {}. Another attempt will be performed in {} seconds".format( - str(self.node_uri), str(e), sleep_time - ) - ) - await asyncio.sleep(sleep_time) - - async def _setup_connection(self) -> None: - """Set up connection to node over tcp connection.""" - if not self._node_client: # pragma: nocover - raise ValueError("Connection was not connected!") - - await self._node_client.register() - - async def disconnect(self) -> None: - """Disconnect from the channel.""" - if self.is_disconnected: # pragma: nocover - return - - self.state = ConnectionStates.disconnecting - self.logger.debug("disconnecting libp2p client connection...") - - if self._process_messages_task is not None: - if not self._process_messages_task.done(): - self._process_messages_task.cancel() - self._process_messages_task = None - - if self._send_task is not None: - if not self._send_task.done(): - self._send_task.cancel() - self._send_task = None - - try: - self.logger.debug("disconnecting libp2p node client connection...") - if self._node_client is not None: - await self._node_client.close() - except Exception: # pragma: nocover # pylint:disable=broad-except - self.logger.exception("exception on node client close") - raise - finally: - # set disconnected state anyway - if self._in_queue is not None: - self._in_queue.put_nowait(None) - - self.state = ConnectionStates.disconnected - self.logger.debug("libp2p client connection disconnected.") - - async def receive(self, *args: Any, **kwargs: Any) -> Optional["Envelope"]: - """ - Receive an envelope. Blocking. - - :param args: positional arguments - :param kwargs: keyword arguments - :return: the envelope received, or None. - """ - try: - if self._in_queue is None: - raise ValueError("Input queue not initialized.") # pragma: nocover - envelope = await self._in_queue.get() - if envelope is None: # pragma: no cover - self.logger.debug("Received None.") - return None - self.logger.debug("Received envelope: {}".format(envelope)) - return envelope - except CancelledError: # pragma: no cover - self.logger.debug("Receive cancelled.") - return None - except Exception as e: # pragma: no cover # pylint: disable=broad-except - self.logger.exception(e) - return None - - async def send(self, envelope: Envelope) -> None: - """ - Send messages. - - :param envelope: the envelope - """ - if not self._node_client or not self._send_queue: - raise ValueError("Node is not connected!") # pragma: nocover - - self._ensure_valid_envelope_for_external_comms(envelope) - await self._send_queue.put(envelope) - - async def _read_envelope_from_node(self) -> Optional[Envelope]: - """Read envelope from node, reconnec on error.""" - if not self._node_client: # pragma: nocover - raise ValueError("Connection not connected to node!") - - try: - self.logger.debug("Waiting for messages...") - envelope = await self._node_client.read_envelope() - return envelope - except ConnectionError as e: # pragma: nocover - self.logger.error(f"Connection error: {e}. Try to reconnect and read again") - except IncompleteReadError as e: # pragma: no cover - self.logger.error( - "Connection disconnected while reading from node ({}/{})".format( - len(e.partial), e.expected - ) - ) - except Exception as e: # pylint: disable=broad-except # pragma: nocover - self.logger.exception(f"On envelope read: {e}") - - try: - self.logger.debug("Read envelope retry! Reconnect first!") - await self._perform_connection_to_node() - envelope = await self._node_client.read_envelope() - return envelope - except Exception: # pragma: no cover # pylint: disable=broad-except - self.logger.exception("Failed to read with reconnect!") - return None - - async def _process_messages(self) -> None: - """Receive data from node.""" - if not self._node_client: # pragma: nocover - raise ValueError("Connection not connected to node!") - - while True: - envelope = await self._read_envelope_from_node() - if self._in_queue is None: - raise ValueError("Input queue not initialized.") # pragma: nocover - self._in_queue.put_nowait(envelope) - if envelope is None: - break # pragma: no cover - - -class TCPSocketChannelClientTLS(TCPSocketChannelClient): - """Interprocess communication channel client using tcp sockets with TLS.""" - - DEFAULT_VERIFICATION_SIGNATURE_WAIT_TIMEOUT = 5.0 - - def __init__( - self, - in_path: str, - out_path: str, - server_pub_key: str, - logger: logging.Logger = _default_logger, - loop: Optional[AbstractEventLoop] = None, - verification_signature_wait_timeout: Optional[float] = None, - ) -> None: - """ - Initialize a tcp socket communication channel client. - - :param in_path: rendezvous point for incoming data - :param out_path: rendezvous point for outgoing data - :param server_pub_key: str, server public key to verify identity - :param logger: the logger - :param loop: the event loop - :param verification_signature_wait_timeout: optional float, if not provided, default value will be used - """ - super().__init__(in_path, out_path, logger, loop) - self.verification_signature_wait_timeout = ( - self.DEFAULT_VERIFICATION_SIGNATURE_WAIT_TIMEOUT - if verification_signature_wait_timeout is None - else verification_signature_wait_timeout - ) - self.server_pub_key = server_pub_key - - @staticmethod - def _get_session_pub_key(writer: StreamWriter) -> bytes: # pragma: nocover - """Get session public key from tls stream writer.""" - cert_data = writer.get_extra_info("ssl_object").getpeercert(binary_form=True) - - cert = x509.Certificate.load(cert_data) - session_pub_key = VerifyingKey.from_der(cert.public_key.dump()).to_string( - "uncompressed" - ) - return session_pub_key - - async def _open_connection(self) -> TCPSocketProtocol: - """Open a connection with TLS support and verify peer.""" - sock = await self._open_tls_connection() - session_pub_key = self._get_session_pub_key(sock.writer) - - try: - signature = await asyncio.wait_for( - sock.read(), timeout=self.verification_signature_wait_timeout - ) - except asyncio.TimeoutError: # pragma: nocover - raise ValueError( - f"Failed to get peer verification record in timeout: {self.verification_signature_wait_timeout}" - ) - - if not signature: # pragma: nocover - raise ValueError("Unexpected socket read data!") - - try: - self._verify_session_key_signature(signature, session_pub_key) - except BadSignatureError as e: # pragma: nocover - with contextlib.suppress(Exception): - await sock.close() - raise ValueError(f"Invalid TLS session key signature: {e}") - return sock - - async def _open_tls_connection(self) -> TCPSocketProtocol: - """Open a connection with TLS support.""" - cadata = await asyncio.get_event_loop().run_in_executor( - None, lambda: ssl.get_server_certificate((self._host, self._port)) - ) - - ssl_ctx = ssl.create_default_context(cadata=cadata) - ssl_ctx.check_hostname = False - ssl_ctx.verify_mode = ssl.CERT_REQUIRED - reader, writer = await asyncio.open_connection( - self._host, - self._port, - ssl=ssl_ctx, - ) - return TCPSocketProtocol(reader, writer, logger=self.logger, loop=self._loop) - - def _verify_session_key_signature( - self, signature: bytes, session_pub_key: bytes - ) -> None: - """ - Validate signature of session public key. - - :param signature: bytes, signature of session public key made with server private key - :param session_pub_key: session public key to check signature for. - """ - vk = VerifyingKey.from_string(bytes.fromhex(self.server_pub_key), SECP256k1) - vk.verify( - signature, session_pub_key, hashfunc=hashlib.sha256, sigdecode=sigdecode_der - ) diff --git a/trader_old/vendor/valory/connections/p2p_libp2p_client/connection.yaml b/trader_old/vendor/valory/connections/p2p_libp2p_client/connection.yaml deleted file mode 100644 index 53576dcdc..000000000 --- a/trader_old/vendor/valory/connections/p2p_libp2p_client/connection.yaml +++ /dev/null @@ -1,51 +0,0 @@ -name: p2p_libp2p_client -author: valory -version: 0.1.0 -type: connection -description: The libp2p client connection implements a tcp connection to a running - libp2p node as a traffic delegate to send/receive envelopes to/from agents in the - DHT. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeiaf5kdnfdc2jifojgniib76zl2c4utnx7ofewc3szqkrxsby62ulu - __init__.py: bafybeid2azroxglu6fl7bxdfcsv3j77vyzgpikjnfwpxg73zeb5orez6ju - connection.py: bafybeiauso3ectgdvbhkt5j6wstfev5mnxiuj6hrkczyqgxurnvva3loqm -fingerprint_ignore_patterns: [] -connections: [] -protocols: -- valory/acn:1.1.0:bafybeidluaoeakae3exseupaea4i3yvvk5vivyt227xshjlffywwxzcxqe -class_name: P2PLibp2pClientConnection -config: - connect_retries: 3 - ledger_id: cosmos - nodes: - - uri: acn.staging.autonolas.tech:9005 - public_key: 02d3a830c9d6ea1ae91936951430dee11f4662f33118b02190693be835359a9d77 - - uri: acn.staging.autonolas.tech:9006 - public_key: 02e741c62d706e1dcf6986bf37fa74b98681bc32669623ac9ee6ff72488d4f59e8 - tls_connection_signature_timeout: 5.0 -cert_requests: -- identifier: acn - ledger_id: ethereum - message_format: '{public_key}' - not_after: '2025-01-01' - not_before: '2024-01-01' - public_key: 02d3a830c9d6ea1ae91936951430dee11f4662f33118b02190693be835359a9d77 - save_path: .certs/acn_cosmos_9005.txt -- identifier: acn - ledger_id: ethereum - message_format: '{public_key}' - not_after: '2025-01-01' - not_before: '2024-01-01' - public_key: 02e741c62d706e1dcf6986bf37fa74b98681bc32669623ac9ee6ff72488d4f59e8 - save_path: .certs/acn_cosmos_9006.txt -excluded_protocols: [] -restricted_to_protocols: [] -dependencies: - asn1crypto: - version: <1.5.0,>=1.4.0 - ecdsa: {} - open-aea-ledger-cosmos: {} - open-aea-ledger-ethereum: {} -is_abstract: false diff --git a/trader_old/vendor/valory/contracts/__init__.py b/trader_old/vendor/valory/contracts/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_old/vendor/valory/contracts/agent_registry/__init__.py b/trader_old/vendor/valory/contracts/agent_registry/__init__.py deleted file mode 100644 index cf1e8467e..000000000 --- a/trader_old/vendor/valory/contracts/agent_registry/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for the agent registry contract.""" diff --git a/trader_old/vendor/valory/contracts/agent_registry/build/AgentRegistry.json b/trader_old/vendor/valory/contracts/agent_registry/build/AgentRegistry.json deleted file mode 100644 index 79a56dba2..000000000 --- a/trader_old/vendor/valory/contracts/agent_registry/build/AgentRegistry.json +++ /dev/null @@ -1,1046 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "AgentRegistry", - "sourceName": "contracts/AgentRegistry.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - }, - { - "internalType": "string", - "name": "_baseURI", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "AgentInstanceRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentInstancesSlotsFilled", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "AgentNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentNotInService", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "componentId", - "type": "uint256" - } - ], - "name": "ComponentNotFound", - "type": "error" - }, - { - "inputs": [], - "name": "HashExists", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectAgentBondingValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectRegistrationDepositValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "provided", - "type": "address" - }, - { - "internalType": "address", - "name": "expected", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OnlyOwnServiceMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorHasNoInstances", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "OperatorOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "Overflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerOnly", - "type": "error" - }, - { - "inputs": [], - "name": "Paused", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrancyGuard", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceMustBeInactive", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "TransferFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "UnauthorizedMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "WrongAgentId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "numValues1", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numValues2", - "type": "uint256" - } - ], - "name": "WrongArrayLength", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongOperator", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "state", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceState", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "currentThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxThreshold", - "type": "uint256" - } - ], - "name": "WrongThreshold", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "string", - "name": "baseURI", - "type": "string" - } - ], - "name": "BaseURIChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "agentHash", - "type": "bytes32" - } - ], - "name": "CreateAgent", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "agentHash", - "type": "bytes32" - } - ], - "name": "UpdateAgentHash", - "type": "event" - }, - { - "inputs": [], - "name": "CID_PREFIX", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newManager", - "type": "address" - } - ], - "name": "changeManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "changeOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "agentOwner", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "agentHash", - "type": "bytes32" - } - ], - "name": "create", - "outputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "name": "exists", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "getHashes", - "outputs": [ - { - "internalType": "uint256", - "name": "numHashes", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "agentHashes", - "type": "bytes32[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "manager", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapAgentIdHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "bURI", - "type": "string" - } - ], - "name": "setBaseURI", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "tokenByIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "agentHash", - "type": "bytes32" - } - ], - "name": "updateHash", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/agent_registry/contract.py b/trader_old/vendor/valory/contracts/agent_registry/contract.py deleted file mode 100644 index 9acf29aad..000000000 --- a/trader_old/vendor/valory/contracts/agent_registry/contract.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- 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 the class to connect to the Agent Registry contract.""" - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi - - -class AgentRegistryContract(Contract): - """The Agent Registry contract.""" - - contract_id = PublicId.from_str("valory/agent_registry:0.1.0") - - @classmethod - def get_hash( - cls, - ledger_api: LedgerApi, - contract_address: str, - agent_id: int, - ) -> JSONLike: - """Retrieve an operator given its agent instance.""" - - contract_instance = cls.get_instance(ledger_api, contract_address) - res = contract_instance.functions.getHashes(agent_id).call() - # ensure that the returned object has the expected format - if len(res) != 2: - msg = f"The `getHashes` method for {contract_address=} returned data in an unexpected format: {res}" - return dict(error=msg) - - # get the agent hashes - hashes = res.pop(-1) - # ensure that there are hashes returned for the agent - if len(hashes) == 0: - msg = f"The `getHashes` method for {contract_address=} returned no hashes for {agent_id=}: {res}" - return dict(error=msg) - - # get the most recent agent hash - hash_ = hashes.pop(-1) - # ensure that the hash is in bytes - if not isinstance(hash_, bytes): - msg = f"The `getHashes` method for {contract_address=} returned non-bytes {hash_=} for {agent_id=}: {res}" - return dict(error=msg) - - # return the hash in hex - return dict(hash=hash_.hex()) diff --git a/trader_old/vendor/valory/contracts/agent_registry/contract.yaml b/trader_old/vendor/valory/contracts/agent_registry/contract.yaml deleted file mode 100644 index c0207fc24..000000000 --- a/trader_old/vendor/valory/contracts/agent_registry/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: agent_registry -author: valory -version: 0.1.0 -type: contract -description: Agent Registry contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeid3wfzglolebuo6jrrsopswzu4lk77bm76mvw3euizlsjtnt3wmgu - build/AgentRegistry.json: bafybeicoe5elvvsv2neiirsdn4uddrilizmyib3x4mvpklr7olhj2kh4ue - contract.py: bafybeihrv6blme3v6diwci6zxxn72qbg5sanzmfq5tobhs4375ebcuyday -fingerprint_ignore_patterns: [] -contracts: [] -class_name: AgentRegistryContract -contract_interface_paths: - ethereum: build/AgentRegistry.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - web3: - version: <7,>=6.0.0 diff --git a/trader_old/vendor/valory/contracts/conditional_tokens/__init__.py b/trader_old/vendor/valory/contracts/conditional_tokens/__init__.py deleted file mode 100644 index 047a3b03a..000000000 --- a/trader_old/vendor/valory/contracts/conditional_tokens/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for the ConditionalTokens contract.""" diff --git a/trader_old/vendor/valory/contracts/conditional_tokens/build/ConditionalTokens.json b/trader_old/vendor/valory/contracts/conditional_tokens/build/ConditionalTokens.json deleted file mode 100644 index 3906d3592..000000000 --- a/trader_old/vendor/valory/contracts/conditional_tokens/build/ConditionalTokens.json +++ /dev/null @@ -1,708 +0,0 @@ -{ - "abi": [ - { - "constant": true, - "inputs": [ - { - "name": "owner", - "type": "address" - }, - { - "name": "id", - "type": "uint256" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "collateralToken", - "type": "address" - }, - { - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "name": "conditionId", - "type": "bytes32" - }, - { - "name": "indexSets", - "type": "uint256[]" - } - ], - "name": "redeemPositions", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - }, - { - "name": "", - "type": "uint256" - } - ], - "name": "payoutNumerators", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "from", - "type": "address" - }, - { - "name": "to", - "type": "address" - }, - { - "name": "ids", - "type": "uint256[]" - }, - { - "name": "values", - "type": "uint256[]" - }, - { - "name": "data", - "type": "bytes" - } - ], - "name": "safeBatchTransferFrom", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "collateralToken", - "type": "address" - }, - { - "name": "collectionId", - "type": "bytes32" - } - ], - "name": "getPositionId", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "pure", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "owners", - "type": "address[]" - }, - { - "name": "ids", - "type": "uint256[]" - } - ], - "name": "balanceOfBatch", - "outputs": [ - { - "name": "", - "type": "uint256[]" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "collateralToken", - "type": "address" - }, - { - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "name": "conditionId", - "type": "bytes32" - }, - { - "name": "partition", - "type": "uint256[]" - }, - { - "name": "amount", - "type": "uint256" - } - ], - "name": "splitPosition", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "oracle", - "type": "address" - }, - { - "name": "questionId", - "type": "bytes32" - }, - { - "name": "outcomeSlotCount", - "type": "uint256" - } - ], - "name": "getConditionId", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "pure", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "name": "conditionId", - "type": "bytes32" - }, - { - "name": "indexSet", - "type": "uint256" - } - ], - "name": "getCollectionId", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "collateralToken", - "type": "address" - }, - { - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "name": "conditionId", - "type": "bytes32" - }, - { - "name": "partition", - "type": "uint256[]" - }, - { - "name": "amount", - "type": "uint256" - } - ], - "name": "mergePositions", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "operator", - "type": "address" - }, - { - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "questionId", - "type": "bytes32" - }, - { - "name": "payouts", - "type": "uint256[]" - } - ], - "name": "reportPayouts", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "conditionId", - "type": "bytes32" - } - ], - "name": "getOutcomeSlotCount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "oracle", - "type": "address" - }, - { - "name": "questionId", - "type": "bytes32" - }, - { - "name": "outcomeSlotCount", - "type": "uint256" - } - ], - "name": "prepareCondition", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "payoutDenominator", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "owner", - "type": "address" - }, - { - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "from", - "type": "address" - }, - { - "name": "to", - "type": "address" - }, - { - "name": "id", - "type": "uint256" - }, - { - "name": "value", - "type": "uint256" - }, - { - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "conditionId", - "type": "bytes32" - }, - { - "indexed": true, - "name": "oracle", - "type": "address" - }, - { - "indexed": true, - "name": "questionId", - "type": "bytes32" - }, - { - "indexed": false, - "name": "outcomeSlotCount", - "type": "uint256" - } - ], - "name": "ConditionPreparation", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "conditionId", - "type": "bytes32" - }, - { - "indexed": true, - "name": "oracle", - "type": "address" - }, - { - "indexed": true, - "name": "questionId", - "type": "bytes32" - }, - { - "indexed": false, - "name": "outcomeSlotCount", - "type": "uint256" - }, - { - "indexed": false, - "name": "payoutNumerators", - "type": "uint256[]" - } - ], - "name": "ConditionResolution", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "stakeholder", - "type": "address" - }, - { - "indexed": false, - "name": "collateralToken", - "type": "address" - }, - { - "indexed": true, - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "indexed": true, - "name": "conditionId", - "type": "bytes32" - }, - { - "indexed": false, - "name": "partition", - "type": "uint256[]" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "PositionSplit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "stakeholder", - "type": "address" - }, - { - "indexed": false, - "name": "collateralToken", - "type": "address" - }, - { - "indexed": true, - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "indexed": true, - "name": "conditionId", - "type": "bytes32" - }, - { - "indexed": false, - "name": "partition", - "type": "uint256[]" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "PositionsMerge", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "redeemer", - "type": "address" - }, - { - "indexed": true, - "name": "collateralToken", - "type": "address" - }, - { - "indexed": true, - "name": "parentCollectionId", - "type": "bytes32" - }, - { - "indexed": false, - "name": "conditionId", - "type": "bytes32" - }, - { - "indexed": false, - "name": "indexSets", - "type": "uint256[]" - }, - { - "indexed": false, - "name": "payout", - "type": "uint256" - } - ], - "name": "PayoutRedemption", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "name": "from", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" - }, - { - "indexed": false, - "name": "id", - "type": "uint256" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "TransferSingle", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "name": "from", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" - }, - { - "indexed": false, - "name": "ids", - "type": "uint256[]" - }, - { - "indexed": false, - "name": "values", - "type": "uint256[]" - } - ], - "name": "TransferBatch", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "value", - "type": "string" - }, - { - "indexed": true, - "name": "id", - "type": "uint256" - } - ], - "name": "URI", - "type": "event" - } - ], - "bytecode": "6080604052620000387f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b036200007216565b6200006c7fd9b67a26000000000000000000000000000000000000000000000000000000006001600160e01b036200007216565b62000141565b7fffffffff0000000000000000000000000000000000000000000000000000000080821614156200010457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152602081905260409020805460ff19166001179055565b6139b380620001516000396000f3fe608060405234801561001057600080fd5b50600436106101155760003560e01c8063856296f7116100a2578063d42dc0c211610071578063d42dc0c21461071a578063d96ee75414610737578063dd34de6714610769578063e985e9c514610786578063f242432a146107b457610115565b8063856296f7146105c45780639e7212ad146105ed578063a22cb46514610677578063c49298ac146106a557610115565b80632eb2c2d6116100e95780632eb2c2d61461024257806339dd7530146103695780634e1273f41461039557806372ce427514610508578063852c6ae21461059257610115565b8062fdd58e1461011a57806301b7037c1461015857806301ffc9a7146101e45780630504c8141461021f575b600080fd5b6101466004803603604081101561013057600080fd5b506001600160a01b038135169060200135610847565b60408051918252519081900360200190f35b6101e26004803603608081101561016e57600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b8111156101a457600080fd5b8201836020820111156101b657600080fd5b803590602001918460208302840111600160201b831117156101d757600080fd5b5090925090506108b9565b005b61020b600480360360208110156101fa57600080fd5b50356001600160e01b031916610c38565b604080519115158252519081900360200190f35b6101466004803603604081101561023557600080fd5b5080359060200135610c57565b6101e2600480360360a081101561025857600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b81111561028b57600080fd5b82018360208201111561029d57600080fd5b803590602001918460208302840111600160201b831117156102be57600080fd5b919390929091602081019035600160201b8111156102db57600080fd5b8201836020820111156102ed57600080fd5b803590602001918460208302840111600160201b8311171561030e57600080fd5b919390929091602081019035600160201b81111561032b57600080fd5b82018360208201111561033d57600080fd5b803590602001918460018302840111600160201b8311171561035e57600080fd5b509092509050610c85565b6101466004803603604081101561037f57600080fd5b506001600160a01b038135169060200135611012565b6104b8600480360360408110156103ab57600080fd5b810190602081018135600160201b8111156103c557600080fd5b8201836020820111156103d757600080fd5b803590602001918460208302840111600160201b831117156103f857600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561044757600080fd5b82018360208201111561045957600080fd5b803590602001918460208302840111600160201b8311171561047a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611025945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156104f45781810151838201526020016104dc565b505050509050019250505060405180910390f35b6101e2600480360360a081101561051e57600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b81111561055457600080fd5b82018360208201111561056657600080fd5b803590602001918460208302840111600160201b8311171561058757600080fd5b91935091503561118c565b610146600480360360608110156105a857600080fd5b506001600160a01b038135169060208101359060400135611573565b610146600480360360608110156105da57600080fd5b5080359060208101359060400135611588565b6101e2600480360360a081101561060357600080fd5b6001600160a01b038235169160208101359160408201359190810190608081016060820135600160201b81111561063957600080fd5b82018360208201111561064b57600080fd5b803590602001918460208302840111600160201b8311171561066c57600080fd5b919350915035611595565b6101e26004803603604081101561068d57600080fd5b506001600160a01b038135169060200135151561198c565b6101e2600480360360408110156106bb57600080fd5b81359190810190604081016020820135600160201b8111156106dc57600080fd5b8201836020820111156106ee57600080fd5b803590602001918460208302840111600160201b8311171561070f57600080fd5b5090925090506119fa565b6101466004803603602081101561073057600080fd5b5035611ce4565b6101e26004803603606081101561074d57600080fd5b506001600160a01b038135169060208101359060400135611cf6565b6101466004803603602081101561077f57600080fd5b5035611e8e565b61020b6004803603604081101561079c57600080fd5b506001600160a01b0381358116916020013516611ea0565b6101e2600480360360a08110156107ca57600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b81111561080957600080fd5b82018360208201111561081b57600080fd5b803590602001918460018302840111600160201b8311171561083c57600080fd5b509092509050611ece565b60006001600160a01b03831661088e5760405162461bcd60e51b815260040180806020018281038252602b8152602001806136fc602b913960400191505060405180910390fd5b5060008181526001602090815260408083206001600160a01b03861684529091529020545b92915050565b600083815260046020526040902054806109045760405162461bcd60e51b81526004018080602001828103825260258152602001806136d76025913960400191505060405180910390fd5b60008481526003602052604090205480610962576040805162461bcd60e51b815260206004820152601a60248201527918dbdb991a5d1a5bdb881b9bdd081c1c995c185c9959081e595d60321b604482015290519081900360640190fd5b60006000196001831b01815b85811015610aba57600087878381811061098457fe5b90506020020135905060008111801561099c57508281105b6109e5576040805162461bcd60e51b815260206004820152601560248201527419dbdd081a5b9d985b1a59081a5b99195e081cd95d605a1b604482015290519081900360640190fd5b60006109fb8c6109f68d8d866120aa565b6123d9565b90506000805b87811015610a58576001811b841615610a505760008c81526003602052604090208054610a4d919083908110610a3357fe5b90600052602060002001548361241d90919063ffffffff16565b91505b600101610a01565b506000610a653384610847565b90508015610aaa57610a9d610a908a610a84848663ffffffff61247716565b9063ffffffff6124d016565b889063ffffffff61241d16565b9650610aaa33848361253a565b50506001909201915061096e9050565b508115610ba55787610b81576040805163a9059cbb60e01b81523360048201526024810184905290516001600160a01b038b169163a9059cbb9160448083019260209291908290030181600087803b158015610b1557600080fd5b505af1158015610b29573d6000803e3d6000fd5b505050506040513d6020811015610b3f57600080fd5b5051610b7c5760405162461bcd60e51b815260040180806020018281038252602b815260200180613727602b913960400191505060405180910390fd5b610ba5565b610ba533610b8f8b8b6123d9565b84604051806020016040528060008152506125d5565b87896001600160a01b0316336001600160a01b03167f2682012a4a4f1973119f1c9b90745d1bd91fa2bab387344f044cb3586864d18d8a8a8a8860405180858152602001806020018381526020018281038252858582818152602001925060200280828437600083820152604051601f909101601f191690920182900397509095505050505050a4505050505050505050565b6001600160e01b03191660009081526020819052604090205460ff1690565b60036020528160005260406000208181548110610c7057fe5b90600052602060002001600091509150505481565b848314610cc35760405162461bcd60e51b815260040180806020018281038252602e815260200180613876602e913960400191505060405180910390fd5b6001600160a01b038716610d085760405162461bcd60e51b81526004018080602001828103825260288152602001806137526028913960400191505060405180910390fd5b6001600160a01b038816331480610d4757506001600160a01b038816600090815260026020908152604080832033845290915290205460ff1615156001145b610d825760405162461bcd60e51b81526004018080602001828103825260388152602001806138a46038913960400191505060405180910390fd5b60005b85811015610eb2576000878783818110610d9b57fe5b9050602002013590506000868684818110610db257fe5b905060200201359050610e04816001600085815260200190815260200160002060008e6001600160a01b03166001600160a01b03168152602001908152602001600020546126c390919063ffffffff16565b6001600084815260200190815260200160002060008d6001600160a01b03166001600160a01b0316815260200190815260200160002081905550610e876001600084815260200190815260200160002060008c6001600160a01b03166001600160a01b03168152602001908152602001600020548261241d90919063ffffffff16565b60009283526001602081815260408086206001600160a01b038f168752909152909320555001610d85565b50866001600160a01b0316886001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb898989896040518080602001806020018381038352878782818152602001925060200280828437600083820152601f01601f19169091018481038352858152602090810191508690860280828437600083820152604051601f909101601f19169092018290039850909650505050505050a461100833898989898080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b91829185019084908082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a915089908190840183828082843760009201919091525061272092505050565b5050505050505050565b600061101e83836123d9565b9392505050565b606081518351146110675760405162461bcd60e51b815260040180806020018281038252602e815260200180613848602e913960400191505060405180910390fd5b60608351604051908082528060200260200182016040528015611094578160200160208202803883390190505b50905060005b84518110156111845760006001600160a01b03168582815181106110ba57fe5b60200260200101516001600160a01b031614156111085760405162461bcd60e51b81526004018080602001828103825260348152602001806137f36034913960400191505060405180910390fd5b6001600085838151811061111857fe5b60200260200101518152602001908152602001600020600086838151811061113c57fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061117157fe5b602090810291909101015260010161109a565b509392505050565b600182116111e1576040805162461bcd60e51b815260206004820181905260248201527f676f7420656d707479206f722073696e676c65746f6e20706172746974696f6e604482015290519081900360640190fd5b6000848152600360205260409020548061123f576040805162461bcd60e51b815260206004820152601a60248201527918dbdb991a5d1a5bdb881b9bdd081c1c995c185c9959081e595d60321b604482015290519081900360640190fd5b6040805184815260208086028201019091526000196001831b01908190606090868015611276578160200160208202803883390190505b5090506060878790506040519080825280602002602001820160405280156112a8578160200160208202803883390190505b50905060005b878110156113c05760008989838181106112c457fe5b9050602002013590506000811180156112dc57508581105b611325576040805162461bcd60e51b815260206004820152601560248201527419dbdd081a5b9d985b1a59081a5b99195e081cd95d605a1b604482015290519081900360640190fd5b8085821614611374576040805162461bcd60e51b81526020600482015260166024820152751c185c9d1a5d1a5bdb881b9bdd08191a5cda9bda5b9d60521b604482015290519081900360640190fd5b938418936113878d6109f68e8e856120aa565b84838151811061139357fe5b602002602001018181525050878383815181106113ac57fe5b6020908102919091010152506001016112ae565b50826114a5578961148c57604080516323b872dd60e01b81523360048201523060248201526044810188905290516001600160a01b038d16916323b872dd9160648083019260209291908290030181600087803b15801561142057600080fd5b505af1158015611434573d6000803e3d6000fd5b505050506040513d602081101561144a57600080fd5b50516114875760405162461bcd60e51b81526004018080602001828103825260238152602001806137d06023913960400191505060405180910390fd5b6114a0565b6114a03361149a8d8d6123d9565b8861253a565b6114ba565b6114ba3361149a8d6109f68e8e898b186120aa565b6114d5338383604051806020016040528060008152506128fd565b888a336001600160a01b03167f2e6bb91f8cbcda0c93623c54d0403a43514fabc40084ec96b6d5379a747862988e8c8c8c60405180856001600160a01b03166001600160a01b03168152602001806020018381526020018281038252858582818152602001925060200280828437600083820152604051601f909101601f191690920182900397509095505050505050a45050505050505050505050565b6000611580848484612b30565b949350505050565b60006115808484846120aa565b600182116115ea576040805162461bcd60e51b815260206004820181905260248201527f676f7420656d707479206f722073696e676c65746f6e20706172746974696f6e604482015290519081900360640190fd5b60008481526003602052604090205480611648576040805162461bcd60e51b815260206004820152601a60248201527918dbdb991a5d1a5bdb881b9bdd081c1c995c185c9959081e595d60321b604482015290519081900360640190fd5b6040805184815260208086028201019091526000196001831b0190819060609086801561167f578160200160208202803883390190505b5090506060878790506040519080825280602002602001820160405280156116b1578160200160208202803883390190505b50905060005b878110156117c95760008989838181106116cd57fe5b9050602002013590506000811180156116e557508581105b61172e576040805162461bcd60e51b815260206004820152601560248201527419dbdd081a5b9d985b1a59081a5b99195e081cd95d605a1b604482015290519081900360640190fd5b808582161461177d576040805162461bcd60e51b81526020600482015260166024820152751c185c9d1a5d1a5bdb881b9bdd08191a5cda9bda5b9d60521b604482015290519081900360640190fd5b938418936117908d6109f68e8e856120aa565b84838151811061179c57fe5b602002602001018181525050878383815181106117b557fe5b6020908102919091010152506001016116b7565b506117d5338383612b7d565b826118d957896118b0576040805163a9059cbb60e01b81523360048201526024810188905290516001600160a01b038d169163a9059cbb9160448083019260209291908290030181600087803b15801561182e57600080fd5b505af1158015611842573d6000803e3d6000fd5b505050506040513d602081101561185857600080fd5b50516118ab576040805162461bcd60e51b815260206004820181905260248201527f636f756c64206e6f742073656e6420636f6c6c61746572616c20746f6b656e73604482015290519081900360640190fd5b6118d4565b6118d4336118be8d8d6123d9565b88604051806020016040528060008152506125d5565b6118ee565b6118ee336118be8d6109f68e8e898b186120aa565b888a336001600160a01b03167f6f13ca62553fcc2bcd2372180a43949c1e4cebba603901ede2f4e14f36b282ca8e8c8c8c60405180856001600160a01b03166001600160a01b03168152602001806020018381526020018281038252858582818152602001925060200280828437600083820152604051601f909101601f191690920182900397509095505050505050a45050505050505050505050565b3360008181526002602090815260408083206001600160a01b03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b8060018111611a3a5760405162461bcd60e51b815260040180806020018281038252602a8152602001806138dc602a913960400191505060405180910390fd5b6000611a47338684612b30565b6000818152600360205260409020549091508214611aac576040805162461bcd60e51b815260206004820152601f60248201527f636f6e646974696f6e206e6f74207072657061726564206f7220666f756e6400604482015290519081900360640190fd5b60008181526004602052604090205415611b0d576040805162461bcd60e51b815260206004820152601e60248201527f7061796f75742064656e6f6d696e61746f7220616c7265616479207365740000604482015290519081900360640190fd5b6000805b83811015611bf2576000868683818110611b2757fe5b905060200201359050611b43818461241d90919063ffffffff16565b600085815260036020526040902080549194509083908110611b6157fe5b9060005260206000200154600014611bc0576040805162461bcd60e51b815260206004820152601c60248201527f7061796f7574206e756d657261746f7220616c72656164792073657400000000604482015290519081900360640190fd5b6000848152600360205260409020805482919084908110611bdd57fe5b60009182526020909120015550600101611b11565b5060008111611c3f576040805162461bcd60e51b81526020600482015260146024820152737061796f757420697320616c6c207a65726f657360601b604482015290519081900360640190fd5b60008281526004602090815260408083208490556003825291829020825186815291820183815281549383018490528993339387937fb44d84d3289691f71497564b85d4233648d9dbae8cbdbb4329f301c3a0185894938a93919291606083019084908015611ccd57602002820191906000526020600020905b815481526020019060010190808311611cb9575b5050935050505060405180910390a4505050505050565b60009081526003602052604090205490565b610100811115611d46576040805162461bcd60e51b8152602060048201526016602482015275746f6f206d616e79206f7574636f6d6520736c6f747360501b604482015290519081900360640190fd5b60018111611d855760405162461bcd60e51b815260040180806020018281038252602a8152602001806138dc602a913960400191505060405180910390fd5b6000611d92848484612b30565b60008181526003602052604090205490915015611df6576040805162461bcd60e51b815260206004820152601a60248201527f636f6e646974696f6e20616c7265616479207072657061726564000000000000604482015290519081900360640190fd5b81604051908082528060200260200182016040528015611e20578160200160208202803883390190505b5060008281526003602090815260409091208251611e44939192919091019061366e565b5082846001600160a01b0316827fab3760c3bd2bb38b5bcf54dc79802ed67338b4cf29f3054ded67ed24661e4177856040518082815260200191505060405180910390a450505050565b60046020526000908152604090205481565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205460ff1690565b6001600160a01b038516611f135760405162461bcd60e51b81526004018080602001828103825260288152602001806137526028913960400191505060405180910390fd5b6001600160a01b038616331480611f5257506001600160a01b038616600090815260026020908152604080832033845290915290205460ff1615156001145b611f8d5760405162461bcd60e51b81526004018080602001828103825260388152602001806138a46038913960400191505060405180910390fd5b60008481526001602090815260408083206001600160a01b038a168452909152902054611fc0908463ffffffff6126c316565b60008581526001602090815260408083206001600160a01b038b81168552925280832093909355871681522054611ff890849061241d565b60008581526001602090815260408083206001600160a01b03808b16808652918452938290209490945580518881529182018790528051928a169233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a46120a2338787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612d6192505050565b505050505050565b6040805160208082018590528183018490528251808303840181526060909201909252805191012060009060ff81901c151582805b60008051602061377a83398151915260018508935060008051602061377a833981519152600360008051602061377a83398151915280878809870908905061212681612ec3565b91508060008051602061377a83398151915283840914156120df5782801561214f575060028206155b806121665750821580156121665750600282066001145b1561217f578160008051602061377a8339815191520391505b8780156123b65760fe81901c151593506001600160fe1b031660008051602061377a833981519152600360008051602061377a83398151915280848509840908915060006121cc83612ec3565b90508480156121dc575060028106155b806121f35750841580156121f35750600281066001145b156122095760008051602061377a833981519152035b8260008051602061377a8339815191528283091461226e576040805162461bcd60e51b815260206004820152601c60248201527f696e76616c696420706172656e7420636f6c6c656374696f6e20494400000000604482015290519081900360640190fd5b6000606060066001600160a01b031688878686604051602001808581526020018481526020018381526020018281526020019450505050506040516020818303038152906040526040518082805190602001908083835b602083106122e45780518252601f1990920191602091820191016122c5565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114612344576040519150601f19603f3d011682016040523d82523d6000602084013e612349565b606091505b50915091508161238f576040805162461bcd60e51b815260206004820152600c60248201526b1958d859190819985a5b195960a21b604482015290519081900360640190fd5b8080602001905160408110156123a457600080fd5b50805160209091015190985095505050505b60028306600114156123cc57600160fe1b851894505b5092979650505050505050565b6040805160609390931b6bffffffffffffffffffffffff19166020808501919091526034808501939093528151808503909301835260549093019052805191012090565b60008282018381101561101e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082612486575060006108b3565b8282028284828161249357fe5b041461101e5760405162461bcd60e51b81526004018080602001828103825260218152602001806138276021913960400191505060405180910390fd5b6000808211612526576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b600082848161253157fe5b04949350505050565b60008281526001602090815260408083206001600160a01b038716845290915290205461256d908263ffffffff6126c316565b60008381526001602090815260408083206001600160a01b038816808552908352818420949094558051868152918201859052805192939233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a4505050565b6001600160a01b03841661261a5760405162461bcd60e51b815260040180806020018281038252602181526020018061392d6021913960400191505060405180910390fd5b60008381526001602090815260408083206001600160a01b038816845290915290205461264e90839063ffffffff61241d16565b60008481526001602090815260408083206001600160a01b038916808552908352818420949094558051878152918201869052805133927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a46126bd33600086868686612d61565b50505050565b60008282111561271a576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b612732846001600160a01b0316613668565b156120a25760405163bc197c8160e01b8082526001600160a01b0388811660048401908152888216602485015260a060448501908152875160a4860152875193949289169363bc197c81938c938c938b938b938b9392916064820191608481019160c4909101906020808a01910280838360005b838110156127be5781810151838201526020016127a6565b50505050905001848103835286818151815260200191508051906020019060200280838360005b838110156127fd5781810151838201526020016127e5565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015612839578181015183820152602001612821565b50505050905090810190601f1680156128665780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b15801561288b57600080fd5b505af115801561289f573d6000803e3d6000fd5b505050506040513d60208110156128b557600080fd5b50516001600160e01b031916146120a25760405162461bcd60e51b815260040180806020018281038252603681526020018061379a6036913960400191505060405180910390fd5b6001600160a01b0384166129425760405162461bcd60e51b81526004018080602001828103825260278152602001806139066027913960400191505060405180910390fd5b81518351146129825760405162461bcd60e51b815260040180806020018281038252602e815260200180613876602e913960400191505060405180910390fd5b60005b8351811015612a46576129fd600160008684815181106129a157fe5b602002602001015181526020019081526020016000206000876001600160a01b03166001600160a01b03168152602001908152602001600020548483815181106129e757fe5b602002602001015161241d90919063ffffffff16565b60016000868481518110612a0d57fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038a168252909252902055600101612985565b50836001600160a01b031660006001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015612acd578181015183820152602001612ab5565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612b0c578181015183820152602001612af4565b5050505090500194505050505060405180910390a46126bd33600086868686612720565b6040805160609490941b6bffffffffffffffffffffffff19166020808601919091526034850193909352605480850192909252805180850390920182526074909301909252815191012090565b8051825114612bbd5760405162461bcd60e51b815260040180806020018281038252602e815260200180613876602e913960400191505060405180910390fd5b60005b8251811015612c8157612c38828281518110612bd857fe5b602002602001015160016000868581518110612bf057fe5b602002602001015181526020019081526020016000206000876001600160a01b03166001600160a01b03168152602001908152602001600020546126c390919063ffffffff16565b60016000858481518110612c4857fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b0389168252909252902055600101612bc0565b5060006001600160a01b0316836001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8585604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015612d08578181015183820152602001612cf0565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612d47578181015183820152602001612d2f565b5050505090500194505050505060405180910390a4505050565b612d73846001600160a01b0316613668565b156120a25760405163f23a6e6160e01b8082526001600160a01b03888116600484019081528882166024850152604484018790526064840186905260a060848501908152855160a4860152855193949289169363f23a6e61938c938c938b938b938b93929160c490910190602085019080838360005b83811015612e01578181015183820152602001612de9565b50505050905090810190601f168015612e2e5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b158015612e5157600080fd5b505af1158015612e65573d6000803e3d6000fd5b505050506040513d6020811015612e7b57600080fd5b50516001600160e01b031916146120a25760405162461bcd60e51b815260040180806020018281038252603181526020018061394e6031913960400191505060405180910390fd5b600060008051602061377a833981519152808380099150808283098181820990508181840992508183850993508184840992508183840990508181820982818309905082818209905082818209905082818309915082828609945082858609915082828309915082828509935082848509915082828309915082828309915082828509915082828609945082858609915082828309915082828309915082828609915082828509935082848609945082858609915082828309915082828509935082848509915082828309905082818209905082818209905082818309915082828609945082858509935082848509915082828309915082828309915082828609945082858609915082828309915082828609915082828309915082828309915082828609915082828509935082848509915082828309905082818209905082818309905082818509905082818209905082818209905082818209905082818209905082818309915082828609945082858609915082828609915082828509935082848509915082828509915082828309915082828309905082818309905082818209838182099050838182099050838182099050838182099050838183099150508281830991508282860994508285850993508284850991508282860994508285850993508284860994508285850993508284860994508285860991508282860991508282830991508282850993508284850991508282830991508282860994508285850993508284850991508282850991508282860994508285850993508284860994508285850993508284850991508282830991508282850991508282860994508285860991508282860991508282850993508284860994508285850993508284860994508285850993508284850991508282850991508282830991508282860994508285850993508284850991508282850991508282830991508282860994508285860991508282830990508281820990508281830990508281860990508281820990508281820990508281820990508281820990508281830991508282850993508284860994508285850993508284860994508285860991508282860991508282830991508282830991508282830991508282860991508282850993508284850991508282850991508282830991508282860994508285860991508282860991508282850993508284860994508285860991508282830991508282850993508284860994508285860991508282850993508284860994508285850993508284850991508282850991508282860994508285850993508284850991508282850991508282830991508282830991508282860994508285860991508282830991508282830991508282860991508282850993508284860994508285860991508282860990508281820990508281820990508281830991508282850993508284850991508282860994508285850993508284860994508285850993508284860994508285850993508284850991508282850990508281850991508282830991508282830991508282820991505081818509935081848409925081838509935081848409925081838509935081848509905081818509905081818409925050808284099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808384099250808383099392505050565b3b151590565b8280548282559060005260206000209081019282156136a9579160200282015b828111156136a957825182559160200191906001019061368e565b506136b59291506136b9565b5090565b6136d391905b808211156136b557600081556001016136bf565b9056fe726573756c7420666f7220636f6e646974696f6e206e6f7420726563656976656420796574455243313135353a2062616c616e636520717565727920666f7220746865207a65726f2061646472657373636f756c64206e6f74207472616e73666572207061796f757420746f206d6573736167652073656e646572455243313135353a207461726765742061646472657373206d757374206265206e6f6e2d7a65726f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47455243313135353a20676f7420756e6b6e6f776e2076616c75652066726f6d206f6e4552433131353542617463685265636569766564636f756c64206e6f74207265636569766520636f6c6c61746572616c20746f6b656e73455243313135353a20736f6d65206164647265737320696e2062617463682062616c616e6365207175657279206973207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77455243313135353a206f776e65727320616e6420494473206d75737420686176652073616d65206c656e67746873455243313135353a2049447320616e642076616c756573206d75737420686176652073616d65206c656e67746873455243313135353a206e656564206f70657261746f7220617070726f76616c20666f7220337264207061727479207472616e73666572732e74686572652073686f756c64206265206d6f7265207468616e206f6e65206f7574636f6d6520736c6f74455243313135353a206261746368206d696e7420746f20746865207a65726f2061646472657373455243313135353a206d696e7420746f20746865207a65726f2061646472657373455243313135353a20676f7420756e6b6e6f776e2076616c75652066726f6d206f6e455243313135355265636569766564a265627a7a72305820bb492e79ca824aaf4ea2279d9e6fd09603dd4860390a782c93aaffb1144f4b5064736f6c634300050a0032" -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/conditional_tokens/contract.py b/trader_old/vendor/valory/contracts/conditional_tokens/contract.py deleted file mode 100644 index bc7485e15..000000000 --- a/trader_old/vendor/valory/contracts/conditional_tokens/contract.py +++ /dev/null @@ -1,420 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the conditional tokens contract definition.""" -import concurrent.futures -from typing import List, Any, Dict, Union, Callable - -from requests.exceptions import ReadTimeout as RequestsReadTimeoutError -from urllib3.exceptions import ReadTimeoutError as Urllib3ReadTimeoutError -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from hexbytes import HexBytes -from web3.types import BlockIdentifier - - -FIVE_MINUTES = 300.0 -DEFAULT_OUTCOME_SLOT = 2 - -class ConditionalTokensContract(Contract): - """The ConditionalTokens smart contract.""" - - contract_id = PublicId.from_str("valory/conditional_tokens:0.1.0") - - @staticmethod - def execute_with_timeout(func: Callable, timeout: float) -> Any: - """Execute a function with a timeout.""" - - # Create a ProcessPoolExecutor with a maximum of 1 worker (process) - with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: - # Submit the function to the executor - future = executor.submit( - func, - ) - - try: - # Wait for the result with a 5-minute timeout - data = future.result(timeout=timeout) - except TimeoutError: - # Handle the case where the execution times out - err = f"The RPC didn't respond in {timeout}." - return None, err - - # Check if an error occurred - if isinstance(data, str): - # Handle the case where the execution failed - return None, data - - return data, None - - @classmethod - def check_redeemed( - cls, - ledger_api: LedgerApi, - contract_address: str, - redeemer: str, - from_block: int, - to_block: int, - collateral_tokens: List[str], - parent_collection_ids: List[bytes], - condition_ids: List[HexBytes], - index_sets: List[List[int]], - timeout: float = FIVE_MINUTES, - ) -> JSONLike: - """Filter to find out whether a position has already been redeemed.""" - - def get_redeem_events() -> Union[List[Dict[str, Any]], str]: - """Get the redeem events.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - to_checksum = ledger_api.api.to_checksum_address - redeemer_checksummed = to_checksum(redeemer) - collateral_tokens_checksummed = [ - to_checksum(token) for token in collateral_tokens - ] - try: - payout_filter = contract_instance.events.PayoutRedemption.build_filter() - payout_filter.args.redeemer.match_single(redeemer_checksummed) - payout_filter.args.collateralToken.match_any(*collateral_tokens_checksummed) - payout_filter.args.parentCollectionId.match_any(*parent_collection_ids) - payout_filter.args.conditionId.match_any(*condition_ids) - payout_filter.args.indexSets.match_any(*index_sets) - payout_filter.fromBlock = from_block - payout_filter.toBlock = to_block - redeemed = list(payout_filter.deploy(ledger_api.api).get_all_entries()) - return redeemed - - except (Urllib3ReadTimeoutError, RequestsReadTimeoutError): - msg = ( - "The RPC timed out! This usually happens if the filtering is too wide. " - f"The service tried to filter from block {from_block} to {to_block}. " - f"If this issue persists, please try lowering the `EVENT_FILTERING_BATCH_SIZE`!" - ) - return msg - - redeemed, err = cls.execute_with_timeout(get_redeem_events, timeout) - if err is not None: - return dict(error=err) - - payouts = {} - for redeeming in redeemed: - args = redeeming.get("args", {}) - condition_id = args.get("conditionId", None) - payout = args.get("payout", 0) - if condition_id is not None and payout > 0: - if isinstance(condition_id, bytes): - condition_id = condition_id.hex() - payouts[condition_id] = payout - - return dict(payouts=payouts) - - @classmethod - def check_resolved( - cls, - ledger_api: LedgerApi, - contract_address: str, - condition_id: HexBytes, - ) -> JSONLike: - """Check whether a position has already been resolved.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - payout_denominator = contract_instance.functions.payoutDenominator - payout = payout_denominator(condition_id).call() - if payout == 0: - return dict(resolved=False) - return dict(resolved=True) - - @classmethod - def build_redeem_positions_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - collateral_token: str, - parent_collection_id: bytes, - condition_id: HexBytes, - index_sets: List[int], - ) -> JSONLike: - """Build a `redeemPositions` tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI( - fn_name="redeemPositions", - args=[ - ledger_api.api.to_checksum_address(collateral_token), - parent_collection_id, - condition_id, - index_sets, - ], - ) - return dict(data=data) - - @classmethod - def get_raw_transaction( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> JSONLike: - """ - Handler method for the 'GET_RAW_TRANSACTION' requests. - - Implement this method in the sub class if you want - to handle the contract requests manually. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param kwargs: the keyword arguments. - :return: the tx # noqa: DAR202 - """ - raise NotImplementedError - - @classmethod - def get_raw_message( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> bytes: - """ - Handler method for the 'GET_RAW_MESSAGE' requests. - - Implement this method in the sub class if you want - to handle the contract requests manually. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param kwargs: the keyword arguments. - :return: the tx # noqa: DAR202 - """ - raise NotImplementedError - - @classmethod - def get_state( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> JSONLike: - """ - Handler method for the 'GET_STATE' requests. - - Implement this method in the sub class if you want - to handle the contract requests manually. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param kwargs: the keyword arguments. - :return: the tx # noqa: DAR202 - """ - raise NotImplementedError - - @classmethod - def get_prepare_condition_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: str, - oracle_contract: str, - outcome_slot_count: int = DEFAULT_OUTCOME_SLOT, - ) -> JSONLike: - """Tx for preparing condition for marker maker.""" - kwargs = { - "oracle": ledger_api.api.to_checksum_address(oracle_contract), - "questionId": question_id, - "outcomeSlotCount": outcome_slot_count, - } - return ledger_api.build_transaction( - contract_instance=cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ), - method_name="prepareCondition", - method_args=kwargs, - ) - - @classmethod - def get_prepare_condition_tx_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: str, - oracle_contract: str, - outcome_slot_count: int = DEFAULT_OUTCOME_SLOT, - ) -> JSONLike: - """Tx for preparing condition for marker maker.""" - kwargs = { - "oracle": ledger_api.api.to_checksum_address(oracle_contract), - "questionId": question_id, - "outcomeSlotCount": outcome_slot_count, - } - contract_instance = cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - data = contract_instance.encodeABI(fn_name="prepareCondition", kwargs=kwargs) - return {"data": bytes.fromhex(data[2:])} - - @classmethod - def calculate_condition_id( - cls, - ledger_api: LedgerApi, - contract_address: str, - oracle_contract: str, - question_id: str, - outcome_slot_count: int, - ) -> str: - """Calculate condition ID.""" - return { - "condition_id": ledger_api.api.solidity_keccak( - ["address", "bytes32", "uint256"], - [ - ledger_api.api.to_checksum_address(oracle_contract), - bytes.fromhex(question_id[2:]), - outcome_slot_count, - ], - ).hex() - } - - @classmethod - def get_condition_id( - cls, - ledger_api: LedgerApi, - contract_address: str, - tx_digest: str, # retrieved from `prepareCondition` tx - ) -> JSONLike: - """Tx for preparing condition for marker maker.""" - contract_instance = cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - tx_receipt = ledger_api.api.eth.getTransactionReceipt(tx_digest) - (log,) = contract_instance.events.ConditionPreparation().process_receipt( - tx_receipt - ) - return "0x" + log["args"]["conditionId"].hex() - - @classmethod - def get_condition_preparation_events( - cls, - ledger_api: LedgerApi, - contract_address: str, - condition_ids: List[bytes], - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - ) -> JSONLike: - """Get condition preparation events.""" - contract_instance = cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - entries = ( - contract_instance.events.ConditionPreparation() - .create_filter( - fromBlock=from_block, - toBlock=to_block, - argument_filters={ - "conditionId": condition_ids, - }, - ) - .get_all_entries() - ) - events = list( - dict( - tx_hash=entry.transactionHash.hex(), - block_number=entry.blockNumber, - condition_id=entry["args"]["conditionId"], - oracle=entry["args"]["oracle"], - question_id=entry["args"]["questionId"], - outcome_slot_count=entry["args"]["outcomeSlotCount"], - ) - for entry in entries - ) - return dict(data=events) - - @staticmethod - def get_partitions(count: int) -> List[int]: - """Calculate and return partitions.""" - return list(map(lambda x: 1 << x, range(count))) - - @classmethod - def get_user_holdings( - cls, - ledger_api: LedgerApi, - contract_address: str, - outcome_slot_count: int, - condition_id: str, - creator: str, - collateral_token: str, - market: str, - parent_collection_id: str, - ) -> JSONLike: - """Returns user holding.""" - holdings = [] - shares = [] - instance = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - for i in cls.get_partitions(count=outcome_slot_count): - collection_id = int.from_bytes( - instance.functions.getCollectionId( - parent_collection_id, condition_id, i - ).call(), - "big", - ) - position_id = int.from_bytes( - ledger_api.api.solidity_keccak( - ["address", "uint256"], - [ - ledger_api.api.to_checksum_address(collateral_token), - collection_id, - ], - ), - "big", - ) - holdings.append( - instance.functions.balanceOf( - ledger_api.api.to_checksum_address(market), - position_id, - ).call() - ) - shares.append( - instance.functions.balanceOf( - ledger_api.api.to_checksum_address(creator), position_id - ).call() - ) - return dict( - holdings=holdings, - shares=shares, - ) - - @classmethod - def build_merge_positions_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - collateral_token: str, - parent_collection_id: bytes, - condition_id: bytes, - outcome_slot_count: int, - amount: int, - **kwargs: Any - ) -> JSONLike: - """Build mergePositions tx.""" - instance = cls.get_instance(ledger_api, contract_address) - partition = cls.get_partitions(count=outcome_slot_count) - data = instance.encodeABI( - fn_name="mergePositions", - args=[ - ledger_api.api.to_checksum_address(collateral_token), - parent_collection_id, - condition_id, - partition, - amount, - ], - ) - return dict( - data=data, - ) diff --git a/trader_old/vendor/valory/contracts/conditional_tokens/contract.yaml b/trader_old/vendor/valory/contracts/conditional_tokens/contract.yaml deleted file mode 100644 index d5b5b8def..000000000 --- a/trader_old/vendor/valory/contracts/conditional_tokens/contract.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: conditional_tokens -author: valory -version: 0.1.0 -type: contract -description: ConditionalTokens contract. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeidhdxio3oq5gqdnxmngumvt3fcd6zyiyrpk5f2k4dwhflbg4e5iky - build/ConditionalTokens.json: bafybeia2ahis7zx2yhhf23kpkcxu56hto6fwg6ptjg5ld46lp4dgz7cz3e - contract.py: bafybeigdhjd2qvkmawsxd4afufr6uy3hufxwi3chcne5gba5i6whitn2r4 -fingerprint_ignore_patterns: [] -class_name: ConditionalTokensContract -contract_interface_paths: - ethereum: build/ConditionalTokens.json -dependencies: - hexbytes: {} - web3: - version: <7,>=6.0.0 - requests: - version: ==2.28.1 - urllib3: - version: ==1.26.16 -contracts: [] diff --git a/trader_old/vendor/valory/contracts/erc20/README.md b/trader_old/vendor/valory/contracts/erc20/README.md deleted file mode 100644 index 8c0c7780b..000000000 --- a/trader_old/vendor/valory/contracts/erc20/README.md +++ /dev/null @@ -1 +0,0 @@ -# ERC20 token contract diff --git a/trader_old/vendor/valory/contracts/erc20/__init__.py b/trader_old/vendor/valory/contracts/erc20/__init__.py deleted file mode 100644 index dce069dfb..000000000 --- a/trader_old/vendor/valory/contracts/erc20/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the support resources for an ERC20 token.""" diff --git a/trader_old/vendor/valory/contracts/erc20/build/ERC20.json b/trader_old/vendor/valory/contracts/erc20/build/ERC20.json deleted file mode 100644 index da6252cad..000000000 --- a/trader_old/vendor/valory/contracts/erc20/build/ERC20.json +++ /dev/null @@ -1,288 +0,0 @@ -{ - "_format": "", - "contractName": "", - "sourceName": "", - "abi": [ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "guy", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "src", - "type": "address" - }, - { - "name": "dst", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "wad", - "type": "uint256" - } - ], - "name": "withdraw", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "dst", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "deposit", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": true, - "name": "guy", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": true, - "name": "dst", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "dst", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Withdrawal", - "type": "event" - } - ], - "bytecode": "", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/erc20/contract.py b/trader_old/vendor/valory/contracts/erc20/contract.py deleted file mode 100644 index 9ad5c0686..000000000 --- a/trader_old/vendor/valory/contracts/erc20/contract.py +++ /dev/null @@ -1,101 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the class to connect to an ERC20 token contract.""" - -from typing import Dict - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi - - -PUBLIC_ID = PublicId.from_str("valory/erc20:0.1.0") - - -class ERC20(Contract): - """The ERC20 contract.""" - - contract_id = PUBLIC_ID - - @classmethod - def check_balance( - cls, - ledger_api: EthereumApi, - contract_address: str, - account: str, - ) -> JSONLike: - """Check the balance of the given account.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - balance_of = getattr(contract_instance.functions, "balanceOf") # noqa - token_balance = balance_of(account).call() - wallet_balance = ledger_api.api.eth.get_balance(account) - return dict(token=token_balance, wallet=wallet_balance) - - @classmethod - def get_allowance( - cls, - ledger_api: EthereumApi, - contract_address: str, - owner: str, - spender: str, - ) -> JSONLike: - """Check the balance of the given account.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - allowance = contract_instance.functions.allowance(owner, spender).call() - return dict(data=allowance) - - @classmethod - def build_deposit_tx( - cls, - ledger_api: EthereumApi, - contract_address: str, - ) -> Dict[str, bytes]: - """Build a deposit transaction.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("deposit") - return {"data": bytes.fromhex(data[2:])} - - @classmethod - def build_withdraw_tx( - cls, - ledger_api: EthereumApi, - contract_address: str, - amount: int, - ) -> Dict[str, bytes]: - """Build a deposit transaction.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("withdraw", args=(amount,)) - return {"data": bytes.fromhex(data[2:])} - - @classmethod - def build_approval_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - spender: str, - amount: int, - ) -> Dict[str, bytes]: - """Build an ERC20 approval.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - checksumed_spender = ledger_api.api.to_checksum_address(spender) - data = contract_instance.encodeABI("approve", args=(checksumed_spender, amount)) - return {"data": bytes.fromhex(data[2:])} diff --git a/trader_old/vendor/valory/contracts/erc20/contract.yaml b/trader_old/vendor/valory/contracts/erc20/contract.yaml deleted file mode 100644 index 060881677..000000000 --- a/trader_old/vendor/valory/contracts/erc20/contract.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: erc20 -author: valory -version: 0.1.0 -type: contract -description: ERC20 token contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeifmfma6rglvpa22odtozyosnp5mwljum64utxip2wgmezuhnjjjyi - __init__.py: bafybeif5vpc3dfrlxlch7brbhmdwksabyzddpfqgm56vdbbkek3t3br6ke - build/ERC20.json: bafybeiemn5b5nszuss7xj6lmvmjuendltp6wz7ubihdvd7c6wqw4bohbpa - contract.py: bafybeien5pkaqqlwhp76r2jepzh4c2ww7nbyuyhwxqseeeojxpcmulxixm -fingerprint_ignore_patterns: [] -contracts: [] -class_name: ERC20 -contract_interface_paths: - ethereum: build/ERC20.json -dependencies: - ecdsa: - version: '>=0.15' - eth_typing: {} - hexbytes: {} - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - packaging: {} - py-eth-sig-utils: {} - requests: - version: ==2.28.1 - web3: - version: <7,>=6.0.0 diff --git a/trader_old/vendor/valory/contracts/gnosis_safe/README.md b/trader_old/vendor/valory/contracts/gnosis_safe/README.md deleted file mode 100644 index c9c48a5e5..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Gnosis Safe contract - -## Description - -## Functions - diff --git a/trader_old/vendor/valory/contracts/gnosis_safe/__init__.py b/trader_old/vendor/valory/contracts/gnosis_safe/__init__.py deleted file mode 100644 index e394b583e..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the support resources for the gnosis_safe (GnosisSafeL2) contract.""" # pragma: nocover diff --git a/trader_old/vendor/valory/contracts/gnosis_safe/build/GnosisSafe_V1_3_0.json b/trader_old/vendor/valory/contracts/gnosis_safe/build/GnosisSafe_V1_3_0.json deleted file mode 100644 index 7e0b017d2..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe/build/GnosisSafe_V1_3_0.json +++ /dev/null @@ -1,1179 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "GnosisSafeL2", - "sourceName": "contracts/GnosisSafeL2.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "AddedOwner", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "approvedHash", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "ApproveHash", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "handler", - "type": "address" - } - ], - "name": "ChangedFallbackHandler", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "guard", - "type": "address" - } - ], - "name": "ChangedGuard", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - } - ], - "name": "ChangedThreshold", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "DisabledModule", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "EnabledModule", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "txHash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "payment", - "type": "uint256" - } - ], - "name": "ExecutionFailure", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "ExecutionFromModuleFailure", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "ExecutionFromModuleSuccess", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32", - "name": "txHash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "payment", - "type": "uint256" - } - ], - "name": "ExecutionSuccess", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "RemovedOwner", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "module", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - } - ], - "name": "SafeModuleTransaction", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "safeTxGas", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "baseGas", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "gasPrice", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "gasToken", - "type": "address" - }, - { - "indexed": false, - "internalType": "address payable", - "name": "refundReceiver", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "signatures", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "additionalInfo", - "type": "bytes" - } - ], - "name": "SafeMultiSigTransaction", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "SafeReceived", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "initiator", - "type": "address" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "owners", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "initializer", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "fallbackHandler", - "type": "address" - } - ], - "name": "SafeSetup", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "msgHash", - "type": "bytes32" - } - ], - "name": "SignMsg", - "type": "event" - }, - { - "stateMutability": "nonpayable", - "type": "fallback" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_threshold", - "type": "uint256" - } - ], - "name": "addOwnerWithThreshold", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "hashToApprove", - "type": "bytes32" - } - ], - "name": "approveHash", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "approvedHashes", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_threshold", - "type": "uint256" - } - ], - "name": "changeThreshold", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "signatures", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "requiredSignatures", - "type": "uint256" - } - ], - "name": "checkNSignatures", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "signatures", - "type": "bytes" - } - ], - "name": "checkSignatures", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "prevModule", - "type": "address" - }, - { - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "disableModule", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "domainSeparator", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "enableModule", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "safeTxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "baseGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gasPrice", - "type": "uint256" - }, - { - "internalType": "address", - "name": "gasToken", - "type": "address" - }, - { - "internalType": "address", - "name": "refundReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nonce", - "type": "uint256" - } - ], - "name": "encodeTransactionData", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "safeTxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "baseGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gasPrice", - "type": "uint256" - }, - { - "internalType": "address", - "name": "gasToken", - "type": "address" - }, - { - "internalType": "address payable", - "name": "refundReceiver", - "type": "address" - }, - { - "internalType": "bytes", - "name": "signatures", - "type": "bytes" - } - ], - "name": "execTransaction", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - } - ], - "name": "execTransactionFromModule", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - } - ], - "name": "execTransactionFromModuleReturnData", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "returnData", - "type": "bytes" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getChainId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "message", - "type": "bytes" - } - ], - "name": "getMessageHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "start", - "type": "address" - }, - { - "internalType": "uint256", - "name": "pageSize", - "type": "uint256" - } - ], - "name": "getModulesPaginated", - "outputs": [ - { - "internalType": "address[]", - "name": "array", - "type": "address[]" - }, - { - "internalType": "address", - "name": "next", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOwners", - "outputs": [ - { - "internalType": "address[]", - "name": "", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "offset", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "length", - "type": "uint256" - } - ], - "name": "getStorageAt", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getThreshold", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "safeTxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "baseGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "gasPrice", - "type": "uint256" - }, - { - "internalType": "address", - "name": "gasToken", - "type": "address" - }, - { - "internalType": "address", - "name": "refundReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nonce", - "type": "uint256" - } - ], - "name": "getTransactionHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "module", - "type": "address" - } - ], - "name": "isModuleEnabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "isOwner", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "nonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "prevOwner", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_threshold", - "type": "uint256" - } - ], - "name": "removeOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - } - ], - "name": "requiredTxGas", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "handler", - "type": "address" - } - ], - "name": "setFallbackHandler", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "guard", - "type": "address" - } - ], - "name": "setGuard", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "_owners", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "_threshold", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "address", - "name": "fallbackHandler", - "type": "address" - }, - { - "internalType": "address", - "name": "paymentToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "payment", - "type": "uint256" - }, - { - "internalType": "address payable", - "name": "paymentReceiver", - "type": "address" - } - ], - "name": "setup", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "signMessage", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "signedMessages", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "targetContract", - "type": "address" - }, - { - "internalType": "bytes", - "name": "calldataPayload", - "type": "bytes" - } - ], - "name": "simulateAndRevert", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "prevOwner", - "type": "address" - }, - { - "internalType": "address", - "name": "oldOwner", - "type": "address" - }, - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "swapOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b506001600481905550615f6280620000296000396000f3fe6080604052600436106101f25760003560e01c8063a0e67e2b1161010d578063e009cfde116100a0578063e86637db1161006f578063e86637db14611620578063f08a0323146117bf578063f698da2514611810578063f8dc5dd91461183b578063ffa1ad74146118b657610247565b8063e009cfde146114a2578063e19a9dd914611513578063e318b52b14611564578063e75235b8146115f557610247565b8063c4ca3a9c116100dc578063c4ca3a9c1461118f578063cc2f845214611260578063d4d9bdcd1461132d578063d8d11f781461136857610247565b8063a0e67e2b14610ea0578063affed0e014610f0c578063b4faba0914610f37578063b63e800d1461101f57610247565b80635624b25b116101855780636a761202116101545780636a76120214610a865780637d83297414610c4257806385a5affe14610cb1578063934f3a1114610d3757610247565b80635624b25b146108ed5780635ae6bd37146109ab578063610b5925146109fa578063694e80c314610a4b57610247565b80632f54bf6e116101c15780632f54bf6e146105c55780633408e4701461062c578063468721a7146106575780635229073f1461076c57610247565b80630a1028c4146102b45780630d582f131461039057806312fb68e0146103eb5780632d9ad53d1461055e57610247565b36610247573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561025357600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061028857600080f35b36600080373360601b365260008060143601600080855af13d6000803e806102af573d6000fd5b3d6000f35b3480156102c057600080fd5b5061037a600480360360208110156102d757600080fd5b81019080803590602001906401000000008111156102f457600080fd5b82018360208201111561030657600080fd5b8035906020019184600183028401116401000000008311171561032857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611946565b6040518082815260200191505060405180910390f35b34801561039c57600080fd5b506103e9600480360360408110156103b357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611a3e565b005b3480156103f757600080fd5b5061055c6004803603608081101561040e57600080fd5b81019080803590602001909291908035906020019064010000000081111561043557600080fd5b82018360208201111561044757600080fd5b8035906020019184600183028401116401000000008311171561046957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156104cc57600080fd5b8201836020820111156104de57600080fd5b8035906020019184600183028401116401000000008311171561050057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611e2e565b005b34801561056a57600080fd5b506105ad6004803603602081101561058157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506126b0565b60405180821515815260200191505060405180910390f35b3480156105d157600080fd5b50610614600480360360208110156105e857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612782565b60405180821515815260200191505060405180910390f35b34801561063857600080fd5b50610641612854565b6040518082815260200191505060405180910390f35b34801561066357600080fd5b506107546004803603608081101561067a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106c157600080fd5b8201836020820111156106d357600080fd5b803590602001918460018302840111640100000000831117156106f557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050612861565b60405180821515815260200191505060405180910390f35b34801561077857600080fd5b506108696004803603608081101561078f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156107d657600080fd5b8201836020820111156107e857600080fd5b8035906020019184600183028401116401000000008311171561080a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff16906020019092919050505061296c565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156108b1578082015181840152602081019050610896565b50505050905090810190601f1680156108de5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b3480156108f957600080fd5b506109306004803603604081101561091057600080fd5b8101908080359060200190929190803590602001909291905050506129a2565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610970578082015181840152602081019050610955565b50505050905090810190601f16801561099d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156109b757600080fd5b506109e4600480360360208110156109ce57600080fd5b8101908080359060200190929190505050612a29565b6040518082815260200191505060405180910390f35b348015610a0657600080fd5b50610a4960048036036020811015610a1d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a41565b005b348015610a5757600080fd5b50610a8460048036036020811015610a6e57600080fd5b8101908080359060200190929190505050612dd3565b005b610c2a6004803603610140811015610a9d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610ae457600080fd5b820183602082011115610af657600080fd5b80359060200191846001830284011164010000000083111715610b1857600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ba457600080fd5b820183602082011115610bb657600080fd5b80359060200191846001830284011164010000000083111715610bd857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612f0d565b60405180821515815260200191505060405180910390f35b348015610c4e57600080fd5b50610c9b60048036036040811015610c6557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061314c565b6040518082815260200191505060405180910390f35b348015610cbd57600080fd5b50610d3560048036036020811015610cd457600080fd5b8101908080359060200190640100000000811115610cf157600080fd5b820183602082011115610d0357600080fd5b80359060200191846001830284011164010000000083111715610d2557600080fd5b9091929391929390505050613171565b005b348015610d4357600080fd5b50610e9e60048036036060811015610d5a57600080fd5b810190808035906020019092919080359060200190640100000000811115610d8157600080fd5b820183602082011115610d9357600080fd5b80359060200191846001830284011164010000000083111715610db557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610e1857600080fd5b820183602082011115610e2a57600080fd5b80359060200191846001830284011164010000000083111715610e4c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613215565b005b348015610eac57600080fd5b50610eb56132a4565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610ef8578082015181840152602081019050610edd565b505050509050019250505060405180910390f35b348015610f1857600080fd5b50610f2161344d565b6040518082815260200191505060405180910390f35b348015610f4357600080fd5b5061101d60048036036040811015610f5a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f9757600080fd5b820183602082011115610fa957600080fd5b80359060200191846001830284011164010000000083111715610fcb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613453565b005b34801561102b57600080fd5b5061118d600480360361010081101561104357600080fd5b810190808035906020019064010000000081111561106057600080fd5b82018360208201111561107257600080fd5b8035906020019184602083028401116401000000008311171561109457600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156110df57600080fd5b8201836020820111156110f157600080fd5b8035906020019184600183028401116401000000008311171561111357600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613475565b005b34801561119b57600080fd5b5061124a600480360360808110156111b257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156111f957600080fd5b82018360208201111561120b57600080fd5b8035906020019184600183028401116401000000008311171561122d57600080fd5b9091929391929390803560ff169060200190929190505050613633565b6040518082815260200191505060405180910390f35b34801561126c57600080fd5b506112b96004803603604081101561128357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061375b565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156113185780820151818401526020810190506112fd565b50505050905001935050505060405180910390f35b34801561133957600080fd5b506113666004803603602081101561135057600080fd5b810190808035906020019092919050505061394d565b005b34801561137457600080fd5b5061148c600480360361014081101561138c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156113d357600080fd5b8201836020820111156113e557600080fd5b8035906020019184600183028401116401000000008311171561140757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613aec565b6040518082815260200191505060405180910390f35b3480156114ae57600080fd5b50611511600480360360408110156114c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b19565b005b34801561151f57600080fd5b506115626004803603602081101561153657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613eaa565b005b34801561157057600080fd5b506115f36004803603606081101561158757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f2e565b005b34801561160157600080fd5b5061160a6145a0565b6040518082815260200191505060405180910390f35b34801561162c57600080fd5b50611744600480360361014081101561164457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561168b57600080fd5b82018360208201111561169d57600080fd5b803590602001918460018302840111640100000000831117156116bf57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506145aa565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611784578082015181840152602081019050611769565b50505050905090810190601f1680156117b15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156117cb57600080fd5b5061180e600480360360208110156117e257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614752565b005b34801561181c57600080fd5b506118256147b3565b6040518082815260200191505060405180910390f35b34801561184757600080fd5b506118b46004803603606081101561185e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614831565b005b3480156118c257600080fd5b506118cb614c64565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561190b5780820151818401526020810190506118f0565b50505050905090810190601f1680156119385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000807f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca60001b83805190602001206040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050601960f81b600160f81b6119b66147b3565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260010183815260200182815260200194505050505060405160208183030381529060405280519060200120915050919050565b611a46614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611ab05750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b8015611ae857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611b5a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611c5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611e2a57611e2981612dd3565b5b5050565b611e42604182614d4090919063ffffffff16565b82511015611eb8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b868110156126a457611ed48882614d7a565b80945081955082965050505060008460ff1614156122dd578260001c9450611f06604188614d4090919063ffffffff16565b8260001c1015611f7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611f9760208460001c614da990919063ffffffff16565b111561200b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a010151905088516120418261203360208760001c614da990919063ffffffff16565b614da990919063ffffffff16565b11156120b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561215757808201518184015260208101905061213c565b50505050905090810190601f1680156121845780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b838110156121bd5780820151818401526020810190506121a2565b50505050905090810190601f1680156121ea5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b15801561220957600080fd5b505afa15801561221d573d6000803e3d6000fd5b505050506040513d602081101561223357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146122d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5050612522565b60018460ff1614156123f1578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061237a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b6123ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612521565b601e8460ff1611156124b95760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156124a8573d6000803e3d6000fd5b505050602060405103519450612520565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612513573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156125e95750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156126225750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612694576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611ec2565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561277b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561284d5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b60007fb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e3386868686604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018360018111156128db57fe5b8152602001828103825284818151815260200191508051906020019080838360005b838110156129185780820151818401526020810190506128fd565b50505050905090810190601f1680156129455780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a161296285858585614dc8565b9050949350505050565b6000606061297c86868686612861565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff811180156129c057600080fd5b506040519080825280601f01601f1916602001820160405280156129f35781602001600182028036833780820191505090505b50905060005b83811015612a1e578085015480602083026020850101525080806001019150506129f9565b508091505092915050565b60076020528060005260406000206000915090505481565b612a49614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015612ab35750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612b25576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612c26576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612ddb614c9d565b600354811115612e53576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612eca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000606060055433600454604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405160208183030381529060405290507f66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed8d8d8d8d8d8d8d8d8d8d8d8c604051808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612fc057fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184810384528e8e82818152602001925080828437600081840152601f19601f820116905080830192505050848103835286818151815260200191508051906020019080838360005b8381101561307a57808201518184015260208101905061305f565b50505050905090810190601f1680156130a75780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b838110156130e05780820151818401526020810190506130c5565b50505050905090810190601f16801561310d5780820380516001836020036101000a031916815260200191505b509f5050505050505050505050505050505060405180910390a161313a8d8d8d8d8d8d8d8d8d8d8d614fae565b9150509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b613179614c9d565b60006131c883838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611946565b905060016007600083815260200190815260200160002081905550807fe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e460405160405180910390a2505050565b6000600454905060008111613292576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61329e84848484611e2e565b50505050565b6060600060035467ffffffffffffffff811180156132c157600080fd5b506040519080825280602002602001820160405280156132f05781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613444578083838151811061339b57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061335a565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6134c08a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505089615441565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146134fe576134fd84615941565b5b61354c8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615970565b60008211156135665761356482600060018685615bab565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a905061368a878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a615db1565b61369357600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613720578082015181840152602081019050613705565b50505050905090810190601f16801561374d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561377657600080fd5b506040519080825280602002602001820160405280156137a55781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156138785750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561388357508482105b1561393e578084838151811061389557fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061380e565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613a4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b6000613b018c8c8c8c8c8c8c8c8c8c8c6145aa565b8051906020012090509b9a5050505050505050505050565b613b21614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613b8b5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613bfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613cfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613eb2614c9d565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613f36614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613fa05750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015613fd857503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61404a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461414b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156141b55750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614227576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614327576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561463b57fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b6146c76147b3565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b61475a614c9d565b61476381615941565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6147e1612854565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b614839614c9d565b8060016003540310156148b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561491e5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614a90576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414614c5f57614c5e81612dd3565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614d3e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614d535760009050614d74565b6000828402905082848281614d6457fe5b0414614d6f57600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614dbe57600080fd5b8091505092915050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015614e935750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b614f05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b614f12858585855a615db1565b90508015614f62573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a2614fa6565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b6000806000614fc88e8e8e8e8e8e8e8e8e8e6005546145aa565b905060056000815480929190600101919050555080805190602001209150614ff1828286613215565b506000614ffc615dfd565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146151e2578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a600181111561509f57fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015615171578082015181840152602081019050615156565b50505050905090810190601f16801561519e5780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b1580156151c957600080fd5b505af11580156151dd573d6000803e3d6000fd5b505050505b506101f461520a6109c48a01603f60408c02816151fb57fe5b04615e2e90919063ffffffff16565b015a1015615280576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a90506152e98e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d60008c146152de578d6152e4565b6109c45a035b615db1565b92506152fe5a82615e4890919063ffffffff16565b9050828061530d575060008914155b80615319575060008714155b61538b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808811156153a5576153a2828a8a8a8a615bab565b90505b83156153ef577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8382604051808381526020018281526020019250505060405180910390a161542f565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238382604051808381526020018281526020019250505060405180910390a15b5050509b9a5050505050505050505050565b6000600454146154b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8151811115615530576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60018110156155a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b83518110156158ad5760008482815181106155c757fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561563b5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561567357503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156156ab57508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b61571d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461581e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506155b0565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615a72576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614615ba757615b348260008360015a615db1565b615ba6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614615be85782615bea565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615d0257615c543a8610615c31573a615c33565b855b615c46888a614da990919063ffffffff16565b614d4090919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615cfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615da7565b615d2785615d19888a614da990919063ffffffff16565b614d4090919063ffffffff16565b9150615d34848284615e68565b615da6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600180811115615dbf57fe5b836001811115615dcb57fe5b1415615de4576000808551602087018986f49050615df4565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015615e3e5781615e40565b825b905092915050565b600082821115615e5757600080fd5b600082840390508091505092915050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d60008114615f0f5760208114615f175760009350615f22565b819350615f22565b600051158215171593505b505050939250505056fea26469706673582212201626cf01be22a899e6f136e8877b04e8217b963c12508420280eb5a8dfe10fec64736f6c63430007060033", - "deployedBytecode": "0x6080604052600436106101f25760003560e01c8063a0e67e2b1161010d578063e009cfde116100a0578063e86637db1161006f578063e86637db14611620578063f08a0323146117bf578063f698da2514611810578063f8dc5dd91461183b578063ffa1ad74146118b657610247565b8063e009cfde146114a2578063e19a9dd914611513578063e318b52b14611564578063e75235b8146115f557610247565b8063c4ca3a9c116100dc578063c4ca3a9c1461118f578063cc2f845214611260578063d4d9bdcd1461132d578063d8d11f781461136857610247565b8063a0e67e2b14610ea0578063affed0e014610f0c578063b4faba0914610f37578063b63e800d1461101f57610247565b80635624b25b116101855780636a761202116101545780636a76120214610a865780637d83297414610c4257806385a5affe14610cb1578063934f3a1114610d3757610247565b80635624b25b146108ed5780635ae6bd37146109ab578063610b5925146109fa578063694e80c314610a4b57610247565b80632f54bf6e116101c15780632f54bf6e146105c55780633408e4701461062c578063468721a7146106575780635229073f1461076c57610247565b80630a1028c4146102b45780630d582f131461039057806312fb68e0146103eb5780632d9ad53d1461055e57610247565b36610247573373ffffffffffffffffffffffffffffffffffffffff167f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d346040518082815260200191505060405180910390a2005b34801561025357600080fd5b5060007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b905080548061028857600080f35b36600080373360601b365260008060143601600080855af13d6000803e806102af573d6000fd5b3d6000f35b3480156102c057600080fd5b5061037a600480360360208110156102d757600080fd5b81019080803590602001906401000000008111156102f457600080fd5b82018360208201111561030657600080fd5b8035906020019184600183028401116401000000008311171561032857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611946565b6040518082815260200191505060405180910390f35b34801561039c57600080fd5b506103e9600480360360408110156103b357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611a3e565b005b3480156103f757600080fd5b5061055c6004803603608081101561040e57600080fd5b81019080803590602001909291908035906020019064010000000081111561043557600080fd5b82018360208201111561044757600080fd5b8035906020019184600183028401116401000000008311171561046957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156104cc57600080fd5b8201836020820111156104de57600080fd5b8035906020019184600183028401116401000000008311171561050057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190505050611e2e565b005b34801561056a57600080fd5b506105ad6004803603602081101561058157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506126b0565b60405180821515815260200191505060405180910390f35b3480156105d157600080fd5b50610614600480360360208110156105e857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612782565b60405180821515815260200191505060405180910390f35b34801561063857600080fd5b50610641612854565b6040518082815260200191505060405180910390f35b34801561066357600080fd5b506107546004803603608081101561067a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156106c157600080fd5b8201836020820111156106d357600080fd5b803590602001918460018302840111640100000000831117156106f557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff169060200190929190505050612861565b60405180821515815260200191505060405180910390f35b34801561077857600080fd5b506108696004803603608081101561078f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156107d657600080fd5b8201836020820111156107e857600080fd5b8035906020019184600183028401116401000000008311171561080a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803560ff16906020019092919050505061296c565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b838110156108b1578082015181840152602081019050610896565b50505050905090810190601f1680156108de5780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b3480156108f957600080fd5b506109306004803603604081101561091057600080fd5b8101908080359060200190929190803590602001909291905050506129a2565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610970578082015181840152602081019050610955565b50505050905090810190601f16801561099d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156109b757600080fd5b506109e4600480360360208110156109ce57600080fd5b8101908080359060200190929190505050612a29565b6040518082815260200191505060405180910390f35b348015610a0657600080fd5b50610a4960048036036020811015610a1d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a41565b005b348015610a5757600080fd5b50610a8460048036036020811015610a6e57600080fd5b8101908080359060200190929190505050612dd3565b005b610c2a6004803603610140811015610a9d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610ae457600080fd5b820183602082011115610af657600080fd5b80359060200191846001830284011164010000000083111715610b1857600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610ba457600080fd5b820183602082011115610bb657600080fd5b80359060200191846001830284011164010000000083111715610bd857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612f0d565b60405180821515815260200191505060405180910390f35b348015610c4e57600080fd5b50610c9b60048036036040811015610c6557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061314c565b6040518082815260200191505060405180910390f35b348015610cbd57600080fd5b50610d3560048036036020811015610cd457600080fd5b8101908080359060200190640100000000811115610cf157600080fd5b820183602082011115610d0357600080fd5b80359060200191846001830284011164010000000083111715610d2557600080fd5b9091929391929390505050613171565b005b348015610d4357600080fd5b50610e9e60048036036060811015610d5a57600080fd5b810190808035906020019092919080359060200190640100000000811115610d8157600080fd5b820183602082011115610d9357600080fd5b80359060200191846001830284011164010000000083111715610db557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610e1857600080fd5b820183602082011115610e2a57600080fd5b80359060200191846001830284011164010000000083111715610e4c57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613215565b005b348015610eac57600080fd5b50610eb56132a4565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610ef8578082015181840152602081019050610edd565b505050509050019250505060405180910390f35b348015610f1857600080fd5b50610f2161344d565b6040518082815260200191505060405180910390f35b348015610f4357600080fd5b5061101d60048036036040811015610f5a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610f9757600080fd5b820183602082011115610fa957600080fd5b80359060200191846001830284011164010000000083111715610fcb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050613453565b005b34801561102b57600080fd5b5061118d600480360361010081101561104357600080fd5b810190808035906020019064010000000081111561106057600080fd5b82018360208201111561107257600080fd5b8035906020019184602083028401116401000000008311171561109457600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156110df57600080fd5b8201836020820111156110f157600080fd5b8035906020019184600183028401116401000000008311171561111357600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613475565b005b34801561119b57600080fd5b5061124a600480360360808110156111b257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156111f957600080fd5b82018360208201111561120b57600080fd5b8035906020019184600183028401116401000000008311171561122d57600080fd5b9091929391929390803560ff169060200190929190505050613633565b6040518082815260200191505060405180910390f35b34801561126c57600080fd5b506112b96004803603604081101561128357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061375b565b60405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019060200280838360005b838110156113185780820151818401526020810190506112fd565b50505050905001935050505060405180910390f35b34801561133957600080fd5b506113666004803603602081101561135057600080fd5b810190808035906020019092919050505061394d565b005b34801561137457600080fd5b5061148c600480360361014081101561138c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156113d357600080fd5b8201836020820111156113e557600080fd5b8035906020019184600183028401116401000000008311171561140757600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050613aec565b6040518082815260200191505060405180910390f35b3480156114ae57600080fd5b50611511600480360360408110156114c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613b19565b005b34801561151f57600080fd5b506115626004803603602081101561153657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613eaa565b005b34801561157057600080fd5b506115f36004803603606081101561158757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613f2e565b005b34801561160157600080fd5b5061160a6145a0565b6040518082815260200191505060405180910390f35b34801561162c57600080fd5b50611744600480360361014081101561164457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561168b57600080fd5b82018360208201111561169d57600080fd5b803590602001918460018302840111640100000000831117156116bf57600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506145aa565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611784578082015181840152602081019050611769565b50505050905090810190601f1680156117b15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156117cb57600080fd5b5061180e600480360360208110156117e257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050614752565b005b34801561181c57600080fd5b506118256147b3565b6040518082815260200191505060405180910390f35b34801561184757600080fd5b506118b46004803603606081101561185e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050614831565b005b3480156118c257600080fd5b506118cb614c64565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561190b5780820151818401526020810190506118f0565b50505050905090810190601f1680156119385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000807f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca60001b83805190602001206040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050601960f81b600160f81b6119b66147b3565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260010183815260200182815260200194505050505060405160208183030381529060405280519060200120915050919050565b611a46614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015611ab05750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b8015611ae857503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611b5a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611c5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600081548092919060010191905055507f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2682604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414611e2a57611e2981612dd3565b5b5050565b611e42604182614d4090919063ffffffff16565b82511015611eb8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808060008060005b868110156126a457611ed48882614d7a565b80945081955082965050505060008460ff1614156122dd578260001c9450611f06604188614d4090919063ffffffff16565b8260001c1015611f7e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8751611f9760208460001c614da990919063ffffffff16565b111561200b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006020838a010151905088516120418261203360208760001c614da990919063ffffffff16565b614da990919063ffffffff16565b11156120b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60606020848b010190506320c13b0b60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168773ffffffffffffffffffffffffffffffffffffffff166320c13b0b8d846040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561215757808201518184015260208101905061213c565b50505050905090810190601f1680156121845780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b838110156121bd5780820151818401526020810190506121a2565b50505050905090810190601f1680156121ea5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b15801561220957600080fd5b505afa15801561221d573d6000803e3d6000fd5b505050506040513d602081101561223357600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146122d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5050612522565b60018460ff1614156123f1578260001c94508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061237a57506000600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c81526020019081526020016000205414155b6123ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b612521565b601e8460ff1611156124b95760018a60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012060048603858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156124a8573d6000803e3d6000fd5b505050602060405103519450612520565b60018a85858560405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015612513573d6000803e3d6000fd5b5050506020604051035194505b5b5b8573ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161180156125e95750600073ffffffffffffffffffffffffffffffffffffffff16600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b80156126225750600173ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612694576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330323600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8495508080600101915050611ec2565b50505050505050505050565b60008173ffffffffffffffffffffffffffffffffffffffff16600173ffffffffffffffffffffffffffffffffffffffff161415801561277b5750600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561284d5750600073ffffffffffffffffffffffffffffffffffffffff16600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b9050919050565b6000804690508091505090565b60007fb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e3386868686604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018360018111156128db57fe5b8152602001828103825284818151815260200191508051906020019080838360005b838110156129185780820151818401526020810190506128fd565b50505050905090810190601f1680156129455780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a161296285858585614dc8565b9050949350505050565b6000606061297c86868686612861565b915060405160203d0181016040523d81523d6000602083013e8091505094509492505050565b606060006020830267ffffffffffffffff811180156129c057600080fd5b506040519080825280601f01601f1916602001820160405280156129f35781602001600182028036833780820191505090505b50905060005b83811015612a1e578085015480602083026020850101525080806001019150506129f9565b508091505092915050565b60076020528060005260406000206000915090505481565b612a49614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015612ab35750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b612b25576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612c26576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b612ddb614c9d565b600354811115612e53576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001811015612eca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b806004819055507f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c936004546040518082815260200191505060405180910390a150565b6000606060055433600454604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405160208183030381529060405290507f66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed8d8d8d8d8d8d8d8d8d8d8d8c604051808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a6001811115612fc057fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200184810384528e8e82818152602001925080828437600081840152601f19601f820116905080830192505050848103835286818151815260200191508051906020019080838360005b8381101561307a57808201518184015260208101905061305f565b50505050905090810190601f1680156130a75780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b838110156130e05780820151818401526020810190506130c5565b50505050905090810190601f16801561310d5780820380516001836020036101000a031916815260200191505b509f5050505050505050505050505050505060405180910390a161313a8d8d8d8d8d8d8d8d8d8d8d614fae565b9150509b9a5050505050505050505050565b6008602052816000526040600020602052806000526040600020600091509150505481565b613179614c9d565b60006131c883838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611946565b905060016007600083815260200190815260200160002081905550807fe7f4675038f4f6034dfcbbb24c4dc08e4ebf10eb9d257d3d02c0f38d122ac6e460405160405180910390a2505050565b6000600454905060008111613292576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61329e84848484611e2e565b50505050565b6060600060035467ffffffffffffffff811180156132c157600080fd5b506040519080825280602002602001820160405280156132f05781602001602082028036833780820191505090505b50905060008060026000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613444578083838151811061339b57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061335a565b82935050505090565b60055481565b600080825160208401855af4806000523d6020523d600060403e60403d016000fd5b6134c08a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505089615441565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146134fe576134fd84615941565b5b61354c8787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050615970565b60008211156135665761356482600060018685615bab565b505b3373ffffffffffffffffffffffffffffffffffffffff167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b8960405180806020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281038252878782818152602001925060200280828437600081840152601f19601f820116905080830192505050965050505050505060405180910390a250505050505050505050565b6000805a905061368a878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050865a615db1565b61369357600080fd5b60005a8203905080604051602001808281526020019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613720578082015181840152602081019050613705565b50505050905090810190601f16801561374d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b606060008267ffffffffffffffff8111801561377657600080fd5b506040519080825280602002602001820160405280156137a55781602001602082028036833780820191505090505b509150600080600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156138785750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561388357508482105b1561393e578084838151811061389557fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050818060010192505061380e565b80925081845250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415613a4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff16817ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c60405160405180910390a350565b6000613b018c8c8c8c8c8c8c8c8c8c8c6145aa565b8051906020012090509b9a5050505050505050505050565b613b21614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613b8b5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b613bfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613cfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613eb2614c9d565b60007f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b90508181557f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa282604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15050565b613f36614c9d565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015613fa05750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015613fd857503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b61404a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461414b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156141b55750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614227576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614327576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a17f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea2681604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505050565b6000600454905090565b606060007fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d860001b8d8d8d8d60405180838380828437808301925050509250505060405180910390208c8c8c8c8c8c8c604051602001808c81526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018a815260200189815260200188600181111561463b57fe5b81526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019b505050505050505050505050604051602081830303815290604052805190602001209050601960f81b600160f81b6146c76147b3565b8360405160200180857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152600101847effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526001018381526020018281526020019450505050506040516020818303038152906040529150509b9a5050505050505050505050565b61475a614c9d565b61476381615941565b7f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b081604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b60007f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a7946921860001b6147e1612854565b30604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001935050505060405160208183030381529060405280519060200120905090565b614839614c9d565b8060016003540310156148b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415801561491e5750600173ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b614990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614614a90576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360008154809291906001900391905055507ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf82604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18060045414614c5f57614c5e81612dd3565b5b505050565b6040518060400160405280600581526020017f312e332e3000000000000000000000000000000000000000000000000000000081525081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614614d3e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330333100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b600080831415614d535760009050614d74565b6000828402905082848281614d6457fe5b0414614d6f57600080fd5b809150505b92915050565b60008060008360410260208101860151925060408101860151915060ff60418201870151169350509250925092565b600080828401905083811015614dbe57600080fd5b8091505092915050565b6000600173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015614e935750600073ffffffffffffffffffffffffffffffffffffffff16600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b614f05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b614f12858585855a615db1565b90508015614f62573373ffffffffffffffffffffffffffffffffffffffff167f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb860405160405180910390a2614fa6565b3373ffffffffffffffffffffffffffffffffffffffff167facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd37560405160405180910390a25b949350505050565b6000806000614fc88e8e8e8e8e8e8e8e8e8e6005546145aa565b905060056000815480929190600101919050555080805190602001209150614ff1828286613215565b506000614ffc615dfd565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146151e2578073ffffffffffffffffffffffffffffffffffffffff166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c8152602001806020018a600181111561509f57fe5b81526020018981526020018881526020018781526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018473ffffffffffffffffffffffffffffffffffffffff16815260200183810383528d8d82818152602001925080828437600081840152601f19601f820116905080830192505050838103825285818151815260200191508051906020019080838360005b83811015615171578082015181840152602081019050615156565b50505050905090810190601f16801561519e5780820380516001836020036101000a031916815260200191505b509e505050505050505050505050505050600060405180830381600087803b1580156151c957600080fd5b505af11580156151dd573d6000803e3d6000fd5b505050505b506101f461520a6109c48a01603f60408c02816151fb57fe5b04615e2e90919063ffffffff16565b015a1015615280576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60005a90506152e98e8e8e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508d60008c146152de578d6152e4565b6109c45a035b615db1565b92506152fe5a82615e4890919063ffffffff16565b9050828061530d575060008914155b80615319575060008714155b61538b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000808811156153a5576153a2828a8a8a8a615bab565b90505b83156153ef577f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e8382604051808381526020018281526020019250505060405180910390a161542f565b7f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d238382604051808381526020018281526020019250505060405180910390a15b5050509b9a5050505050505050505050565b6000600454146154b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8151811115615530576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60018110156155a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006001905060005b83518110156158ad5760008482815181106155c757fe5b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561563b5750600173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561567357503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b80156156ab57508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b61571d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461581e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475332303400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508092505080806001019150506155b0565b506001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550825160038190555081600481905550505050565b60007f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d560001b90508181555050565b600073ffffffffffffffffffffffffffffffffffffffff1660016000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614615a72576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475331303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001806000600173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614615ba757615b348260008360015a615db1565b615ba6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330303000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5050565b600080600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614615be85782615bea565b325b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415615d0257615c543a8610615c31573a615c33565b855b615c46888a614da990919063ffffffff16565b614d4090919063ffffffff16565b91508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050615cfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b615da7565b615d2785615d19888a614da990919063ffffffff16565b614d4090919063ffffffff16565b9150615d34848284615e68565b615da6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f475330313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b5095945050505050565b6000600180811115615dbf57fe5b836001811115615dcb57fe5b1415615de4576000808551602087018986f49050615df4565b600080855160208701888a87f190505b95945050505050565b6000807f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c860001b9050805491505090565b600081831015615e3e5781615e40565b825b905092915050565b600082821115615e5757600080fd5b600082840390508091505092915050565b60008063a9059cbb8484604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050602060008251602084016000896127105a03f13d60008114615f0f5760208114615f175760009350615f22565b819350615f22565b600051158215171593505b505050939250505056fea26469706673582212201626cf01be22a899e6f136e8877b04e8217b963c12508420280eb5a8dfe10fec64736f6c63430007060033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/gnosis_safe/contract.py b/trader_old/vendor/valory/contracts/gnosis_safe/contract.py deleted file mode 100644 index 417a3913d..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe/contract.py +++ /dev/null @@ -1,1004 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the class to connect to an Gnosis Safe contract.""" -import binascii -import logging -import secrets -from enum import Enum -from typing import Any, Dict, List, Optional, Tuple, Union, cast - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi -from eth_typing import ChecksumAddress, HexAddress, HexStr -from hexbytes import HexBytes -from packaging.version import Version -from requests import HTTPError -from web3.exceptions import ContractLogicError, TransactionNotFound -from web3.types import BlockIdentifier, Nonce, TxData, TxParams, Wei - -from packages.valory.contracts.gnosis_safe.encode import encode_typed_data -from packages.valory.contracts.gnosis_safe_proxy_factory.contract import ( - GnosisSafeProxyFactoryContract, -) - - -PUBLIC_ID = PublicId.from_str("valory/gnosis_safe:0.1.0") -MIN_GAS = MIN_GASPRICE = 1 -# see https://github.com/safe-global/safe-eth-py/blob/6c0e0d80448e5f3496d0d94985bca239df6eb399/gnosis/safe/safe_tx.py#L354 -GAS_ADJUSTMENT = 75_000 - -_logger = logging.getLogger( - f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" -) - -NULL_ADDRESS: str = "0x" + "0" * 40 -SAFE_CONTRACT = "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552" -DEFAULT_CALLBACK_HANDLER = "0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4" -PROXY_FACTORY_CONTRACT = "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2" -SAFE_DEPLOYED_BYTECODE = "0x608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea2646970667358221220d1429297349653a4918076d650332de1a1068c5f3e07c5c82360c277770b955264736f6c63430007060033" - - -def _get_nonce() -> int: - """Generate a nonce for the Safe deployment.""" - return secrets.SystemRandom().randint(0, 2**256 - 1) - - -def checksum_address(agent_address: str) -> ChecksumAddress: - """Get the checksum address.""" - return ChecksumAddress(HexAddress(HexStr(agent_address))) - - -class SafeOperation(Enum): - """Operation types.""" - - CALL = 0 - DELEGATE_CALL = 1 - CREATE = 2 - - -class GnosisSafeContract(Contract): - """The Gnosis Safe contract.""" - - contract_id = PUBLIC_ID - _SENTINEL_OWNERS = "0x0000000000000000000000000000000000000001" - - @classmethod - def get_raw_transaction( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get the Safe transaction.""" - raise NotImplementedError - - @classmethod - def get_raw_message( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[bytes]: - """Get raw message.""" - raise NotImplementedError - - @classmethod - def get_state( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get state.""" - raise NotImplementedError - - @classmethod - def get_deploy_transaction( - cls, ledger_api: LedgerApi, deployer_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """ - Get deploy transaction. - - :param ledger_api: ledger API object. - :param deployer_address: the deployer address. - :param kwargs: the keyword arguments. - :return: an optional JSON-like object. - """ - owners = kwargs.pop("owners") - threshold = kwargs.pop("threshold") - ledger_api = cast(EthereumApi, ledger_api) - tx_params, contract_address = cls._get_deploy_transaction( - ledger_api, deployer_address, owners=owners, threshold=threshold, **kwargs - ) - result = dict(cast(Dict, tx_params)) - # piggyback the contract address - result["contract_address"] = contract_address - return result - - @classmethod - def _get_deploy_transaction( # pylint: disable=too-many-locals,too-many-arguments - cls, - ledger_api: EthereumApi, - deployer_address: str, - owners: List[str], - threshold: int, - salt_nonce: Optional[int] = None, - gas: int = 0, - gas_price: Optional[int] = None, - max_fee_per_gas: Optional[int] = None, - max_priority_fee_per_gas: Optional[int] = None, - ) -> Tuple[TxParams, str]: - """ - Get the deployment transaction of the new Safe. - - Taken from: - https://github.com/gnosis/safe-cli/blob/contracts_v1.3.0/safe_creator.py - - :param ledger_api: Ethereum APIs. - :param deployer_address: public key of the sender of the transaction - :param owners: a list of public keys - :param threshold: the signature threshold - :param salt_nonce: Use a custom nonce for the deployment. Defaults to random nonce. - :param gas: gas cost - :param gas_price: Gas price that should be used for the payment calculation - :param max_fee_per_gas: max - :param max_priority_fee_per_gas: max - :return: transaction params and contract address - """ - salt_nonce = salt_nonce if salt_nonce is not None else _get_nonce() - salt_nonce = cast(int, salt_nonce) - to_address = NULL_ADDRESS - data = b"" - payment_token = NULL_ADDRESS - payment = 0 - payment_receiver = NULL_ADDRESS - - if len(owners) < threshold: - raise ValueError( - "Threshold cannot be bigger than the number of unique owners" - ) - - safe_contract_address = SAFE_CONTRACT - proxy_factory_address = PROXY_FACTORY_CONTRACT - fallback_handler = DEFAULT_CALLBACK_HANDLER - - account_address = checksum_address(deployer_address) - account_balance: int = ledger_api.api.eth.get_balance(account_address) - if not account_balance: - raise ValueError("Client does not have any funds") - - ether_account_balance = round( - ledger_api.api.from_wei(account_balance, "ether"), 6 - ) - _logger.info( - "Network %s - Sender %s - Balance: %sΞ", - ledger_api.api.net.version, - account_address, - ether_account_balance, - ) - - if not ledger_api.api.eth.get_code( - safe_contract_address - ) or not ledger_api.api.eth.get_code(proxy_factory_address): - raise ValueError("Network not supported") # pragma: nocover - - _logger.info( - "Creating new Safe with owners=%s threshold=%s " - "fallback-handler=%s salt-nonce=%s", - owners, - threshold, - fallback_handler, - salt_nonce, - ) - safe_contract = cls.get_instance(ledger_api, safe_contract_address) - safe_creation_tx_data = HexBytes( - safe_contract.functions.setup( - owners, - threshold, - to_address, - data, - fallback_handler, - payment_token, - payment, - payment_receiver, - ).build_transaction({"gas": MIN_GAS, "gasPrice": MIN_GASPRICE})["data"] - ) - - nonce = ( - ledger_api._try_get_transaction_count( # pylint: disable=protected-access - account_address - ) - ) - if nonce is None: - raise ValueError("No nonce returned.") # pragma: nocover - - ( - tx_params, - contract_address, - ) = GnosisSafeProxyFactoryContract.build_tx_deploy_proxy_contract_with_nonce( - ledger_api, - proxy_factory_address, - safe_contract_address, - account_address, - safe_creation_tx_data, - salt_nonce, - nonce=nonce, - gas=gas, - gas_price=gas_price, - max_fee_per_gas=max_fee_per_gas, - max_priority_fee_per_gas=max_priority_fee_per_gas, - ) - return tx_params, contract_address - - @classmethod - def get_raw_safe_transaction_hash( # pylint: disable=too-many-arguments,too-many-locals - cls, - ledger_api: EthereumApi, - contract_address: str, - to_address: str, - value: int, - data: bytes, - operation: int = SafeOperation.CALL.value, - safe_tx_gas: int = 0, - base_gas: int = 0, - gas_price: int = 0, - gas_token: str = NULL_ADDRESS, - refund_receiver: str = NULL_ADDRESS, - safe_nonce: Optional[int] = None, - safe_version: Optional[str] = None, - chain_id: Optional[int] = None, - ) -> JSONLike: - """ - Get the hash of the raw Safe transaction. - - Adapted from https://github.com/gnosis/gnosis-py/blob/69f1ee3263086403f6017effa0841c6a2fbba6d6/gnosis/safe/safe_tx.py#L125 - - Note, because safe_nonce is included in the tx_hash the agents implicitly agree on the order of txs if they agree on a tx_hash. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param to_address: the tx recipient address - :param value: the ETH value of the transaction - :param data: the data of the transaction - :param operation: Operation type of Safe transaction - :param safe_tx_gas: Gas that should be used for the Safe transaction - :param base_gas: Gas costs for that are independent of the transaction execution - (e.g. base transaction fee, signature check, payment of the refund) - :param gas_price: Gas price that should be used for the payment calculation - :param gas_token: Token address (or `0x000..000` if ETH) that is used for the payment - :param refund_receiver: Address of receiver of gas payment (or `0x000..000` if tx.origin). - :param safe_nonce: Current nonce of the Safe. If not provided, it will be retrieved from network - :param safe_version: Safe version 1.0.0 renamed `baseGas` to `dataGas`. Safe version 1.3.0 added `chainId` to the `domainSeparator`. If not provided, it will be retrieved from network - :param chain_id: Ethereum network chain_id is used in hash calculation for Safes >= 1.3.0. If not provided, it will be retrieved from the provided ethereum_client - :return: the hash of the raw Safe transaction - """ - safe_contract = cls.get_instance(ledger_api, contract_address) - if safe_nonce is None: - safe_nonce = safe_contract.functions.nonce().call(block_identifier="latest") - if safe_version is None: - safe_version = safe_contract.functions.VERSION().call( - block_identifier="latest" - ) - if chain_id is None: - chain_id = ledger_api.api.eth.chain_id - - data_ = HexBytes(data).hex() - - # Safes >= 1.0.0 Renamed `baseGas` to `dataGas` - safe_version_ = Version(safe_version) - base_gas_name = "baseGas" if safe_version_ >= Version("1.0.0") else "dataGas" - - structured_data = { - "types": { - "EIP712Domain": [ - {"name": "verifyingContract", "type": "address"}, - ], - "SafeTx": [ - {"name": "to", "type": "address"}, - {"name": "value", "type": "uint256"}, - {"name": "data", "type": "bytes"}, - {"name": "operation", "type": "uint8"}, - {"name": "safeTxGas", "type": "uint256"}, - {"name": base_gas_name, "type": "uint256"}, - {"name": "gasPrice", "type": "uint256"}, - {"name": "gasToken", "type": "address"}, - {"name": "refundReceiver", "type": "address"}, - {"name": "nonce", "type": "uint256"}, - ], - }, - "primaryType": "SafeTx", - "domain": { - "verifyingContract": contract_address, - }, - "message": { - "to": to_address, - "value": value, - "data": data_, - "operation": operation, - "safeTxGas": safe_tx_gas, - base_gas_name: base_gas, - "gasPrice": gas_price, - "gasToken": gas_token, - "refundReceiver": refund_receiver, - "nonce": safe_nonce, - }, - } - - # Safes >= 1.3.0 Added `chainId` to the domain - if safe_version_ >= Version("1.3.0"): - # EIP712Domain(uint256 chainId,address verifyingContract) - structured_data["types"]["EIP712Domain"].insert( # type: ignore - 0, {"name": "chainId", "type": "uint256"} - ) - structured_data["domain"]["chainId"] = chain_id # type: ignore - - return dict(tx_hash=HexBytes(encode_typed_data(structured_data)).hex()) - - @classmethod - def get_packed_signatures( - cls, owners: Tuple[str], signatures_by_owner: Dict[str, str] - ) -> bytes: - """Get the packed signatures.""" - sorted_owners = sorted(owners, key=str.lower) - signatures = b"" - for signer in sorted_owners: - if signer not in signatures_by_owner: - continue # pragma: nocover - signature = signatures_by_owner[signer] - signature_bytes = binascii.unhexlify(signature) - signatures += signature_bytes - # Packed signature data ({bytes32 r}{bytes32 s}{uint8 v}) - return signatures - - @classmethod - def get_raw_safe_transaction( # pylint: disable=too-many-arguments,too-many-locals - cls, - ledger_api: EthereumApi, - contract_address: str, - sender_address: str, - owners: Tuple[str], - to_address: str, - value: int, - data: bytes, - signatures_by_owner: Dict[str, str], - operation: int = SafeOperation.CALL.value, - safe_tx_gas: int = 0, - base_gas: int = 0, - safe_gas_price: int = 0, - gas_token: str = NULL_ADDRESS, - refund_receiver: str = NULL_ADDRESS, - gas_price: Optional[int] = None, - nonce: Optional[Nonce] = None, - max_fee_per_gas: Optional[int] = None, - max_priority_fee_per_gas: Optional[int] = None, - old_price: Optional[Dict[str, Wei]] = None, - fallback_gas: int = 0, - ) -> JSONLike: - """ - Get the raw Safe transaction - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param sender_address: the address of the sender - :param owners: the sequence of owners - :param to_address: Destination address of Safe transaction - :param value: Ether value of Safe transaction - :param data: Data payload of Safe transaction - :param signatures_by_owner: mapping from owners to signatures - :param operation: Operation type of Safe transaction - :param safe_tx_gas: Gas that should be used for the Safe transaction - :param base_gas: Gas costs for that are independent of the transaction execution - (e.g. base transaction fee, signature check, payment of the refund) - :param safe_gas_price: Gas price that should be used for the payment calculation - :param gas_token: Token address (or `0x000..000` if ETH) that is used for the payment - :param refund_receiver: Address of receiver of gas payment (or `0x000..000` if tx.origin). - :param gas_price: gas price - :param nonce: the nonce - :param max_fee_per_gas: max - :param max_priority_fee_per_gas: max - :param old_price: the old gas price params in case that we are trying to resubmit a transaction. - :param fallback_gas: (external) gas to spend when base_gas and safe_tx_gas are zero and no gas estimation is possible. - :return: the raw Safe transaction - """ - sender_address = ledger_api.api.to_checksum_address(sender_address) - to_address = ledger_api.api.to_checksum_address(to_address) - ledger_api = cast(EthereumApi, ledger_api) - signatures = cls.get_packed_signatures(owners, signatures_by_owner) - safe_contract = cls.get_instance(ledger_api, contract_address) - - w3_tx = safe_contract.functions.execTransaction( - to_address, - value, - data, - operation, - safe_tx_gas, - base_gas, - safe_gas_price, - gas_token, - refund_receiver, - signatures, - ) - # see https://github.com/safe-global/safe-eth-py/blob/6c0e0d80448e5f3496d0d94985bca239df6eb399/gnosis/safe/safe_tx.py#L354 - configured_gas = ( - base_gas + safe_tx_gas + GAS_ADJUSTMENT - if base_gas != 0 or safe_tx_gas != 0 - else MIN_GAS - ) - tx_parameters: Dict[str, Union[str, int]] = { - "from": sender_address, - "gas": configured_gas, - } - actual_nonce = ledger_api.api.eth.get_transaction_count( - ledger_api.api.to_checksum_address(sender_address) - ) - if actual_nonce != nonce: - nonce = actual_nonce - old_price = None - if gas_price is not None: - tx_parameters["gasPrice"] = gas_price - if max_fee_per_gas is not None: - tx_parameters["maxFeePerGas"] = max_fee_per_gas # pragma: nocover - if max_priority_fee_per_gas is not None: # pragma: nocover - tx_parameters["maxPriorityFeePerGas"] = max_priority_fee_per_gas - if ( - gas_price is None - and max_fee_per_gas is None - and max_priority_fee_per_gas is None - ): - tx_parameters.update(ledger_api.try_get_gas_pricing(old_price=old_price)) - # note, the next line makes an eth_estimateGas call if gas is not set! - transaction_dict = w3_tx.build_transaction(tx_parameters) - if configured_gas != MIN_GAS: - transaction_dict["gas"] = Wei(configured_gas) - else: - gas_estimate = ( - ledger_api._try_get_gas_estimate( # pylint: disable=protected-access - transaction_dict - ) - ) - transaction_dict["gas"] = ( - Wei(gas_estimate) if gas_estimate is not None else fallback_gas - ) - transaction_dict["nonce"] = nonce # pragma: nocover - return transaction_dict - - @classmethod - def verify_contract(cls, ledger_api: LedgerApi, contract_address: str) -> JSONLike: - """ - Verify the contract's bytecode - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :return: the verified status - """ - ledger_api = cast(EthereumApi, ledger_api) - deployed_bytecode = ledger_api.api.eth.get_code(contract_address).hex() - # we cannot use cls.contract_interface["ethereum"]["deployedBytecode"] because the - # contract is created via a proxy - local_bytecode = SAFE_DEPLOYED_BYTECODE - verified = deployed_bytecode == local_bytecode - return dict(verified=verified) - - @classmethod - def verify_tx( # pylint: disable=too-many-arguments,too-many-locals - cls, - ledger_api: EthereumApi, - contract_address: str, - tx_hash: str, - owners: Tuple[str], - to_address: str, - value: int, - data: bytes, - signatures_by_owner: Dict[str, str], - operation: int = SafeOperation.CALL.value, - safe_tx_gas: int = 0, - base_gas: int = 0, - gas_price: int = 0, - gas_token: str = NULL_ADDRESS, - refund_receiver: str = NULL_ADDRESS, - safe_version: Optional[str] = None, - ) -> JSONLike: - """ - Verify a tx hash exists on the blockchain. - - Currently, the implementation is an overkill as most of the verification is implicit by the acceptance of the transaction in the Safe. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param tx_hash: the transaction hash - :param owners: the sequence of owners - :param to_address: Destination address of Safe transaction - :param value: Ether value of Safe transaction - :param data: Data payload of Safe transaction - :param signatures_by_owner: mapping from owners to signatures - :param operation: Operation type of Safe transaction - :param safe_tx_gas: Gas that should be used for the Safe transaction - :param base_gas: Gas costs for that are independent of the transaction execution - (e.g. base transaction fee, signature check, payment of the refund) - :param gas_price: Gas price that should be used for the payment calculation - :param gas_token: Token address (or `0x000..000` if ETH) that is used for the payment - :param refund_receiver: Address of receiver of gas payment (or `0x000..000` if tx.origin). - :param safe_version: Safe version 1.0.0 renamed `baseGas` to `dataGas`. Safe version 1.3.0 added `chainId` to the `domainSeparator`. If not provided, it will be retrieved from network - :return: the verified status - """ - to_address = ledger_api.api.to_checksum_address(to_address) - ledger_api = cast(EthereumApi, ledger_api) - safe_contract = cls.get_instance(ledger_api, contract_address) - signatures = cls.get_packed_signatures(owners, signatures_by_owner) - - if safe_version is None: - safe_version = safe_contract.functions.VERSION().call( - block_identifier="latest" - ) - # Safes >= 1.0.0 Renamed `baseGas` to `dataGas` - safe_version_ = Version(safe_version) - base_gas_name = "baseGas" if safe_version_ >= Version("1.0.0") else "dataGas" - - try: - _logger.info(f"Trying to get transaction and receipt from hash {tx_hash}") - transaction = ledger_api.api.eth.get_transaction(tx_hash) - receipt = ledger_api.get_transaction_receipt(tx_hash) - _logger.info( - f"Received transaction: {transaction}, with receipt: {receipt}." - ) - if receipt is None: - raise ValueError # pragma: nocover - except (TransactionNotFound, ValueError): # pragma: nocover - return dict(verified=False, status=-1) - - expected = dict( - contract_address=contract_address, - to_address=to_address, - value=value, - data=data, - operation=operation, - safe_tx_gas=safe_tx_gas, - base_gas=base_gas, - gas_price=gas_price, - gas_token=gas_token, - refund_receiver=refund_receiver, - signatures=signatures, - ) - decoded: Tuple[Any, Dict] = (None, {}) - diff: Dict = {} - try: - decoded = safe_contract.decode_function_input(transaction["input"]) - actual = dict( - contract_address=transaction["to"], - to_address=decoded[1]["to"], - value=decoded[1]["value"], - data=decoded[1]["data"], - operation=decoded[1]["operation"], - safe_tx_gas=decoded[1]["safeTxGas"], - base_gas=decoded[1][base_gas_name], - gas_price=decoded[1]["gasPrice"], - gas_token=decoded[1]["gasToken"], - refund_receiver=decoded[1]["refundReceiver"], - signatures=decoded[1]["signatures"], - ) - diff = {k: (v, actual[k]) for k, v in expected.items() if v != actual[k]} - verified = ( - receipt["status"] - and "execTransaction" in str(decoded[0]) - and len(diff) == 0 - ) - except (TransactionNotFound, KeyError, ValueError): # pragma: nocover - verified = False - return dict( - verified=verified, - status=receipt["status"], - transaction=transaction, - actual=decoded, # type: ignore - expected=expected, - diff=diff, - ) - - @classmethod - def revert_reason( # pylint: disable=unused-argument - cls, - ledger_api: EthereumApi, - contract_address: str, - tx: TxData, - ) -> JSONLike: - """Check the revert reason of a transaction. - - :param ledger_api: the ledger API object. - :param contract_address: the contract address - :param tx: the transaction for which we want to get the revert reason. - - :return: the revert reason message. - """ - ledger_api = cast(EthereumApi, ledger_api) - - # build a new transaction to replay: - replay_tx = { - "to": tx["to"], - "from": tx["from"], - "value": tx["value"], - "data": tx["input"], - } - - try: - # replay the transaction locally: - ledger_api.api.eth.call(replay_tx, tx["blockNumber"] - 1) - except ContractLogicError as e: - # execution reverted exception - return dict(revert_reason=repr(e)) - except HTTPError as e: # pragma: nocover - # http exception - raise e - else: - # given tx not reverted - raise ValueError(f"The given transaction has not been reverted!\ntx: {tx}") - - @classmethod - def get_safe_nonce(cls, ledger_api: EthereumApi, contract_address: str) -> JSONLike: - """ - Retrieve the safe's nonce - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :return: the safe nonce - """ - safe_contract = cls.get_instance(ledger_api, contract_address) - safe_nonce = safe_contract.functions.nonce().call(block_identifier="latest") - return dict(safe_nonce=safe_nonce) - - @classmethod - def get_ingoing_transfers( - cls, - ledger_api: EthereumApi, - contract_address: str, - from_block: Optional[str] = None, - to_block: Optional[str] = "latest", - ) -> JSONLike: - """ - A list of transfers into the contract. - - :param ledger_api: the ledger API object - :param contract_address: the contract address, - :param from_block: from which block to start tje search - :param to_block: at which block to end the search - :return: list of transfers - """ - safe_contract = cls.get_instance(ledger_api, contract_address) - - if from_block is None: - logging.info( - "'from_block' not provided, checking for transfers to the safe contract in the last 50 blocks." - ) - current_block = ledger_api.api.eth.get_block("latest")["number"] - from_block = hex(max(0, current_block - 50)) # check in the last ~10 min - - safe_filter = safe_contract.events.SafeReceived.create_filter( - fromBlock=from_block, toBlock=to_block - ) - all_entries = safe_filter.get_all_entries() - - return { - "data": list( - map( - lambda entry: { - "sender": entry["args"]["sender"], - "amount": int(entry["args"]["value"]), - "blockNumber": entry["blockNumber"], - }, - all_entries, - ) - ) - } - - @classmethod - def get_balance(cls, ledger_api: EthereumApi, contract_address: str) -> JSONLike: - """ - Retrieve the safe's balance - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :return: the safe balance (in wei) - """ - return dict(balance=ledger_api.get_balance(address=contract_address)) - - @classmethod - def get_amount_spent( # pylint: disable=unused-argument - cls, - ledger_api: EthereumApi, - contract_address: str, - tx_hash: str, - ) -> JSONLike: - """ - Get the amount of ether spent in a tx. - - :param ledger_api: the ledger API object - :param contract_address: the contract address (not used) - :param tx_hash: the settled tx hash - :return: the safe balance (in wei) - """ - tx_receipt = ledger_api.get_transaction_receipt(tx_hash) - tx = ledger_api.get_transaction(tx_hash) - - tx_value = int(tx["value"]) - gas_price = int(tx["gasPrice"]) - gas_used = int(tx_receipt["gasUsed"]) - total_spent = tx_value + (gas_price * gas_used) - - return dict(amount_spent=total_spent) - - @classmethod - def get_safe_txs( - cls, - ledger_api: EthereumApi, - contract_address: str, - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - ) -> JSONLike: - """ - Get all the safe tx hashes. - - :param ledger_api: the ledger API object - :param contract_address: the contract address (not used) - :param from_block: from which block to search for events - :param to_block: to which block to search for events - :return: the safe txs - """ - - ledger_api = cast(EthereumApi, ledger_api) - factory_contract = cls.get_instance(ledger_api, contract_address) - entries = factory_contract.events.ExecutionSuccess.create_filter( - fromBlock=from_block, - toBlock=to_block, - ).get_all_entries() - - return dict( - txs=list( - map( - lambda entry: dict( - tx_hash=entry.transactionHash.hex(), - block_number=entry.blockNumber, - ), - entries, - ) - ) - ) - - @classmethod - def get_removed_owner_events( - cls, - ledger_api: EthereumApi, - contract_address: str, - removed_owner: Optional[str] = None, - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - ) -> JSONLike: - """ - Get all RemovedOwner events for a safe contract. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param removed_owner: the owner to check for, any owner qualifies if not provided. - :param from_block: from which block to search for events - :param to_block: to which block to search for events - :return: the added owner events - """ - ledger_api = cast(EthereumApi, ledger_api) - safe_contract = cls.get_instance(ledger_api, contract_address) - entries = safe_contract.events.RemovedOwner.create_filter( - fromBlock=from_block, - toBlock=to_block, - ).get_all_entries() - if removed_owner is None: - removed_owner_events = list( - dict( - tx_hash=entry.transactionHash.hex(), - block_number=entry.blockNumber, - owner=entry["args"]["owner"], - ) - for entry in entries - ) - return dict( - data=removed_owner_events, - ) - - checksummed_removed_owner = ledger_api.api.to_checksum_address(removed_owner) - removed_owner_events = list( - dict( - tx_hash=entry.transactionHash.hex(), - block_number=entry.blockNumber, - owner=entry["args"]["owner"], - ) - for entry in entries - if ( - ledger_api.api.to_checksum_address(entry["args"]["owner"]) - == checksummed_removed_owner - ) - ) - return dict( - data=removed_owner_events, - ) - - @classmethod - def get_zero_transfer_events( - cls, - ledger_api: EthereumApi, - contract_address: str, - sender_address: str, - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - ) -> JSONLike: - """ - Get all zero transfer events from a given sender to the safe address. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param sender_address: the owner of the service, ie the address that triggers termination - :param from_block: from which block to search for events - :param to_block: to which block to search for events - :return: the zero transfer events - """ - ledger_api = cast(EthereumApi, ledger_api) - safe_contract = cls.get_instance(ledger_api, contract_address) - sender_address = ledger_api.api.to_checksum_address(sender_address) - entries = safe_contract.events.SafeReceived.create_filter( - fromBlock=from_block, - toBlock=to_block, - argument_filters=dict(sender=sender_address), - ).get_all_entries() - zero_transfer_events = list( - dict( - tx_hash=entry.transactionHash.hex(), - block_number=entry.blockNumber, - sender=ledger_api.api.to_checksum_address(entry["args"]["sender"]), - ) - for entry in entries - if int(entry["args"]["value"]) == 0 - ) - return dict( - data=zero_transfer_events, - ) - - @classmethod - def get_remove_owner_data( - cls, - ledger_api: EthereumApi, - contract_address: str, - owner: str, - threshold: int, - ) -> JSONLike: - """ - Get a removeOwner() encoded tx. - - This method acts as a wrapper for `removeOwner()` - https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/base/OwnerManager.sol#L70 - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param owner: the owner to be removed - :param threshold: the new safe threshold to be set - :return: the zero transfer events - """ - ledger_api = cast(EthereumApi, ledger_api) - safe_contract = cls.get_instance(ledger_api, contract_address) - # Note that owners in the safe are stored as a linked list, we need to know the parent (prev_owner) of an owner - # when removing. https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/base/OwnerManager.sol#L15 - owners = [ - ledger_api.api.to_checksum_address(owner) - for owner in safe_contract.functions.getOwners().call() - ] - owner = ledger_api.api.to_checksum_address(owner) - prev_owner = cls._get_prev_owner(owners, owner) - data = safe_contract.encodeABI( - fn_name="removeOwner", - args=[ - ledger_api.api.to_checksum_address(prev_owner), - owner, - threshold, - ], - ) - return dict( - data=data, - ) - - @classmethod - def get_swap_owner_data( - cls, - ledger_api: EthereumApi, - contract_address: str, - old_owner: str, - new_owner: str, - ) -> JSONLike: - """ - Get a swapOwner() encoded tx. - - This method acts as a wrapper for `swapOwner()` - https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/base/OwnerManager.sol#L94 - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param old_owner: the owner to be replaced - :param new_owner: owner to replace old_owner - :return: the zero transfer events - """ - ledger_api = cast(EthereumApi, ledger_api) - safe_contract = cls.get_instance(ledger_api, contract_address) - # Note that owners in the safe are stored as a linked list, we need to know the parent (prev_owner) of an owner - # when swapping. https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/base/OwnerManager.sol#L15 - owners = [ - ledger_api.api.to_checksum_address(owner) - for owner in safe_contract.functions.getOwners().call() - ] - old_owner = ledger_api.api.to_checksum_address(old_owner) - prev_owner = cls._get_prev_owner(owners, old_owner) - data = safe_contract.encodeABI( - fn_name="swapOwner", - args=[ - ledger_api.api.to_checksum_address(prev_owner), - old_owner, - ledger_api.api.to_checksum_address(new_owner), - ], - ) - return dict( - data=data, - ) - - @classmethod - def _get_prev_owner(cls, linked_list: List[str], target: str) -> str: - """Given a linked list of strings, it returns the one pointing to target.""" - root = cls._SENTINEL_OWNERS - index = linked_list.index(target) - 1 - if index < 0: - # if target is the first element in the list, the root is pointing to it - return root - return linked_list[index] - - @classmethod - def get_owners( - cls, - ledger_api: EthereumApi, - contract_address: str, - ) -> JSONLike: - """ - Get the safe owners. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :return: the safe owners - """ - ledger_api = cast(EthereumApi, ledger_api) - safe_contract = cls.get_instance(ledger_api, contract_address) - owners = [ - ledger_api.api.to_checksum_address(owner) - for owner in safe_contract.functions.getOwners().call() - ] - return dict(owners=owners) - - @classmethod - def get_approve_hash_tx( - cls, - ledger_api: EthereumApi, - contract_address: str, - tx_hash: str, - sender: str, - ) -> JSONLike: - """Get approve has tx.""" - ledger_api = cast(EthereumApi, ledger_api) - return ledger_api.build_transaction( - contract_instance=cls.get_instance(ledger_api, contract_address), - method_name="approveHash", - method_args={ - "hashToApprove": tx_hash, - }, - tx_args={ - "sender_address": sender, - }, - ) diff --git a/trader_old/vendor/valory/contracts/gnosis_safe/contract.yaml b/trader_old/vendor/valory/contracts/gnosis_safe/contract.yaml deleted file mode 100644 index 0576cf599..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe/contract.yaml +++ /dev/null @@ -1,40 +0,0 @@ -name: gnosis_safe -author: valory -version: 0.1.0 -type: contract -description: Gnosis Safe (GnosisSafeL2) contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeig26vrs7tcobu4cgk3fpqhvlzjwmb4nqsc7u66n4yhd2dh2rt7ff4 - __init__.py: bafybeib4nfvueif2tkc7migc73qopyjvrbzedyehrexjx4y5vav3clmf34 - build/GnosisSafe_V1_3_0.json: bafybeifxc4pnyus43qfrvxrqunlmkzvwfr5chyjesyobbk5m4smb2hkd4y - contract.py: bafybeiasa5rs5axojfmuztc6powf7twkpwjiacw2fef3xymmd5jd6hz354 - encode.py: bafybeiez2siif4cpntxjvzcxsgpv2xcdgco4xtnr26pjqzwrlu62tmn2na - tests/__init__.py: bafybeihbclcqwfoxoljzwnbg3nf22srsyx5dgdbcyj27irwizktg4ygujy - tests/test_contract.py: bafybeidb4mrkkj6esxejlqdwx3m7skh2fdskqermxpuiuqpkyvkzb4ndyy -fingerprint_ignore_patterns: [] -contracts: -- valory/gnosis_safe_proxy_factory:0.1.0:bafybeieg57u3z7cdlmdamad5e6lk7kmsli2zurzkg3sl4y7lhekcu4y3au -class_name: GnosisSafeContract -contract_interface_paths: - ethereum: build/GnosisSafe_V1_3_0.json -dependencies: - ecdsa: - version: '>=0.15' - eth-abi: - version: ==4.0.0 - eth-utils: - version: ==2.2.0 - eth_typing: {} - hexbytes: {} - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - packaging: {} - pycryptodome: - version: ==3.18.0 - requests: {} - web3: - version: <7,>=6.0.0 diff --git a/trader_old/vendor/valory/contracts/gnosis_safe/encode.py b/trader_old/vendor/valory/contracts/gnosis_safe/encode.py deleted file mode 100644 index e65cf5e0a..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe/encode.py +++ /dev/null @@ -1,155 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""ETH encoder.""" - -import typing as t - -from Crypto.Hash import keccak # nosec -from eth_abi.abi import default_codec # nosec -from eth_utils import decode_hex - - -def encode(typ: t.Any, arg: t.Any) -> bytes: - """Encode by type.""" - encoder = default_codec._registry.get_encoder( # pylint: disable=protected-access - typ - ) - return encoder(arg) - - -def to_string(value: t.Union[bytes, str, int]) -> bytes: - """Convert to byte string.""" - if isinstance(value, bytes): - return value - if isinstance(value, str): - return bytes(value, "utf-8") - if isinstance(value, int): - return bytes(str(value), "utf-8") - raise ValueError("Invalid data") - - -def sha3_256(x: bytes) -> bytes: - """Calculate SHA3-256 hash.""" - return keccak.new(digest_bits=256, data=x).digest() - - -def sha3(seed: t.Union[bytes, str, int]) -> bytes: - """Calculate SHA3-256 hash.""" - return sha3_256(to_string(seed)) - - -def scan_bin(v: str) -> bytes: - """Scan bytes.""" - if v[:2] in ("0x", b"0x"): - return decode_hex(v[2:]) - return decode_hex(v) - - -def create_struct_definition(name: str, schema: t.List[t.Dict[str, str]]) -> str: - """Create method struction defintion.""" - schema_types = [ - (schema_type["type"] + " " + schema_type["name"]) for schema_type in schema - ] - return name + "(" + ",".join(schema_types) + ")" - - -def find_dependencies( - name: str, types: t.Dict[str, t.Any], dependencies: t.Set -) -> None: - """Find dependencies.""" - if name in dependencies: - return - schema = types.get(name) - if not schema: - return - dependencies.add(name) - for schema_type in schema: - find_dependencies(schema_type["type"], types, dependencies) - - -def create_schema(name: str, types: t.Dict) -> str: - """Create schema.""" - array_start = name.find("[") - clean_name = name if array_start < 0 else name[:array_start] - dependencies: t.Set = set() - find_dependencies(clean_name, types, dependencies) - dependencies.discard(clean_name) - dependency_definitions = [ - create_struct_definition(dependency, types[dependency]) - for dependency in sorted(dependencies) - if types.get(dependency) - ] - return create_struct_definition(clean_name, types[clean_name]) + "".join( - dependency_definitions - ) - - -def create_schema_hash(name: str, types: t.Dict) -> bytes: - """Create schema hash.""" - return encode("bytes32", sha3(create_schema(name, types))) - - -def encode_value(data_type: str, value: t.Any, types: t.Dict) -> bytes: - """Encode value.""" - if data_type == "string": - return encode("bytes32", sha3(value)) - if data_type == "bytes": - return encode("bytes32", sha3(scan_bin(value))) - if types.get(data_type): - return encode("bytes32", sha3(encode_data(data_type, value, types))) - if data_type.endswith("]"): - arrayType = data_type[: data_type.index("[")] - return encode( - "bytes32", - sha3( - b"".join( - [encode_data(arrayType, arrayValue, types) for arrayValue in value] - ) - ), - ) - return encode(data_type, value) - - -def encode_data(name: str, data: t.Dict[str, t.Dict[str, str]], types: t.Dict) -> bytes: - """Encode data.""" - return create_schema_hash(name, types) + b"".join( - [ - encode_value(schema_type["type"], data[schema_type["name"]], types) - for schema_type in types[name] - ] - ) - - -def create_struct_hash( - name: str, data: t.Dict[str, t.Dict[str, str]], types: t.Dict -) -> bytes: - """Create struct hash.""" - return sha3(encode_data(name, data, types)) - - -def encode_typed_data(data: t.Dict[str, t.Any]) -> bytes: - """Encode typed data.""" - types = t.cast(t.Dict, data.get("types")) - primary_type = t.cast(str, data.get("primaryType")) - domain = t.cast(t.Dict[str, t.Dict[str, str]], data.get("domain")) - message = t.cast(t.Dict[str, t.Any], data.get("message")) - domain_hash = create_struct_hash("EIP712Domain", domain, types) - message_hash = create_struct_hash(primary_type, message, types) - return sha3(bytes.fromhex("19") + bytes.fromhex("01") + domain_hash + message_hash) diff --git a/trader_old/vendor/valory/contracts/gnosis_safe/tests/__init__.py b/trader_old/vendor/valory/contracts/gnosis_safe/tests/__init__.py deleted file mode 100644 index 2d8e4570c..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/gnosis_safe contract.""" diff --git a/trader_old/vendor/valory/contracts/gnosis_safe/tests/test_contract.py b/trader_old/vendor/valory/contracts/gnosis_safe/tests/test_contract.py deleted file mode 100644 index 8e938bb1d..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe/tests/test_contract.py +++ /dev/null @@ -1,845 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/gnosis contract.""" - -import binascii -import secrets -import time -from pathlib import Path -from typing import Any, Dict, List, Optional, Tuple, cast -from unittest import mock - -import pytest -from aea.common import JSONLike -from aea.crypto.registries import crypto_registry -from aea_ledger_ethereum import EthereumApi, EthereumCrypto -from aea_test_autonomy.base_test_classes.contracts import ( - BaseGanacheContractTest, - BaseHardhatGnosisContractTest, -) -from aea_test_autonomy.configurations import ( - ETHEREUM_KEY_PATH_1, - ETHEREUM_KEY_PATH_2, - ETHEREUM_KEY_PATH_3, - KEY_PAIRS, -) -from aea_test_autonomy.docker.base import skip_docker_tests -from aea_test_autonomy.helpers.contracts import get_register_contract -from hexbytes import HexBytes -from web3 import Web3 -from web3.datastructures import AttributeDict -from web3.eth import Eth -from web3.exceptions import ContractLogicError -from web3.types import TxData - -from packages.valory.contracts.gnosis_safe.contract import ( - GnosisSafeContract, - SAFE_CONTRACT, -) -from packages.valory.contracts.gnosis_safe_proxy_factory.tests.test_contract import ( - PACKAGE_DIR as PROXY_DIR, -) - - -PACKAGE_DIR = Path(__file__).parent.parent - -DEFAULT_GAS = 1000000 -DEFAULT_MAX_FEE_PER_GAS = 10**15 -DEFAULT_MAX_PRIORITY_FEE_PER_GAS = 10**15 -EXPECTED_TX_KEYS = { - "chainId", - "data", - "from", - "gas", - "maxFeePerGas", - "maxPriorityFeePerGas", - "nonce", - "to", - "value", -} - - -class BaseContractTest(BaseGanacheContractTest): - """Base test case for GnosisSafeContract""" - - NB_OWNERS: int = 4 - THRESHOLD: int = 1 - SALT_NONCE: Optional[int] = None - contract_directory = PACKAGE_DIR - contract: GnosisSafeContract - - @classmethod - def setup_class( - cls, - ) -> None: - """Setup test.""" - # workaround for the fact that contract dependencies are not possible yet - _ = get_register_contract(PROXY_DIR) - super().setup_class() - - @classmethod - def deployment_kwargs(cls) -> Dict[str, Any]: - """Get deployment kwargs.""" - return dict( - owners=cls.owners(), - threshold=int(cls.threshold()), - gas=DEFAULT_GAS, - ) - - @classmethod - def owners(cls) -> List[str]: - """Get the owners.""" - return [ - Web3.to_checksum_address(t[0]) for t in cls.key_pairs()[: cls.NB_OWNERS] - ] - - @classmethod - def deployer(cls) -> Tuple[str, str]: - """Get the key pair of the deployer.""" - # for simplicity, get the first owner - return cls.key_pairs()[0] - - @classmethod - def threshold( - cls, - ) -> int: - """Returns the amount of threshold.""" - return cls.THRESHOLD - - @classmethod - def get_nonce(cls) -> int: - """Get the nonce.""" - if cls.SALT_NONCE is not None: - return cls.SALT_NONCE - return secrets.SystemRandom().randint(0, 2**256 - 1) - - -class BaseContractTestHardHatSafeNet(BaseHardhatGnosisContractTest): - """Base test case for GnosisSafeContract""" - - NB_OWNERS: int = 4 - THRESHOLD: int = 1 - SALT_NONCE: Optional[int] = None - contract_directory = PACKAGE_DIR - sanitize_from_deploy_tx = ["contract_address"] - contract: GnosisSafeContract - - @classmethod - def setup_class( - cls, - ) -> None: - """Setup test.""" - _ = get_register_contract(PROXY_DIR) - super().setup_class() - - @classmethod - def deployment_kwargs(cls) -> Dict[str, Any]: - """Get deployment kwargs.""" - return dict( - owners=cls.owners(), - threshold=int(cls.threshold()), - gas=DEFAULT_GAS, - ) - - @classmethod - def owners(cls) -> List[str]: - """Get the owners.""" - return [ - Web3.to_checksum_address(t[0]) for t in cls.key_pairs()[: cls.NB_OWNERS] - ] - - @classmethod - def deployer(cls) -> Tuple[str, str]: - """Get the key pair of the deployer.""" - # for simplicity, get the first owner - return cls.key_pairs()[0] - - @classmethod - def threshold( - cls, - ) -> int: - """Returns the amount of threshold.""" - return cls.THRESHOLD - - @classmethod - def get_nonce(cls) -> int: - """Get the nonce.""" - if cls.SALT_NONCE is not None: - return cls.SALT_NONCE - return secrets.SystemRandom().randint(0, 2**256 - 1) - - def _verify_safe_tx( - self, - tx_hash: str, - value: int, - data: bytes, - to_address: str, - signatures_by_owners: Dict, - ) -> bool: - """Helper to verify tx.""" - ledger_api = cast(EthereumApi, self.ledger_api) - contract_address = cast(str, self.contract_address) - return self.contract.verify_tx( - ledger_api=ledger_api, - contract_address=contract_address, - tx_hash=tx_hash, - owners=(self.deployer_crypto.address.lower(),), - to_address=to_address, - value=value, - data=data, - signatures_by_owner={ - self.deployer_crypto.address.lower(): signatures_by_owners[ - self.deployer_crypto.address - ] - }, - )["verified"] - - def _get_raw_safe_tx( - self, - sender_address: str, - value: int, - data: bytes, - to_address: str, - signatures_by_owners: Dict, - ) -> JSONLike: - """Helper to prepare a safe tx.""" - ledger_api = cast(EthereumApi, self.ledger_api) - contract_address = cast(str, self.contract_address) - tx = self.contract.get_raw_safe_transaction( - ledger_api=ledger_api, - contract_address=contract_address, - sender_address=sender_address, - owners=(self.deployer_crypto.address.lower(),), - to_address=to_address, - value=value, - data=data, - signatures_by_owner={ - self.deployer_crypto.address.lower(): signatures_by_owners[ - self.deployer_crypto.address - ] - }, - ) - return tx - - -@skip_docker_tests -class TestDeployTransactionHardhat(BaseContractTestHardHatSafeNet): - """Test.""" - - ledger_api: EthereumApi - - def test_deployed(self) -> None: - """Run tests.""" - result = self.contract.get_deploy_transaction( - ledger_api=self.ledger_api, - deployer_address=str(self.deployer_crypto.address), - owners=self.owners(), - threshold=int(self.threshold()), - gas=DEFAULT_GAS, - ) - assert isinstance(result, dict) - assert len(result) == 10 - data = result.pop("data") - assert isinstance(data, str) - assert len(data) > 0 and data.startswith("0x") - # there is no "data" field on the deploy tx - # but there is contract_address - expected_deploy_tx_fields = EXPECTED_TX_KEYS - {"data"} - expected_deploy_tx_fields.add("contract_address") - assert all( - key in result.keys() for key in expected_deploy_tx_fields - ), "Error, found: {}".format(result) - - def test_exceptions( - self, - ) -> None: - """Test exceptions.""" - - with pytest.raises( - ValueError, - match="Threshold cannot be bigger than the number of unique owners", - ): - # Tests for `ValueError("Threshold cannot be bigger than the number of unique owners")`.` - self.contract.get_deploy_transaction( - ledger_api=self.ledger_api, - deployer_address=str(self.deployer_crypto.address), - owners=[], - threshold=1, - ) - - with pytest.raises(ValueError, match="Client does not have any funds"): - # Tests for `ValueError("Client does not have any funds")`. - self.contract.get_deploy_transaction( - ledger_api=self.ledger_api, - deployer_address=crypto_registry.make( - EthereumCrypto.identifier - ).address, - owners=self.owners(), - threshold=int(self.threshold()), - ) - - def test_non_implemented_methods( - self, - ) -> None: - """Test not implemented methods.""" - with pytest.raises(NotImplementedError): - self.contract.get_raw_transaction(self.ledger_api, "") - - with pytest.raises(NotImplementedError): - self.contract.get_raw_message(self.ledger_api, "") - - with pytest.raises(NotImplementedError): - self.contract.get_state(self.ledger_api, "") - - def test_verify(self) -> None: - """Run verify test.""" - assert self.contract_address is not None - result = self.contract.verify_contract( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - ) - assert result["verified"], "Contract not verified." - - verified = self.contract.verify_contract( - ledger_api=self.ledger_api, - contract_address=SAFE_CONTRACT, - )["verified"] - assert not verified, "Not verified" - - def test_get_safe_nonce(self) -> None: - """Run get_safe_nonce test.""" - safe_nonce = self.contract.get_safe_nonce( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - )["safe_nonce"] - assert safe_nonce == 0 - - def test_revert_reason( - self, - ) -> None: - """Test `revert_reason` method.""" - tx = { - "to": "to", - "from": "from", - "value": "value", - "input": "input", - "blockNumber": 1, - } - - def _raise_solidity_error(*_: Any) -> None: - raise ContractLogicError("reason") - - with mock.patch.object( - self.ledger_api.api.eth, "call", new=_raise_solidity_error - ): - reason = self.contract.revert_reason( - self.ledger_api, "contract_address", cast(TxData, tx) - ) - assert "revert_reason" in reason - assert ( - reason["revert_reason"] == "ContractLogicError('reason')" - or reason["revert_reason"] == "ContractLogicError('reason', None)" - ) - - with mock.patch.object(self.ledger_api.api.eth, "call"), pytest.raises( - ValueError, match=f"The given transaction has not been reverted!\ntx: {tx}" - ): - self.contract.revert_reason( - self.ledger_api, "contract_address", cast(TxData, tx) - ) - - def test_get_incoming_transfers(self) -> None: - """Run get_incoming txs.""" - from_block = cast(int, self.ledger_api.api.eth.get_block_number()) + 1 - self.ledger_api.api.eth.send_transaction( - { - "to": self.contract_address, - "from": self.deployer_crypto.address, - "value": 10, - } - ) - - res = cast( - JSONLike, - self.contract.get_ingoing_transfers( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - from_block=hex(from_block), - ), - ) - data = cast(List[JSONLike], res["data"]) - - time.sleep(1) - - assert len(res) == 1, "one transfer should exist" - assert data[0]["amount"] == 10, "transfer amount should be 10" - assert ( - data[0]["sender"] == self.deployer_crypto.address - ), f"{data[0]['sender']} should be the sender" - assert data[0]["blockNumber"] is not None, "tx is still pending" - assert ( - self.ledger_api.api.eth.get_balance(self.contract_address) == 10 - ), "incorrect balance" - - self.ledger_api.api.eth.send_transaction( - { - "to": self.contract_address, - "from": self.deployer_crypto.address, - "value": 100, - } - ) - from_block = cast(int, data[0]["blockNumber"]) + 1 - - time.sleep(3) - res = self.contract.get_ingoing_transfers( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - from_block=hex(from_block), - ) - data = cast(List[JSONLike], res["data"]) - - assert len(res) == 1, "one transfer should exist" - assert data[0]["amount"] == 100, "transfer amount should be 100" - assert ( - data[0]["sender"] == self.deployer_crypto.address - ), f"{data[0]['sender']} should be the sender" - assert data[0]["blockNumber"] is not None, "tx is still pending" - assert ( - self.ledger_api.api.eth.get_balance(self.contract_address) == 110 - ), "incorrect balance" - - def test_get_zero_transfer_events(self) -> None: - """Test get_zero_transfer_events.""" - # check that the safe has no zero transfers - res = cast( - JSONLike, - self.contract.get_zero_transfer_events( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - sender_address=self.deployer_crypto.address, - ), - ) - data = cast(List[JSONLike], res["data"]) - assert len(data) == 0, "no zero transfers should be in the safe" - - # make a zero transfer - self.ledger_api.api.eth.send_transaction( - { - "to": self.contract_address, - "from": self.deployer_crypto.address, - "value": 0, - } - ) - - time.sleep(3) - - res = cast( - JSONLike, - self.contract.get_zero_transfer_events( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - sender_address=self.deployer_crypto.address, - ), - ) - data = cast(List[JSONLike], res["data"]) - - assert len(res) == 1, "one zero transfer should exist" - assert ( - data[0]["sender"] == self.deployer_crypto.address - ), f"{data[0]['sender']} should be the sender" - assert data[0]["block_number"] is not None, "tx is still pending" - - # make a second zero transfer - prev_block = cast(int, self.ledger_api.api.eth.get_block_number()) + 1 - self.ledger_api.api.eth.send_transaction( - { - "to": self.contract_address, - "from": self.deployer_crypto.address, - "value": 0, - } - ) - time.sleep(3) - - res = self.contract.get_zero_transfer_events( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - sender_address=self.deployer_crypto.address, - from_block=prev_block, - ) - data = cast(List[JSONLike], res["data"]) - - assert len(res) == 1, "one zero transfer should exist" - assert ( - data[0]["sender"] == self.deployer_crypto.address - ), f"{data[0]['sender']} should be the sender" - assert data[0]["block_number"] is not None, "tx is still pending" - - def test_get_owners(self) -> None: - """Test the owners are as expected.""" - owners = self.contract.get_owners( - ledger_api=self.ledger_api, - contract_address=cast(str, self.contract_address), - )["owners"] - assert owners == self.owners() - - -@skip_docker_tests -class TestRawSafeTransaction(BaseContractTestHardHatSafeNet): - """Test `get_raw_safe_transaction`""" - - ledger_api: EthereumApi - - def test_run(self) -> None: - """Run tests.""" - assert self.contract_address is not None - value = 0 - data = b"" - sender = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_1 - ) - assert sender.address == self.owners()[1] - receiver = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_2 - ) - assert receiver.address == self.owners()[2] - fourth = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_3 - ) - assert fourth.address == self.owners()[3] - cryptos = [self.deployer_crypto, sender, receiver, fourth] - tx_hash = self.contract.get_raw_safe_transaction_hash( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - to_address=receiver.address, - value=value, - data=data, - )["tx_hash"] - b_tx_hash = binascii.unhexlify(cast(str, tx_hash)[2:]) - signatures_by_owners = { - crypto.address: crypto.sign_message(b_tx_hash, is_deprecated_mode=True)[2:] - for crypto in cryptos - } - assert list(signatures_by_owners.keys()) == self.owners() - - tx = self._get_raw_safe_tx( - sender_address=sender.address, - value=value, - data=data, - signatures_by_owners=signatures_by_owners, - to_address=receiver.address, - ) - assert all(key in tx.keys() for key in EXPECTED_TX_KEYS), "Missing key" - - tx_signed = sender.sign_transaction(tx) - tx_hash = self.ledger_api.send_signed_transaction(tx_signed) - assert tx_hash is not None, "Tx hash is `None`" - - verified = self._verify_safe_tx( - tx_hash, value, data, receiver.address, signatures_by_owners - ) - assert verified, f"Not verified: {verified}" - - def test_verify_negative(self) -> None: - """Test verify negative.""" - assert self.contract_address is not None - verified = self.contract.verify_tx( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - tx_hash="0xfc6d7c491688840e79ed7d8f0fc73494be305250f0d5f62d04c41bc4467e8603", - owners=("",), - to_address=crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_1 - ).address, - value=0, - data=b"", - signatures_by_owner={}, - )["verified"] - assert not verified, "Should not be verified" - - # mock `get_transaction` and `get_transaction_receipt` using a copy of a real reverted tx and its receipt - @mock.patch.object( - Eth, - "get_transaction", - return_value=AttributeDict( - { - "accessList": [], - "blockHash": HexBytes( - "0x8543592f08d1d9e6d722ba9d600270d7e7789ecc9b66f27ca81b104df9c5dd4a" - ), - "blockNumber": 31190129, - "chainId": "0x89", - "from": "0x5eF6567079c6c26d8ebf61AC0716163367E9B3cf", - "gas": 270000, - "gasPrice": 36215860217, - "hash": HexBytes( - "0x09d5be525caea564b2d4fd31af424c8f0414a9b270937a1bee29167a883e6ce5" - ), - "input": "0x6a7612020000000000000000000000003d9e92b0fe7673dda3d7c33b9ff302768a03de190000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000000000000000001d4c0000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000" - "0000000000000000000000000000000000000000000000000000000000000846b0bac970000000000000000000000" - "000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000" - "000000000004000000000000000000000000000000000000000000000000000000000001df5000000000000000000" - "00000000000000000000000000000487da3583c85e1e0000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000104c292f99a14d354c669" - "3f9037a4a3d09c85c8ad5f1ab4de79bbc8bab845560f797f385ecbe77e90245b7b45e218a2c56fec17c9d38729264" - "83d0ed800df46daa71c3afaa87b5959d644cd0d311a93acb398ec4f9d4c545c54ea6f4adbaa3e99dd9668f948eb64" - "10f1b2105e2f6ca762badf17539d9221cef7af55a244c6ae3c6b401cfd01fe829d711a372b9d8ad5b91e0956a4da1" - "6929d04a2581b10f9f4599899b625c367bef18656c90efcf9d9ee5063860774f08517488b05ef5090acd31aa9d91b" - "7df8080d69fdddfe9b326f3ae0cb95227e21d2d265b6a83861998dd9e91fb980415e78c2bb0b10dbe3b4d7bead977" - "2f32fa26b738c5670aa69ee9d09973ea2b81c00000000000000000000000000000000000000000000000000000000", - "maxFeePerGas": 36215860217, - "maxPriorityFeePerGas": 36215860202, - "nonce": 2231, - "r": HexBytes( - "0x5d5d369d5fc30c5604d974761d41b08118120eb94fd65a827bab1f6ea558d67c" - ), - "s": HexBytes( - "0x12f68826bd41989335e62d43fd36547fe171ad536b99bc93766622438d3f8355" - ), - "to": "0x37ba5291A5bE8cbE44717a0673fe2c5a45B4B6A8", - "transactionIndex": 28, - "type": "0x2", - "v": 1, - "value": 0, - } - ), - ) - @mock.patch.object( - EthereumApi, - "get_transaction_receipt", - return_value={ - "blockHash": "0x8543592f08d1d9e6d722ba9d600270d7e7789ecc9b66f27ca81b104df9c5dd4a", - "blockNumber": 31190129, - "contractAddress": None, - "cumulativeGasUsed": 5167853, - "effectiveGasPrice": 36215860217, - "from": "0x5eF6567079c6c26d8ebf61AC0716163367E9B3cf", - "gasUsed": 48921, - "logs": [ - { - "address": "0x0000000000000000000000000000000000001010", - "blockHash": "0x8543592f08d1d9e6d722ba9d600270d7e7789ecc9b66f27ca81b104df9c5dd4a", - "blockNumber": 31190129, - "data": "0x00000000000000000000000000000000000000000000000000064b5dcc9920c1000000000000000000000000" - "00000000000000000000000032116d529b00f7490000000000000000000000000000000000000000000004353d" - "1a5e0a73394e1e000000000000000000000000000000000000000000000000320b21f4ce67d688000000000000" - "0000000000000000000000000000000004353d20a9683fd26edf", - "logIndex": 115, - "removed": False, - "topics": [ - "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", - "0x0000000000000000000000000000000000000000000000000000000000001010", - "0x0000000000000000000000005ef6567079c6c26d8ebf61ac0716163367e9b3cf", - "0x000000000000000000000000f0245f6251bef9447a08766b9da2b07b28ad80b0", - ], - "transactionHash": "0x09d5be525caea564b2d4fd31af424c8f0414a9b270937a1bee29167a883e6ce5", - "transactionIndex": 28, - } - ], - "logsBloom": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000" - "000000000800000000000000000000000000000008000000000000000000000000080000000000000000000010000" - "000000000000000000000000000000000000000000000000000000008000000000000000000000008000000000000" - "000000000000000000000000000000000000088000020000000000000000000000000000000000000000000000000" - "000000000000400000000000000000000100000000000000000000000000000010000000000000000000000000000" - "0000000800000000000000000000000000000000000100000", - "status": 0, - "to": "0x37ba5291A5bE8cbE44717a0673fe2c5a45B4B6A8", - "transactionHash": "0x09d5be525caea564b2d4fd31af424c8f0414a9b270937a1bee29167a883e6ce5", - "transactionIndex": 28, - "type": "0x2", - "revert_reason": "execution reverted: GS026", - }, - ) - def test_verify_reverted(self, *_: Any) -> None: - """Test verify for reverted tx.""" - assert self.contract_address is not None - res = self.contract.verify_tx( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - tx_hash="test", - owners=("",), - to_address=crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_1 - ).address, - value=0, - data=b"", - signatures_by_owner={}, - ) - assert not res["verified"], "Should not be verified" - - -@skip_docker_tests -class TestOwnerManagement(BaseContractTestHardHatSafeNet): - """Test owner management related .""" - - ledger_api: EthereumApi - - def test_remove(self) -> None: # pylint: disable=too-many-locals - """Test owner removal.""" - assert self.contract_address is not None - owner_to_be_removed = self.owners()[2] - threshold = max(self.threshold() - 1, 1) - value = 0 - data_str = self.contract.get_remove_owner_data( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - owner=owner_to_be_removed, - threshold=threshold, - ).get("data") - data = bytes.fromhex(data_str[2:]) # strip 0x before converting to bytes - - sender = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_1 - ) - assert sender.address == self.owners()[1] - receiver = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_2 - ) - assert receiver.address == self.owners()[2] - fourth = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_3 - ) - assert fourth.address == self.owners()[3] - cryptos = [self.deployer_crypto, sender, receiver, fourth] - tx_hash = self.contract.get_raw_safe_transaction_hash( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - to_address=self.contract_address, - value=value, - data=data, - )["tx_hash"] - b_tx_hash = binascii.unhexlify(cast(str, tx_hash)[2:]) - signatures_by_owners = { - crypto.address: crypto.sign_message(b_tx_hash, is_deprecated_mode=True)[2:] - for crypto in cryptos - } - assert list(signatures_by_owners.keys()) == self.owners() - - tx = self._get_raw_safe_tx( - sender_address=sender.address, - value=value, - data=data, - to_address=self.contract_address, - signatures_by_owners=signatures_by_owners, - ) - assert all(key in tx.keys() for key in EXPECTED_TX_KEYS), "Missing key" - - prev_block = cast(int, self.ledger_api.api.eth.get_block_number()) + 1 - tx_signed = sender.sign_transaction(tx) - tx_hash = self.ledger_api.send_signed_transaction(tx_signed) - - assert tx_hash is not None, "Tx hash is `None`" - - verified = self._verify_safe_tx( - tx_hash, value, data, self.contract_address, signatures_by_owners - ) - assert verified, f"Not verified: {verified}" - time.sleep(1) - remove_events = self.contract.get_removed_owner_events( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - removed_owner=owner_to_be_removed, - from_block=prev_block, - ).get("data") - - assert remove_events is not None, "a RemovedOwner event was expected" - assert len(remove_events) == 1, "1 RemovedOwner event was expected" - assert ( - remove_events[0].get("owner") == owner_to_be_removed - ), "a different owner than expected was removed" - - def test_swap(self) -> None: # pylint: disable=too-many-locals - """Test owner swapping.""" - assert self.contract_address is not None - old_owner = self.owners()[1] - new_owner = KEY_PAIRS[-1][0] - value = 0 - data_str = self.contract.get_swap_owner_data( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - old_owner=old_owner, - new_owner=new_owner, - ).get("data") - data = bytes.fromhex(data_str[2:]) # strip 0x before converting to bytes - - sender = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_1 - ) - assert sender.address == self.owners()[1] - receiver = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_2 - ) - assert receiver.address == self.owners()[2] - fourth = crypto_registry.make( - EthereumCrypto.identifier, private_key_path=ETHEREUM_KEY_PATH_3 - ) - assert fourth.address == self.owners()[3] - cryptos = [self.deployer_crypto, sender, receiver, fourth] - tx_hash = self.contract.get_raw_safe_transaction_hash( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - to_address=self.contract_address, - value=value, - data=data, - )["tx_hash"] - b_tx_hash = binascii.unhexlify(cast(str, tx_hash)[2:]) - signatures_by_owners = { - crypto.address: crypto.sign_message(b_tx_hash, is_deprecated_mode=True)[2:] - for crypto in cryptos - } - assert list(signatures_by_owners.keys()) == self.owners() - - tx = self._get_raw_safe_tx( - sender_address=sender.address, - to_address=self.contract_address, - value=value, - data=data, - signatures_by_owners=signatures_by_owners, - ) - assert all(key in tx.keys() for key in EXPECTED_TX_KEYS), "Missing key" - - prev_block = cast(int, self.ledger_api.api.eth.get_block_number()) + 1 - tx_signed = sender.sign_transaction(tx) - tx_hash = self.ledger_api.send_signed_transaction(tx_signed) - - assert tx_hash is not None, "Tx hash is `None`" - - verified = self._verify_safe_tx( - tx_hash, value, data, self.contract_address, signatures_by_owners - ) - assert verified, f"Not verified: {verified}" - time.sleep(1) - remove_events = self.contract.get_removed_owner_events( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - removed_owner=old_owner, - from_block=prev_block, - ).get("data") - - assert remove_events is not None, "a RemovedOwner event was expected" - assert len(remove_events) == 1, "1 RemovedOwner event was expected" - assert ( - remove_events[0].get("owner") == old_owner - ), "a different owner than expected was removed" diff --git a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/README.md b/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/README.md deleted file mode 100644 index 0fe891711..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Gnosis Safe Proxy Factory contract - -## Description - -## Functions - diff --git a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/__init__.py b/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/__init__.py deleted file mode 100644 index d0992d1cb..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the support resources for the gnosis_safe_proxy_contract (GnosisSafeProxyFactory) contract.""" diff --git a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/build/ProxyFactory_V1_3_0.json b/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/build/ProxyFactory_V1_3_0.json deleted file mode 100644 index ef03cd84a..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/build/ProxyFactory_V1_3_0.json +++ /dev/null @@ -1,172 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "GnosisSafeProxyFactory", - "sourceName": "contracts/proxies/GnosisSafeProxyFactory.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "contract GnosisSafeProxy", - "name": "proxy", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "singleton", - "type": "address" - } - ], - "name": "ProxyCreation", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_singleton", - "type": "address" - }, - { - "internalType": "bytes", - "name": "initializer", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "saltNonce", - "type": "uint256" - } - ], - "name": "calculateCreateProxyWithNonceAddress", - "outputs": [ - { - "internalType": "contract GnosisSafeProxy", - "name": "proxy", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "singleton", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "createProxy", - "outputs": [ - { - "internalType": "contract GnosisSafeProxy", - "name": "proxy", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_singleton", - "type": "address" - }, - { - "internalType": "bytes", - "name": "initializer", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "saltNonce", - "type": "uint256" - }, - { - "internalType": "contract IProxyCreationCallback", - "name": "callback", - "type": "address" - } - ], - "name": "createProxyWithCallback", - "outputs": [ - { - "internalType": "contract GnosisSafeProxy", - "name": "proxy", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_singleton", - "type": "address" - }, - { - "internalType": "bytes", - "name": "initializer", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "saltNonce", - "type": "uint256" - } - ], - "name": "createProxyWithNonce", - "outputs": [ - { - "internalType": "contract GnosisSafeProxy", - "name": "proxy", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "proxyCreationCode", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "proxyRuntimeCode", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "pure", - "type": "function" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610ebe806100206000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c80631688f0b9146100675780632500510e1461017657806353e5d9351461024357806361b69abd146102c6578063addacc0f146103cb578063d18af54d1461044e575b600080fd5b61014a6004803603606081101561007d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156100ba57600080fd5b8201836020820111156100cc57600080fd5b803590602001918460018302840111640100000000831117156100ee57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919050505061057d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102176004803603606081101561018c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156101c957600080fd5b8201836020820111156101db57600080fd5b803590602001918460018302840111640100000000831117156101fd57600080fd5b909192939192939080359060200190929190505050610624565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61024b610751565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561028b578082015181840152602081019050610270565b50505050905090810190601f1680156102b85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61039f600480360360408110156102dc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561031957600080fd5b82018360208201111561032b57600080fd5b8035906020019184600183028401116401000000008311171561034d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061077c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103d3610861565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104135780820151818401526020810190506103f8565b50505050905090810190601f1680156104405780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6105516004803603608081101561046457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156104a157600080fd5b8201836020820111156104b357600080fd5b803590602001918460018302840111640100000000831117156104d557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061088c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600061058a848484610a3b565b90506000835111156105b25760008060008551602087016000865af114156105b157600080fd5b5b7f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2358185604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a19392505050565b60006106758585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084610a3b565b905080604051602001808273ffffffffffffffffffffffffffffffffffffffff1660601b81526014019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156107165780820151818401526020810190506106fb565b50505050905090810190601f1680156107435780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60606040518060200161076390610bde565b6020820181038252601f19601f82011660405250905090565b60008260405161078b90610bde565b808273ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f0801580156107c7573d6000803e3d6000fd5b5090506000825111156107f05760008060008451602086016000865af114156107ef57600080fd5b5b7f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2358184604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a192915050565b60606040518060200161087390610beb565b6020820181038252601f19601f82011660405250905090565b6000808383604051602001808381526020018273ffffffffffffffffffffffffffffffffffffffff1660601b8152601401925050506040516020818303038152906040528051906020012060001c90506108e786868361057d565b9150600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610a32578273ffffffffffffffffffffffffffffffffffffffff16631e52b518838888886040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156109ca5780820151818401526020810190506109af565b50505050905090810190601f1680156109f75780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015610a1957600080fd5b505af1158015610a2d573d6000803e3d6000fd5b505050505b50949350505050565b6000808380519060200120836040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050600060405180602001610a8890610bde565b6020820181038252601f19601f820116604052508673ffffffffffffffffffffffffffffffffffffffff166040516020018083805190602001908083835b60208310610ae95780518252602082019150602081019050602083039250610ac6565b6001836020036101000a038019825116818451168082178552505050505050905001828152602001925050506040516020818303038152906040529050818151826020016000f59250600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610bd5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f437265617465322063616c6c206661696c65640000000000000000000000000081525060200191505060405180910390fd5b50509392505050565b6101e680610bf883390190565b60ab80610dde8339019056fe608060405234801561001057600080fd5b506040516101e63803806101e68339818101604052602081101561003357600080fd5b8101908080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156100ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101c46022913960400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505060ab806101196000396000f3fe608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea2646970667358221220d1429297349653a4918076d650332de1a1068c5f3e07c5c82360c277770b955264736f6c63430007060033496e76616c69642073696e676c65746f6e20616464726573732070726f7669646564608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea2646970667358221220d1429297349653a4918076d650332de1a1068c5f3e07c5c82360c277770b955264736f6c63430007060033a26469706673582212200c75fe2196b9f752c82794253f2ebce0d821afef5997e1d5a35ec316ce592f6664736f6c63430007060033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c80631688f0b9146100675780632500510e1461017657806353e5d9351461024357806361b69abd146102c6578063addacc0f146103cb578063d18af54d1461044e575b600080fd5b61014a6004803603606081101561007d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156100ba57600080fd5b8201836020820111156100cc57600080fd5b803590602001918460018302840111640100000000831117156100ee57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919050505061057d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102176004803603606081101561018c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156101c957600080fd5b8201836020820111156101db57600080fd5b803590602001918460018302840111640100000000831117156101fd57600080fd5b909192939192939080359060200190929190505050610624565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61024b610751565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561028b578082015181840152602081019050610270565b50505050905090810190601f1680156102b85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61039f600480360360408110156102dc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561031957600080fd5b82018360208201111561032b57600080fd5b8035906020019184600183028401116401000000008311171561034d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061077c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103d3610861565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104135780820151818401526020810190506103f8565b50505050905090810190601f1680156104405780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6105516004803603608081101561046457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001906401000000008111156104a157600080fd5b8201836020820111156104b357600080fd5b803590602001918460018302840111640100000000831117156104d557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061088c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600061058a848484610a3b565b90506000835111156105b25760008060008551602087016000865af114156105b157600080fd5b5b7f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2358185604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a19392505050565b60006106758585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505084610a3b565b905080604051602001808273ffffffffffffffffffffffffffffffffffffffff1660601b81526014019150506040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156107165780820151818401526020810190506106fb565b50505050905090810190601f1680156107435780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60606040518060200161076390610bde565b6020820181038252601f19601f82011660405250905090565b60008260405161078b90610bde565b808273ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f0801580156107c7573d6000803e3d6000fd5b5090506000825111156107f05760008060008451602086016000865af114156107ef57600080fd5b5b7f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2358184604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a192915050565b60606040518060200161087390610beb565b6020820181038252601f19601f82011660405250905090565b6000808383604051602001808381526020018273ffffffffffffffffffffffffffffffffffffffff1660601b8152601401925050506040516020818303038152906040528051906020012060001c90506108e786868361057d565b9150600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610a32578273ffffffffffffffffffffffffffffffffffffffff16631e52b518838888886040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156109ca5780820151818401526020810190506109af565b50505050905090810190601f1680156109f75780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015610a1957600080fd5b505af1158015610a2d573d6000803e3d6000fd5b505050505b50949350505050565b6000808380519060200120836040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050600060405180602001610a8890610bde565b6020820181038252601f19601f820116604052508673ffffffffffffffffffffffffffffffffffffffff166040516020018083805190602001908083835b60208310610ae95780518252602082019150602081019050602083039250610ac6565b6001836020036101000a038019825116818451168082178552505050505050905001828152602001925050506040516020818303038152906040529050818151826020016000f59250600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610bd5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f437265617465322063616c6c206661696c65640000000000000000000000000081525060200191505060405180910390fd5b50509392505050565b6101e680610bf883390190565b60ab80610dde8339019056fe608060405234801561001057600080fd5b506040516101e63803806101e68339818101604052602081101561003357600080fd5b8101908080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156100ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101c46022913960400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505060ab806101196000396000f3fe608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea2646970667358221220d1429297349653a4918076d650332de1a1068c5f3e07c5c82360c277770b955264736f6c63430007060033496e76616c69642073696e676c65746f6e20616464726573732070726f7669646564608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea2646970667358221220d1429297349653a4918076d650332de1a1068c5f3e07c5c82360c277770b955264736f6c63430007060033a26469706673582212200c75fe2196b9f752c82794253f2ebce0d821afef5997e1d5a35ec316ce592f6664736f6c63430007060033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.py b/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.py deleted file mode 100644 index 0294e5be0..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the class to connect to an Gnosis Safe Proxy Factory contract.""" -import logging -from typing import Any, Optional, Tuple, cast - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi -from web3.types import Nonce, TxParams, Wei - - -PUBLIC_ID = PublicId.from_str("valory/gnosis_safe_proxy_factory:0.1.0") -MIN_GAS = 1 -# see https://github.com/valory-xyz/open-autonomy/pull/1209#discussion_r950129886 -GAS_ESTIMATE_ADJUSTMENT = 50_000 - - -_logger = logging.getLogger( - f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" -) - -PROXY_FACTORY_CONTRACT = "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2" - - -class GnosisSafeProxyFactoryContract(Contract): - """The Gnosis Safe Proxy Factory contract.""" - - contract_id = PUBLIC_ID - - @classmethod - def get_raw_transaction( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get the raw transaction.""" - raise NotImplementedError # pragma: nocover - - @classmethod - def get_raw_message( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[bytes]: - """Get raw message.""" - raise NotImplementedError # pragma: nocover - - @classmethod - def get_state( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get state.""" - raise NotImplementedError # pragma: nocover - - @classmethod - def get_deploy_transaction( - cls, ledger_api: LedgerApi, deployer_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """ - Get deploy transaction. - - :param ledger_api: ledger API object. - :param deployer_address: the deployer address. - :param kwargs: the keyword arguments. - :return: an optional JSON-like object. - """ - return super().get_deploy_transaction(ledger_api, deployer_address, **kwargs) - - @classmethod - def build_tx_deploy_proxy_contract_with_nonce( # pylint: disable=too-many-arguments,too-many-locals - cls, - ledger_api: EthereumApi, - proxy_factory_address: str, - master_copy: str, - address: str, - initializer: bytes, - salt_nonce: int, - gas: int = MIN_GAS, - gas_price: Optional[int] = None, - max_fee_per_gas: Optional[int] = None, - max_priority_fee_per_gas: Optional[int] = None, - nonce: Optional[int] = None, - ) -> Tuple[TxParams, str]: - """ - Deploy proxy contract via Proxy Factory using `createProxyWithNonce` (create2) - - :param ledger_api: ledger API object - :param proxy_factory_address: the address of the proxy factory - :param address: Ethereum address - :param master_copy: Address the proxy will point at - :param initializer: Data for safe creation - :param salt_nonce: Uint256 for `create2` salt - :param gas: Gas - :param gas_price: Gas Price - :param max_fee_per_gas: max - :param max_priority_fee_per_gas: max - :param nonce: Nonce - :return: Tuple(tx-hash, tx, deployed contract address) - """ - proxy_factory_contract = cls.get_instance(ledger_api, proxy_factory_address) - - create_proxy_fn = proxy_factory_contract.functions.createProxyWithNonce( - master_copy, initializer, salt_nonce - ) - - tx_parameters = TxParams({"from": address}) - contract_address = create_proxy_fn.call(tx_parameters) - - if gas_price is not None: - tx_parameters["gasPrice"] = Wei(gas_price) # pragma: nocover - - if max_fee_per_gas is not None: - tx_parameters["maxFeePerGas"] = Wei(max_fee_per_gas) # pragma: nocover - - if max_priority_fee_per_gas is not None: - tx_parameters["maxPriorityFeePerGas"] = Wei( # pragma: nocover - max_priority_fee_per_gas - ) - - if ( - gas_price is None - and max_fee_per_gas is None - and max_priority_fee_per_gas is None - ): - tx_parameters.update(ledger_api.try_get_gas_pricing()) - - # we set a value to avoid triggering the gas estimation during `buildTransaction` below - tx_parameters["gas"] = Wei(max(gas, MIN_GAS)) - - if nonce is not None: - tx_parameters["nonce"] = Nonce(nonce) - - transaction_dict = create_proxy_fn.build_transaction(tx_parameters) - gas_estimate = ( - ledger_api._try_get_gas_estimate( # pylint: disable=protected-access - transaction_dict - ) - ) - # see https://github.com/valory-xyz/open-autonomy/pull/1209#discussion_r950129886 - transaction_dict["gas"] = ( - Wei(max(gas_estimate + GAS_ESTIMATE_ADJUSTMENT, gas)) - if gas_estimate is not None - else Wei(gas) - ) - return transaction_dict, contract_address - - @classmethod - def verify_contract( - cls, ledger_api: EthereumApi, contract_address: str - ) -> JSONLike: - """ - Verify the contract's bytecode - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :return: the verified status - """ - ledger_api = cast(EthereumApi, ledger_api) - deployed_bytecode = ledger_api.api.eth.get_code(contract_address).hex() - local_bytecode = cls.contract_interface["ethereum"]["deployedBytecode"] - verified = deployed_bytecode == local_bytecode - return dict(verified=verified) diff --git a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.yaml b/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.yaml deleted file mode 100644 index 7a8bf9e9f..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/contract.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: gnosis_safe_proxy_factory -author: valory -version: 0.1.0 -type: contract -description: Gnosis Safe proxy factory (GnosisSafeProxyFactory) contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeibobgyzn3kozckup5uxbugbgkiqrc7d5okmj6gahctccqfifu7e4e - __init__.py: bafybeif32mykzila23udgceziog2zr4tkreij6zn43ybbtzonojsfmy5ee - build/ProxyFactory_V1_3_0.json: bafybeibmhgw6us3nzg5d4vb3krg3udxgnux66vuz26pjcigdjc7zn5jrxm - contract.py: bafybeiefqqgav5dfw5p7nnwd3yq7ls4636dgsaolkau2nd5tslsvp66m6u - tests/__init__.py: bafybeied5o76k2pgmpqlofnfo2mhoncecnigkm24t26qrnhhqzvtg3g3b4 - tests/test_contract.py: bafybeidgcxvkl4xjg5dbjzl3o6ffoylkdewrpni6lxm3624qrebbwmqeay -fingerprint_ignore_patterns: [] -contracts: [] -class_name: GnosisSafeProxyFactoryContract -contract_interface_paths: - ethereum: build/ProxyFactory_V1_3_0.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - web3: - version: <7,>=6.0.0 diff --git a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/__init__.py b/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/__init__.py deleted file mode 100644 index 8e71b2cb5..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/gnosis_safe_proxy_factory contract.""" diff --git a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/test_contract.py b/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/test_contract.py deleted file mode 100644 index 8c106a1f8..000000000 --- a/trader_old/vendor/valory/contracts/gnosis_safe_proxy_factory/tests/test_contract.py +++ /dev/null @@ -1,103 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/gnosis contract.""" - -from pathlib import Path -from typing import Any, Dict - -from aea_test_autonomy.base_test_classes.contracts import BaseGanacheContractTest -from aea_test_autonomy.docker.base import skip_docker_tests - -from packages.valory.contracts.gnosis_safe_proxy_factory.contract import ( - GnosisSafeProxyFactoryContract, - PROXY_FACTORY_CONTRACT, -) - - -PACKAGE_DIR = Path(__file__).parent.parent - -DEFAULT_GAS = 1000000 -DEFAULT_MAX_FEE_PER_GAS = 10**10 -DEFAULT_MAX_PRIORITY_FEE_PER_GAS = 10**10 -SAFE_CONTRACT = "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552" - - -@skip_docker_tests -class TestGnosisSafeProxyFactory(BaseGanacheContractTest): - """Test deployment of the proxy to Ganache.""" - - contract_directory = PACKAGE_DIR - contract: GnosisSafeProxyFactoryContract - - @classmethod - def deployment_kwargs(cls) -> Dict[str, Any]: - """Get deployment kwargs.""" - return dict( - gas=DEFAULT_GAS, - ) - - def test_deploy(self) -> None: - """Test deployment results.""" - assert ( - self.contract_address != PROXY_FACTORY_CONTRACT - ), "Contract addresses should differ as we don't use deterministic deployment here." - - def test_build_tx_deploy_proxy_contract_with_nonce(self) -> None: - """Test build_tx_deploy_proxy_contract_with_nonce method.""" - assert self.contract_address is not None - result = self.contract.build_tx_deploy_proxy_contract_with_nonce( - self.ledger_api, - self.contract_address, - SAFE_CONTRACT, - self.deployer_crypto.address, - b"", - 1, - gas=DEFAULT_GAS, - nonce=1, - ) - assert len(result) == 2 - assert len(result[0]) == 9 - assert all( - [ - key - in [ - "value", - "gas", - "maxFeePerGas", - "maxPriorityFeePerGas", - "chainId", - "from", - "to", - "data", - "nonce", - ] - for key in result[0].keys() - ] - ) - - def test_verify(self) -> None: - """Test verification of deployed contract results.""" - assert self.contract_address is not None - result = self.contract.verify_contract( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - ) - - assert result["verified"], "Contract not verified." diff --git a/trader_old/vendor/valory/contracts/market_maker/README.md b/trader_old/vendor/valory/contracts/market_maker/README.md deleted file mode 100644 index 6c58c0f7e..000000000 --- a/trader_old/vendor/valory/contracts/market_maker/README.md +++ /dev/null @@ -1 +0,0 @@ -# Market Maker contract diff --git a/trader_old/vendor/valory/contracts/market_maker/__init__.py b/trader_old/vendor/valory/contracts/market_maker/__init__.py deleted file mode 100644 index 85fd10b57..000000000 --- a/trader_old/vendor/valory/contracts/market_maker/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for the market maker contract.""" diff --git a/trader_old/vendor/valory/contracts/market_maker/build/FixedProductMarketMaker.json b/trader_old/vendor/valory/contracts/market_maker/build/FixedProductMarketMaker.json deleted file mode 100644 index b6d1ea43f..000000000 --- a/trader_old/vendor/valory/contracts/market_maker/build/FixedProductMarketMaker.json +++ /dev/null @@ -1,662 +0,0 @@ -{ - "_format": "", - "contractName": "", - "sourceName": "", - "abi": [ - { - "constant": true, - "inputs": [ - { - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "spender", - "type": "address" - }, - { - "name": "amount", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "account", - "type": "address" - } - ], - "name": "withdrawFees", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "account", - "type": "address" - } - ], - "name": "feesWithdrawableBy", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "sender", - "type": "address" - }, - { - "name": "recipient", - "type": "address" - }, - { - "name": "amount", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "spender", - "type": "address" - }, - { - "name": "addedValue", - "type": "uint256" - } - ], - "name": "increaseAllowance", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "investmentAmount", - "type": "uint256" - }, - { - "name": "outcomeIndex", - "type": "uint256" - }, - { - "name": "minOutcomeTokensToBuy", - "type": "uint256" - } - ], - "name": "buy", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "returnAmount", - "type": "uint256" - }, - { - "name": "outcomeIndex", - "type": "uint256" - } - ], - "name": "calcSellAmount", - "outputs": [ - { - "name": "outcomeTokenSellAmount", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "conditionalTokens", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "account", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "collectedFees", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "spender", - "type": "address" - }, - { - "name": "subtractedValue", - "type": "uint256" - } - ], - "name": "decreaseAllowance", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "recipient", - "type": "address" - }, - { - "name": "amount", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "collateralToken", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "operator", - "type": "address" - }, - { - "name": "from", - "type": "address" - }, - { - "name": "ids", - "type": "uint256[]" - }, - { - "name": "values", - "type": "uint256[]" - }, - { - "name": "data", - "type": "bytes" - } - ], - "name": "onERC1155BatchReceived", - "outputs": [ - { - "name": "", - "type": "bytes4" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "returnAmount", - "type": "uint256" - }, - { - "name": "outcomeIndex", - "type": "uint256" - }, - { - "name": "maxOutcomeTokensToSell", - "type": "uint256" - } - ], - "name": "sell", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "addedFunds", - "type": "uint256" - }, - { - "name": "distributionHint", - "type": "uint256[]" - } - ], - "name": "addFunding", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "conditionIds", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "owner", - "type": "address" - }, - { - "name": "spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "fee", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "sharesToBurn", - "type": "uint256" - } - ], - "name": "removeFunding", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "operator", - "type": "address" - }, - { - "name": "from", - "type": "address" - }, - { - "name": "id", - "type": "uint256" - }, - { - "name": "value", - "type": "uint256" - }, - { - "name": "data", - "type": "bytes" - } - ], - "name": "onERC1155Received", - "outputs": [ - { - "name": "", - "type": "bytes4" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "investmentAmount", - "type": "uint256" - }, - { - "name": "outcomeIndex", - "type": "uint256" - } - ], - "name": "calcBuyAmount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "funder", - "type": "address" - }, - { - "indexed": false, - "name": "amountsAdded", - "type": "uint256[]" - }, - { - "indexed": false, - "name": "sharesMinted", - "type": "uint256" - } - ], - "name": "FPMMFundingAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "funder", - "type": "address" - }, - { - "indexed": false, - "name": "amountsRemoved", - "type": "uint256[]" - }, - { - "indexed": false, - "name": "collateralRemovedFromFeePool", - "type": "uint256" - }, - { - "indexed": false, - "name": "sharesBurnt", - "type": "uint256" - } - ], - "name": "FPMMFundingRemoved", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "buyer", - "type": "address" - }, - { - "indexed": false, - "name": "investmentAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "feeAmount", - "type": "uint256" - }, - { - "indexed": true, - "name": "outcomeIndex", - "type": "uint256" - }, - { - "indexed": false, - "name": "outcomeTokensBought", - "type": "uint256" - } - ], - "name": "FPMMBuy", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "seller", - "type": "address" - }, - { - "indexed": false, - "name": "returnAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "feeAmount", - "type": "uint256" - }, - { - "indexed": true, - "name": "outcomeIndex", - "type": "uint256" - }, - { - "indexed": false, - "name": "outcomeTokensSold", - "type": "uint256" - } - ], - "name": "FPMMSell", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "from", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - ], - "bytecode": "", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/market_maker/contract.py b/trader_old/vendor/valory/contracts/market_maker/contract.py deleted file mode 100644 index e77c282ca..000000000 --- a/trader_old/vendor/valory/contracts/market_maker/contract.py +++ /dev/null @@ -1,186 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the class to connect to a Market Maker contract.""" - -from typing import Any, Dict - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract as BaseContract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi - -PUBLIC_ID = PublicId.from_str("valory/market_maker:0.1.0") - - -class Contract(BaseContract): - """Extended abstract definition of a contract.""" - - @classmethod - def _method_call( - cls, - ledger_api: EthereumApi, - contract_address: str, - method_name: str, - **kwargs: Any, - ): - """Call a contract's method. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param method_name: the contract method to call - :param kwargs: the contract call parameters - :return: the call result - """ - contract_instance = cls.get_instance(ledger_api, contract_address) - return ledger_api.contract_method_call( - contract_instance, - method_name, - **kwargs, - ) - - @classmethod - def _encode_abi( - cls, - ledger_api: LedgerApi, - contract_address: str, - method_name: str, - **kwargs: Any, - ) -> Dict[str, bytes]: - """Gets the encoded data for a contract's method call. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param method_name: the contract method to call - :param kwargs: the contract call parameters - :return: the call result - """ - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI(method_name, kwargs=kwargs) - return {"data": bytes.fromhex(data[2:])} - - -class FixedProductMarketMakerContract(Contract): - """The Market Maker contract.""" - - contract_id = PUBLIC_ID - - @classmethod - def calc_buy_amount( - cls, - ledger_api: EthereumApi, - contract_address: str, - investment_amount: int, - outcome_index: int, - ) -> JSONLike: - """ - Calculate the buy amount. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param investment_amount: the amount the user is willing to invest for an answer - :param outcome_index: the index of the answer's outcome that the user wants to vote for - :return: the buy amount - """ - amount = cls._method_call( - ledger_api, - contract_address, - "calcBuyAmount", - investmentAmount=investment_amount, - outcomeIndex=outcome_index, - ) - return dict(amount=amount) - - @classmethod - def get_buy_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - investment_amount: int, - outcome_index: int, - min_outcome_tokens_to_buy: int, - ) -> Dict[str, bytes]: - """Gets the encoded arguments for a buy tx, which should only be called via the multisig. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param investment_amount: the amount the user is willing to invest for an answer - :param outcome_index: the index of the answer's outcome that the user wants to vote for - :param min_outcome_tokens_to_buy: the output of the `calcBuyAmount` contract method - """ - return cls._encode_abi( - ledger_api, - contract_address, - "buy", - investmentAmount=investment_amount, - outcomeIndex=outcome_index, - minOutcomeTokensToBuy=min_outcome_tokens_to_buy, - ) - - @classmethod - def calc_sell_amount( - cls, - ledger_api: EthereumApi, - contract_address: str, - return_amount: int, - outcome_index: int, - ) -> JSONLike: - """ - Calculate the buy amount. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param return_amount: the amount the user will have returned - :param outcome_index: the index of the answer's outcome that the user wants to sell for - :return: the outcomeTokenSellAmount - """ - outcome_token_sell_amount = cls._method_call( - ledger_api, - contract_address, - "calcSellAmount", - returnAmount=return_amount, - outcomeIndex=outcome_index, - ) - return dict(outcomeTokenSellAmount=outcome_token_sell_amount) - - def get_sell_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - return_amount: int, - outcome_index: int, - max_outcome_tokens_to_sell: int, - ) -> Dict[str, bytes]: - """Gets the encoded arguments for a sell tx, which should only be called via the multisig. - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :param return_amount: the amount the user have returned - :param outcome_index: the index of the answer's outcome that the user wants to sell tokens for - :param max_outcome_tokens_to_sell: the output of the `calcSellAmount` contract method - """ - return cls._encode_abi( - ledger_api, - contract_address, - "sell", - returnAmount=return_amount, - outcomeIndex=outcome_index, - maxOutcomeTokenSellAmount=max_outcome_tokens_to_sell, - ) diff --git a/trader_old/vendor/valory/contracts/market_maker/contract.yaml b/trader_old/vendor/valory/contracts/market_maker/contract.yaml deleted file mode 100644 index 0065c491b..000000000 --- a/trader_old/vendor/valory/contracts/market_maker/contract.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: market_maker -author: valory -version: 0.1.0 -type: contract -description: Fixed product market maker contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeiegnihrovfkk5big52pl4bo6evt5toqvvmft2jgnq6ofdbhfp7xwa - __init__.py: bafybeicoucixii3fv5xlpk3zfewm4ys4okidcng54bhtjxvwup7g2jcjza - build/FixedProductMarketMaker.json: bafybeigim7n3f67r5czfc5wp2m7cxzxwvnhxops3n5j2zlawenan7qrrtu - contract.py: bafybeifcopgnnts3dbfh636vvdsgporlkt2olwr2iwuwaom5vjcrtbe5wi -fingerprint_ignore_patterns: [] -contracts: [] -class_name: FixedProductMarketMakerContract -contract_interface_paths: - ethereum: build/FixedProductMarketMaker.json -dependencies: - ecdsa: - version: '>=0.15' - eth_typing: {} - hexbytes: {} - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - packaging: {} - py-eth-sig-utils: {} - requests: - version: ==2.28.1 - web3: - version: <7,>=6.0.0 diff --git a/trader_old/vendor/valory/contracts/mech/README.md b/trader_old/vendor/valory/contracts/mech/README.md deleted file mode 100644 index c321ae231..000000000 --- a/trader_old/vendor/valory/contracts/mech/README.md +++ /dev/null @@ -1 +0,0 @@ -# Agent Mech contract diff --git a/trader_old/vendor/valory/contracts/mech/__init__.py b/trader_old/vendor/valory/contracts/mech/__init__.py deleted file mode 100644 index e34c6e4ef..000000000 --- a/trader_old/vendor/valory/contracts/mech/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for an agent Mech.""" diff --git a/trader_old/vendor/valory/contracts/mech/build/mech.json b/trader_old/vendor/valory/contracts/mech/build/mech.json deleted file mode 100644 index 18aa41151..000000000 --- a/trader_old/vendor/valory/contracts/mech/build/mech.json +++ /dev/null @@ -1,746 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "AgentMech", - "sourceName": "contracts/AgentMech.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_tokenId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_price", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "AgentNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "NotEnoughPaid", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "Overflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "name": "RequestIdNotFound", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "Deliver", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "price", - "type": "uint256" - } - ], - "name": "PriceUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "Request", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "deliver", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "entryPoint", - "outputs": [ - { - "internalType": "contract IEntryPoint", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "enum Enum.Operation", - "name": "operation", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "txGas", - "type": "uint256" - } - ], - "name": "exec", - "outputs": [ - { - "internalType": "bytes", - "name": "returnData", - "type": "bytes" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "getRequestId", - "outputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "getRequestsCount", - "outputs": [ - { - "internalType": "uint256", - "name": "requestsCount", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "size", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "offset", - "type": "uint256" - } - ], - "name": "getUndeliveredRequestIds", - "outputs": [ - { - "internalType": "uint256[]", - "name": "requestIds", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "signer", - "type": "address" - } - ], - "name": "isOperator", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "hash", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "signature", - "type": "bytes" - } - ], - "name": "isValidSignature", - "outputs": [ - { - "internalType": "bytes4", - "name": "magicValue", - "type": "bytes4" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapRequestIds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapRequestsCounts", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "nonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "numUndeliveredRequests", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC1155BatchReceived", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC1155Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC721Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "price", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "request", - "outputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "newPrice", - "type": "uint256" - } - ], - "name": "setPrice", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "initParams", - "type": "bytes" - } - ], - "name": "setUp", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "token", - "outputs": [ - { - "internalType": "contract IERC721", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "tokenId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "tokensReceived", - "outputs": [], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "initCode", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "callData", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "callGasLimit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "verificationGasLimit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "preVerificationGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxFeePerGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxPriorityFeePerGas", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "paymasterAndData", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "signature", - "type": "bytes" - } - ], - "internalType": "struct UserOperation", - "name": "userOp", - "type": "tuple" - }, - { - "internalType": "bytes32", - "name": "userOpHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "missingAccountFunds", - "type": "uint256" - } - ], - "name": "validateUserOp", - "outputs": [ - { - "internalType": "uint256", - "name": "validationData", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapUndeliveredRequestsCounts", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x60806040525f805534801562000013575f80fd5b50604051620026cc380380620026cc833981016040819052620000369162000391565b604080516001600160a01b03851660208201528082018490528151808203830181526060909101909152839083906200006f8162000145565b5050506001600160a01b0383166200009a5760405163d92e233d60e01b815260040160405180910390fd5b6040516331a9108f60e11b8152600481018390525f906001600160a01b03851690636352211e90602401602060405180830381865afa158015620000e0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001069190620003c6565b90506001600160a01b0381166200013857604051630ede975960e01b8152600481018490526024015b60405180910390fd5b50600155506200049a9050565b6200014f620001ad565b51156200019f5760405162461bcd60e51b815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016200012f565b620001aa8162000218565b50565b6060620002136200020d604051606b60f91b6020820152602560fa1b60218201526001600160601b03193060601b166022820152600160f81b60368201525f90603701604051602081830303815290604052805190602001205f1c905090565b620002e1565b905090565b5f620002248262000339565b90505f8151602083015ff090506200028b604051606b60f91b6020820152602560fa1b60218201526001600160601b03193060601b166022820152600160f81b60368201525f90603701604051602081830303815290604052805190602001205f1c905090565b6001600160a01b0316816001600160a01b031614620002dc5760405162461bcd60e51b815260206004820152600c60248201526b15dc9a5d194819985a5b195960a21b60448201526064016200012f565b505050565b6060813b600181116200030357505060408051602081019091525f8152919050565b806200030f81620003fd565b9150506040519150601f19601f602083010116820160405280825280600160208401853c50919050565b6060815160016200034b919062000415565b826040516020016200035f92919062000431565b6040516020818303038152906040529050919050565b80516001600160a01b03811681146200038c575f80fd5b919050565b5f805f60608486031215620003a4575f80fd5b620003af8462000375565b925060208401519150604084015190509250925092565b5f60208284031215620003d7575f80fd5b620003e28262000375565b9392505050565b634e487b7160e01b5f52601160045260245ffd5b5f816200040e576200040e620003e9565b505f190190565b808201808211156200042b576200042b620003e9565b92915050565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b60058201525f600e82018190528251815b8181101562000489576020818601810151600f8684010152016200046a565b505f9201600f019182525092915050565b61222480620004a85f395ff3fe60806040526004361061017a575f3560e01c8063a035b1fe116100d1578063bdf863171161007c578063f23a6e6111610057578063f23a6e61146104d2578063f6171e4414610517578063fc0c546a14610536575f80fd5b8063bdf8631714610472578063c7dec3fc14610487578063e00b9118146104b3575f80fd5b8063b0d691fe116100ac578063b0d691fe146103d1578063b94207d314610418578063bc197c811461042b575f80fd5b8063a035b1fe1461038a578063a4f9edbf1461039f578063affed0e0146103be575f80fd5b80633a871cdd116101315780636d70f7ae1161010c5780636d70f7ae146102fb5780637af734731461032a57806391b7f5ed1461036b575f80fd5b80633a871cdd1461028557806358ce0909146102a45780635fee6085146102d0575f80fd5b8063157305fe11610161578063157305fe146102255780631626ba7e1461024457806317d70f7c14610263575f80fd5b806223de2914610185578063150b7a02146101ab575f80fd5b3661018157005b5f80fd5b348015610190575f80fd5b506101a961019f366004611943565b5050505050505050565b005b3480156101b6575f80fd5b506101ef6101c53660046119ed565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b348015610230575f80fd5b506101a961023f366004611b2f565b61054a565b34801561024f575f80fd5b506101ef61025e366004611b2f565b610771565b34801561026e575f80fd5b50610277610914565b60405190815260200161021c565b348015610290575f80fd5b5061027761029f366004611b73565b610938565b3480156102af575f80fd5b506102c36102be366004611bc2565b610974565b60405161021c9190611be2565b3480156102db575f80fd5b506102776102ea366004611c25565b60036020525f908152604090205481565b348015610306575f80fd5b5061031a610315366004611c25565b610ada565b604051901515815260200161021c565b348015610335575f80fd5b50610277610344366004611c25565b73ffffffffffffffffffffffffffffffffffffffff165f9081526003602052604090205490565b348015610376575f80fd5b506101a9610385366004611c40565b610bac565b348015610395575f80fd5b5061027760015481565b3480156103aa575f80fd5b506101a96103b9366004611c57565b610c9a565b3480156103c9575f80fd5b505f54610277565b3480156103dc575f80fd5b50730576a174d229e3cfa37253523e645a78a0c91b575b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021c565b610277610426366004611c57565b610d16565b348015610436575f80fd5b506101ef610445366004611cd2565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561047d575f80fd5b5061027760025481565b348015610492575f80fd5b506104a66104a1366004611d68565b610e63565b60405161021c9190611e45565b3480156104be575f80fd5b506102776104cd366004611e57565b610f4d565b3480156104dd575f80fd5b506101ef6104ec366004611e8e565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b348015610522575f80fd5b50610277610531366004611bc2565b610f9e565b348015610541575f80fd5b506103f3610fc0565b61055333610ada565b80610571575033730576a174d229e3cfa37253523e645a78a0c91b57145b610602576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084015b60405180910390fd5b5f828152600460205260408082208151808301928390529160029082845b8154815260200190600101908083116106205750505050509050805f6002811061064c5761064c611f05565b602002015115801561066057506020810151155b801561069557505f805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed548314155b156106cf576040517ffe239804000000000000000000000000000000000000000000000000000000008152600481018490526024016105f9565b6020818101805183515f908152600490935260408084206001908101929092558451925184528084209290925585835290822082815501819055600280549161071783611f5f565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f0cd979445339c62199996f208428d987b1cea24d18e62b79ec24d94b636e8b708484604051610764929190611f93565b60405180910390a2505050565b5f805f8061079185602081015160408201516060909201515f1a92909190565b9094509250905060ff81165f036108a757828583016020016107b282610ada565b1580156107d5575073ffffffffffffffffffffffffffffffffffffffff82163014155b1561080857507fffffffff00000000000000000000000000000000000000000000000000000000945061090e9350505050565b6040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831690631626ba7e9061085c908b908590600401611f93565b602060405180830381865afa158015610877573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061089b9190611fab565b9550505050505061090e565b6108b661031587838686610fdd565b156108e757507f1626ba7e00000000000000000000000000000000000000000000000000000000925061090e915050565b507fffffffff00000000000000000000000000000000000000000000000000000000925050505b92915050565b5f8061091e610ff9565b8060200190518101906109319190611fea565b9392505050565b5f6109416110cd565b61094b848461114c565b905061095a6040850185612016565b90505f0361096b5761096b8461124c565b610931826112ca565b6002546060905f849003610986578093505b806109918486612077565b11156109de576109a18385612077565b6040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016105f9565b8315610ad3578367ffffffffffffffff8111156109fd576109fd611a5b565b604051908082528060200260200182016040528015610a26578160200160208202803683370190505b505f80805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed549193505b84811015610a81575f828152600460205260409020600101549150610a7a8161208a565b9050610a56565b505f5b85811015610ad05781848281518110610a9f57610a9f611f05565b6020908102919091018101919091525f9283526004905260409091206001015490610ac98161208a565b9050610a84565b50505b5092915050565b5f805f610ae5610ff9565b806020019051810190610af89190611fea565b915091508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610b4e91815260200190565b602060405180830381865afa158015610b69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b8d91906120c1565b73ffffffffffffffffffffffffffffffffffffffff1614949350505050565b610bb533610ada565b80610bd3575033730576a174d229e3cfa37253523e645a78a0c91b57145b610c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b60018190556040518181527f66cbca4f3c64fecf1dcb9ce094abcf7f68c3450a1d4e3a8e917dd621edb4ebe09060200160405180910390a150565b610ca2610ff9565b5115610d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016105f9565b610d138161133e565b50565b5f600154341015610d60576001546040517fb489782800000000000000000000000000000000000000000000000000000000815234600482015260248101919091526044016105f9565b610d6a3383610f4d565b335f908152600360205260408120805492935090610d878361208a565b909155505060046020525f81815260408082207f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed80546001830181905590859055808452918320849055600280547f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec94929392909190610e068361208a565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f4bda649efe6b98b0f9c1d5e859c29e20910f45c66dabfe6fad4a4881f7faf9cc8587604051610e53929190611f93565b60405180910390a2505050919050565b6060610e6e33610ada565b80610e8c575033730576a174d229e3cfa37253523e645a78a0c91b57145b610f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b5f610f32878787878715610f2c57876114b3565b5a6114b3565b9250905080610f4357815160208301fd5b5095945050505050565b5f8282604051602001610f619291906120dc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6004602052815f5260405f208160028110610fb7575f80fd5b01549150829050565b5f80610fca610ff9565b80602001905181019061090e91906120c1565b5f805f610fec878787876115b6565b91509150610f438161169e565b60606110c86110c36040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b611850565b905090565b33730576a174d229e3cfa37253523e645a78a0c91b571461114a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016105f9565b565b5f806111a4836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018290525f90605c01604051602081830303815290604052805190602001209050919050565b90507f1626ba7e00000000000000000000000000000000000000000000000000000000611212826111d9610140880188612016565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061077192505050565b7fffffffff00000000000000000000000000000000000000000000000000000000161461124357600191505061090e565b505f9392505050565b5f80546020830135918061125f8361208a565b9190505514610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c6964206e6f6e63650000000000000000000000000000000000000060448201526064016105f9565b8015610d13576040515f9033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d805f8114611332576040519150601f19603f3d011682016040523d82523d5f602084013e611337565b606091505b5050505050565b5f611348826118a5565b90505f8151602083015ff0905061141a6040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146114ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5772697465206661696c6564000000000000000000000000000000000000000060448201526064016105f9565b505050565b5f606060018460018111156114ca576114ca61210a565b0361153e578673ffffffffffffffffffffffffffffffffffffffff1683866040516114f59190612137565b5f604051808303818686f4925050503d805f811461152e576040519150601f19603f3d011682016040523d82523d5f602084013e611533565b606091505b5090925090506115ac565b8673ffffffffffffffffffffffffffffffffffffffff168387876040516115659190612137565b5f60405180830381858888f193505050503d805f81146115a0576040519150601f19603f3d011682016040523d82523d5f602084013e6115a5565b606091505b5090925090505b9550959350505050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156115eb57505f90506003611695565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561163c573d5f803e3d5ffd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661168f575f60019250925050611695565b91505f90505b94509492505050565b5f8160048111156116b1576116b161210a565b036116b95750565b60018160048111156116cd576116cd61210a565b03611734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105f9565b60028160048111156117485761174861210a565b036117af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105f9565b60038160048111156117c3576117c361210a565b03610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105f9565b6060813b6001811161187157505060408051602081019091525f8152919050565b8061187b81611f5f565b9150506040519150601f19601f602083010116820160405280825280600160208401853c50919050565b6060815160016118b59190612077565b826040516020016118c7929190612152565b6040516020818303038152906040529050919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d13575f80fd5b5f8083601f84011261190e575f80fd5b50813567ffffffffffffffff811115611925575f80fd5b60208301915083602082850101111561193c575f80fd5b9250929050565b5f805f805f805f8060c0898b03121561195a575f80fd5b8835611965816118dd565b97506020890135611975816118dd565b96506040890135611985816118dd565b955060608901359450608089013567ffffffffffffffff808211156119a8575f80fd5b6119b48c838d016118fe565b909650945060a08b01359150808211156119cc575f80fd5b506119d98b828c016118fe565b999c989b5096995094979396929594505050565b5f805f805f60808688031215611a01575f80fd5b8535611a0c816118dd565b94506020860135611a1c816118dd565b935060408601359250606086013567ffffffffffffffff811115611a3e575f80fd5b611a4a888289016118fe565b969995985093965092949392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112611a97575f80fd5b813567ffffffffffffffff80821115611ab257611ab2611a5b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611af857611af8611a5b565b81604052838152866020858801011115611b10575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f8060408385031215611b40575f80fd5b82359150602083013567ffffffffffffffff811115611b5d575f80fd5b611b6985828601611a88565b9150509250929050565b5f805f60608486031215611b85575f80fd5b833567ffffffffffffffff811115611b9b575f80fd5b84016101608187031215611bad575f80fd5b95602085013595506040909401359392505050565b5f8060408385031215611bd3575f80fd5b50508035926020909101359150565b602080825282518282018190525f9190848201906040850190845b81811015611c1957835183529284019291840191600101611bfd565b50909695505050505050565b5f60208284031215611c35575f80fd5b8135610931816118dd565b5f60208284031215611c50575f80fd5b5035919050565b5f60208284031215611c67575f80fd5b813567ffffffffffffffff811115611c7d575f80fd5b611c8984828501611a88565b949350505050565b5f8083601f840112611ca1575f80fd5b50813567ffffffffffffffff811115611cb8575f80fd5b6020830191508360208260051b850101111561193c575f80fd5b5f805f805f805f8060a0898b031215611ce9575f80fd5b8835611cf4816118dd565b97506020890135611d04816118dd565b9650604089013567ffffffffffffffff80821115611d20575f80fd5b611d2c8c838d01611c91565b909850965060608b0135915080821115611d44575f80fd5b611d508c838d01611c91565b909650945060808b01359150808211156119cc575f80fd5b5f805f805f60a08688031215611d7c575f80fd5b8535611d87816118dd565b945060208601359350604086013567ffffffffffffffff811115611da9575f80fd5b611db588828901611a88565b935050606086013560028110611dc9575f80fd5b949793965091946080013592915050565b5f5b83811015611df4578181015183820152602001611ddc565b50505f910152565b5f8151808452611e13816020860160208601611dda565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081525f6109316020830184611dfc565b5f8060408385031215611e68575f80fd5b8235611e73816118dd565b9150602083013567ffffffffffffffff811115611b5d575f80fd5b5f805f805f8060a08789031215611ea3575f80fd5b8635611eae816118dd565b95506020870135611ebe816118dd565b94506040870135935060608701359250608087013567ffffffffffffffff811115611ee7575f80fd5b611ef389828a016118fe565b979a9699509497509295939492505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f81611f6d57611f6d611f32565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b828152604060208201525f611c896040830184611dfc565b5f60208284031215611fbb575f80fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114610931575f80fd5b5f8060408385031215611ffb575f80fd5b8251612006816118dd565b6020939093015192949293505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612049575f80fd5b83018035915067ffffffffffffffff821115612063575f80fd5b60200191503681900382131561193c575f80fd5b8082018082111561090e5761090e611f32565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036120ba576120ba611f32565b5060010190565b5f602082840312156120d1575f80fd5b8151610931816118dd565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f611c896040830184611dfc565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f8251612148818460208701611dda565b9190910192915050565b7f630000000000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008360e01b1660018201527f80600e6000396000f3000000000000000000000000000000000000000000000060058201525f600e8201525f82516121e081600f850160208701611dda565b91909101600f01939250505056fea2646970667358221220c1913351e275e1fecd00c79cd676ed135b575df5d3a88ccc57419dc3081980a264736f6c63430008150033", - "deployedBytecode": "0x60806040526004361061017a575f3560e01c8063a035b1fe116100d1578063bdf863171161007c578063f23a6e6111610057578063f23a6e61146104d2578063f6171e4414610517578063fc0c546a14610536575f80fd5b8063bdf8631714610472578063c7dec3fc14610487578063e00b9118146104b3575f80fd5b8063b0d691fe116100ac578063b0d691fe146103d1578063b94207d314610418578063bc197c811461042b575f80fd5b8063a035b1fe1461038a578063a4f9edbf1461039f578063affed0e0146103be575f80fd5b80633a871cdd116101315780636d70f7ae1161010c5780636d70f7ae146102fb5780637af734731461032a57806391b7f5ed1461036b575f80fd5b80633a871cdd1461028557806358ce0909146102a45780635fee6085146102d0575f80fd5b8063157305fe11610161578063157305fe146102255780631626ba7e1461024457806317d70f7c14610263575f80fd5b806223de2914610185578063150b7a02146101ab575f80fd5b3661018157005b5f80fd5b348015610190575f80fd5b506101a961019f366004611943565b5050505050505050565b005b3480156101b6575f80fd5b506101ef6101c53660046119ed565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b348015610230575f80fd5b506101a961023f366004611b2f565b61054a565b34801561024f575f80fd5b506101ef61025e366004611b2f565b610771565b34801561026e575f80fd5b50610277610914565b60405190815260200161021c565b348015610290575f80fd5b5061027761029f366004611b73565b610938565b3480156102af575f80fd5b506102c36102be366004611bc2565b610974565b60405161021c9190611be2565b3480156102db575f80fd5b506102776102ea366004611c25565b60036020525f908152604090205481565b348015610306575f80fd5b5061031a610315366004611c25565b610ada565b604051901515815260200161021c565b348015610335575f80fd5b50610277610344366004611c25565b73ffffffffffffffffffffffffffffffffffffffff165f9081526003602052604090205490565b348015610376575f80fd5b506101a9610385366004611c40565b610bac565b348015610395575f80fd5b5061027760015481565b3480156103aa575f80fd5b506101a96103b9366004611c57565b610c9a565b3480156103c9575f80fd5b505f54610277565b3480156103dc575f80fd5b50730576a174d229e3cfa37253523e645a78a0c91b575b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021c565b610277610426366004611c57565b610d16565b348015610436575f80fd5b506101ef610445366004611cd2565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561047d575f80fd5b5061027760025481565b348015610492575f80fd5b506104a66104a1366004611d68565b610e63565b60405161021c9190611e45565b3480156104be575f80fd5b506102776104cd366004611e57565b610f4d565b3480156104dd575f80fd5b506101ef6104ec366004611e8e565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b348015610522575f80fd5b50610277610531366004611bc2565b610f9e565b348015610541575f80fd5b506103f3610fc0565b61055333610ada565b80610571575033730576a174d229e3cfa37253523e645a78a0c91b57145b610602576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084015b60405180910390fd5b5f828152600460205260408082208151808301928390529160029082845b8154815260200190600101908083116106205750505050509050805f6002811061064c5761064c611f05565b602002015115801561066057506020810151155b801561069557505f805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed548314155b156106cf576040517ffe239804000000000000000000000000000000000000000000000000000000008152600481018490526024016105f9565b6020818101805183515f908152600490935260408084206001908101929092558451925184528084209290925585835290822082815501819055600280549161071783611f5f565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f0cd979445339c62199996f208428d987b1cea24d18e62b79ec24d94b636e8b708484604051610764929190611f93565b60405180910390a2505050565b5f805f8061079185602081015160408201516060909201515f1a92909190565b9094509250905060ff81165f036108a757828583016020016107b282610ada565b1580156107d5575073ffffffffffffffffffffffffffffffffffffffff82163014155b1561080857507fffffffff00000000000000000000000000000000000000000000000000000000945061090e9350505050565b6040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831690631626ba7e9061085c908b908590600401611f93565b602060405180830381865afa158015610877573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061089b9190611fab565b9550505050505061090e565b6108b661031587838686610fdd565b156108e757507f1626ba7e00000000000000000000000000000000000000000000000000000000925061090e915050565b507fffffffff00000000000000000000000000000000000000000000000000000000925050505b92915050565b5f8061091e610ff9565b8060200190518101906109319190611fea565b9392505050565b5f6109416110cd565b61094b848461114c565b905061095a6040850185612016565b90505f0361096b5761096b8461124c565b610931826112ca565b6002546060905f849003610986578093505b806109918486612077565b11156109de576109a18385612077565b6040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016105f9565b8315610ad3578367ffffffffffffffff8111156109fd576109fd611a5b565b604051908082528060200260200182016040528015610a26578160200160208202803683370190505b505f80805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed549193505b84811015610a81575f828152600460205260409020600101549150610a7a8161208a565b9050610a56565b505f5b85811015610ad05781848281518110610a9f57610a9f611f05565b6020908102919091018101919091525f9283526004905260409091206001015490610ac98161208a565b9050610a84565b50505b5092915050565b5f805f610ae5610ff9565b806020019051810190610af89190611fea565b915091508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610b4e91815260200190565b602060405180830381865afa158015610b69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b8d91906120c1565b73ffffffffffffffffffffffffffffffffffffffff1614949350505050565b610bb533610ada565b80610bd3575033730576a174d229e3cfa37253523e645a78a0c91b57145b610c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b60018190556040518181527f66cbca4f3c64fecf1dcb9ce094abcf7f68c3450a1d4e3a8e917dd621edb4ebe09060200160405180910390a150565b610ca2610ff9565b5115610d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016105f9565b610d138161133e565b50565b5f600154341015610d60576001546040517fb489782800000000000000000000000000000000000000000000000000000000815234600482015260248101919091526044016105f9565b610d6a3383610f4d565b335f908152600360205260408120805492935090610d878361208a565b909155505060046020525f81815260408082207f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed80546001830181905590859055808452918320849055600280547f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec94929392909190610e068361208a565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f4bda649efe6b98b0f9c1d5e859c29e20910f45c66dabfe6fad4a4881f7faf9cc8587604051610e53929190611f93565b60405180910390a2505050919050565b6060610e6e33610ada565b80610e8c575033730576a174d229e3cfa37253523e645a78a0c91b57145b610f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b5f610f32878787878715610f2c57876114b3565b5a6114b3565b9250905080610f4357815160208301fd5b5095945050505050565b5f8282604051602001610f619291906120dc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6004602052815f5260405f208160028110610fb7575f80fd5b01549150829050565b5f80610fca610ff9565b80602001905181019061090e91906120c1565b5f805f610fec878787876115b6565b91509150610f438161169e565b60606110c86110c36040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b611850565b905090565b33730576a174d229e3cfa37253523e645a78a0c91b571461114a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016105f9565b565b5f806111a4836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018290525f90605c01604051602081830303815290604052805190602001209050919050565b90507f1626ba7e00000000000000000000000000000000000000000000000000000000611212826111d9610140880188612016565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061077192505050565b7fffffffff00000000000000000000000000000000000000000000000000000000161461124357600191505061090e565b505f9392505050565b5f80546020830135918061125f8361208a565b9190505514610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c6964206e6f6e63650000000000000000000000000000000000000060448201526064016105f9565b8015610d13576040515f9033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d805f8114611332576040519150601f19603f3d011682016040523d82523d5f602084013e611337565b606091505b5050505050565b5f611348826118a5565b90505f8151602083015ff0905061141a6040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146114ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5772697465206661696c6564000000000000000000000000000000000000000060448201526064016105f9565b505050565b5f606060018460018111156114ca576114ca61210a565b0361153e578673ffffffffffffffffffffffffffffffffffffffff1683866040516114f59190612137565b5f604051808303818686f4925050503d805f811461152e576040519150601f19603f3d011682016040523d82523d5f602084013e611533565b606091505b5090925090506115ac565b8673ffffffffffffffffffffffffffffffffffffffff168387876040516115659190612137565b5f60405180830381858888f193505050503d805f81146115a0576040519150601f19603f3d011682016040523d82523d5f602084013e6115a5565b606091505b5090925090505b9550959350505050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156115eb57505f90506003611695565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561163c573d5f803e3d5ffd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661168f575f60019250925050611695565b91505f90505b94509492505050565b5f8160048111156116b1576116b161210a565b036116b95750565b60018160048111156116cd576116cd61210a565b03611734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105f9565b60028160048111156117485761174861210a565b036117af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105f9565b60038160048111156117c3576117c361210a565b03610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105f9565b6060813b6001811161187157505060408051602081019091525f8152919050565b8061187b81611f5f565b9150506040519150601f19601f602083010116820160405280825280600160208401853c50919050565b6060815160016118b59190612077565b826040516020016118c7929190612152565b6040516020818303038152906040529050919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d13575f80fd5b5f8083601f84011261190e575f80fd5b50813567ffffffffffffffff811115611925575f80fd5b60208301915083602082850101111561193c575f80fd5b9250929050565b5f805f805f805f8060c0898b03121561195a575f80fd5b8835611965816118dd565b97506020890135611975816118dd565b96506040890135611985816118dd565b955060608901359450608089013567ffffffffffffffff808211156119a8575f80fd5b6119b48c838d016118fe565b909650945060a08b01359150808211156119cc575f80fd5b506119d98b828c016118fe565b999c989b5096995094979396929594505050565b5f805f805f60808688031215611a01575f80fd5b8535611a0c816118dd565b94506020860135611a1c816118dd565b935060408601359250606086013567ffffffffffffffff811115611a3e575f80fd5b611a4a888289016118fe565b969995985093965092949392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112611a97575f80fd5b813567ffffffffffffffff80821115611ab257611ab2611a5b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611af857611af8611a5b565b81604052838152866020858801011115611b10575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f8060408385031215611b40575f80fd5b82359150602083013567ffffffffffffffff811115611b5d575f80fd5b611b6985828601611a88565b9150509250929050565b5f805f60608486031215611b85575f80fd5b833567ffffffffffffffff811115611b9b575f80fd5b84016101608187031215611bad575f80fd5b95602085013595506040909401359392505050565b5f8060408385031215611bd3575f80fd5b50508035926020909101359150565b602080825282518282018190525f9190848201906040850190845b81811015611c1957835183529284019291840191600101611bfd565b50909695505050505050565b5f60208284031215611c35575f80fd5b8135610931816118dd565b5f60208284031215611c50575f80fd5b5035919050565b5f60208284031215611c67575f80fd5b813567ffffffffffffffff811115611c7d575f80fd5b611c8984828501611a88565b949350505050565b5f8083601f840112611ca1575f80fd5b50813567ffffffffffffffff811115611cb8575f80fd5b6020830191508360208260051b850101111561193c575f80fd5b5f805f805f805f8060a0898b031215611ce9575f80fd5b8835611cf4816118dd565b97506020890135611d04816118dd565b9650604089013567ffffffffffffffff80821115611d20575f80fd5b611d2c8c838d01611c91565b909850965060608b0135915080821115611d44575f80fd5b611d508c838d01611c91565b909650945060808b01359150808211156119cc575f80fd5b5f805f805f60a08688031215611d7c575f80fd5b8535611d87816118dd565b945060208601359350604086013567ffffffffffffffff811115611da9575f80fd5b611db588828901611a88565b935050606086013560028110611dc9575f80fd5b949793965091946080013592915050565b5f5b83811015611df4578181015183820152602001611ddc565b50505f910152565b5f8151808452611e13816020860160208601611dda565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081525f6109316020830184611dfc565b5f8060408385031215611e68575f80fd5b8235611e73816118dd565b9150602083013567ffffffffffffffff811115611b5d575f80fd5b5f805f805f8060a08789031215611ea3575f80fd5b8635611eae816118dd565b95506020870135611ebe816118dd565b94506040870135935060608701359250608087013567ffffffffffffffff811115611ee7575f80fd5b611ef389828a016118fe565b979a9699509497509295939492505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f81611f6d57611f6d611f32565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b828152604060208201525f611c896040830184611dfc565b5f60208284031215611fbb575f80fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114610931575f80fd5b5f8060408385031215611ffb575f80fd5b8251612006816118dd565b6020939093015192949293505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612049575f80fd5b83018035915067ffffffffffffffff821115612063575f80fd5b60200191503681900382131561193c575f80fd5b8082018082111561090e5761090e611f32565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036120ba576120ba611f32565b5060010190565b5f602082840312156120d1575f80fd5b8151610931816118dd565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f611c896040830184611dfc565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f8251612148818460208701611dda565b9190910192915050565b7f630000000000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008360e01b1660018201527f80600e6000396000f3000000000000000000000000000000000000000000000060058201525f600e8201525f82516121e081600f850160208701611dda565b91909101600f01939250505056fea2646970667358221220c1913351e275e1fecd00c79cd676ed135b575df5d3a88ccc57419dc3081980a264736f6c63430008150033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/mech/contract.py b/trader_old/vendor/valory/contracts/mech/contract.py deleted file mode 100644 index 55a5b54b5..000000000 --- a/trader_old/vendor/valory/contracts/mech/contract.py +++ /dev/null @@ -1,401 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the class to connect to a Mech contract.""" - -import concurrent.futures -from typing import Any, Callable, Dict, List, cast - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi -from eth_typing import HexStr -from web3.types import BlockData, BlockIdentifier, EventData, TxReceipt - - -PUBLIC_ID = PublicId.from_str("valory/mech:0.1.0") -FIVE_MINUTES = 300.0 - - -partial_abis = [ - [ - { - "anonymous": False, - "inputs": [ - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256", - }, - { - "indexed": False, - "internalType": "bytes", - "name": "data", - "type": "bytes", - }, - ], - "name": "Deliver", - "type": "event", - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address", - }, - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256", - }, - { - "indexed": False, - "internalType": "bytes", - "name": "data", - "type": "bytes", - }, - ], - "name": "Request", - "type": "event", - }, - ], - [ - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address", - }, - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256", - }, - { - "indexed": False, - "internalType": "uint256", - "name": "requestIdWithNonce", - "type": "uint256", - }, - { - "indexed": False, - "internalType": "bytes", - "name": "data", - "type": "bytes", - }, - ], - "name": "Request", - "type": "event", - }, - { - "anonymous": False, - "inputs": [ - { - "indexed": True, - "internalType": "address", - "name": "sender", - "type": "address", - }, - { - "indexed": False, - "internalType": "uint256", - "name": "requestId", - "type": "uint256", - }, - { - "indexed": False, - "internalType": "bytes", - "name": "data", - "type": "bytes", - }, - ], - "name": "Deliver", - "type": "event", - }, - ], -] - - -class Mech(Contract): - """The Mech contract.""" - - contract_id = PUBLIC_ID - - @staticmethod - def execute_with_timeout(func: Callable, timeout: float) -> Any: - """Execute a function with a timeout.""" - - # Create a ProcessPoolExecutor with a maximum of 1 worker (process) - with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: - # Submit the function to the executor - future = executor.submit( - func, - ) - - try: - # Wait for the result with a 5-minute timeout - data = future.result(timeout=timeout) - except TimeoutError: - # Handle the case where the execution times out - err = f"The RPC didn't respond in {timeout}." - return None, err - - # Check if an error occurred - if isinstance(data, str): - # Handle the case where the execution failed - return None, data - - return data, None - - @classmethod - def get_price( - cls, - ledger_api: EthereumApi, - contract_address: str, - **kwargs: Any - ) -> JSONLike: - """Get the price of a request.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - price = ledger_api.contract_method_call(contract_instance, "price") - return dict(price=price) - - @classmethod - def get_request_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - request_data: bytes, - **kwargs: Any - ) -> Dict[str, bytes]: - """Gets the encoded arguments for a request tx, which should only be called via the multisig. - - :param ledger_api: the ledger API object - :param contract_address: the contract's address - :param request_data: the request data - """ - contract_address = ledger_api.api.to_checksum_address(contract_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - encoded_data = contract_instance.encodeABI("request", args=(request_data,)) - return {"data": bytes.fromhex(encoded_data[2:])} - - @classmethod - def _process_event( - cls, - ledger_api: LedgerApi, - contract: Any, - tx_hash: HexStr, - expected_logs: int, - event_name: str, - *args: Any, - **kwargs: Any - ) -> JSONLike: - """Process the logs of the given event.""" - ledger_api = cast(EthereumApi, ledger_api) - receipt: TxReceipt = ledger_api.api.eth.get_transaction_receipt(tx_hash) - event_method = getattr(contract.events, event_name) - logs: List[EventData] = list(event_method().process_receipt(receipt)) - - n_logs = len(logs) - if n_logs != expected_logs: - error = f"{expected_logs} {event_name!r} events were expected. tx {tx_hash} emitted {n_logs} instead." - return {"error": error} - - results = [] - for log in logs: - event_args = log.get("args", None) - if event_args is None or any( - expected_key not in event_args for expected_key in args - ): - return {"error": f"The emitted event's ({event_name}) logs for tx {tx_hash} do not match the expected format: {log}"} - results.append({arg_name: event_args[arg_name] for arg_name in args}) - - return dict(results=results) - - @classmethod - def process_request_event( - cls, - ledger_api: LedgerApi, - contract_address: str, - tx_hash: HexStr, - expected_logs: int = 1, - **kwargs: Any - ) -> JSONLike: - """ - Process the request receipt to get the requestId and the given data from the `Request` event's logs. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param tx_hash: the hash of a request tx to be processed. - :param expected_logs: the number of logs expected. - :return: a dictionary with a key named `results` - which contains a list of dictionaries (as many as the expected logs) containing the request id and the data. - """ - contract_address = ledger_api.api.to_checksum_address(contract_address) - res = {} - for abi in partial_abis: - contract_instance = ledger_api.api.eth.contract(contract_address, abi=abi) - res = cls._process_event( - ledger_api, contract_instance, tx_hash, expected_logs, "Request", "requestId", "data" - ) - if "error" not in res: - return res - - return res - - @classmethod - def process_deliver_event( - cls, - ledger_api: LedgerApi, - contract_address: str, - tx_hash: HexStr, - expected_logs: int = 1, - **kwargs: Any - ) -> JSONLike: - """ - Process the request receipt to get the requestId and the delivered data if the `Deliver` event has been emitted. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param tx_hash: the hash of a request tx to be processed. - :param expected_logs: the number of logs expected. - :return: a dictionary with the request id and the data. - """ - contract_address = ledger_api.api.to_checksum_address(contract_address) - res = {} - for abi in partial_abis: - contract_instance = ledger_api.api.eth.contract(contract_address, abi=abi) - res = cls._process_event( - ledger_api, contract_instance, tx_hash, expected_logs, "Deliver", "requestId", "data" - ) - if "error" not in res: - return res - - return res - @classmethod - def get_block_number( - cls, - ledger_api: EthereumApi, - contract_address: str, - tx_hash: HexStr, - **kwargs: Any - ) -> JSONLike: - """Get the number of the block in which the tx of the given hash was settled.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - receipt: TxReceipt = ledger_api.api.eth.get_transaction_receipt(tx_hash) - block: BlockData = ledger_api.api.eth.get_block(receipt["blockNumber"]) - return dict(number=block["number"]) - - @classmethod - def get_response( - cls, - ledger_api: LedgerApi, - contract_address: str, - request_id: int, - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - timeout: float = FIVE_MINUTES, - **kwargs: Any - ) -> JSONLike: - """Filter the `Deliver` events emitted by the contract and get the data of the given `request_id`.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - ledger_api = cast(EthereumApi, ledger_api) - - def get_responses() -> Any: - """Get the responses from the contract.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - deliver_filter = contract_instance.events.Deliver.build_filter() - deliver_filter.fromBlock = from_block - deliver_filter.toBlock = to_block - deliver_filter.args.requestId.match_single(request_id) - delivered = list(deliver_filter.deploy(ledger_api.api).get_all_entries()) - n_delivered = len(delivered) - - if n_delivered == 0: - info = f"The mech ({contract_address}) has not delivered a response yet for request with id {request_id}." - return {"info": info} - - if n_delivered != 1: - error = ( - f"A single response was expected by the mech ({contract_address}) for request with id {request_id}. " - f"Received {n_delivered} responses: {delivered}." - ) - return error - - delivered_event = delivered.pop() - deliver_args = delivered_event.get("args", None) - if deliver_args is None or "data" not in deliver_args: - error = f"The mech's response does not match the expected format: {delivered_event}" - return error - - return dict(data=deliver_args["data"]) - - data, err = cls.execute_with_timeout(get_responses, timeout=timeout) - if err is not None: - return {"error": err} - - return data - - @classmethod - def get_mech_id( - cls, - ledger_api: EthereumApi, - contract_address: str, - **kwargs: Any - ) -> JSONLike: - """Get the price of a request.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - mech_id = ledger_api.contract_method_call(contract_instance, "tokenId") - return dict(id=mech_id) - - @classmethod - def get_requests_count( - cls, - ledger_api: EthereumApi, - contract_address: str, - address: str, - **kwargs: Any - ) -> JSONLike: - """Get the requests count.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - address = ledger_api.api.to_checksum_address(address) - contract_instance = cls.get_instance(ledger_api, contract_address) - requests_count = contract_instance.functions.getRequestsCount(address).call() - return {"requests_count": requests_count} - - @classmethod - def get_pending_requests(cls, ledger_api: EthereumApi, contract_address: str, sender_address: str, **kwargs: Any) -> JSONLike: - """Get the pending requests.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - sender_address = ledger_api.api.to_checksum_address(sender_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - pending_requests = contract_instance.functions.mapUndeliveredRequestsCounts(sender_address).call() - return {"pending_requests": pending_requests} diff --git a/trader_old/vendor/valory/contracts/mech/contract.yaml b/trader_old/vendor/valory/contracts/mech/contract.yaml deleted file mode 100644 index 17f9b747f..000000000 --- a/trader_old/vendor/valory/contracts/mech/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: mech -author: valory -version: 0.1.0 -type: contract -description: Agent mech contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeibl4uw7rs6mwh7zuvdnqmj2o2xyr7nx5qk3w7torwx3jg6farn6ca - __init__.py: bafybeicx5pxh3cxnml2biuuoebvafvu5tvy6mgkzyjzuubuoeebb5yzjsm - build/mech.json: bafybeibrocnkmfe46ylcso7245qq5ysl5z6ydr4xumjt6zl4satc7uqt4m - contract.py: bafybeiavom4ssfo6qngem34ymifb6upx5fodafkfa27cmzifuln5jqg4xe -fingerprint_ignore_patterns: [] -contracts: [] -class_name: Mech -contract_interface_paths: - ethereum: build/mech.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - web3: - version: <7,>=6.0.0 - eth_typing: {} diff --git a/trader_old/vendor/valory/contracts/mech_activity/__init__.py b/trader_old/vendor/valory/contracts/mech_activity/__init__.py deleted file mode 100644 index 1120bac15..000000000 --- a/trader_old/vendor/valory/contracts/mech_activity/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the support resources for the mech activity checker contract.""" diff --git a/trader_old/vendor/valory/contracts/mech_activity/build/MechActivity.json b/trader_old/vendor/valory/contracts/mech_activity/build/MechActivity.json deleted file mode 100644 index 67cb00fcf..000000000 --- a/trader_old/vendor/valory/contracts/mech_activity/build/MechActivity.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ServiceStakingToken", - "sourceName": "contracts/staking/ServiceStakingToken.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_agentMech", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_livenessRatio", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "ZeroMechAgentAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "inputs": [], - "name": "agentMech", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "getMultisigNonces", - "outputs": [ - { - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256[]", - "name": "curNonces", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "lastNonces", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "ts", - "type": "uint256" - } - ], - "name": "isRatioPass", - "outputs": [ - { - "internalType": "bool", - "name": "ratioPass", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "livenessRatio", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x6102606040523480156200001257600080fd5b506040516200383a3803806200383a833981016040819052620000359162000453565b8484828260000151600014806200004e57506020830151155b806200005c575060a0830151155b806200006a575060c0830151155b8062000078575060e0830151155b806200008657506060830151155b806200009457506080830151155b15620000b357604051637c946ed760e01b815260040160405180910390fd5b826080015183606001511015620000f5576060830151608084015160405163491a2bb160e01b8152600481019290925260248201526044015b60405180910390fd5b6002836040015110156200012d57604080840151905163491a2bb160e01b8152600481019190915260026024820152604401620000ec565b6001600160a01b038216620001555760405163d92e233d60e01b815260040160405180910390fd5b82516080908152602084015160a0908152604085015160c09081529185015160e0908152908501516101005290840151610120908152908401516101409081526001600160a01b0384166101a0529084015161016052830151610180526000805b846101000151518110156200029257818561010001518281518110620001e057620001e062000576565b6020026020010151116200022d57846101000151818151811062000208576200020862000576565b6020026020010151604051632ab10b0b60e21b8152600401620000ec91815260200190565b846101000151818151811062000247576200024762000576565b602090810291909101015160048054600181810183556000929092527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0182905590925001620001b6565b5081620002b257604051637c946ed760e01b815260040160405180910390fd5b6101c0829052610100516060850151620002cd91906200058c565b6101e052610100516080850151620002e691906200058c565b6102005250504260035550506001600160a01b03821615806200031057506001600160a01b038316155b156200032f5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b0390811661024052166102205250620005b89050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b03811182821017156200038957620003896200034d565b60405290565b600082601f830112620003a157600080fd5b815160206001600160401b0380831115620003c057620003c06200034d565b8260051b604051601f19603f83011681018181108482111715620003e857620003e86200034d565b60405293845260208187018101949081019250878511156200040957600080fd5b6020870191505b848210156200042b5781518352918301919083019062000410565b979650505050505050565b80516001600160a01b03811681146200044e57600080fd5b919050565b600080600080600060a086880312156200046c57600080fd5b85516001600160401b03808211156200048457600080fd5b90870190610160828a0312156200049a57600080fd5b620004a462000363565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010080840151838111156200050357600080fd5b620005118c8287016200038f565b918301919091525061012083810151908201526101409283015192810192909252509450620005436020870162000436565b9350620005536040870162000436565b9250620005636060870162000436565b9150608086015190509295509295909350565b634e487b7160e01b600052603260045260246000fd5b8082028115828204841417620005b257634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161311962000721600039600081816104110152818161130901528181611c1401528181611d1e0152611d6201526000818161030501528181611ca40152611e0e01526000818161068e015281816118a50152611b1401526000818161024b0152818161074d015261079f01526000818161044b0152610fca0152600081816105cf01528181610a0101528181610d8601526111bd0152600081816105f601528181610e4e0152610e7d01526000818161036201528181610ec40152610ef80152600081816103c30152610e0c0152600081816103ea015261294a01526000818161038901528181611bc60152611fb80152600061049b01526000818161061d0152611d9901526000818161064401526122ae0152600081816102de01528181610d0d0152610d4101526131196000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c8063a0ed60e011610145578063cbcf252a116100bd578063eb338c961161008c578063f4dce71411610071578063f4dce71414610681578063f86ad2b614610689578063ffa1ad74146106b057600080fd5b8063eb338c9614610666578063f189e85a1461067957600080fd5b8063cbcf252a146105ca578063e1f1176d146105f1578063e77cdcc914610618578063eacdaabc1461063f57600080fd5b8063b69ef8a811610114578063c2c4c5c1116100f9578063c2c4c5c11461057e578063c889921d14610597578063cae2a5f0146105aa57600080fd5b8063b69ef8a814610562578063b6b55f251461056b57600080fd5b8063a0ed60e014610496578063a694fc3a146104bd578063a74466ad146104d0578063b15087601461054d57600080fd5b806352c824f5116101d857806372f702f3116101a7578063809cee2f1161018c578063809cee2f1461044657806382a8ea581461046d578063879d90901461048d57600080fd5b806372f702f31461040c57806378e061361461043357600080fd5b806352c824f51461038457806356e76058146103ab5780635829c5ec146103be578063592cf3fb146103e557600080fd5b8063287140511161021457806328714051146103005780632e17de781461033f5780633e7329971461035457806342cde4e81461035d57600080fd5b806308ae7e541461024657806314b19c5a14610280578063150b7a021461028957806316a75172146102d9575b600080fd5b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61026d60005481565b6102a8610297366004612a0a565b630a85bd0160e11b95945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610277565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b61035261034d366004612aa9565b6106e1565b005b61026d60035481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d6103b9366004612aa9565b610acf565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d610441366004612aa9565b610af0565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61048061047b366004612aa9565b610bba565b6040516102779190612afe565b61026d60025481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103526104cb366004612aa9565b610cb1565b61051a6104de366004612aa9565b6005602081905260009182526040909120805460018201546003830154600484015493909401546001600160a01b039283169492909116929085565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610277565b61055561127e565b6040516102779190612b65565b61026d60015481565b610352610579366004612aa9565b6112d6565b610586611378565b604051610277959493929190612b78565b61026d6105a5366004612aa9565b6119ad565b6105bd6105b8366004612aa9565b611a69565b6040516102779190612c3d565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d610674366004612aa9565b611b5c565b610555611b6c565b61026d611bc2565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6106d4604051806040016040528060058152602001640302e312e360dc1b81525081565b6040516102779190612c65565b600081815260056020526040902060018101546001600160a01b0316331461073857600181015460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b600381015460006107498242612cca565b90507f0000000000000000000000000000000000000000000000000000000000000000811115801561077d57506000600254115b156107cb5760405163ba2bbc6b60e01b815260048101859052602481018290527f0000000000000000000000000000000000000000000000000000000000000000604482015260640161072f565b6000806107d6611378565b945050505091508151600003610837576107ee611b6c565b9150815167ffffffffffffffff81111561080a5761080a612cdd565b604051908082528060200260200182016040528015610833578160200160208202803683370190505b5090505b6000805b8351821015610898578783838151811061085757610857612cf3565b60200260200101510315610898578784838151811061087857610878612cf3565b60200260200101510361088d57506001610898565b81600101915061083b565b600487015460028801805460408051602080840282018101909252828152600093909290918301828280156108ec57602002820191906000526020600020905b8154815260200190600101908083116108d8575b50508c5460008f8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff19908116825560018201805490911690559596506001600160a01b03909116949350915061094890506002830182612974565b506000600382018190556004820181905560059091015583156109d7576006805461097590600190612cca565b8154811061098557610985612cf3565b9060005260206000200154600686815481106109a3576109a3612cf3565b60009182526020909120015560068054806109c0576109c0612d09565b600190038181906000526020600020016000905590555b604051632142170760e11b8152306004820152336024820152604481018c90526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342842e0e90606401600060405180830381600087803b158015610a4557600080fd5b505af1158015610a59573d6000803e3d6000fd5b505050506000831115610a7057610a708184611bf7565b806001600160a01b0316336001600160a01b03168c7f950733f4c0bf951b8e770f3cc619a4288e7b59b1236d59aeaf2c238488e8ae816000548688604051610aba93929190612d1f565b60405180910390a45050505050505050505050565b60048181548110610adf57600080fd5b600091825260209091200154905081565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015610b7057602002820191906000526020600020905b815481526020019060010190808311610b5c575b505050505081526020016003820154815260200160048201548152602001600582015481525050905080608001519150610ba9836119ad565b610bb39083612d48565b9392505050565b610c056040518060c0016040528060006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016000815260200160008152602001600081525090565b600082815260056020908152604091829020825160c08101845281546001600160a01b0390811682526001830154168184015260028201805485518186028101860187528181529295939493860193830182828015610c8357602002820191906000526020600020905b815481526020019060010190808311610c6f575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050919050565b600254600003610cd45760405163afb0be3360e01b815260040160405180910390fd5b6000818152600560205260409020600381015415610d085760405163b4817ce760e01b81526004810183905260240161072f565b6006547f00000000000000000000000000000000000000000000000000000000000000008103610d6d5760405163fd20861560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260240161072f565b60405163ef0e239b60e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ef0e239b90602401600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dfd9190810190612e79565b9050806080015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014610e4c57604051637ad404bf60e11b81526004810185905260240161072f565b7f000000000000000000000000000000000000000000000000000000000000000015801590610e9f575080604001517f000000000000000000000000000000000000000000000000000000000000000014155b15610ec057604051637ad404bf60e11b81526004810185905260240161072f565b60007f0000000000000000000000000000000000000000000000000000000000000000118015610f1a5750806060015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014155b15610f3b57604051637ad404bf60e11b81526004810185905260240161072f565b60048160c001516005811115610f5357610f53612c27565b14610f92578060c001516005811115610f6e57610f6e612c27565b604051633c053f9d60e21b815260048101919091526024810185905260440161072f565b600081602001516001600160a01b0316803b806020016040519081016040528181526000908060200190933c805190602001209050807f00000000000000000000000000000000000000000000000000000000000000001461101757602082015160405162a2307960e51b81526001600160a01b03909116600482015260240161072f565b60045480156110e05760e08301515181811461104957604051637ad404bf60e11b81526004810188905260240161072f565b60005b818110156110dd578460e00151818151811061106a5761106a612cf3565b602002602001015163ffffffff166004828154811061108b5761108b612cf3565b9060005260206000200154146110d557600481815481106110ae576110ae612cf3565b9060005260206000200154604051632ab10b0b60e21b815260040161072f91815260200190565b60010161104c565b50505b6111018684600001516bffffffffffffffffffffffff168560e00151611c81565b602083015185546001600160a01b03821673ffffffffffffffffffffffffffffffffffffffff199182161787556001870180549091163317905560009061114790611f02565b805190915061115f9060028801906020840190612995565b50426003870155600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01879055604051632142170760e11b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342842e0e90606401600060405180830381600087803b15801561120957600080fd5b505af115801561121d573d6000803e3d6000fd5b5050505083602001516001600160a01b0316336001600160a01b0316887faa6b005b4958114a0c90492461c24af6525ae0178db7fbf44125ae9217c69ccb6000548560405161126d929190612f57565b60405180910390a450505050505050565b606060048054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020905b8154815260200190600101908083116112b8575b5050505050905090565b6000816001546112e69190612d48565b90506000826002546112f89190612d48565b6001839055600281905590506113307f0000000000000000000000000000000000000000000000000000000000000000333086611f13565b604080518481526020810184905290810182905233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9060600160405180910390a2505050565b6060806060806060600080600080600080600080611394611f9d565b97509750975097509750975097509750606080845167ffffffffffffffff8111156113c1576113c1612cdd565b6040519080825280602002602001820160405280156113ea578160200160208202803683370190505b509a506000891561177d578967ffffffffffffffff81111561140e5761140e612cdd565b604051908082528060200260200182016040528015611437578160200160208202803683370190505b5092508967ffffffffffffffff81111561145357611453612cdd565b60405190808252806020026020018201604052801561147c578160200160208202803683370190505b5091508a8911156116865760008060015b8c811015611579578b8e8b83815181106114a9576114a9612cf3565b60200260200101516114bb9190612f70565b6114c59190612f87565b92506114d18383612d48565b91508a81815181106114e5576114e5612cf3565b602002602001015193508a818151811061150157611501612cf3565b602002602001015186828151811061151b5761151b612cf3565b6020026020010181815250508285828151811061153a5761153a612cf3565b6020026020010181815250508260056000868152602001908152602001600020600401600082825461156c9190612d48565b909155505060010161148d565b508a8d8a60008151811061158f5761158f612cf3565b60200260200101516115a19190612f70565b6115ab9190612f87565b91506115b78282612d48565b9050896000815181106115cc576115cc612cf3565b60200260200101519250896000815181106115e9576115e9612cf3565b60200260200101518560008151811061160457611604612cf3565b602002602001018181525050808d111561162f57611622818e612cca565b61162c9083612d48565b91505b818460008151811061164357611643612cf3565b602002602001018181525050816005600085815260200190815260200160002060040160008282546116759190612d48565b9091555060009d5061177792505050565b60005b8a811015611769578881815181106116a3576116a3612cf3565b602002602001015191508881815181106116bf576116bf612cf3565b60200260200101518482815181106116d9576116d9612cf3565b6020026020010181815250508781815181106116f7576116f7612cf3565b602002602001015183828151811061171157611711612cf3565b60200260200101818152505087818151811061172f5761172f612cf3565b602002602001015160056000848152602001908152602001600020600401600082825461175c9190612d48565b9091555050600101611689565b50611774898c612cca565b9a505b60028b90555b855115611997576000995060005b8651811015611930578681815181106117a6576117a6612cf3565b602002602001015191508581815181106117c2576117c2612cf3565b60200260200101516005600084815260200190815260200160002060020190805190602001906117f3929190612995565b50600085828151811061180857611808612cf3565b602002602001015111156119155784818151811061182857611828612cf3565b602002602001015160056000848152602001908152602001600020600501546118519190612d48565b85828151811061186357611863612cf3565b60200260200101818152505084818151811061188157611881612cf3565b602002602001015160056000848152602001908152602001600020600501819055507f00000000000000000000000000000000000000000000000000000000000000008582815181106118d6576118d6612cf3565b6020026020010151111561191057818d82815181106118f7576118f7612cf3565b60209081029190910101528a61190c81612fa9565b9b50505b611928565b6000828152600560208190526040822001555b60010161178b565b508915611942576119428c858c61239b565b42600355600054611954816001612d48565b60005560405181907f06a98bdd4732811ab3214800ed1ada2dce66a2bce301d250c3ca7d6b461ee6669061198d908f9088908890612fc2565b60405180910390a2505b50939e929d509b50919950969750505050505050565b6000806000806000806119be611f9d565b5050509450945094509450945060005b84811015611a5e57878382815181106119e9576119e9612cf3565b602002602001015103611a565785841115611a35578386838381518110611a1257611a12612cf3565b6020026020010151611a249190612f70565b611a2e9190612f87565b9650611a5e565b818181518110611a4757611a47612cf3565b60200260200101519650611a5e565b6001016119ce565b505050505050919050565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015611ae957602002820191906000526020600020905b815481526020019060010190808311611ad5575b50505050508152602001600382015481526020016004820154815260200160058201548152505090507f00000000000000000000000000000000000000000000000000000000000000008160a001511115611b475760029150611b56565b606081015115611b5657600191505b50919050565b60068181548110610adf57600080fd5b606060068054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020908154815260200190600101908083116112b8575050505050905090565b60007f0000000000000000000000000000000000000000000000000000000000000000600354611bf29190612d48565b905090565b8060016000828254611c099190612cca565b90915550611c3a90507f00000000000000000000000000000000000000000000000000000000000000008383612760565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051611c7591815260200190565b60405180910390a25050565b604051633cebfa4f60e01b81526004810184905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633cebfa4f906024016040805180830381865afa158015611cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0e9190612ff7565b91509150816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611d9757604051630b80380d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161072f565b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff8216811115611dfe57604051632b30b24760e21b81526bffffffffffffffffffffffff831660048201526024810182905260440161072f565b60005b8451811015611ef95760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166375c1f93489888581518110611e4e57611e4e612cf3565b60200260200101516040518363ffffffff1660e01b8152600401611e8292919091825263ffffffff16602082015260400190565b602060405180830381865afa158015611e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec3919061302c565b905082811015611ef057604051632b30b24760e21b8152600481018290526024810184905260440161072f565b50600101611e01565b50505050505050565b6060611f0d826127e3565b92915050565b60006040516323b872dd60e01b6000528460045283602452826044526020600060646000808a5af13d15601f3d1160016000511416171691506000606052806040525080611f965760405163abae3d6d60e01b81526001600160a01b0380871660048301528086166024830152841660448201526064810183905260840161072f565b5050505050565b600080600060608060608060606000600354905060025498507f00000000000000000000000000000000000000000000000000000000000000008142611fe39190612cca565b10158015611ff15750600089115b15612390576006548067ffffffffffffffff81111561201257612012612cdd565b60405190808252806020026020018201604052801561203b578160200160208202803683370190505b5094508067ffffffffffffffff81111561205757612057612cdd565b604051908082528060200260200182016040528015612080578160200160208202803683370190505b5096508067ffffffffffffffff81111561209c5761209c612cdd565b6040519080825280602002602001820160405280156120c5578160200160208202803683370190505b5095508067ffffffffffffffff8111156120e1576120e1612cdd565b60405190808252806020026020018201604052801561211457816020015b60608152602001906001900390816120ff5790505b5093508067ffffffffffffffff81111561213057612130612cdd565b604051908082528060200260200182016040528015612159578160200160208202803683370190505b50925060005b8181101561238d576006818154811061217a5761217a612cf3565b906000526020600020015486828151811061219757612197612cf3565b6020026020010181815250506000600560008884815181106121bb576121bb612cf3565b602090810291909101810151825281019190915260400160002080549091506121ec906001600160a01b0316611f02565b8683815181106121fe576121fe612cf3565b6020908102919091010152600381015484908181111561221c578091505b6122268242612cca565b905060006122a089868151811061223f5761223f612cf3565b60200260200101518560020180548060200260200160405190810160405280929190818152602001828054801561229557602002820191906000526020600020905b815481526020019060010190808311612281575b50505050508461288b565b9050801561235e576122d2827f0000000000000000000000000000000000000000000000000000000000000000612f70565b8b8f815181106122e4576122e4612cf3565b6020026020010181815250508a8e8151811061230257612302612cf3565b60200260200101518d6123159190612d48565b9c5089858151811061232957612329612cf3565b60200260200101518c8f8151811061234357612343612cf3565b60209081029190910101526123578e612fa9565b9d5061237e565b8188868151811061237157612371612cf3565b6020026020010181815250505b5050505080600101905061215f565b50505b509091929394959697565b825160008267ffffffffffffffff8111156123b8576123b8612cdd565b6040519080825280602002602001820160405280156123e1578160200160208202803683370190505b50905060008367ffffffffffffffff8111156123ff576123ff612cdd565b604051908082528060200260200182016040528015612428578160200160208202803683370190505b50905060008467ffffffffffffffff81111561244657612446612cdd565b60405190808252806020026020018201604052801561246f578160200160208202803683370190505b50905060008567ffffffffffffffff81111561248d5761248d612cdd565b6040519080825280602002602001820160405280156124b6578160200160208202803683370190505b50905060008667ffffffffffffffff8111156124d4576124d4612cdd565b6040519080825280602002602001820160405280156124fd578160200160208202803683370190505b50905060008060005b8881101561265d5760008c828151811061252257612522612cf3565b60200260200101511115612655578b818151811061254257612542612cf3565b602002602001015191508188848151811061255f5761255f612cf3565b6020908102919091018101919091526000838152600590915260409020600181015488516001600160a01b03909116908990869081106125a1576125a1612cf3565b6001600160a01b039283166020918202929092010152815488519116908890869081106125d0576125d0612cf3565b60200260200101906001600160a01b031690816001600160a01b0316815250508b828151811061260257612602612cf3565b602002602001015186858151811061261c5761261c612cf3565b6020026020010181815250508185858151811061263b5761263b612cf3565b60209081029190910101528361265081612fa9565b945050505b600101612506565b50885b8015612712578861267081613045565b99506000905084612682600184612cca565b8151811061269257612692612cf3565b6020026020010151905060068a815481106126af576126af612cf3565b9060005260206000200154600682815481106126cd576126cd612cf3565b60009182526020909120015560068054806126ea576126ea612d09565b60019003818190600052602060002001600090559055508061270b90613045565b9050612660565b506000547fd19a3d42ed383465e4058c322d9411aeac76ddb8454d22e139fc99808bd569528888888860405161274b9493929190613096565b60405180910390a25050505050505050505050565b600060405163a9059cbb60e01b6000528360045282602452602060006044600080895af13d15601f3d11600160005114161716915060006060528060405250806127dd5760405163abae3d6d60e01b81526001600160a01b038086166004830152306024830152841660448201526064810183905260840161072f565b50505050565b60408051600180825281830190925260609160208083019080368337019050509050816001600160a01b031663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612843573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612867919061302c565b8160008151811061287a5761287a612cf3565b602002602001018181525050919050565b60006128988484846128a0565b949350505050565b600080821180156128e45750826000815181106128bf576128bf612cf3565b6020026020010151846000815181106128da576128da612cf3565b6020026020010151115b15610bb357600082846000815181106128ff576128ff612cf3565b60200260200101518660008151811061291a5761291a612cf3565b602002602001015161292c9190612cca565b61293e90670de0b6b3a7640000612f70565b6129489190612f87565b7f0000000000000000000000000000000000000000000000000000000000000000111595945050505050565b508054600082559060005260206000209081019061299291906129e0565b50565b8280548282559060005260206000209081019282156129d0579160200282015b828111156129d05782518255916020019190600101906129b5565b506129dc9291506129e0565b5090565b5b808211156129dc57600081556001016129e1565b6001600160a01b038116811461299257600080fd5b600080600080600060808688031215612a2257600080fd5b8535612a2d816129f5565b94506020860135612a3d816129f5565b935060408601359250606086013567ffffffffffffffff80821115612a6157600080fd5b818801915088601f830112612a7557600080fd5b813581811115612a8457600080fd5b896020828501011115612a9657600080fd5b9699959850939650602001949392505050565b600060208284031215612abb57600080fd5b5035919050565b60008151808452602080850194506020840160005b83811015612af357815187529582019590820190600101612ad7565b509495945050505050565b6020815260006001600160a01b0380845116602084015280602085015116604084015250604083015160c06060840152612b3b60e0840182612ac2565b905060608401516080840152608084015160a084015260a084015160c08401528091505092915050565b602081526000610bb36020830184612ac2565b60a081526000612b8b60a0830188612ac2565b6020838203818501528188518084528284019150828160051b850101838b0160005b83811015612bdb57601f19878403018552612bc9838351612ac2565b94860194925090850190600101612bad565b50508681036040880152612bef818b612ac2565b9450505050508281036060840152612c078186612ac2565b90508281036080840152612c1b8185612ac2565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6020810160038310612c5f57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020808352835180602085015260005b81811015612c9357858101830151858201604001528201612c77565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115611f0d57611f0d612cb4565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b838152606060208201526000612d386060830185612ac2565b9050826040830152949350505050565b80820180821115611f0d57611f0d612cb4565b604051610100810167ffffffffffffffff81118282101715612d7f57612d7f612cdd565b60405290565b80516bffffffffffffffffffffffff81168114612da157600080fd5b919050565b8051612da1816129f5565b805163ffffffff81168114612da157600080fd5b805160068110612da157600080fd5b600082601f830112612de557600080fd5b8151602067ffffffffffffffff80831115612e0257612e02612cdd565b8260051b604051601f19603f83011681018181108482111715612e2757612e27612cdd565b6040529384526020818701810194908101925087851115612e4757600080fd5b6020870191505b84821015612e6e57612e5f82612db1565b83529183019190830190612e4e565b979650505050505050565b600060208284031215612e8b57600080fd5b815167ffffffffffffffff80821115612ea357600080fd5b908301906101008286031215612eb857600080fd5b612ec0612d5b565b612ec983612d85565b8152612ed760208401612da6565b602082015260408301516040820152612ef260608401612db1565b6060820152612f0360808401612db1565b6080820152612f1460a08401612db1565b60a0820152612f2560c08401612dc5565b60c082015260e083015182811115612f3c57600080fd5b612f4887828601612dd4565b60e08301525095945050505050565b8281526040602082015260006128986040830184612ac2565b8082028115828204841417611f0d57611f0d612cb4565b600082612fa457634e487b7160e01b600052601260045260246000fd5b500490565b600060018201612fbb57612fbb612cb4565b5060010190565b838152606060208201526000612fdb6060830185612ac2565b8281036040840152612fed8185612ac2565b9695505050505050565b6000806040838503121561300a57600080fd5b8251613015816129f5565b915061302360208401612d85565b90509250929050565b60006020828403121561303e57600080fd5b5051919050565b60008161305457613054612cb4565b506000190190565b60008151808452602080850194506020840160005b83811015612af35781516001600160a01b031687529582019590820190600101613071565b6080815260006130a96080830187612ac2565b82810360208401526130bb818761305c565b905082810360408401526130cf818661305c565b90508281036060840152612e6e8185612ac256fea26469706673582212201cbb3243bdf2246a74a754c4b24385dc52b256b192f67778a3b3a76648374a5864736f6c63430008170033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102415760003560e01c8063a0ed60e011610145578063cbcf252a116100bd578063eb338c961161008c578063f4dce71411610071578063f4dce71414610681578063f86ad2b614610689578063ffa1ad74146106b057600080fd5b8063eb338c9614610666578063f189e85a1461067957600080fd5b8063cbcf252a146105ca578063e1f1176d146105f1578063e77cdcc914610618578063eacdaabc1461063f57600080fd5b8063b69ef8a811610114578063c2c4c5c1116100f9578063c2c4c5c11461057e578063c889921d14610597578063cae2a5f0146105aa57600080fd5b8063b69ef8a814610562578063b6b55f251461056b57600080fd5b8063a0ed60e014610496578063a694fc3a146104bd578063a74466ad146104d0578063b15087601461054d57600080fd5b806352c824f5116101d857806372f702f3116101a7578063809cee2f1161018c578063809cee2f1461044657806382a8ea581461046d578063879d90901461048d57600080fd5b806372f702f31461040c57806378e061361461043357600080fd5b806352c824f51461038457806356e76058146103ab5780635829c5ec146103be578063592cf3fb146103e557600080fd5b8063287140511161021457806328714051146103005780632e17de781461033f5780633e7329971461035457806342cde4e81461035d57600080fd5b806308ae7e541461024657806314b19c5a14610280578063150b7a021461028957806316a75172146102d9575b600080fd5b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61026d60005481565b6102a8610297366004612a0a565b630a85bd0160e11b95945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610277565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b61035261034d366004612aa9565b6106e1565b005b61026d60035481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d6103b9366004612aa9565b610acf565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d610441366004612aa9565b610af0565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61048061047b366004612aa9565b610bba565b6040516102779190612afe565b61026d60025481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103526104cb366004612aa9565b610cb1565b61051a6104de366004612aa9565b6005602081905260009182526040909120805460018201546003830154600484015493909401546001600160a01b039283169492909116929085565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610277565b61055561127e565b6040516102779190612b65565b61026d60015481565b610352610579366004612aa9565b6112d6565b610586611378565b604051610277959493929190612b78565b61026d6105a5366004612aa9565b6119ad565b6105bd6105b8366004612aa9565b611a69565b6040516102779190612c3d565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d610674366004612aa9565b611b5c565b610555611b6c565b61026d611bc2565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6106d4604051806040016040528060058152602001640302e312e360dc1b81525081565b6040516102779190612c65565b600081815260056020526040902060018101546001600160a01b0316331461073857600181015460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b600381015460006107498242612cca565b90507f0000000000000000000000000000000000000000000000000000000000000000811115801561077d57506000600254115b156107cb5760405163ba2bbc6b60e01b815260048101859052602481018290527f0000000000000000000000000000000000000000000000000000000000000000604482015260640161072f565b6000806107d6611378565b945050505091508151600003610837576107ee611b6c565b9150815167ffffffffffffffff81111561080a5761080a612cdd565b604051908082528060200260200182016040528015610833578160200160208202803683370190505b5090505b6000805b8351821015610898578783838151811061085757610857612cf3565b60200260200101510315610898578784838151811061087857610878612cf3565b60200260200101510361088d57506001610898565b81600101915061083b565b600487015460028801805460408051602080840282018101909252828152600093909290918301828280156108ec57602002820191906000526020600020905b8154815260200190600101908083116108d8575b50508c5460008f8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff19908116825560018201805490911690559596506001600160a01b03909116949350915061094890506002830182612974565b506000600382018190556004820181905560059091015583156109d7576006805461097590600190612cca565b8154811061098557610985612cf3565b9060005260206000200154600686815481106109a3576109a3612cf3565b60009182526020909120015560068054806109c0576109c0612d09565b600190038181906000526020600020016000905590555b604051632142170760e11b8152306004820152336024820152604481018c90526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342842e0e90606401600060405180830381600087803b158015610a4557600080fd5b505af1158015610a59573d6000803e3d6000fd5b505050506000831115610a7057610a708184611bf7565b806001600160a01b0316336001600160a01b03168c7f950733f4c0bf951b8e770f3cc619a4288e7b59b1236d59aeaf2c238488e8ae816000548688604051610aba93929190612d1f565b60405180910390a45050505050505050505050565b60048181548110610adf57600080fd5b600091825260209091200154905081565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015610b7057602002820191906000526020600020905b815481526020019060010190808311610b5c575b505050505081526020016003820154815260200160048201548152602001600582015481525050905080608001519150610ba9836119ad565b610bb39083612d48565b9392505050565b610c056040518060c0016040528060006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016000815260200160008152602001600081525090565b600082815260056020908152604091829020825160c08101845281546001600160a01b0390811682526001830154168184015260028201805485518186028101860187528181529295939493860193830182828015610c8357602002820191906000526020600020905b815481526020019060010190808311610c6f575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050919050565b600254600003610cd45760405163afb0be3360e01b815260040160405180910390fd5b6000818152600560205260409020600381015415610d085760405163b4817ce760e01b81526004810183905260240161072f565b6006547f00000000000000000000000000000000000000000000000000000000000000008103610d6d5760405163fd20861560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260240161072f565b60405163ef0e239b60e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ef0e239b90602401600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dfd9190810190612e79565b9050806080015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014610e4c57604051637ad404bf60e11b81526004810185905260240161072f565b7f000000000000000000000000000000000000000000000000000000000000000015801590610e9f575080604001517f000000000000000000000000000000000000000000000000000000000000000014155b15610ec057604051637ad404bf60e11b81526004810185905260240161072f565b60007f0000000000000000000000000000000000000000000000000000000000000000118015610f1a5750806060015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014155b15610f3b57604051637ad404bf60e11b81526004810185905260240161072f565b60048160c001516005811115610f5357610f53612c27565b14610f92578060c001516005811115610f6e57610f6e612c27565b604051633c053f9d60e21b815260048101919091526024810185905260440161072f565b600081602001516001600160a01b0316803b806020016040519081016040528181526000908060200190933c805190602001209050807f00000000000000000000000000000000000000000000000000000000000000001461101757602082015160405162a2307960e51b81526001600160a01b03909116600482015260240161072f565b60045480156110e05760e08301515181811461104957604051637ad404bf60e11b81526004810188905260240161072f565b60005b818110156110dd578460e00151818151811061106a5761106a612cf3565b602002602001015163ffffffff166004828154811061108b5761108b612cf3565b9060005260206000200154146110d557600481815481106110ae576110ae612cf3565b9060005260206000200154604051632ab10b0b60e21b815260040161072f91815260200190565b60010161104c565b50505b6111018684600001516bffffffffffffffffffffffff168560e00151611c81565b602083015185546001600160a01b03821673ffffffffffffffffffffffffffffffffffffffff199182161787556001870180549091163317905560009061114790611f02565b805190915061115f9060028801906020840190612995565b50426003870155600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01879055604051632142170760e11b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342842e0e90606401600060405180830381600087803b15801561120957600080fd5b505af115801561121d573d6000803e3d6000fd5b5050505083602001516001600160a01b0316336001600160a01b0316887faa6b005b4958114a0c90492461c24af6525ae0178db7fbf44125ae9217c69ccb6000548560405161126d929190612f57565b60405180910390a450505050505050565b606060048054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020905b8154815260200190600101908083116112b8575b5050505050905090565b6000816001546112e69190612d48565b90506000826002546112f89190612d48565b6001839055600281905590506113307f0000000000000000000000000000000000000000000000000000000000000000333086611f13565b604080518481526020810184905290810182905233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9060600160405180910390a2505050565b6060806060806060600080600080600080600080611394611f9d565b97509750975097509750975097509750606080845167ffffffffffffffff8111156113c1576113c1612cdd565b6040519080825280602002602001820160405280156113ea578160200160208202803683370190505b509a506000891561177d578967ffffffffffffffff81111561140e5761140e612cdd565b604051908082528060200260200182016040528015611437578160200160208202803683370190505b5092508967ffffffffffffffff81111561145357611453612cdd565b60405190808252806020026020018201604052801561147c578160200160208202803683370190505b5091508a8911156116865760008060015b8c811015611579578b8e8b83815181106114a9576114a9612cf3565b60200260200101516114bb9190612f70565b6114c59190612f87565b92506114d18383612d48565b91508a81815181106114e5576114e5612cf3565b602002602001015193508a818151811061150157611501612cf3565b602002602001015186828151811061151b5761151b612cf3565b6020026020010181815250508285828151811061153a5761153a612cf3565b6020026020010181815250508260056000868152602001908152602001600020600401600082825461156c9190612d48565b909155505060010161148d565b508a8d8a60008151811061158f5761158f612cf3565b60200260200101516115a19190612f70565b6115ab9190612f87565b91506115b78282612d48565b9050896000815181106115cc576115cc612cf3565b60200260200101519250896000815181106115e9576115e9612cf3565b60200260200101518560008151811061160457611604612cf3565b602002602001018181525050808d111561162f57611622818e612cca565b61162c9083612d48565b91505b818460008151811061164357611643612cf3565b602002602001018181525050816005600085815260200190815260200160002060040160008282546116759190612d48565b9091555060009d5061177792505050565b60005b8a811015611769578881815181106116a3576116a3612cf3565b602002602001015191508881815181106116bf576116bf612cf3565b60200260200101518482815181106116d9576116d9612cf3565b6020026020010181815250508781815181106116f7576116f7612cf3565b602002602001015183828151811061171157611711612cf3565b60200260200101818152505087818151811061172f5761172f612cf3565b602002602001015160056000848152602001908152602001600020600401600082825461175c9190612d48565b9091555050600101611689565b50611774898c612cca565b9a505b60028b90555b855115611997576000995060005b8651811015611930578681815181106117a6576117a6612cf3565b602002602001015191508581815181106117c2576117c2612cf3565b60200260200101516005600084815260200190815260200160002060020190805190602001906117f3929190612995565b50600085828151811061180857611808612cf3565b602002602001015111156119155784818151811061182857611828612cf3565b602002602001015160056000848152602001908152602001600020600501546118519190612d48565b85828151811061186357611863612cf3565b60200260200101818152505084818151811061188157611881612cf3565b602002602001015160056000848152602001908152602001600020600501819055507f00000000000000000000000000000000000000000000000000000000000000008582815181106118d6576118d6612cf3565b6020026020010151111561191057818d82815181106118f7576118f7612cf3565b60209081029190910101528a61190c81612fa9565b9b50505b611928565b6000828152600560208190526040822001555b60010161178b565b508915611942576119428c858c61239b565b42600355600054611954816001612d48565b60005560405181907f06a98bdd4732811ab3214800ed1ada2dce66a2bce301d250c3ca7d6b461ee6669061198d908f9088908890612fc2565b60405180910390a2505b50939e929d509b50919950969750505050505050565b6000806000806000806119be611f9d565b5050509450945094509450945060005b84811015611a5e57878382815181106119e9576119e9612cf3565b602002602001015103611a565785841115611a35578386838381518110611a1257611a12612cf3565b6020026020010151611a249190612f70565b611a2e9190612f87565b9650611a5e565b818181518110611a4757611a47612cf3565b60200260200101519650611a5e565b6001016119ce565b505050505050919050565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015611ae957602002820191906000526020600020905b815481526020019060010190808311611ad5575b50505050508152602001600382015481526020016004820154815260200160058201548152505090507f00000000000000000000000000000000000000000000000000000000000000008160a001511115611b475760029150611b56565b606081015115611b5657600191505b50919050565b60068181548110610adf57600080fd5b606060068054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020908154815260200190600101908083116112b8575050505050905090565b60007f0000000000000000000000000000000000000000000000000000000000000000600354611bf29190612d48565b905090565b8060016000828254611c099190612cca565b90915550611c3a90507f00000000000000000000000000000000000000000000000000000000000000008383612760565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051611c7591815260200190565b60405180910390a25050565b604051633cebfa4f60e01b81526004810184905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633cebfa4f906024016040805180830381865afa158015611cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0e9190612ff7565b91509150816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611d9757604051630b80380d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161072f565b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff8216811115611dfe57604051632b30b24760e21b81526bffffffffffffffffffffffff831660048201526024810182905260440161072f565b60005b8451811015611ef95760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166375c1f93489888581518110611e4e57611e4e612cf3565b60200260200101516040518363ffffffff1660e01b8152600401611e8292919091825263ffffffff16602082015260400190565b602060405180830381865afa158015611e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec3919061302c565b905082811015611ef057604051632b30b24760e21b8152600481018290526024810184905260440161072f565b50600101611e01565b50505050505050565b6060611f0d826127e3565b92915050565b60006040516323b872dd60e01b6000528460045283602452826044526020600060646000808a5af13d15601f3d1160016000511416171691506000606052806040525080611f965760405163abae3d6d60e01b81526001600160a01b0380871660048301528086166024830152841660448201526064810183905260840161072f565b5050505050565b600080600060608060608060606000600354905060025498507f00000000000000000000000000000000000000000000000000000000000000008142611fe39190612cca565b10158015611ff15750600089115b15612390576006548067ffffffffffffffff81111561201257612012612cdd565b60405190808252806020026020018201604052801561203b578160200160208202803683370190505b5094508067ffffffffffffffff81111561205757612057612cdd565b604051908082528060200260200182016040528015612080578160200160208202803683370190505b5096508067ffffffffffffffff81111561209c5761209c612cdd565b6040519080825280602002602001820160405280156120c5578160200160208202803683370190505b5095508067ffffffffffffffff8111156120e1576120e1612cdd565b60405190808252806020026020018201604052801561211457816020015b60608152602001906001900390816120ff5790505b5093508067ffffffffffffffff81111561213057612130612cdd565b604051908082528060200260200182016040528015612159578160200160208202803683370190505b50925060005b8181101561238d576006818154811061217a5761217a612cf3565b906000526020600020015486828151811061219757612197612cf3565b6020026020010181815250506000600560008884815181106121bb576121bb612cf3565b602090810291909101810151825281019190915260400160002080549091506121ec906001600160a01b0316611f02565b8683815181106121fe576121fe612cf3565b6020908102919091010152600381015484908181111561221c578091505b6122268242612cca565b905060006122a089868151811061223f5761223f612cf3565b60200260200101518560020180548060200260200160405190810160405280929190818152602001828054801561229557602002820191906000526020600020905b815481526020019060010190808311612281575b50505050508461288b565b9050801561235e576122d2827f0000000000000000000000000000000000000000000000000000000000000000612f70565b8b8f815181106122e4576122e4612cf3565b6020026020010181815250508a8e8151811061230257612302612cf3565b60200260200101518d6123159190612d48565b9c5089858151811061232957612329612cf3565b60200260200101518c8f8151811061234357612343612cf3565b60209081029190910101526123578e612fa9565b9d5061237e565b8188868151811061237157612371612cf3565b6020026020010181815250505b5050505080600101905061215f565b50505b509091929394959697565b825160008267ffffffffffffffff8111156123b8576123b8612cdd565b6040519080825280602002602001820160405280156123e1578160200160208202803683370190505b50905060008367ffffffffffffffff8111156123ff576123ff612cdd565b604051908082528060200260200182016040528015612428578160200160208202803683370190505b50905060008467ffffffffffffffff81111561244657612446612cdd565b60405190808252806020026020018201604052801561246f578160200160208202803683370190505b50905060008567ffffffffffffffff81111561248d5761248d612cdd565b6040519080825280602002602001820160405280156124b6578160200160208202803683370190505b50905060008667ffffffffffffffff8111156124d4576124d4612cdd565b6040519080825280602002602001820160405280156124fd578160200160208202803683370190505b50905060008060005b8881101561265d5760008c828151811061252257612522612cf3565b60200260200101511115612655578b818151811061254257612542612cf3565b602002602001015191508188848151811061255f5761255f612cf3565b6020908102919091018101919091526000838152600590915260409020600181015488516001600160a01b03909116908990869081106125a1576125a1612cf3565b6001600160a01b039283166020918202929092010152815488519116908890869081106125d0576125d0612cf3565b60200260200101906001600160a01b031690816001600160a01b0316815250508b828151811061260257612602612cf3565b602002602001015186858151811061261c5761261c612cf3565b6020026020010181815250508185858151811061263b5761263b612cf3565b60209081029190910101528361265081612fa9565b945050505b600101612506565b50885b8015612712578861267081613045565b99506000905084612682600184612cca565b8151811061269257612692612cf3565b6020026020010151905060068a815481106126af576126af612cf3565b9060005260206000200154600682815481106126cd576126cd612cf3565b60009182526020909120015560068054806126ea576126ea612d09565b60019003818190600052602060002001600090559055508061270b90613045565b9050612660565b506000547fd19a3d42ed383465e4058c322d9411aeac76ddb8454d22e139fc99808bd569528888888860405161274b9493929190613096565b60405180910390a25050505050505050505050565b600060405163a9059cbb60e01b6000528360045282602452602060006044600080895af13d15601f3d11600160005114161716915060006060528060405250806127dd5760405163abae3d6d60e01b81526001600160a01b038086166004830152306024830152841660448201526064810183905260840161072f565b50505050565b60408051600180825281830190925260609160208083019080368337019050509050816001600160a01b031663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612843573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612867919061302c565b8160008151811061287a5761287a612cf3565b602002602001018181525050919050565b60006128988484846128a0565b949350505050565b600080821180156128e45750826000815181106128bf576128bf612cf3565b6020026020010151846000815181106128da576128da612cf3565b6020026020010151115b15610bb357600082846000815181106128ff576128ff612cf3565b60200260200101518660008151811061291a5761291a612cf3565b602002602001015161292c9190612cca565b61293e90670de0b6b3a7640000612f70565b6129489190612f87565b7f0000000000000000000000000000000000000000000000000000000000000000111595945050505050565b508054600082559060005260206000209081019061299291906129e0565b50565b8280548282559060005260206000209081019282156129d0579160200282015b828111156129d05782518255916020019190600101906129b5565b506129dc9291506129e0565b5090565b5b808211156129dc57600081556001016129e1565b6001600160a01b038116811461299257600080fd5b600080600080600060808688031215612a2257600080fd5b8535612a2d816129f5565b94506020860135612a3d816129f5565b935060408601359250606086013567ffffffffffffffff80821115612a6157600080fd5b818801915088601f830112612a7557600080fd5b813581811115612a8457600080fd5b896020828501011115612a9657600080fd5b9699959850939650602001949392505050565b600060208284031215612abb57600080fd5b5035919050565b60008151808452602080850194506020840160005b83811015612af357815187529582019590820190600101612ad7565b509495945050505050565b6020815260006001600160a01b0380845116602084015280602085015116604084015250604083015160c06060840152612b3b60e0840182612ac2565b905060608401516080840152608084015160a084015260a084015160c08401528091505092915050565b602081526000610bb36020830184612ac2565b60a081526000612b8b60a0830188612ac2565b6020838203818501528188518084528284019150828160051b850101838b0160005b83811015612bdb57601f19878403018552612bc9838351612ac2565b94860194925090850190600101612bad565b50508681036040880152612bef818b612ac2565b9450505050508281036060840152612c078186612ac2565b90508281036080840152612c1b8185612ac2565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6020810160038310612c5f57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020808352835180602085015260005b81811015612c9357858101830151858201604001528201612c77565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115611f0d57611f0d612cb4565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b838152606060208201526000612d386060830185612ac2565b9050826040830152949350505050565b80820180821115611f0d57611f0d612cb4565b604051610100810167ffffffffffffffff81118282101715612d7f57612d7f612cdd565b60405290565b80516bffffffffffffffffffffffff81168114612da157600080fd5b919050565b8051612da1816129f5565b805163ffffffff81168114612da157600080fd5b805160068110612da157600080fd5b600082601f830112612de557600080fd5b8151602067ffffffffffffffff80831115612e0257612e02612cdd565b8260051b604051601f19603f83011681018181108482111715612e2757612e27612cdd565b6040529384526020818701810194908101925087851115612e4757600080fd5b6020870191505b84821015612e6e57612e5f82612db1565b83529183019190830190612e4e565b979650505050505050565b600060208284031215612e8b57600080fd5b815167ffffffffffffffff80821115612ea357600080fd5b908301906101008286031215612eb857600080fd5b612ec0612d5b565b612ec983612d85565b8152612ed760208401612da6565b602082015260408301516040820152612ef260608401612db1565b6060820152612f0360808401612db1565b6080820152612f1460a08401612db1565b60a0820152612f2560c08401612dc5565b60c082015260e083015182811115612f3c57600080fd5b612f4887828601612dd4565b60e08301525095945050505050565b8281526040602082015260006128986040830184612ac2565b8082028115828204841417611f0d57611f0d612cb4565b600082612fa457634e487b7160e01b600052601260045260246000fd5b500490565b600060018201612fbb57612fbb612cb4565b5060010190565b838152606060208201526000612fdb6060830185612ac2565b8281036040840152612fed8185612ac2565b9695505050505050565b6000806040838503121561300a57600080fd5b8251613015816129f5565b915061302360208401612d85565b90509250929050565b60006020828403121561303e57600080fd5b5051919050565b60008161305457613054612cb4565b506000190190565b60008151808452602080850194506020840160005b83811015612af35781516001600160a01b031687529582019590820190600101613071565b6080815260006130a96080830187612ac2565b82810360208401526130bb818761305c565b905082810360408401526130cf818661305c565b90508281036060840152612e6e8185612ac256fea26469706673582212201cbb3243bdf2246a74a754c4b24385dc52b256b192f67778a3b3a76648374a5864736f6c63430008170033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/trader_old/vendor/valory/contracts/mech_activity/contract.py b/trader_old/vendor/valory/contracts/mech_activity/contract.py deleted file mode 100644 index c411d06e1..000000000 --- a/trader_old/vendor/valory/contracts/mech_activity/contract.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the class to connect to the `MechActivityContract` contract.""" - -from enum import Enum - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi - - -class MechActivityContract(Contract): - """The Service Staking contract.""" - - contract_id = PublicId.from_str("valory/mech_activity:0.1.0") - - @classmethod - def liveness_ratio( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the liveness ratio.""" - contract = cls.get_instance(ledger_api, contract_address) - liveness_ratio = contract.functions.livenessRatio().call() - return dict(data=liveness_ratio) diff --git a/trader_old/vendor/valory/contracts/mech_activity/contract.yaml b/trader_old/vendor/valory/contracts/mech_activity/contract.yaml deleted file mode 100644 index 1a1828d46..000000000 --- a/trader_old/vendor/valory/contracts/mech_activity/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: mech_activity -author: valory -version: 0.1.0 -type: contract -description: Mech activity checker contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeid4hg5rx75ltdjmekmxdddwqzbvblygmvlhws5samjxfirnkp666i - build/MechActivity.json: bafybeiagrufcoljrlo2zklc7kxwh7eyrf67usos2bqnf7hss47hgm6low4 - contract.py: bafybeihgiwyy5gj5tpyz6wnjlfsywssanrbuzskqctt557f3galofewqse -fingerprint_ignore_patterns: [] -contracts: [] -class_name: MechActivityContract -contract_interface_paths: - ethereum: build/MechActivity.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - web3: - version: <7,>=6.0.0 diff --git a/trader_old/vendor/valory/contracts/mech_marketplace/README.md b/trader_old/vendor/valory/contracts/mech_marketplace/README.md deleted file mode 100644 index 22522064e..000000000 --- a/trader_old/vendor/valory/contracts/mech_marketplace/README.md +++ /dev/null @@ -1 +0,0 @@ -# Agent Mech Marketplace Contract diff --git a/trader_old/vendor/valory/contracts/mech_marketplace/__init__.py b/trader_old/vendor/valory/contracts/mech_marketplace/__init__.py deleted file mode 100644 index bb07482ea..000000000 --- a/trader_old/vendor/valory/contracts/mech_marketplace/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the support resources for an agent MechMarketplace.""" diff --git a/trader_old/vendor/valory/contracts/mech_marketplace/build/mech.json b/trader_old/vendor/valory/contracts/mech_marketplace/build/mech.json deleted file mode 100644 index dae53c607..000000000 --- a/trader_old/vendor/valory/contracts/mech_marketplace/build/mech.json +++ /dev/null @@ -1,837 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "AgentMech", - "sourceName": "contracts/AgentMech.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_stakingFactory", - "type": "address" - }, - { - "internalType": "address", - "name": "_karmaProxy", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_minResponseTimeout", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_maxResponseTimeout", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "name": "AlreadyDelivered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "min", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "OutOfBounds", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "Overflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "current", - "type": "uint256" - } - ], - "name": "PriorityMechResponseTimeout", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrancyGuard", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "stakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceNotStaked", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "UnauthorizedAccount", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "factory", - "type": "address" - } - ], - "name": "FactoryUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "priorityMech", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "actualMech", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "requester", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "MarketplaceDeliver", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "requester", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "requestedMech", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "MarketplaceRequest", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "mech", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "status", - "type": "bool" - } - ], - "name": "MechRegistrationStatusChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "minResponseTimeout", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "maxResponseTimeout", - "type": "uint256" - } - ], - "name": "MinMaxResponseTimeoutUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "inputs": [], - "name": "DOMAIN_SEPARATOR_TYPE_HASH", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "chainId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "mech", - "type": "address" - }, - { - "internalType": "address", - "name": "mechStakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "mechServiceId", - "type": "uint256" - } - ], - "name": "checkMech", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "requester", - "type": "address" - }, - { - "internalType": "address", - "name": "requesterStakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "requesterServiceId", - "type": "uint256" - } - ], - "name": "checkRequester", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "stakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "checkStakingInstance", - "outputs": [], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "requestData", - "type": "bytes" - }, - { - "internalType": "address", - "name": "deliveryMechStakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deliveryMechServiceId", - "type": "uint256" - } - ], - "name": "deliverMarketplace", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "domainSeparator", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "getDeliveriesCount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getDomainSeparator", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "name": "getMechDeliveryInfo", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "name": "priorityMech", - "type": "address" - }, - { - "internalType": "address", - "name": "deliveryMech", - "type": "address" - }, - { - "internalType": "address", - "name": "requester", - "type": "address" - }, - { - "internalType": "uint32", - "name": "responseTimeout", - "type": "uint32" - } - ], - "internalType": "struct MechDelivery", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "mechService", - "type": "address" - } - ], - "name": "getMechServiceDeliveriesCount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "nonce", - "type": "uint256" - } - ], - "name": "getRequestId", - "outputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "name": "getRequestStatus", - "outputs": [ - { - "internalType": "enum MechMarketplace.RequestStatus", - "name": "status", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "getRequestsCount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "karmaProxy", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapDeliveryCounts", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapMechServiceDeliveryCounts", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapNonces", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapRequestCounts", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapRequestIdDeliveries", - "outputs": [ - { - "internalType": "address", - "name": "priorityMech", - "type": "address" - }, - { - "internalType": "address", - "name": "deliveryMech", - "type": "address" - }, - { - "internalType": "address", - "name": "requester", - "type": "address" - }, - { - "internalType": "uint32", - "name": "responseTimeout", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxResponseTimeout", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minResponseTimeout", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "numTotalRequests", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "numUndeliveredRequests", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - }, - { - "internalType": "address", - "name": "priorityMech", - "type": "address" - }, - { - "internalType": "address", - "name": "priorityMechStakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "priorityMechServiceId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "requesterStakingInstance", - "type": "address" - }, - { - "internalType": "uint256", - "name": "requesterServiceId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "responseTimeout", - "type": "uint256" - } - ], - "name": "request", - "outputs": [ - { - "internalType": "uint256", - "name": "requestId", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "stakingFactory", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x60806040525f805534801562000013575f80fd5b50604051620026cc380380620026cc833981016040819052620000369162000391565b604080516001600160a01b03851660208201528082018490528151808203830181526060909101909152839083906200006f8162000145565b5050506001600160a01b0383166200009a5760405163d92e233d60e01b815260040160405180910390fd5b6040516331a9108f60e11b8152600481018390525f906001600160a01b03851690636352211e90602401602060405180830381865afa158015620000e0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001069190620003c6565b90506001600160a01b0381166200013857604051630ede975960e01b8152600481018490526024015b60405180910390fd5b50600155506200049a9050565b6200014f620001ad565b51156200019f5760405162461bcd60e51b815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016200012f565b620001aa8162000218565b50565b6060620002136200020d604051606b60f91b6020820152602560fa1b60218201526001600160601b03193060601b166022820152600160f81b60368201525f90603701604051602081830303815290604052805190602001205f1c905090565b620002e1565b905090565b5f620002248262000339565b90505f8151602083015ff090506200028b604051606b60f91b6020820152602560fa1b60218201526001600160601b03193060601b166022820152600160f81b60368201525f90603701604051602081830303815290604052805190602001205f1c905090565b6001600160a01b0316816001600160a01b031614620002dc5760405162461bcd60e51b815260206004820152600c60248201526b15dc9a5d194819985a5b195960a21b60448201526064016200012f565b505050565b6060813b600181116200030357505060408051602081019091525f8152919050565b806200030f81620003fd565b9150506040519150601f19601f602083010116820160405280825280600160208401853c50919050565b6060815160016200034b919062000415565b826040516020016200035f92919062000431565b6040516020818303038152906040529050919050565b80516001600160a01b03811681146200038c575f80fd5b919050565b5f805f60608486031215620003a4575f80fd5b620003af8462000375565b925060208401519150604084015190509250925092565b5f60208284031215620003d7575f80fd5b620003e28262000375565b9392505050565b634e487b7160e01b5f52601160045260245ffd5b5f816200040e576200040e620003e9565b505f190190565b808201808211156200042b576200042b620003e9565b92915050565b606360f81b815260e083901b6001600160e01b03191660018201526880600e6000396000f360b81b60058201525f600e82018190528251815b8181101562000489576020818601810151600f8684010152016200046a565b505f9201600f019182525092915050565b61222480620004a85f395ff3fe60806040526004361061017a575f3560e01c8063a035b1fe116100d1578063bdf863171161007c578063f23a6e6111610057578063f23a6e61146104d2578063f6171e4414610517578063fc0c546a14610536575f80fd5b8063bdf8631714610472578063c7dec3fc14610487578063e00b9118146104b3575f80fd5b8063b0d691fe116100ac578063b0d691fe146103d1578063b94207d314610418578063bc197c811461042b575f80fd5b8063a035b1fe1461038a578063a4f9edbf1461039f578063affed0e0146103be575f80fd5b80633a871cdd116101315780636d70f7ae1161010c5780636d70f7ae146102fb5780637af734731461032a57806391b7f5ed1461036b575f80fd5b80633a871cdd1461028557806358ce0909146102a45780635fee6085146102d0575f80fd5b8063157305fe11610161578063157305fe146102255780631626ba7e1461024457806317d70f7c14610263575f80fd5b806223de2914610185578063150b7a02146101ab575f80fd5b3661018157005b5f80fd5b348015610190575f80fd5b506101a961019f366004611943565b5050505050505050565b005b3480156101b6575f80fd5b506101ef6101c53660046119ed565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b348015610230575f80fd5b506101a961023f366004611b2f565b61054a565b34801561024f575f80fd5b506101ef61025e366004611b2f565b610771565b34801561026e575f80fd5b50610277610914565b60405190815260200161021c565b348015610290575f80fd5b5061027761029f366004611b73565b610938565b3480156102af575f80fd5b506102c36102be366004611bc2565b610974565b60405161021c9190611be2565b3480156102db575f80fd5b506102776102ea366004611c25565b60036020525f908152604090205481565b348015610306575f80fd5b5061031a610315366004611c25565b610ada565b604051901515815260200161021c565b348015610335575f80fd5b50610277610344366004611c25565b73ffffffffffffffffffffffffffffffffffffffff165f9081526003602052604090205490565b348015610376575f80fd5b506101a9610385366004611c40565b610bac565b348015610395575f80fd5b5061027760015481565b3480156103aa575f80fd5b506101a96103b9366004611c57565b610c9a565b3480156103c9575f80fd5b505f54610277565b3480156103dc575f80fd5b50730576a174d229e3cfa37253523e645a78a0c91b575b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021c565b610277610426366004611c57565b610d16565b348015610436575f80fd5b506101ef610445366004611cd2565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561047d575f80fd5b5061027760025481565b348015610492575f80fd5b506104a66104a1366004611d68565b610e63565b60405161021c9190611e45565b3480156104be575f80fd5b506102776104cd366004611e57565b610f4d565b3480156104dd575f80fd5b506101ef6104ec366004611e8e565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b348015610522575f80fd5b50610277610531366004611bc2565b610f9e565b348015610541575f80fd5b506103f3610fc0565b61055333610ada565b80610571575033730576a174d229e3cfa37253523e645a78a0c91b57145b610602576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084015b60405180910390fd5b5f828152600460205260408082208151808301928390529160029082845b8154815260200190600101908083116106205750505050509050805f6002811061064c5761064c611f05565b602002015115801561066057506020810151155b801561069557505f805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed548314155b156106cf576040517ffe239804000000000000000000000000000000000000000000000000000000008152600481018490526024016105f9565b6020818101805183515f908152600490935260408084206001908101929092558451925184528084209290925585835290822082815501819055600280549161071783611f5f565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f0cd979445339c62199996f208428d987b1cea24d18e62b79ec24d94b636e8b708484604051610764929190611f93565b60405180910390a2505050565b5f805f8061079185602081015160408201516060909201515f1a92909190565b9094509250905060ff81165f036108a757828583016020016107b282610ada565b1580156107d5575073ffffffffffffffffffffffffffffffffffffffff82163014155b1561080857507fffffffff00000000000000000000000000000000000000000000000000000000945061090e9350505050565b6040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831690631626ba7e9061085c908b908590600401611f93565b602060405180830381865afa158015610877573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061089b9190611fab565b9550505050505061090e565b6108b661031587838686610fdd565b156108e757507f1626ba7e00000000000000000000000000000000000000000000000000000000925061090e915050565b507fffffffff00000000000000000000000000000000000000000000000000000000925050505b92915050565b5f8061091e610ff9565b8060200190518101906109319190611fea565b9392505050565b5f6109416110cd565b61094b848461114c565b905061095a6040850185612016565b90505f0361096b5761096b8461124c565b610931826112ca565b6002546060905f849003610986578093505b806109918486612077565b11156109de576109a18385612077565b6040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016105f9565b8315610ad3578367ffffffffffffffff8111156109fd576109fd611a5b565b604051908082528060200260200182016040528015610a26578160200160208202803683370190505b505f80805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed549193505b84811015610a81575f828152600460205260409020600101549150610a7a8161208a565b9050610a56565b505f5b85811015610ad05781848281518110610a9f57610a9f611f05565b6020908102919091018101919091525f9283526004905260409091206001015490610ac98161208a565b9050610a84565b50505b5092915050565b5f805f610ae5610ff9565b806020019051810190610af89190611fea565b915091508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610b4e91815260200190565b602060405180830381865afa158015610b69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b8d91906120c1565b73ffffffffffffffffffffffffffffffffffffffff1614949350505050565b610bb533610ada565b80610bd3575033730576a174d229e3cfa37253523e645a78a0c91b57145b610c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b60018190556040518181527f66cbca4f3c64fecf1dcb9ce094abcf7f68c3450a1d4e3a8e917dd621edb4ebe09060200160405180910390a150565b610ca2610ff9565b5115610d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016105f9565b610d138161133e565b50565b5f600154341015610d60576001546040517fb489782800000000000000000000000000000000000000000000000000000000815234600482015260248101919091526044016105f9565b610d6a3383610f4d565b335f908152600360205260408120805492935090610d878361208a565b909155505060046020525f81815260408082207f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed80546001830181905590859055808452918320849055600280547f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec94929392909190610e068361208a565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f4bda649efe6b98b0f9c1d5e859c29e20910f45c66dabfe6fad4a4881f7faf9cc8587604051610e53929190611f93565b60405180910390a2505050919050565b6060610e6e33610ada565b80610e8c575033730576a174d229e3cfa37253523e645a78a0c91b57145b610f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b5f610f32878787878715610f2c57876114b3565b5a6114b3565b9250905080610f4357815160208301fd5b5095945050505050565b5f8282604051602001610f619291906120dc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6004602052815f5260405f208160028110610fb7575f80fd5b01549150829050565b5f80610fca610ff9565b80602001905181019061090e91906120c1565b5f805f610fec878787876115b6565b91509150610f438161169e565b60606110c86110c36040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b611850565b905090565b33730576a174d229e3cfa37253523e645a78a0c91b571461114a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016105f9565b565b5f806111a4836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018290525f90605c01604051602081830303815290604052805190602001209050919050565b90507f1626ba7e00000000000000000000000000000000000000000000000000000000611212826111d9610140880188612016565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061077192505050565b7fffffffff00000000000000000000000000000000000000000000000000000000161461124357600191505061090e565b505f9392505050565b5f80546020830135918061125f8361208a565b9190505514610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c6964206e6f6e63650000000000000000000000000000000000000060448201526064016105f9565b8015610d13576040515f9033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d805f8114611332576040519150601f19603f3d011682016040523d82523d5f602084013e611337565b606091505b5050505050565b5f611348826118a5565b90505f8151602083015ff0905061141a6040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146114ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5772697465206661696c6564000000000000000000000000000000000000000060448201526064016105f9565b505050565b5f606060018460018111156114ca576114ca61210a565b0361153e578673ffffffffffffffffffffffffffffffffffffffff1683866040516114f59190612137565b5f604051808303818686f4925050503d805f811461152e576040519150601f19603f3d011682016040523d82523d5f602084013e611533565b606091505b5090925090506115ac565b8673ffffffffffffffffffffffffffffffffffffffff168387876040516115659190612137565b5f60405180830381858888f193505050503d805f81146115a0576040519150601f19603f3d011682016040523d82523d5f602084013e6115a5565b606091505b5090925090505b9550959350505050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156115eb57505f90506003611695565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561163c573d5f803e3d5ffd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661168f575f60019250925050611695565b91505f90505b94509492505050565b5f8160048111156116b1576116b161210a565b036116b95750565b60018160048111156116cd576116cd61210a565b03611734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105f9565b60028160048111156117485761174861210a565b036117af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105f9565b60038160048111156117c3576117c361210a565b03610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105f9565b6060813b6001811161187157505060408051602081019091525f8152919050565b8061187b81611f5f565b9150506040519150601f19601f602083010116820160405280825280600160208401853c50919050565b6060815160016118b59190612077565b826040516020016118c7929190612152565b6040516020818303038152906040529050919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d13575f80fd5b5f8083601f84011261190e575f80fd5b50813567ffffffffffffffff811115611925575f80fd5b60208301915083602082850101111561193c575f80fd5b9250929050565b5f805f805f805f8060c0898b03121561195a575f80fd5b8835611965816118dd565b97506020890135611975816118dd565b96506040890135611985816118dd565b955060608901359450608089013567ffffffffffffffff808211156119a8575f80fd5b6119b48c838d016118fe565b909650945060a08b01359150808211156119cc575f80fd5b506119d98b828c016118fe565b999c989b5096995094979396929594505050565b5f805f805f60808688031215611a01575f80fd5b8535611a0c816118dd565b94506020860135611a1c816118dd565b935060408601359250606086013567ffffffffffffffff811115611a3e575f80fd5b611a4a888289016118fe565b969995985093965092949392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112611a97575f80fd5b813567ffffffffffffffff80821115611ab257611ab2611a5b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611af857611af8611a5b565b81604052838152866020858801011115611b10575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f8060408385031215611b40575f80fd5b82359150602083013567ffffffffffffffff811115611b5d575f80fd5b611b6985828601611a88565b9150509250929050565b5f805f60608486031215611b85575f80fd5b833567ffffffffffffffff811115611b9b575f80fd5b84016101608187031215611bad575f80fd5b95602085013595506040909401359392505050565b5f8060408385031215611bd3575f80fd5b50508035926020909101359150565b602080825282518282018190525f9190848201906040850190845b81811015611c1957835183529284019291840191600101611bfd565b50909695505050505050565b5f60208284031215611c35575f80fd5b8135610931816118dd565b5f60208284031215611c50575f80fd5b5035919050565b5f60208284031215611c67575f80fd5b813567ffffffffffffffff811115611c7d575f80fd5b611c8984828501611a88565b949350505050565b5f8083601f840112611ca1575f80fd5b50813567ffffffffffffffff811115611cb8575f80fd5b6020830191508360208260051b850101111561193c575f80fd5b5f805f805f805f8060a0898b031215611ce9575f80fd5b8835611cf4816118dd565b97506020890135611d04816118dd565b9650604089013567ffffffffffffffff80821115611d20575f80fd5b611d2c8c838d01611c91565b909850965060608b0135915080821115611d44575f80fd5b611d508c838d01611c91565b909650945060808b01359150808211156119cc575f80fd5b5f805f805f60a08688031215611d7c575f80fd5b8535611d87816118dd565b945060208601359350604086013567ffffffffffffffff811115611da9575f80fd5b611db588828901611a88565b935050606086013560028110611dc9575f80fd5b949793965091946080013592915050565b5f5b83811015611df4578181015183820152602001611ddc565b50505f910152565b5f8151808452611e13816020860160208601611dda565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081525f6109316020830184611dfc565b5f8060408385031215611e68575f80fd5b8235611e73816118dd565b9150602083013567ffffffffffffffff811115611b5d575f80fd5b5f805f805f8060a08789031215611ea3575f80fd5b8635611eae816118dd565b95506020870135611ebe816118dd565b94506040870135935060608701359250608087013567ffffffffffffffff811115611ee7575f80fd5b611ef389828a016118fe565b979a9699509497509295939492505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f81611f6d57611f6d611f32565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b828152604060208201525f611c896040830184611dfc565b5f60208284031215611fbb575f80fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114610931575f80fd5b5f8060408385031215611ffb575f80fd5b8251612006816118dd565b6020939093015192949293505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612049575f80fd5b83018035915067ffffffffffffffff821115612063575f80fd5b60200191503681900382131561193c575f80fd5b8082018082111561090e5761090e611f32565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036120ba576120ba611f32565b5060010190565b5f602082840312156120d1575f80fd5b8151610931816118dd565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f611c896040830184611dfc565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f8251612148818460208701611dda565b9190910192915050565b7f630000000000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008360e01b1660018201527f80600e6000396000f3000000000000000000000000000000000000000000000060058201525f600e8201525f82516121e081600f850160208701611dda565b91909101600f01939250505056fea2646970667358221220c1913351e275e1fecd00c79cd676ed135b575df5d3a88ccc57419dc3081980a264736f6c63430008150033", - "deployedBytecode": "0x60806040526004361061017a575f3560e01c8063a035b1fe116100d1578063bdf863171161007c578063f23a6e6111610057578063f23a6e61146104d2578063f6171e4414610517578063fc0c546a14610536575f80fd5b8063bdf8631714610472578063c7dec3fc14610487578063e00b9118146104b3575f80fd5b8063b0d691fe116100ac578063b0d691fe146103d1578063b94207d314610418578063bc197c811461042b575f80fd5b8063a035b1fe1461038a578063a4f9edbf1461039f578063affed0e0146103be575f80fd5b80633a871cdd116101315780636d70f7ae1161010c5780636d70f7ae146102fb5780637af734731461032a57806391b7f5ed1461036b575f80fd5b80633a871cdd1461028557806358ce0909146102a45780635fee6085146102d0575f80fd5b8063157305fe11610161578063157305fe146102255780631626ba7e1461024457806317d70f7c14610263575f80fd5b806223de2914610185578063150b7a02146101ab575f80fd5b3661018157005b5f80fd5b348015610190575f80fd5b506101a961019f366004611943565b5050505050505050565b005b3480156101b6575f80fd5b506101ef6101c53660046119ed565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b348015610230575f80fd5b506101a961023f366004611b2f565b61054a565b34801561024f575f80fd5b506101ef61025e366004611b2f565b610771565b34801561026e575f80fd5b50610277610914565b60405190815260200161021c565b348015610290575f80fd5b5061027761029f366004611b73565b610938565b3480156102af575f80fd5b506102c36102be366004611bc2565b610974565b60405161021c9190611be2565b3480156102db575f80fd5b506102776102ea366004611c25565b60036020525f908152604090205481565b348015610306575f80fd5b5061031a610315366004611c25565b610ada565b604051901515815260200161021c565b348015610335575f80fd5b50610277610344366004611c25565b73ffffffffffffffffffffffffffffffffffffffff165f9081526003602052604090205490565b348015610376575f80fd5b506101a9610385366004611c40565b610bac565b348015610395575f80fd5b5061027760015481565b3480156103aa575f80fd5b506101a96103b9366004611c57565b610c9a565b3480156103c9575f80fd5b505f54610277565b3480156103dc575f80fd5b50730576a174d229e3cfa37253523e645a78a0c91b575b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021c565b610277610426366004611c57565b610d16565b348015610436575f80fd5b506101ef610445366004611cd2565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561047d575f80fd5b5061027760025481565b348015610492575f80fd5b506104a66104a1366004611d68565b610e63565b60405161021c9190611e45565b3480156104be575f80fd5b506102776104cd366004611e57565b610f4d565b3480156104dd575f80fd5b506101ef6104ec366004611e8e565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b348015610522575f80fd5b50610277610531366004611bc2565b610f9e565b348015610541575f80fd5b506103f3610fc0565b61055333610ada565b80610571575033730576a174d229e3cfa37253523e645a78a0c91b57145b610602576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084015b60405180910390fd5b5f828152600460205260408082208151808301928390529160029082845b8154815260200190600101908083116106205750505050509050805f6002811061064c5761064c611f05565b602002015115801561066057506020810151155b801561069557505f805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed548314155b156106cf576040517ffe239804000000000000000000000000000000000000000000000000000000008152600481018490526024016105f9565b6020818101805183515f908152600490935260408084206001908101929092558451925184528084209290925585835290822082815501819055600280549161071783611f5f565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f0cd979445339c62199996f208428d987b1cea24d18e62b79ec24d94b636e8b708484604051610764929190611f93565b60405180910390a2505050565b5f805f8061079185602081015160408201516060909201515f1a92909190565b9094509250905060ff81165f036108a757828583016020016107b282610ada565b1580156107d5575073ffffffffffffffffffffffffffffffffffffffff82163014155b1561080857507fffffffff00000000000000000000000000000000000000000000000000000000945061090e9350505050565b6040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831690631626ba7e9061085c908b908590600401611f93565b602060405180830381865afa158015610877573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061089b9190611fab565b9550505050505061090e565b6108b661031587838686610fdd565b156108e757507f1626ba7e00000000000000000000000000000000000000000000000000000000925061090e915050565b507fffffffff00000000000000000000000000000000000000000000000000000000925050505b92915050565b5f8061091e610ff9565b8060200190518101906109319190611fea565b9392505050565b5f6109416110cd565b61094b848461114c565b905061095a6040850185612016565b90505f0361096b5761096b8461124c565b610931826112ca565b6002546060905f849003610986578093505b806109918486612077565b11156109de576109a18385612077565b6040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810191909152602481018290526044016105f9565b8315610ad3578367ffffffffffffffff8111156109fd576109fd611a5b565b604051908082528060200260200182016040528015610a26578160200160208202803683370190505b505f80805260046020527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed549193505b84811015610a81575f828152600460205260409020600101549150610a7a8161208a565b9050610a56565b505f5b85811015610ad05781848281518110610a9f57610a9f611f05565b6020908102919091018101919091525f9283526004905260409091206001015490610ac98161208a565b9050610a84565b50505b5092915050565b5f805f610ae5610ff9565b806020019051810190610af89190611fea565b915091508373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610b4e91815260200190565b602060405180830381865afa158015610b69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b8d91906120c1565b73ffffffffffffffffffffffffffffffffffffffff1614949350505050565b610bb533610ada565b80610bd3575033730576a174d229e3cfa37253523e645a78a0c91b57145b610c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b60018190556040518181527f66cbca4f3c64fecf1dcb9ce094abcf7f68c3450a1d4e3a8e917dd621edb4ebe09060200160405180910390a150565b610ca2610ff9565b5115610d0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f416c726561647920696e697469616c697a65640000000000000000000000000060448201526064016105f9565b610d138161133e565b50565b5f600154341015610d60576001546040517fb489782800000000000000000000000000000000000000000000000000000000815234600482015260248101919091526044016105f9565b610d6a3383610f4d565b335f908152600360205260408120805492935090610d878361208a565b909155505060046020525f81815260408082207f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed80546001830181905590859055808452918320849055600280547f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec94929392909190610e068361208a565b91905055503373ffffffffffffffffffffffffffffffffffffffff167f4bda649efe6b98b0f9c1d5e859c29e20910f45c66dabfe6fad4a4881f7faf9cc8587604051610e53929190611f93565b60405180910390a2505050919050565b6060610e6e33610ada565b80610e8c575033730576a174d229e3cfa37253523e645a78a0c91b57145b610f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603e60248201527f4f6e6c792063616c6c61626c6520627920746865206d656368206f706572617460448201527f6f72206f722074686520656e74727920706f696e7420636f6e7472616374000060648201526084016105f9565b5f610f32878787878715610f2c57876114b3565b5a6114b3565b9250905080610f4357815160208301fd5b5095945050505050565b5f8282604051602001610f619291906120dc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6004602052815f5260405f208160028110610fb7575f80fd5b01549150829050565b5f80610fca610ff9565b80602001905181019061090e91906120c1565b5f805f610fec878787876115b6565b91509150610f438161169e565b60606110c86110c36040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b611850565b905090565b33730576a174d229e3cfa37253523e645a78a0c91b571461114a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e740000000060448201526064016105f9565b565b5f806111a4836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018290525f90605c01604051602081830303815290604052805190602001209050919050565b90507f1626ba7e00000000000000000000000000000000000000000000000000000000611212826111d9610140880188612016565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061077192505050565b7fffffffff00000000000000000000000000000000000000000000000000000000161461124357600191505061090e565b505f9392505050565b5f80546020830135918061125f8361208a565b9190505514610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f496e76616c6964206e6f6e63650000000000000000000000000000000000000060448201526064016105f9565b8015610d13576040515f9033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d805f8114611332576040519150601f19603f3d011682016040523d82523d5f602084013e611337565b606091505b5050505050565b5f611348826118a5565b90505f8151602083015ff0905061141a6040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201525f90603701604051602081830303815290604052805190602001205f1c905090565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146114ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f5772697465206661696c6564000000000000000000000000000000000000000060448201526064016105f9565b505050565b5f606060018460018111156114ca576114ca61210a565b0361153e578673ffffffffffffffffffffffffffffffffffffffff1683866040516114f59190612137565b5f604051808303818686f4925050503d805f811461152e576040519150601f19603f3d011682016040523d82523d5f602084013e611533565b606091505b5090925090506115ac565b8673ffffffffffffffffffffffffffffffffffffffff168387876040516115659190612137565b5f60405180830381858888f193505050503d805f81146115a0576040519150601f19603f3d011682016040523d82523d5f602084013e6115a5565b606091505b5090925090505b9550959350505050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156115eb57505f90506003611695565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561163c573d5f803e3d5ffd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661168f575f60019250925050611695565b91505f90505b94509492505050565b5f8160048111156116b1576116b161210a565b036116b95750565b60018160048111156116cd576116cd61210a565b03611734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105f9565b60028160048111156117485761174861210a565b036117af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105f9565b60038160048111156117c3576117c361210a565b03610d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105f9565b6060813b6001811161187157505060408051602081019091525f8152919050565b8061187b81611f5f565b9150506040519150601f19601f602083010116820160405280825280600160208401853c50919050565b6060815160016118b59190612077565b826040516020016118c7929190612152565b6040516020818303038152906040529050919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d13575f80fd5b5f8083601f84011261190e575f80fd5b50813567ffffffffffffffff811115611925575f80fd5b60208301915083602082850101111561193c575f80fd5b9250929050565b5f805f805f805f8060c0898b03121561195a575f80fd5b8835611965816118dd565b97506020890135611975816118dd565b96506040890135611985816118dd565b955060608901359450608089013567ffffffffffffffff808211156119a8575f80fd5b6119b48c838d016118fe565b909650945060a08b01359150808211156119cc575f80fd5b506119d98b828c016118fe565b999c989b5096995094979396929594505050565b5f805f805f60808688031215611a01575f80fd5b8535611a0c816118dd565b94506020860135611a1c816118dd565b935060408601359250606086013567ffffffffffffffff811115611a3e575f80fd5b611a4a888289016118fe565b969995985093965092949392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f82601f830112611a97575f80fd5b813567ffffffffffffffff80821115611ab257611ab2611a5b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611af857611af8611a5b565b81604052838152866020858801011115611b10575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f8060408385031215611b40575f80fd5b82359150602083013567ffffffffffffffff811115611b5d575f80fd5b611b6985828601611a88565b9150509250929050565b5f805f60608486031215611b85575f80fd5b833567ffffffffffffffff811115611b9b575f80fd5b84016101608187031215611bad575f80fd5b95602085013595506040909401359392505050565b5f8060408385031215611bd3575f80fd5b50508035926020909101359150565b602080825282518282018190525f9190848201906040850190845b81811015611c1957835183529284019291840191600101611bfd565b50909695505050505050565b5f60208284031215611c35575f80fd5b8135610931816118dd565b5f60208284031215611c50575f80fd5b5035919050565b5f60208284031215611c67575f80fd5b813567ffffffffffffffff811115611c7d575f80fd5b611c8984828501611a88565b949350505050565b5f8083601f840112611ca1575f80fd5b50813567ffffffffffffffff811115611cb8575f80fd5b6020830191508360208260051b850101111561193c575f80fd5b5f805f805f805f8060a0898b031215611ce9575f80fd5b8835611cf4816118dd565b97506020890135611d04816118dd565b9650604089013567ffffffffffffffff80821115611d20575f80fd5b611d2c8c838d01611c91565b909850965060608b0135915080821115611d44575f80fd5b611d508c838d01611c91565b909650945060808b01359150808211156119cc575f80fd5b5f805f805f60a08688031215611d7c575f80fd5b8535611d87816118dd565b945060208601359350604086013567ffffffffffffffff811115611da9575f80fd5b611db588828901611a88565b935050606086013560028110611dc9575f80fd5b949793965091946080013592915050565b5f5b83811015611df4578181015183820152602001611ddc565b50505f910152565b5f8151808452611e13816020860160208601611dda565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081525f6109316020830184611dfc565b5f8060408385031215611e68575f80fd5b8235611e73816118dd565b9150602083013567ffffffffffffffff811115611b5d575f80fd5b5f805f805f8060a08789031215611ea3575f80fd5b8635611eae816118dd565b95506020870135611ebe816118dd565b94506040870135935060608701359250608087013567ffffffffffffffff811115611ee7575f80fd5b611ef389828a016118fe565b979a9699509497509295939492505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f81611f6d57611f6d611f32565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b828152604060208201525f611c896040830184611dfc565b5f60208284031215611fbb575f80fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114610931575f80fd5b5f8060408385031215611ffb575f80fd5b8251612006816118dd565b6020939093015192949293505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612049575f80fd5b83018035915067ffffffffffffffff821115612063575f80fd5b60200191503681900382131561193c575f80fd5b8082018082111561090e5761090e611f32565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036120ba576120ba611f32565b5060010190565b5f602082840312156120d1575f80fd5b8151610931816118dd565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f611c896040830184611dfc565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f8251612148818460208701611dda565b9190910192915050565b7f630000000000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008360e01b1660018201527f80600e6000396000f3000000000000000000000000000000000000000000000060058201525f600e8201525f82516121e081600f850160208701611dda565b91909101600f01939250505056fea2646970667358221220c1913351e275e1fecd00c79cd676ed135b575df5d3a88ccc57419dc3081980a264736f6c63430008150033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/mech_marketplace/contract.py b/trader_old/vendor/valory/contracts/mech_marketplace/contract.py deleted file mode 100644 index 33e5a91cc..000000000 --- a/trader_old/vendor/valory/contracts/mech_marketplace/contract.py +++ /dev/null @@ -1,260 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the class to connect to a Mech Marketplace contract.""" - -import concurrent.futures -from typing import Any, Callable, Dict, List, cast - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi -from eth_typing import HexStr -from web3.types import BlockData, BlockIdentifier, EventData, TxReceipt - - -PUBLIC_ID = PublicId.from_str("valory/mech_marketplace:0.1.0") -FIVE_MINUTES = 300.0 - - - -class MechMarketplace(Contract): - """The Mech Marketplace contract.""" - - contract_id = PUBLIC_ID - - @staticmethod - def execute_with_timeout(func: Callable, timeout: float) -> Any: - """Execute a function with a timeout.""" - - # Create a ProcessPoolExecutor with a maximum of 1 worker (process) - with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: - # Submit the function to the executor - future = executor.submit( - func, - ) - - try: - # Wait for the result with a 5-minute timeout - data = future.result(timeout=timeout) - except TimeoutError: - # Handle the case where the execution times out - err = f"The RPC didn't respond in {timeout}." - return None, err - - # Check if an error occurred - if isinstance(data, str): - # Handle the case where the execution failed - return None, data - - return data, None - - @classmethod - def get_request_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - request_data: bytes, - priority_mech: str, - priority_mech_staking_instance: str, - priority_mech_service_id: int, - requester_staking_instance: str, - requester_service_id: int, - response_timeout: int, - **kwargs: Any - ) -> Dict[str, bytes]: - """Gets the encoded arguments for a request tx, which should only be called via the multisig. - - :param ledger_api: the ledger API object - :param contract_address: the contract's address - :param request_data: the request data - :param priority_mech: the priority mech address - :param priority_mech_staking_instance: the priority mech staking instance address - :param priority_mech_service_id: the priority mech service id - :param requester_staking_instance: the requester staking instance address - :param requester_service_id: the requester service id - :param response_timeout: the response timeout - """ - contract_address = ledger_api.api.to_checksum_address(contract_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - encoded_data = contract_instance.encodeABI( - fn_name="request", - args=( - request_data, - priority_mech, - priority_mech_staking_instance, - priority_mech_service_id, - requester_staking_instance, - requester_service_id, - response_timeout, - ) - ) - return {"data": bytes.fromhex(encoded_data[2:])} - - @classmethod - def _process_event( - cls, - ledger_api: LedgerApi, - contract: Any, - tx_hash: HexStr, - expected_logs: int, - event_name: str, - *args: Any, - **kwargs: Any - ) -> JSONLike: - """Process the logs of the given event.""" - ledger_api = cast(EthereumApi, ledger_api) - receipt: TxReceipt = ledger_api.api.eth.get_transaction_receipt(tx_hash) - event_method = getattr(contract.events, event_name) - logs: List[EventData] = list(event_method().process_receipt(receipt)) - - n_logs = len(logs) - if n_logs != expected_logs: - error = f"{expected_logs} {event_name!r} events were expected. tx {tx_hash} emitted {n_logs} instead." - return {"error": error} - - results = [] - for log in logs: - event_args = log.get("args", None) - if event_args is None or any( - expected_key not in event_args for expected_key in args - ): - return {"error": f"The emitted event's ({event_name}) logs for tx {tx_hash} do not match the expected format: {log}"} - results.append({arg_name: event_args[arg_name] for arg_name in args}) - - return dict(results=results) - - @classmethod - def process_request_event( - cls, - ledger_api: LedgerApi, - contract_address: str, - tx_hash: HexStr, - expected_logs: int = 1, - **kwargs: Any - ) -> JSONLike: - """ - Process the request receipt to get the requestId and the given data from the `Request` event's logs. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param tx_hash: the hash of a request tx to be processed. - :param expected_logs: the number of logs expected. - :return: a dictionary with a key named `results` - which contains a list of dictionaries (as many as the expected logs) containing the request id and the data. - """ - contract_address = ledger_api.api.to_checksum_address(contract_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - res = cls._process_event( - ledger_api, contract_instance, tx_hash, expected_logs, "MarketplaceRequest", "requestId", "data" - ) - - return res - - @classmethod - def process_deliver_event( - cls, - ledger_api: LedgerApi, - contract_address: str, - tx_hash: HexStr, - expected_logs: int = 1, - **kwargs: Any - ) -> JSONLike: - """ - Process the request receipt to get the requestId and the delivered data if the `MarketplaceDeliver` event has been emitted. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param tx_hash: the hash of a request tx to be processed. - :param expected_logs: the number of logs expected. - :return: a dictionary with the request id and the data. - """ - contract_address = ledger_api.api.to_checksum_address(contract_address) - contract_instance = cls.get_instance(ledger_api, contract_address) - res = cls._process_event( - ledger_api, contract_instance, tx_hash, expected_logs, "MarketplaceDeliver", "requestId", "data" - ) - - return res - - @classmethod - def get_block_number( - cls, - ledger_api: EthereumApi, - contract_address: str, - tx_hash: HexStr, - **kwargs: Any - ) -> JSONLike: - """Get the number of the block in which the tx of the given hash was settled.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - receipt: TxReceipt = ledger_api.api.eth.get_transaction_receipt(tx_hash) - block: BlockData = ledger_api.api.eth.get_block(receipt["blockNumber"]) - return dict(number=block["number"]) - - @classmethod - def get_response( - cls, - ledger_api: LedgerApi, - contract_address: str, - request_id: int, - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - timeout: float = FIVE_MINUTES, - **kwargs: Any - ) -> JSONLike: - """Filter the `MarketplaceDeliver` events emitted by the contract and get the data of the given `request_id`.""" - contract_address = ledger_api.api.to_checksum_address(contract_address) - ledger_api = cast(EthereumApi, ledger_api) - - def get_responses() -> Any: - """Get the responses from the contract.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - deliver_filter = contract_instance.events.MarketplaceDeliver.build_filter() - deliver_filter.fromBlock = from_block - deliver_filter.toBlock = to_block - deliver_filter.args.requestId.match_single(request_id) - delivered = list(deliver_filter.deploy(ledger_api.api).get_all_entries()) - n_delivered = len(delivered) - - if n_delivered == 0: - info = f"The mech ({contract_address}) has not delivered a response yet for request with id {request_id}." - return {"info": info} - - if n_delivered != 1: - error = ( - f"A single response was expected by the mech ({contract_address}) for request with id {request_id}. " - f"Received {n_delivered} responses: {delivered}." - ) - return error - - delivered_event = delivered.pop() - deliver_args = delivered_event.get("args", None) - if deliver_args is None or "data" not in deliver_args: - error = f"The mech's response does not match the expected format: {delivered_event}" - return error - - return dict(data=deliver_args["data"]) - - data, err = cls.execute_with_timeout(get_responses, timeout=timeout) - if err is not None: - return {"error": err} - - return data diff --git a/trader_old/vendor/valory/contracts/mech_marketplace/contract.yaml b/trader_old/vendor/valory/contracts/mech_marketplace/contract.yaml deleted file mode 100644 index d41799bd0..000000000 --- a/trader_old/vendor/valory/contracts/mech_marketplace/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: mech_marketplace -author: valory -version: 0.1.0 -type: contract -description: Agent mech marketplace contract. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeihygfmkbo4cegrqnz5ws6bbjaifubvk7r2uyvuanxpqy24l634tba - __init__.py: bafybeie6625ddrcph7pcxef4fbfcuhyd6yuzdyyqcoqpc5xdjb4rttw7my - build/mech.json: bafybeif2doizav5rs5hig6bruaoz2bedlyesyh23s735llblh64vazespi - contract.py: bafybeiawzcqvkx7tip7tck2czf47d5rnolebmet3fbmv5p4hzpv3fmarwq -fingerprint_ignore_patterns: [] -contracts: [] -class_name: MechMarketplace -contract_interface_paths: - ethereum: build/mech.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - web3: - version: <7,>=6.0.0 - eth_typing: {} diff --git a/trader_old/vendor/valory/contracts/multisend/README.md b/trader_old/vendor/valory/contracts/multisend/README.md deleted file mode 100644 index 6570c37f7..000000000 --- a/trader_old/vendor/valory/contracts/multisend/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# `Multisend` contract - -## Description - -## Functions - diff --git a/trader_old/vendor/valory/contracts/multisend/__init__.py b/trader_old/vendor/valory/contracts/multisend/__init__.py deleted file mode 100644 index 218a7d8df..000000000 --- a/trader_old/vendor/valory/contracts/multisend/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the support resources for the multisend (MultiSend) contract.""" diff --git a/trader_old/vendor/valory/contracts/multisend/build/MultiSend.json b/trader_old/vendor/valory/contracts/multisend/build/MultiSend.json deleted file mode 100644 index aa4031f87..000000000 --- a/trader_old/vendor/valory/contracts/multisend/build/MultiSend.json +++ /dev/null @@ -1,358 +0,0 @@ -{ - "contractName": "MultiSend", - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "transactions", - "type": "bytes" - } - ], - "name": "multiSend", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b506101a3806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80638d80ff0a14610030575b600080fd5b6100e96004803603602081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184600183028401116401000000008311171561009757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100eb565b005b805160205b81811015610172578083015160f81c6001820184015160601c601583018501516035840186015160558501870160008560008114610135576001811461014557610150565b6000808585888a5af19150610150565b6000808585895af491505b50600081141561015f57600080fd5b82605501870196505050505050506100f0565b50505056fea165627a7a72305820006744fee21c3396bfcae6ec5f76f06721713e70e465c0041ecbe4c6435633550029", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80638d80ff0a14610030575b600080fd5b6100e96004803603602081101561004657600080fd5b810190808035906020019064010000000081111561006357600080fd5b82018360208201111561007557600080fd5b8035906020019184600183028401116401000000008311171561009757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506100eb565b005b805160205b81811015610172578083015160f81c6001820184015160601c601583018501516035840186015160558501870160008560008114610135576001811461014557610150565b6000808585888a5af19150610150565b6000808585895af491505b50600081141561015f57600080fd5b82605501870196505050505050506100f0565b50505056fea165627a7a72305820006744fee21c3396bfcae6ec5f76f06721713e70e465c0041ecbe4c6435633550029", - "sourceMap": "304:2438:18:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;304:2438:18;;;;;;;", - "deployedSourceMap": "304:2438:18:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;304:2438:18;;;;;;;;;;;;;;;;;;;925:1815;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;925:1815:18;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;925:1815:18;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;925:1815:18;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;925:1815:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;925:1815:18;;;;;;;;;;;;;;;:::i;:::-;;;1107:12;1101:19;1142:4;1159:1565;1173:6;1170:1;1167:13;1159:1565;;;1494:1;1480:12;1476:20;1470:27;1464:4;1460:38;1768:4;1765:1;1761:12;1747;1743:31;1737:38;1731:4;1727:49;1930:4;1927:1;1923:12;1909;1905:31;1899:38;2113:4;2110:1;2106:12;2092;2088:31;2082:38;2307:4;2304:1;2300:12;2286;2282:31;2345:1;2370:9;2401:1;2396:66;;;;2484:1;2479:67;;;;2363:183;;2396:66;2458:1;2455;2443:10;2437:4;2430:5;2426:2;2421:3;2416:44;2405:55;;2396:66;;2479:67;2542:1;2539;2527:10;2521:4;2517:2;2512:3;2499:45;2488:56;;2363:183;;2578:1;2569:7;2566:14;2563:2;;;2593:1;2590;2583:12;2563:2;2698:10;2692:4;2688:21;2685:1;2681:29;2676:34;;1185:1539;;;;;;1159:1565;;;1073:1661;;;:::o", - "source": "pragma solidity ^0.5.0;\n\n\n/// @title Multi Send - Allows to batch multiple transactions into one.\n/// @author Nick Dodson - \n/// @author Gonçalo Sá - \n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract MultiSend {\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n function multiSend(bytes memory transactions)\n public\n {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for { } lt(i, length) { } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes]) to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 { success := call(gas, to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas, to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n}\n", - "sourcePath": "/home/uxio/gnosis/dev/safe-contracts/contracts/libraries/MultiSend.sol", - "ast": { - "absolutePath": "/home/uxio/gnosis/dev/safe-contracts/contracts/libraries/MultiSend.sol", - "exportedSymbols": { - "MultiSend": [ - 2276 - ] - }, - "id": 2277, - "nodeType": "SourceUnit", - "nodes": [ - { - "id": 2268, - "literals": [ - "solidity", - "^", - "0.5", - ".0" - ], - "nodeType": "PragmaDirective", - "src": "0:23:18" - }, - { - "baseContracts": [], - "contractDependencies": [], - "contractKind": "contract", - "documentation": "@title Multi Send - Allows to batch multiple transactions into one.\n @author Nick Dodson - \n @author Gonçalo Sá - \n @author Stefan George - \n @author Richard Meissner - ", - "fullyImplemented": true, - "id": 2276, - "linearizedBaseContracts": [ - 2276 - ], - "name": "MultiSend", - "nodeType": "ContractDefinition", - "nodes": [ - { - "body": { - "id": 2274, - "nodeType": "Block", - "src": "990:1750:18", - "statements": [ - { - "externalReferences": [ - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1107:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1480:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1747:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1909:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "2092:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "2286:12:18", - "valueSize": 1 - } - } - ], - "id": 2273, - "nodeType": "InlineAssembly", - "operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let operation := shr(0xf8, mload(add(transactions, i)))\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n let value := mload(add(transactions, add(i, 0x15)))\n let dataLength := mload(add(transactions, add(i, 0x35)))\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n case 1 {\n success := delegatecall(gas(), to, data, dataLength, 0, 0)\n }\n if eq(success, 0)\n {\n revert(0, 0)\n }\n i := add(i, add(0x55, dataLength))\n }\n}", - "src": "1064:1676:18" - } - ] - }, - "documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n to as a address (=> 20 bytes),\n value as a uint256 (=> 32 bytes),\n data length as a uint256 (=> 32 bytes),\n data as bytes.\n see abi.encodePacked for more information on packed encoding", - "id": 2275, - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "multiSend", - "nodeType": "FunctionDefinition", - "parameters": { - "id": 2271, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2270, - "name": "transactions", - "nodeType": "VariableDeclaration", - "scope": 2275, - "src": "944:25:18", - "stateVariable": false, - "storageLocation": "memory", - "typeDescriptions": { - "typeIdentifier": "t_bytes_memory_ptr", - "typeString": "bytes" - }, - "typeName": { - "id": 2269, - "name": "bytes", - "nodeType": "ElementaryTypeName", - "src": "944:5:18", - "typeDescriptions": { - "typeIdentifier": "t_bytes_storage_ptr", - "typeString": "bytes" - } - }, - "value": null, - "visibility": "internal" - } - ], - "src": "943:27:18" - }, - "returnParameters": { - "id": 2272, - "nodeType": "ParameterList", - "parameters": [], - "src": "990:0:18" - }, - "scope": 2276, - "src": "925:1815:18", - "stateMutability": "nonpayable", - "superFunction": null, - "visibility": "public" - } - ], - "scope": 2277, - "src": "304:2438:18" - } - ], - "src": "0:2743:18" - }, - "legacyAST": { - "absolutePath": "/home/uxio/gnosis/dev/safe-contracts/contracts/libraries/MultiSend.sol", - "exportedSymbols": { - "MultiSend": [ - 2276 - ] - }, - "id": 2277, - "nodeType": "SourceUnit", - "nodes": [ - { - "id": 2268, - "literals": [ - "solidity", - "^", - "0.5", - ".0" - ], - "nodeType": "PragmaDirective", - "src": "0:23:18" - }, - { - "baseContracts": [], - "contractDependencies": [], - "contractKind": "contract", - "documentation": "@title Multi Send - Allows to batch multiple transactions into one.\n @author Nick Dodson - \n @author Gonçalo Sá - \n @author Stefan George - \n @author Richard Meissner - ", - "fullyImplemented": true, - "id": 2276, - "linearizedBaseContracts": [ - 2276 - ], - "name": "MultiSend", - "nodeType": "ContractDefinition", - "nodes": [ - { - "body": { - "id": 2274, - "nodeType": "Block", - "src": "990:1750:18", - "statements": [ - { - "externalReferences": [ - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1107:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1480:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1747:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "1909:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "2092:12:18", - "valueSize": 1 - } - }, - { - "transactions": { - "declaration": 2270, - "isOffset": false, - "isSlot": false, - "src": "2286:12:18", - "valueSize": 1 - } - } - ], - "id": 2273, - "nodeType": "InlineAssembly", - "operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let operation := shr(0xf8, mload(add(transactions, i)))\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n let value := mload(add(transactions, add(i, 0x15)))\n let dataLength := mload(add(transactions, add(i, 0x35)))\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n case 1 {\n success := delegatecall(gas(), to, data, dataLength, 0, 0)\n }\n if eq(success, 0)\n {\n revert(0, 0)\n }\n i := add(i, add(0x55, dataLength))\n }\n}", - "src": "1064:1676:18" - } - ] - }, - "documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n operation as a uint8 with 0 for a call or 1 for a delegatecall (=> 1 byte),\n to as a address (=> 20 bytes),\n value as a uint256 (=> 32 bytes),\n data length as a uint256 (=> 32 bytes),\n data as bytes.\n see abi.encodePacked for more information on packed encoding", - "id": 2275, - "implemented": true, - "kind": "function", - "modifiers": [], - "name": "multiSend", - "nodeType": "FunctionDefinition", - "parameters": { - "id": 2271, - "nodeType": "ParameterList", - "parameters": [ - { - "constant": false, - "id": 2270, - "name": "transactions", - "nodeType": "VariableDeclaration", - "scope": 2275, - "src": "944:25:18", - "stateVariable": false, - "storageLocation": "memory", - "typeDescriptions": { - "typeIdentifier": "t_bytes_memory_ptr", - "typeString": "bytes" - }, - "typeName": { - "id": 2269, - "name": "bytes", - "nodeType": "ElementaryTypeName", - "src": "944:5:18", - "typeDescriptions": { - "typeIdentifier": "t_bytes_storage_ptr", - "typeString": "bytes" - } - }, - "value": null, - "visibility": "internal" - } - ], - "src": "943:27:18" - }, - "returnParameters": { - "id": 2272, - "nodeType": "ParameterList", - "parameters": [], - "src": "990:0:18" - }, - "scope": 2276, - "src": "925:1815:18", - "stateMutability": "nonpayable", - "superFunction": null, - "visibility": "public" - } - ], - "scope": 2277, - "src": "304:2438:18" - } - ], - "src": "0:2743:18" - }, - "compiler": { - "name": "solc", - "version": "0.5.7+commit.6da8b019.Emscripten.clang" - }, - "networks": {}, - "schemaVersion": "2.0.2", - "updatedAt": "2019-07-22T10:39:57.431Z" -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/multisend/contract.py b/trader_old/vendor/valory/contracts/multisend/contract.py deleted file mode 100644 index 0082a6e61..000000000 --- a/trader_old/vendor/valory/contracts/multisend/contract.py +++ /dev/null @@ -1,191 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the class to connect to an Gnosis Safe contract.""" -# heavily borrows from https://github.com/gnosis/gnosis-py/blob/51b41f5a8577a96e296b9b7e037491632cda9d8c/gnosis/safe/multi_send.py -import logging -from enum import Enum -from typing import Any, Dict, List, Optional, Tuple, cast - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from hexbytes import HexBytes -from web3 import Web3 - - -PUBLIC_ID = PublicId.from_str("valory/multisend:0.1.0") -MIN_GAS = MIN_GASPRICE = 1 - -_logger = logging.getLogger( - f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" -) - - -class MultiSendOperation(Enum): - """Operation types.""" - - CALL = 0 - DELEGATE_CALL = 1 - - -def encode_data(tx: Dict) -> bytes: - """Encodes multisend transaction.""" - operation = HexBytes( - "{:0>2x}".format(cast(MultiSendOperation, tx.get("operation")).value) - ) # Operation 1 byte - to = HexBytes( - "{:0>40x}".format(int(cast(str, tx.get("to")), 16)) - ) # Address 20 bytes - value = HexBytes("{:0>64x}".format(cast(int, tx.get("value")))) # Value 32 bytes - data = cast(bytes, tx.get("data", b"")) - data_ = HexBytes(data) - data_length = HexBytes("{:0>64x}".format(len(data_))) # Data length 32 bytes - return operation + to + value + data_length + data_ - - -def decode_data(encoded_tx: bytes) -> Tuple[Dict, int]: - """Decodes multisend transaction.""" - encoded_tx = HexBytes(encoded_tx) - operation = MultiSendOperation(encoded_tx[0]) - to = Web3.to_checksum_address(encoded_tx[1 : 1 + 20]) - value = int.from_bytes(encoded_tx[21 : 21 + 32], byteorder="big") - data_length = int.from_bytes(encoded_tx[21 + 32 : 21 + 32 * 2], byteorder="big") - data = encoded_tx[21 + 32 * 2 : 21 + 32 * 2 + data_length] - len_data = len(data) - if len_data != data_length: # pragma: nocover - raise ValueError( - f"Data length {data_length} is different from len(data) {len_data}" - ) - total_length = 21 + 32 * 2 + data_length - return ( - {"operation": operation, "to": to, "value": value, "data": data}, - total_length, - ) - - -def to_bytes(multi_send_txs: List[Dict]) -> bytes: - """Multi send tx list to bytes.""" - return b"".join([encode_data(tx) for tx in multi_send_txs]) - - -def from_bytes(encoded_multisend_txs: bytes) -> List[Dict]: - """Encoded multi send tx to list.""" - encoded_multisend_txs = HexBytes(encoded_multisend_txs) - next_data_position = 0 - txs = [] - while len(encoded_multisend_txs[next_data_position:]) > 0: - tx, total_length = decode_data(encoded_multisend_txs[next_data_position:]) - next_data_position += total_length - txs.append(tx) - return txs - - -class MultiSendContract(Contract): - """The MultiSend contract.""" - - contract_id = PUBLIC_ID - - @classmethod - def get_raw_transaction( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get the Safe transaction.""" - raise NotImplementedError - - @classmethod - def get_raw_message( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[bytes]: - """Get raw message.""" - raise NotImplementedError - - @classmethod - def get_state( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get state.""" - raise NotImplementedError - - @classmethod - def get_deploy_transaction( - cls, ledger_api: LedgerApi, deployer_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get deploy transaction.""" - raise NotImplementedError - - @classmethod - def get_tx_data( - cls, ledger_api: LedgerApi, contract_address: str, multi_send_txs: List[Dict] - ) -> Optional[JSONLike]: - """ - Get a multisend transaction data from list. - - :param ledger_api: ledger API object. - :param contract_address: the contract address. - :param multi_send_txs: the multisend transaction list. - :return: an optional JSON-like object. - """ - multisend_contract = cls.get_instance(ledger_api, contract_address) - encoded_multisend_data = to_bytes(multi_send_txs) - return { - "data": multisend_contract.functions.multiSend( - encoded_multisend_data - ).build_transaction({"gas": MIN_GAS, "gasPrice": MIN_GASPRICE})["data"] - } - - @classmethod - def get_multisend_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - txs: List[Dict], - ) -> Optional[JSONLike]: - """ - Get a multisend transaction data from list. - - :param ledger_api: ledger API object. - :param contract_address: the contract address. - :param txs: the multisend transaction list. - :return: an optional JSON-like object. - """ - multisend_contract = cls.get_instance(ledger_api, contract_address) - encoded_multisend_data = to_bytes(txs) - return multisend_contract.functions.multiSend( - encoded_multisend_data - ).build_transaction({"gas": MIN_GAS, "gasPrice": MIN_GASPRICE}) - - @classmethod - def get_tx_list( - cls, ledger_api: LedgerApi, contract_address: str, multi_send_data: str - ) -> Optional[JSONLike]: - """ - Get a multisend transaction list from encoded data. - - :param ledger_api: ledger API object. - :param contract_address: the contract address. - :param multi_send_data: the multisend transaction data. - :return: an optional JSON-like object. - """ - multisend_contract = cls.get_instance(ledger_api, contract_address) - _, encoded_multisend_data = multisend_contract.decode_function_input( - multi_send_data - ) - return {"tx_list": from_bytes(encoded_multisend_data["transactions"])} diff --git a/trader_old/vendor/valory/contracts/multisend/contract.yaml b/trader_old/vendor/valory/contracts/multisend/contract.yaml deleted file mode 100644 index 9128ba6ad..000000000 --- a/trader_old/vendor/valory/contracts/multisend/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: multisend -author: valory -version: 0.1.0 -type: contract -description: MultiSend contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeidavn55z6uoz3hdjxs4ukvykl2tkvbntnl22uexfyk7unpnfqjflq - __init__.py: bafybeigzxw44dlgdb4qxhm6zul426uyxnqtlhe3oajivdyo3ue7kb45pai - build/MultiSend.json: bafybeicamzvsaaxtboijwfnv24ctrgv5v7gn5irnydnuf62y57o7fmx2jm - contract.py: bafybeid5h5sro6nt7jmr52ntqdwo4ajhdyxy5estq625gzvo3dbkjuzxia - tests/__init__.py: bafybeifd5zc6x3oxef7uy6mhjnt6oybna6ux7ycareqoqo52czkfxaeawm - tests/test_contract.py: bafybeid72mml6mvtv6qqr7r6a2nfbgbwpkhyitx5mmdtzcejt5zo7wcmje -fingerprint_ignore_patterns: [] -contracts: [] -class_name: MultiSendContract -contract_interface_paths: - ethereum: build/MultiSend.json -dependencies: - hexbytes: {} - web3: - version: <7,>=6.0.0 diff --git a/trader_old/vendor/valory/contracts/multisend/tests/__init__.py b/trader_old/vendor/valory/contracts/multisend/tests/__init__.py deleted file mode 100644 index 93954cfc8..000000000 --- a/trader_old/vendor/valory/contracts/multisend/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/multisend contract.""" diff --git a/trader_old/vendor/valory/contracts/multisend/tests/test_contract.py b/trader_old/vendor/valory/contracts/multisend/tests/test_contract.py deleted file mode 100644 index a854239cf..000000000 --- a/trader_old/vendor/valory/contracts/multisend/tests/test_contract.py +++ /dev/null @@ -1,125 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/gnosis contract.""" - -from pathlib import Path -from typing import Dict -from unittest import mock - -import pytest -from aea.contracts.base import Contract -from aea.crypto.base import Crypto, LedgerApi -from aea.crypto.registries import crypto_registry -from aea.test_tools.test_contract import BaseContractTestCase -from aea_ledger_ethereum import EthereumCrypto -from hexbytes import HexBytes - -from packages.valory.contracts.multisend.contract import ( - MultiSendContract, - MultiSendOperation, -) - - -PACKAGE_DIR = Path(__file__).parent.parent -CONTRACT_ADDRESS = "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2" -CHAIN_ID = 1 - - -class TestMultisendContract(BaseContractTestCase): - """Base test case for GnosisSafeContract""" - - path_to_contract = PACKAGE_DIR - ledger_identifier = EthereumCrypto.identifier - contract: MultiSendContract - tx_list = [ - { - "operation": MultiSendOperation.CALL, - "to": crypto_registry.make(EthereumCrypto.identifier).address, - "value": 1, - "data": HexBytes("0x123456789a"), - }, - { - "operation": MultiSendOperation.DELEGATE_CALL, - "to": crypto_registry.make(EthereumCrypto.identifier).address, - "value": 796, - "data": HexBytes("0x123456789a"), - }, - ] - - @classmethod - def finish_contract_deployment(cls) -> str: - """Finish the contract deployment.""" - contract_address = CONTRACT_ADDRESS - return contract_address - - @classmethod - def _deploy_contract( - cls, - contract: Contract, - ledger_api: LedgerApi, - deployer_crypto: Crypto, - gas: int, - ) -> Dict: - """Deploy contract.""" - return {} - - def test_non_implemented_methods( - self, - ) -> None: - """Test not implemented methods.""" - with pytest.raises(NotImplementedError): - self.contract.get_raw_transaction(self.ledger_api, "") - - with pytest.raises(NotImplementedError): - self.contract.get_raw_message(self.ledger_api, "") - - with pytest.raises(NotImplementedError): - self.contract.get_state(self.ledger_api, "") - - with pytest.raises(NotImplementedError): - self.contract.get_deploy_transaction(self.ledger_api, "") - - def test_get_tx_data_get_tx_list(self) -> None: - """Run end-to-end data conversion test.""" - assert self.contract_address is not None - with mock.patch.object( - self.ledger_api.api.manager, "request_blocking", return_value=CHAIN_ID - ): - result = self.contract.get_tx_data( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - multi_send_txs=self.tx_list, - ) - assert isinstance(result, dict) - assert "data" in result - data = result["data"] - assert isinstance(data, str) - assert len(data) > 0, "No data." - with mock.patch.object( - self.ledger_api.api.manager, "request_blocking", return_value=CHAIN_ID - ): - result = self.contract.get_tx_list( - ledger_api=self.ledger_api, - contract_address=self.contract_address, - multi_send_data=data, - ) - assert isinstance(result, dict) - assert "tx_list" in result - assert self.tx_list == result["tx_list"], "Not same." diff --git a/trader_old/vendor/valory/contracts/realitio/__init__.py b/trader_old/vendor/valory/contracts/realitio/__init__.py deleted file mode 100644 index ff1cf563e..000000000 --- a/trader_old/vendor/valory/contracts/realitio/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for the Realitio_v2_1 contract.""" diff --git a/trader_old/vendor/valory/contracts/realitio/build/Realitio.json b/trader_old/vendor/valory/contracts/realitio/build/Realitio.json deleted file mode 100644 index 79eb60ca4..000000000 --- a/trader_old/vendor/valory/contracts/realitio/build/Realitio.json +++ /dev/null @@ -1,1069 +0,0 @@ -{ - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "history_hashes", - "type": "bytes32[]" - }, - { - "name": "addrs", - "type": "address[]" - }, - { - "name": "bonds", - "type": "uint256[]" - }, - { - "name": "answers", - "type": "bytes32[]" - } - ], - "name": "claimWinnings", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "content_hash", - "type": "bytes32" - }, - { - "name": "arbitrator", - "type": "address" - }, - { - "name": "min_timeout", - "type": "uint32" - }, - { - "name": "min_bond", - "type": "uint256" - } - ], - "name": "getFinalAnswerIfMatches", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getBounty", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getArbitrator", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getBond", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_ids", - "type": "bytes32[]" - }, - { - "name": "lengths", - "type": "uint256[]" - }, - { - "name": "hist_hashes", - "type": "bytes32[]" - }, - { - "name": "addrs", - "type": "address[]" - }, - { - "name": "bonds", - "type": "uint256[]" - }, - { - "name": "answers", - "type": "bytes32[]" - } - ], - "name": "claimMultipleAndWithdrawBalance", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "withdraw", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "answer", - "type": "bytes32" - }, - { - "name": "nonce", - "type": "uint256" - }, - { - "name": "bond", - "type": "uint256" - } - ], - "name": "submitAnswerReveal", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "fee", - "type": "uint256" - } - ], - "name": "setQuestionFee", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "template_hashes", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getContentHash", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "question_claims", - "outputs": [ - { - "name": "payee", - "type": "address" - }, - { - "name": "last_bond", - "type": "uint256" - }, - { - "name": "queued_funds", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "fundAnswerBounty", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "arbitrator_question_fees", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "template_id", - "type": "uint256" - }, - { - "name": "question", - "type": "string" - }, - { - "name": "arbitrator", - "type": "address" - }, - { - "name": "timeout", - "type": "uint32" - }, - { - "name": "opening_ts", - "type": "uint32" - }, - { - "name": "nonce", - "type": "uint256" - } - ], - "name": "askQuestion", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "answer", - "type": "bytes32" - }, - { - "name": "max_previous", - "type": "uint256" - } - ], - "name": "submitAnswer", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "isFinalized", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getHistoryHash", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "commitments", - "outputs": [ - { - "name": "reveal_ts", - "type": "uint32" - }, - { - "name": "is_revealed", - "type": "bool" - }, - { - "name": "revealed_answer", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "content", - "type": "string" - } - ], - "name": "createTemplate", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getBestAnswer", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "isPendingArbitration", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "questions", - "outputs": [ - { - "name": "content_hash", - "type": "bytes32" - }, - { - "name": "arbitrator", - "type": "address" - }, - { - "name": "opening_ts", - "type": "uint32" - }, - { - "name": "timeout", - "type": "uint32" - }, - { - "name": "finalize_ts", - "type": "uint32" - }, - { - "name": "is_pending_arbitration", - "type": "bool" - }, - { - "name": "bounty", - "type": "uint256" - }, - { - "name": "best_answer", - "type": "bytes32" - }, - { - "name": "history_hash", - "type": "bytes32" - }, - { - "name": "bond", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getOpeningTS", - "outputs": [ - { - "name": "", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getTimeout", - "outputs": [ - { - "name": "", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "content", - "type": "string" - }, - { - "name": "question", - "type": "string" - }, - { - "name": "arbitrator", - "type": "address" - }, - { - "name": "timeout", - "type": "uint32" - }, - { - "name": "opening_ts", - "type": "uint32" - }, - { - "name": "nonce", - "type": "uint256" - } - ], - "name": "createTemplateAndAskQuestion", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getFinalAnswer", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "getFinalizeTS", - "outputs": [ - { - "name": "", - "type": "uint32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "templates", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - } - ], - "name": "resultFor", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "answer_hash", - "type": "bytes32" - }, - { - "name": "max_previous", - "type": "uint256" - }, - { - "name": "_answerer", - "type": "address" - } - ], - "name": "submitAnswerCommitment", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "requester", - "type": "address" - }, - { - "name": "max_previous", - "type": "uint256" - } - ], - "name": "notifyOfArbitrationRequest", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "question_id", - "type": "bytes32" - }, - { - "name": "answer", - "type": "bytes32" - }, - { - "name": "answerer", - "type": "address" - } - ], - "name": "submitAnswerByArbitrator", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "arbitrator", - "type": "address" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "LogSetQuestionFee", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "template_id", - "type": "uint256" - }, - { - "indexed": true, - "name": "user", - "type": "address" - }, - { - "indexed": false, - "name": "question_text", - "type": "string" - } - ], - "name": "LogNewTemplate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": true, - "name": "user", - "type": "address" - }, - { - "indexed": false, - "name": "template_id", - "type": "uint256" - }, - { - "indexed": false, - "name": "question", - "type": "string" - }, - { - "indexed": true, - "name": "content_hash", - "type": "bytes32" - }, - { - "indexed": false, - "name": "arbitrator", - "type": "address" - }, - { - "indexed": false, - "name": "timeout", - "type": "uint32" - }, - { - "indexed": false, - "name": "opening_ts", - "type": "uint32" - }, - { - "indexed": false, - "name": "nonce", - "type": "uint256" - }, - { - "indexed": false, - "name": "created", - "type": "uint256" - } - ], - "name": "LogNewQuestion", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": false, - "name": "bounty_added", - "type": "uint256" - }, - { - "indexed": false, - "name": "bounty", - "type": "uint256" - }, - { - "indexed": true, - "name": "user", - "type": "address" - } - ], - "name": "LogFundAnswerBounty", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "answer", - "type": "bytes32" - }, - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": false, - "name": "history_hash", - "type": "bytes32" - }, - { - "indexed": true, - "name": "user", - "type": "address" - }, - { - "indexed": false, - "name": "bond", - "type": "uint256" - }, - { - "indexed": false, - "name": "ts", - "type": "uint256" - }, - { - "indexed": false, - "name": "is_commitment", - "type": "bool" - } - ], - "name": "LogNewAnswer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": true, - "name": "user", - "type": "address" - }, - { - "indexed": true, - "name": "answer_hash", - "type": "bytes32" - }, - { - "indexed": false, - "name": "answer", - "type": "bytes32" - }, - { - "indexed": false, - "name": "nonce", - "type": "uint256" - }, - { - "indexed": false, - "name": "bond", - "type": "uint256" - } - ], - "name": "LogAnswerReveal", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": true, - "name": "user", - "type": "address" - } - ], - "name": "LogNotifyOfArbitrationRequest", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": true, - "name": "answer", - "type": "bytes32" - } - ], - "name": "LogFinalize", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "question_id", - "type": "bytes32" - }, - { - "indexed": true, - "name": "user", - "type": "address" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "LogClaim", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "user", - "type": "address" - }, - { - "indexed": false, - "name": "amount", - "type": "uint256" - } - ], - "name": "LogWithdraw", - "type": "event" - } - ], - "bytecode": "608060405260006001553480156200001657600080fd5b506200008d606060405190810160405280603f81526020017f7b227469746c65223a20222573222c202274797065223a2022626f6f6c222c2081526020017f2263617465676f7279223a20222573222c20226c616e67223a20222573227d0081525062000308640100000000026401000000009004565b506200012a608060405190810160405280604f81526020017f7b227469746c65223a20222573222c202274797065223a202275696e74222c2081526020017f22646563696d616c73223a2031382c202263617465676f7279223a202225732281526020017f2c20226c616e67223a20222573227d000000000000000000000000000000000081525062000308640100000000026401000000009004565b50620001c7608060405190810160405280605a81526020017f7b227469746c65223a20222573222c202274797065223a202273696e676c652d81526020017f73656c656374222c20226f7574636f6d6573223a205b25735d2c20226361746581526020017f676f7279223a20222573222c20226c616e67223a20222573227d00000000000081525062000308640100000000026401000000009004565b5062000264608060405190810160405280605c81526020017f7b227469746c65223a20222573222c202274797065223a20226d756c7469706c81526020017f652d73656c656374222c20226f7574636f6d6573223a205b25735d2c2022636181526020017f7465676f7279223a20222573222c20226c616e67223a20222573227d0000000081525062000308640100000000026401000000009004565b5062000301608060405190810160405280604381526020017f7b227469746c65223a20222573222c202274797065223a20226461746574696d81526020017f65222c202263617465676f7279223a20222573222c20226c616e67223a20222581526020017f73227d000000000000000000000000000000000000000000000000000000000081525062000308640100000000026401000000009004565b50620004ca565b60015460008181526002602090815260408083204390555184519293928592918201918291908401908083835b60208310620003565780518252601f19909201916020918201910162000335565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310620003bb5780518252601f1990920191602091820191016200039a565b51815160209384036101000a6000190180199092169116179052604080519290940182900382206000888152600383528581209190915581835289518383015289513397508896507fb87fb721c0a557bb8dff89a86796466931d82ba530a66a239263eb8735ade2e4958b955084939084019290860191908190849084905b83811015620004545781810151838201526020016200043a565b50505050905090810190601f168015620004825780820380516001836020036101000a031916815260200191505b509250505060405180910390a3620004aa8160016401000000006200314a620004b382021704565b60015592915050565b600082820183811015620004c357fe5b9392505050565b6139a680620004da6000396000f3006080604052600436106101925763ffffffff60e060020a6000350416631101a0fd811461019757806312a203c31461029e5780632417395c146102e35780632518904c146102fb57806326d6c97b1461032f57806328828b1e146103475780633ccfd60b146104b95780634dc266b4146104ce5780634df6ca2a146104ef5780634e60f8831461050757806351577ea91461051f578063590158a71461053757806359245ff3146105775780636fa427421461058257806370a08231146105a3578063762c38fd146105c457806377f325df1461063a5780637f8d429e1461064b57806382ffa9f714610677578063839df9451461068f57806383bf4609146106cc5780638d552d4614610725578063924532fb1461073d57806395addb90146107555780639e63fa6a146107d15780639f1025c614610802578063a1130d041461081a578063a462fb7b146108c9578063acae8f4e146108e1578063bc525652146108f9578063d09cc57e146108c9578063d7cff98614610911578063f6a94ecb1461092e578063fe92049d14610955575b600080fd5b3480156101a357600080fd5b5060408051602060046024803582810135848102808701860190975280865261029c96843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375094975061097c9650505050505050565b005b3480156102aa57600080fd5b506102d1600435602435600160a060020a036044351663ffffffff60643516608435610cac565b60408051918252519081900360200190f35b3480156102ef57600080fd5b506102d1600435610ee9565b34801561030757600080fd5b50610313600435610efe565b60408051600160a060020a039092168252519081900360200190f35b34801561033b57600080fd5b506102d1600435610f1c565b34801561035357600080fd5b506040805160206004803580820135838102808601850190965280855261029c95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610f319650505050505050565b3480156104c557600080fd5b5061029c611145565b3480156104da57600080fd5b5061029c6004356024356044356064356111c0565b3480156104fb57600080fd5b5061029c600435611660565b34801561051357600080fd5b506102d16004356116af565b34801561052b57600080fd5b506102d16004356116c1565b34801561054357600080fd5b5061054f6004356116d3565b60408051600160a060020a039094168452602084019290925282820152519081900360600190f35b61029c6004356116fe565b34801561058e57600080fd5b506102d1600160a060020a036004351661195b565b3480156105af57600080fd5b506102d1600160a060020a036004351661196d565b60408051602060046024803582810135601f81018590048502860185019096528585526102d195833595369560449491939091019190819084018382808284375094975050508335600160a060020a03169450505050602081013563ffffffff908116916040810135909116906060013561197f565b61029c600435602435604435611ca3565b34801561065757600080fd5b50610663600435612037565b604080519115158252519081900360200190f35b34801561068357600080fd5b506102d1600435612094565b34801561069b57600080fd5b506106a76004356120a9565b6040805163ffffffff9094168452911515602084015282820152519081900360600190f35b3480156106d857600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102d19436949293602493928401919081908401838280828437509497506120d69650505050505050565b34801561073157600080fd5b506102d1600435612270565b34801561074957600080fd5b50610663600435612286565b34801561076157600080fd5b5061076d60043561229e565b604080519a8b52600160a060020a0390991660208b015263ffffffff9788168a8a015295871660608a015293909516608088015290151560a087015260c086015260e085019290925261010084019190915261012083015251908190036101400190f35b3480156107dd57600080fd5b506107e9600435612309565b6040805163ffffffff9092168252519081900360200190f35b34801561080e57600080fd5b506107e960043561232b565b6040805160206004803580820135601f81018490048402850184019095528484526102d194369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375094975050508335600160a060020a03169450505050602081013563ffffffff908116916040810135909116906060013561234d565b3480156108d557600080fd5b506102d1600435612375565b3480156108ed57600080fd5b506107e96004356123ef565b34801561090557600080fd5b506102d1600435612411565b61029c600435602435604435600160a060020a0360643516612423565b34801561093a57600080fd5b5061029c600435600160a060020a036024351660443561293a565b34801561096157600080fd5b5061029c600435602435600160a060020a0360443516612d10565b60008060008060008060008b61099181612037565b15156109e7576040805160e560020a62461bcd02815260206004820152601a60248201527f7175657374696f6e206d7573742062652066696e616c697a6564000000000000604482015290519081900360640190fd5b8b51600010610a66576040805160e560020a62461bcd02815260206004820152603060248201527f6174206c65617374206f6e6520686973746f7279206861736820656e7472792060448201527f6d7573742062652070726f766964656400000000000000000000000000000000606482015290519081900360840190fd5b60008d815260056020818152604080842080546001820154600290920154600494859052928620948501549490930154600160a060020a039093169c509a509850909650945092505b8b51831015610bcf57610b21858d85815181101515610aca57fe5b906020019060200201518b86815181101515610ae257fe5b906020019060200201518d87815181101515610afa57fe5b906020019060200201518f88815181101515610b1257fe5b90602001906020020151612f34565b9150610b33868863ffffffff61314a16565b9550610b8a8d85888b8f88815181101515610b4a57fe5b906020019060200201518f89815181101515610b6257fe5b906020019060200201518f8a815181101515610b7a57fe5b9060200190602002015189613164565b8b519099509096508a9084908110610b9e57fe5b9060200190602002015196508b83815181101515610bb857fe5b602090810290910101519450600190920191610aaf565b8415610c3a57600160a060020a03881615610bf457610bef8d8988613294565b600095505b60008d8152600560205260409020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038a1617815560018101889055600201869055610c89565b610c548d89610c4f898b63ffffffff61314a16565b613294565b60008d8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff1916815560018101829055600201555b5050506000998a5250600460205260409098206005019790975550505050505050565b600085610cb881612037565b1515610d0e576040805160e560020a62461bcd02815260206004820152601a60248201527f7175657374696f6e206d7573742062652066696e616c697a6564000000000000604482015290519081900360640190fd5b6000878152600460205260409020548614610d73576040805160e560020a62461bcd02815260206004820152601760248201527f636f6e74656e742068617368206d757374206d61746368000000000000000000604482015290519081900360640190fd5b600087815260046020526040902060010154600160a060020a03868116911614610de7576040805160e560020a62461bcd02815260206004820152601560248201527f61726269747261746f72206d757374206d617463680000000000000000000000604482015290519081900360640190fd5b60008781526004602052604090206001015463ffffffff60c060020a90910481169085161115610e61576040805160e560020a62461bcd02815260206004820152601b60248201527f74696d656f7574206d757374206265206c6f6e6720656e6f7567680000000000604482015290519081900360640190fd5b600087815260046020526040902060060154831115610eca576040805160e560020a62461bcd02815260206004820152601860248201527f626f6e64206d757374206265206869676820656e6f7567680000000000000000604482015290519081900360640190fd5b6000878152600460208190526040909120015491505095945050505050565b60009081526004602052604090206003015490565b600090815260046020526040902060010154600160a060020a031690565b60009081526004602052604090206006015490565b60008080806060808080845b8e5189101561112c578e89815181101515610f5457fe5b9060200190602002015196508d89815181101515610f6e57fe5b90602001906020020151955085604051908082528060200260200182016040528015610fa4578160200160208202803883390190505b50945085604051908082528060200260200182016040528015610fd1578160200160208202803883390190505b50935085604051908082528060200260200182016040528015610ffe578160200160208202803883390190505b5092508560405190808252806020026020018201604052801561102b578160200160208202803883390190505b509150600090505b85811015611114578c8881518110151561104957fe5b90602001906020020151858281518110151561106157fe5b602090810290910101528b518c908990811061107957fe5b90602001906020020151848281518110151561109157fe5b600160a060020a039092166020928302909101909101528a518b90899081106110b657fe5b9060200190602002015183828151811015156110ce57fe5b6020908102909101015289518a90899081106110e657fe5b9060200190602002015182828151811015156110fe57fe5b6020908102909101015260019788019701611033565b611121878686868661097c565b600190980197610f3d565b611134611145565b505050505050505050505050505050565b33600081815260208190526040808220805490839055905190929183156108fc02918491818181858888f19350505050158015611186573d6000803e3d6000fd5b5060408051828152905133917f4ce7033d118120e254016dccf195288400b28fc8936425acd5f17ce2df3ab708919081900360200190a250565b600084815260046020526040812060010154819086908290819060c060020a900463ffffffff16811061122b576040805160e560020a62461bcd02815260206004820152601360248201526000805160206138bb833981519152604482015290519081900360640190fd5b60008381526004602052604090206001015460e060020a900463ffffffff16915081158061126457504263ffffffff168263ffffffff16115b15156112e0576040805160e560020a62461bcd02815260206004820152602960248201527f66696e616c697a6174696f6e206465616c696e65206d757374206e6f7420686160448201527f7665207061737365640000000000000000000000000000000000000000000000606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff1680158061131957504263ffffffff168163ffffffff1611155b151561135d576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061393b833981519152604482015290519081900360640190fd5b6040805160208082018b90528183018a9052825180830384018152606090920192839052815191929182918401908083835b602083106113ae5780518252601f19909201916020918201910161138f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209450888587604051602001808460001916600019168152602001836000191660001916815260200182815260200193505050506040516020818303038152906040526040518082805190602001908083835b6020831061144c5780518252601f19909201916020918201910161142d565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120600081815260069092529290205491975050640100000000900460ff161591506115109050576040805160e560020a62461bcd02815260206004820152602a60248201527f636f6d6d69746d656e74206d757374206e6f742068617665206265656e20726560448201527f7665616c65642079657400000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008481526006602052604090205463ffffffff4281169116116115a3576040805160e560020a62461bcd028152602060048201526024808201527f72657665616c20646561646c696e65206d757374206e6f74206861766520706160448201527f7373656400000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6000848152600660208181526040808420600181018d9055805464ff0000000019166401000000001790558c84526004909152909120015486141561160e5760008981526004602052604090206001015461160e908a908a9060c060020a900463ffffffff16613315565b60408051898152602081018990528082018890529051869133918c917fa7b2d313bc7a062e30b2c3b811aa4c9faf09755a6b4ea3bf42deff920944332f919081900360600190a4505050505050505050565b336000818152600760209081526040918290208490558151928352820183905280517fdca703d022171824d3d639b33c1525fd2338120b4cfb89507c0b59596893acda9281900390910190a150565b60036020526000908152604090205481565b60009081526004602052604090205490565b600560205260009081526040902080546001820154600290920154600160a060020a03909116919083565b600081815260046020526040812060010154829190819060c060020a900463ffffffff168110611766576040805160e560020a62461bcd02815260206004820152601360248201526000805160206138bb833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff16156117d2576040805160e560020a62461bcd02815260206004820152602860248201526000805160206138fb83398151915260448201526000805160206138db833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff16915081158061180b57504263ffffffff168263ffffffff16115b1515611863576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061391b833981519152604482015260008051602061395b833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff1680158061189c57504263ffffffff168163ffffffff1611155b15156118e0576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061393b833981519152604482015290519081900360640190fd5b600084815260046020526040902060030154611902903463ffffffff61314a16565b6000858152600460209081526040918290206003018390558151348152908101929092528051339287927f54d68405b79f2aa4fd4e8db7b67844ad254cf8f208aac476c2894134a9deab6692918290030190a350505050565b60076020526000908152604090205481565b60006020819052908152604090205481565b6000868152600260205260408120548190819081106119e8576040805160e560020a62461bcd02815260206004820152601360248201527f74656d706c617465206d75737420657869737400000000000000000000000000604482015290519081900360640190fd5b888589604051602001808481526020018363ffffffff1663ffffffff1660e060020a02815260040182805190602001908083835b60208310611a3b5780518252601f199092019160209182019101611a1c565b6001836020036101000a03801982511681845116808217855250505050505090500193505050506040516020818303038152906040526040518082805190602001908083835b60208310611aa05780518252601f199092019160209182019101611a81565b51815160209384036101000a600019018019909216911617905260408051929094018290038220828201819052600160a060020a038e166c010000000000000000000000009081028487015263ffffffff8e1660e060020a02605485015233026058840152606c8084018c905285518085039091018152608c9093019485905282519098509195509293508392850191508083835b60208310611b545780518252601f199092019160209182019101611b35565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209050611b90818389898961338c565b816000191633600160a060020a031682600019167ffe2dac156a3890636ce13f65f4fdf41dcaee11526e4a5374531572d92194796c8c8c8c8c8c8c42604051808881526020018060200187600160a060020a0316600160a060020a031681526020018663ffffffff1663ffffffff1681526020018563ffffffff1663ffffffff168152602001848152602001838152602001828103825288818151815260200191508051906020019080838360005b83811015611c57578181015183820152602001611c3f565b50505050905090810190601f168015611c845780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390a498975050505050505050565b600083815260046020526040812060010154849190819060c060020a900463ffffffff168110611d0b576040805160e560020a62461bcd02815260206004820152601360248201526000805160206138bb833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff1615611d77576040805160e560020a62461bcd02815260206004820152602860248201526000805160206138fb83398151915260448201526000805160206138db833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff169150811580611db057504263ffffffff168263ffffffff16115b1515611e08576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061391b833981519152604482015260008051602061395b833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff16801580611e4157504263ffffffff168163ffffffff1611155b1515611e85576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061393b833981519152604482015290519081900360640190fd5b8560003411611ede576040805160e560020a62461bcd02815260206004820152601560248201527f626f6e64206d75737420626520706f7369746976650000000000000000000000604482015290519081900360640190fd5b600081815260046020526040902060060154611f0190600263ffffffff6136ed16565b341015611f7e576040805160e560020a62461bcd02815260206004820152602a60248201527f626f6e64206d75737420626520646f75626c65206174206c656173742070726560448201527f76696f757320626f6e6400000000000000000000000000000000000000000000606482015290519081900360840190fd5b86856000811115611ff257600082815260046020526040902060060154811015611ff2576040805160e560020a62461bcd02815260206004820152601d60248201527f626f6e64206d75737420657863656564206d61785f70726576696f7573000000604482015290519081900360640190fd5b612000898933346000613718565b60008981526004602052604090206001015461202c908a908a9060c060020a900463ffffffff16613315565b505050505050505050565b6000818152600460205260408120600181015460029091015460e060020a90910463ffffffff169060ff161580156120755750600063ffffffff8216115b801561208d57504263ffffffff168163ffffffff1611155b9392505050565b60009081526004602052604090206005015490565b6006602052600090815260409020805460019091015463ffffffff821691640100000000900460ff169083565b60015460008181526002602090815260408083204390555184519293928592918201918291908401908083835b602083106121225780518252601f199092019160209182019101612103565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b602083106121855780518252601f199092019160209182019101612166565b51815160209384036101000a6000190180199092169116179052604080519290940182900382206000888152600383528581209190915581835289518383015289513397508896507fb87fb721c0a557bb8dff89a86796466931d82ba530a66a239263eb8735ade2e4958b955084939084019290860191908190849084905b8381101561221c578181015183820152602001612204565b50505050905090810190601f1680156122495780820380516001836020036101000a031916815260200191505b509250505060405180910390a361226781600163ffffffff61314a16565b60015592915050565b6000908152600460208190526040909120015490565b60009081526004602052604090206002015460ff1690565b600460208190526000918252604090912080546001820154600283015460038401549484015460058501546006909501549395600160a060020a0384169563ffffffff60a060020a860481169660c060020a870482169660e060020a90049091169460ff169391908a565b60009081526004602052604090206001015460a060020a900463ffffffff1690565b60009081526004602052604090206001015460c060020a900463ffffffff1690565b600080612359886120d6565b905061236981888888888861197f565b98975050505050505050565b60008161238181612037565b15156123d7576040805160e560020a62461bcd02815260206004820152601a60248201527f7175657374696f6e206d7573742062652066696e616c697a6564000000000000604482015290519081900360640190fd5b50506000908152600460208190526040909120015490565b60009081526004602052604090206001015460e060020a900463ffffffff1690565b60026020526000908152604090205481565b6000848152600460205260408120600101548190819087908290819060c060020a900463ffffffff168110612490576040805160e560020a62461bcd02815260206004820152601360248201526000805160206138bb833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff16156124fc576040805160e560020a62461bcd02815260206004820152602860248201526000805160206138fb83398151915260448201526000805160206138db833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff16915081158061253557504263ffffffff168263ffffffff16115b151561258d576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061391b833981519152604482015260008051602061395b833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff168015806125c657504263ffffffff168163ffffffff1611155b151561260a576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061393b833981519152604482015290519081900360640190fd5b8960003411612663576040805160e560020a62461bcd02815260206004820152601560248201527f626f6e64206d75737420626520706f7369746976650000000000000000000000604482015290519081900360640190fd5b60008181526004602052604090206006015461268690600263ffffffff6136ed16565b341015612703576040805160e560020a62461bcd02815260206004820152602a60248201527f626f6e64206d75737420626520646f75626c65206174206c656173742070726560448201527f76696f757320626f6e6400000000000000000000000000000000000000000000606482015290519081900360840190fd5b8a89600081111561277757600082815260046020526040902060060154811015612777576040805160e560020a62461bcd02815260206004820152601d60248201527f626f6e64206d75737420657863656564206d61785f70726576696f7573000000604482015290519081900360640190fd5b8c8c34604051602001808460001916600019168152602001836000191660001916815260200182815260200193505050506040516020818303038152906040526040518082805190602001908083835b602083106127e65780518252601f1990920191602091820191016127c7565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209b50505050600160a060020a038a1615612829578961282b565b335b60008a81526006602052604090205490985063ffffffff16156128be576040805160e560020a62461bcd02815260206004820152602160248201527f636f6d6d69746d656e74206d757374206e6f7420616c7265616479206578697360448201527f7400000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008d81526004602052604090206001015460089060c060020a900463ffffffff160496506128f763ffffffff42811690899061389016565b60008a8152600660205260409020805463ffffffff191663ffffffff9290921691909117905561292b8d8a8a346001613718565b50505050505050505050505050565b6000838152600460205260409020600101548390600160a060020a031633146129ad576040805160e560020a62461bcd02815260206004820152601d60248201527f6d73672e73656e646572206d7573742062652061726269747261746f72000000604482015290519081900360640190fd5b600084815260046020526040812060010154859190819060c060020a900463ffffffff168110612a15576040805160e560020a62461bcd02815260206004820152601360248201526000805160206138bb833981519152604482015290519081900360640190fd5b60008381526004602052604090206002015460ff1615612a81576040805160e560020a62461bcd02815260206004820152602860248201526000805160206138fb83398151915260448201526000805160206138db833981519152606482015290519081900360840190fd5b60008381526004602052604090206001015460e060020a900463ffffffff169150811580612aba57504263ffffffff168263ffffffff16115b1515612b12576040805160e560020a62461bcd02815260206004820152602a602482015260008051602061391b833981519152604482015260008051602061395b833981519152606482015290519081900360840190fd5b5060008281526004602052604090206001015460a060020a900463ffffffff16801580612b4b57504263ffffffff168163ffffffff1611155b1515612b8f576040805160e560020a62461bcd02815260206004820152601d602482015260008051602061393b833981519152604482015290519081900360640190fd5b86856000811115612c0357600082815260046020526040902060060154811015612c03576040805160e560020a62461bcd02815260206004820152601d60248201527f626f6e64206d75737420657863656564206d61785f70726576696f7573000000604482015290519081900360640190fd5b60008981526004602052604081206006015411612cb6576040805160e560020a62461bcd02815260206004820152604260248201527f5175657374696f6e206d75737420616c7265616479206861766520616e20616e60448201527f73776572207768656e206172626974726174696f6e206973207265717565737460648201527f6564000000000000000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b600089815260046020526040808220600201805460ff1916600117905551600160a060020a038a16918b917f75d7939999bc902187c4aed400872883e445145f1983539166f783fa040b47629190a3505050505050505050565b6000838152600460205260409020600101548390600160a060020a03163314612d83576040805160e560020a62461bcd02815260206004820152601d60248201527f6d73672e73656e646572206d7573742062652061726269747261746f72000000604482015290519081900360640190fd5b600084815260046020526040902060020154849060ff161515612e15576040805160e560020a62461bcd028152602060048201526024808201527f7175657374696f6e206d7573742062652070656e64696e67206172626974726160448201527f74696f6e00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b3415612e6b576040805160e560020a62461bcd02815260206004820152601160248201527f626f6e64206d757374206265207a65726f000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0383161515612ecb576040805160e560020a62461bcd02815260206004820152601960248201527f616e737765726572206d7573742062652070726f766964656400000000000000604482015290519081900360640190fd5b604051849086907f18d760beffe3717270cd90d9d920ec1a48c194e9ad7bba23eb1c92d3eb974f9790600090a36000858152600460205260408120600201805460ff19169055612f219086908690869080613718565b612f2d85856000613315565b5050505050565b604080516020808201879052818301869052606082018590526c01000000000000000000000000600160a060020a0385160260808301527f01000000000000000000000000000000000000000000000000000000000000006094830152825160758184030181526095909201928390528151600093918291908401908083835b60208310612fd35780518252601f199092019160209182019101612fb4565b5181516020939093036101000a60001901801990911692169190911790526040519201829003909120891415925061301091505057506001613141565b604080516020808201889052818301879052606082018690526c01000000000000000000000000600160a060020a0386160260808301526000609483015282516075818403018152609590920192839052815191929182918401908083835b6020831061308e5780518252601f19909201916020918201910161306f565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912089141592506130cb91505057506000613141565b6040805160e560020a62461bcd02815260206004820152603660248201527f486973746f727920696e7075742070726f766964656420646964206e6f74206d60448201527f6174636820746865206578706563746564206861736800000000000000000000606482015290519081900360840190fd5b95945050505050565b60008282018381101561315957fe5b8091505b5092915050565b60008060008084156131e457600086815260066020526040902054869250640100000000900460ff1615156131bc576000828152600660205260408120805464ffffffffff1916815560010155899350889250613285565b6000828152600660205260408120600181018054825464ffffffffff19169092559190915595505b858b141561327e57600160a060020a038916151561323d5760008c8152600460205260409020600301549798508897613224908b9063ffffffff61314a16565b60008d815260046020526040812060030155995061327e565b600160a060020a03888116908a161461327e57868a101561325e5789613260565b865b90506132778c8a610c4f8d8563ffffffff6138a816565b8798508099505b8989935093505b50509850989650505050505050565b600160a060020a0382166000908152602081905260409020546132bd908263ffffffff61314a16565b600160a060020a038316600081815260208181526040918290209390935580518481529051919286927f9c121aff33b50c1a53fef034ebec5f83da2d5a5187048f9c76c397ba27c1a1a69281900390910190a3505050565b60008381526004602081905260409091200182905561333e63ffffffff42811690839061389016565b600093845260046020526040909320600101805463ffffffff9490941660e060020a027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909416939093179092555050565b6000858152600460205260408120600101548190879060c060020a900463ffffffff1615613404576040805160e560020a62461bcd02815260206004820152601760248201527f7175657374696f6e206d757374206e6f74206578697374000000000000000000604482015290519081900360640190fd5b600063ffffffff861611613462576040805160e560020a62461bcd02815260206004820152601860248201527f74696d656f7574206d75737420626520706f7369746976650000000000000000604482015290519081900360640190fd5b6301e1338063ffffffff8616106134e9576040805160e560020a62461bcd02815260206004820152602260248201527f74696d656f7574206d757374206265206c657373207468616e2033363520646160448201527f7973000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0386161515613549576040805160e560020a62461bcd02815260206004820152601660248201527f61726269747261746f72206d7573742062652073657400000000000000000000604482015290519081900360640190fd5b34925033600160a060020a0387161461364a57600160a060020a0386166000908152600760205260409020549150818310156135f4576040805160e560020a62461bcd028152602060048201526024808201527f4554482070726f7669646564206d75737420636f766572207175657374696f6e60448201527f2066656500000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b613604838363ffffffff6138a816565b600160a060020a038716600090815260208190526040902054909350613630908363ffffffff61314a16565b600160a060020a0387166000908152602081905260409020555b505060009586526004602052604090952093845560018401805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03949094169390931777ffffffff0000000000000000000000000000000000000000191660a060020a63ffffffff92831602177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1660c060020a929091169190910217905560030155565b600080831515613700576000915061315d565b5082820282848281151561371057fe5b041461315957fe5b600085815260046020908152604080832060050154815180840191909152808201889052606081018690526c01000000000000000000000000600160a060020a0388160260808201527f010000000000000000000000000000000000000000000000000000000000000085151502609482015281516075818303018152609590910191829052805190928291908401908083835b602083106137cb5780518252601f1990920191602091820191016137ac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905060008311156138185760008681526004602052604090206006018390555b600086815260046020908152604091829020600501839055815187815290810183905280820185905242606082015283151560808201529051600160a060020a0386169188917fe47ca4ebbbc2990134d1168821f38c5e177f3d5ee564bffeadeaa351905e62219181900360a00190a3505050505050565b600082820163ffffffff808516908216101561315957fe5b6000828211156138b457fe5b5090039056007175657374696f6e206d757374206578697374000000000000000000000000006974726174696f6e0000000000000000000000000000000000000000000000007175657374696f6e206d757374206e6f742062652070656e64696e672061726266696e616c697a6174696f6e20646561646c696e65206d757374206e6f7420686f70656e696e672064617465206d7573742068617665207061737365640000006176652070617373656400000000000000000000000000000000000000000000a165627a7a72305820e7af9378240e218241c6138a31e3e3b63a25874b9949b4e903f6f855bfc899100029" -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/realitio/contract.py b/trader_old/vendor/valory/contracts/realitio/contract.py deleted file mode 100644 index b04dca8fd..000000000 --- a/trader_old/vendor/valory/contracts/realitio/contract.py +++ /dev/null @@ -1,428 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the Realitio_v2_1 contract definition.""" -import concurrent.futures -import logging -from typing import List, Tuple, Union, Dict, Callable, Any - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from eth_typing import ChecksumAddress -from requests.exceptions import ReadTimeout as RequestsReadTimeoutError -from urllib3.exceptions import ReadTimeoutError as Urllib3ReadTimeoutError -from web3.exceptions import ContractLogicError -from web3.types import BlockIdentifier - - -ClaimParamsType = Tuple[ - List[bytes], List[ChecksumAddress], List[int], List[bytes] -] - -FIVE_MINUTES = 300.0 - -PUBLIC_ID = PublicId.from_str("valory/realitio:0.1.0") -_logger = logging.getLogger( - f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" -) - -MARKET_FEE = 2.0 -UNIT_SEPARATOR = chr(9247) - - -def format_answers(answers: List[str]) -> str: - """Format answers.""" - return ",".join(map(lambda x: '"' + x + '"', answers)) - - -def build_question(question_data: Dict) -> str: - """Build question.""" - return UNIT_SEPARATOR.join( - [ - question_data["question"], - format_answers(question_data["answers"]), - question_data["topic"], - question_data["language"], - ] - ) - - -class RealitioContract(Contract): - """The Realitio_v2_1 smart contract.""" - - contract_id = PUBLIC_ID - - @staticmethod - def execute_with_timeout(func: Callable, timeout: float) -> Any: - """Execute a function with a timeout.""" - - # Create a ProcessPoolExecutor with a maximum of 1 worker (process) - with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: - # Submit the function to the executor - future = executor.submit( - func, - ) - - try: - # Wait for the result with a 5-minute timeout - data = future.result(timeout=timeout) - except TimeoutError: - # Handle the case where the execution times out - err = f"The RPC didn't respond in {timeout}." - return None, err - - # Check if an error occurred - if isinstance(data, str): - # Handle the case where the execution failed - return None, data - - return data, None - - @classmethod - def check_finalized( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: bytes, - ) -> JSONLike: - """Check whether a market has been finalized.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - is_finalized = contract_instance.functions.isFinalized(question_id).call() - return dict(finalized=is_finalized) - - @classmethod - def get_claim_params( - cls, - ledger_api: LedgerApi, - contract_address: str, - from_block: int, - to_block: int, - question_id: bytes, - timeout: float = FIVE_MINUTES, - ) -> Dict[str, Union[str, list]]: - """Filters the `LogNewAnswer` event by question id to calculate the history hashes.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - - def get_claim_params() -> Any: - """Get claim params.""" - try: - answer_filter = contract_instance.events.LogNewAnswer.build_filter() - answer_filter.fromBlock = from_block - answer_filter.toBlock = to_block - answer_filter.args.question_id.match_single(question_id) - answered = list(answer_filter.deploy(ledger_api.api).get_all_entries()) - return answered - except (Urllib3ReadTimeoutError, RequestsReadTimeoutError): - msg = ( - "The RPC timed out! This usually happens if the filtering is too wide. " - f"The service tried to filter from block {from_block} to {to_block}. " - f"If this issue persists, please try lowering the `EVENT_FILTERING_BATCH_SIZE`!" - ) - return msg - - answered, err = cls.execute_with_timeout(get_claim_params, timeout=timeout) - if err is not None: - return dict(error=err) - - msg = ( - f"Found {len(answered)} answer(s) for question with id {question_id.hex()} " - f"between blocks {from_block} and {to_block}." - ) - return dict(info=msg, answered=answered) - - @classmethod - def build_claim_winnings( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: bytes, - claim_params: ClaimParamsType, - ) -> JSONLike: - """Build `claimWinnings` transaction.""" - contract = cls.get_instance(ledger_api, contract_address) - data = contract.encodeABI( - fn_name="claimWinnings", - args=(question_id, *claim_params), - ) - return dict(data=data) - - @classmethod - def simulate_claim_winnings( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: bytes, - claim_params: ClaimParamsType, - sender_address: str, - ) -> JSONLike: - """Simulate `claimWinnings` transaction.""" - data = cls.build_claim_winnings(ledger_api, contract_address, question_id, claim_params)["data"] - try: - ledger_api.api.eth.call( - { - "from": ledger_api.api.to_checksum_address(sender_address), - "to": ledger_api.api.to_checksum_address(contract_address), - "data": data[2:], - } - ) - simulation_ok = True - except (ValueError, ContractLogicError) as e: - _logger.info(f"Simulation failed: {str(e)}") - simulation_ok = False - return dict(data=simulation_ok) - - @classmethod - def get_history_hash( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: bytes, - ) -> JSONLike: - """Get history hash for a question""" - contract = cls.get_instance(ledger_api, contract_address) - data = contract.functions.getHistoryHash(question_id).call() - return dict(data=data) - - @classmethod - def get_raw_transaction( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> JSONLike: - """ - Handler method for the 'GET_RAW_TRANSACTION' requests. - - Implement this method in the sub class if you want - to handle the contract requests manually. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param kwargs: the keyword arguments. - :return: the tx # noqa: DAR202 - """ - raise NotImplementedError - - @classmethod - def get_raw_message( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> bytes: - """ - Handler method for the 'GET_RAW_MESSAGE' requests. - - Implement this method in the sub class if you want - to handle the contract requests manually. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param kwargs: the keyword arguments. - :return: the tx # noqa: DAR202 - """ - raise NotImplementedError - - @classmethod - def get_state( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> JSONLike: - """ - Handler method for the 'GET_STATE' requests. - - Implement this method in the sub class if you want - to handle the contract requests manually. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param kwargs: the keyword arguments. - :return: the tx # noqa: DAR202 - """ - raise NotImplementedError - - @classmethod - def get_ask_question_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_data: Dict, - opening_timestamp: int, - timeout: int, - arbitrator_contract: str, - template_id: int = 2, - question_nonce: int = 0, - ) -> JSONLike: - """Get ask question transaction.""" - question = build_question(question_data=question_data) - kwargs = { - "template_id": template_id, - "question": question, - "arbitrator": ledger_api.api.to_checksum_address(arbitrator_contract), - "timeout": timeout, - "opening_ts": opening_timestamp, - "nonce": question_nonce, - } - return ledger_api.build_transaction( - contract_instance=cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ), - method_name="askQuestion", - method_args=kwargs, - ) - - @classmethod - def get_ask_question_tx_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_data: Dict, - opening_timestamp: int, - timeout: int, - arbitrator_contract: str, - template_id: int = 2, - question_nonce: int = 0, - ) -> JSONLike: - """Get ask question transaction.""" - question = build_question(question_data=question_data) - kwargs = { - "template_id": template_id, - "question": question, - "arbitrator": ledger_api.api.to_checksum_address(arbitrator_contract), - "timeout": timeout, - "opening_ts": opening_timestamp, - "nonce": question_nonce, - } - contract_instance = cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - data = contract_instance.encodeABI(fn_name="askQuestion", kwargs=kwargs) - return {"data": bytes.fromhex(data[2:])} # type: ignore - - @classmethod - def calculate_question_id( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_data: Dict, - opening_timestamp: int, - timeout: int, - arbitrator_contract: str, - sender: str, - template_id: int = 2, - question_nonce: int = 0, - ) -> JSONLike: - """Get ask question transaction.""" - question = build_question(question_data=question_data) - content_hash = ledger_api.api.solidity_keccak( - ["uint256", "uint32", "string"], - [template_id, opening_timestamp, question], - ) - question_id = ledger_api.api.solidity_keccak( - ["bytes32", "address", "uint32", "address", "uint256"], - [ - content_hash, - ledger_api.api.to_checksum_address(arbitrator_contract), - timeout, - ledger_api.api.to_checksum_address(sender), - question_nonce, - ], - ) - return {"question_id": question_id.hex()} - - @classmethod - def get_question_events( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_ids: List[bytes], - from_block: BlockIdentifier = "earliest", - to_block: BlockIdentifier = "latest", - ) -> JSONLike: - """Get questions.""" - # TODO: consider using multicall2 or constructor trick instead of filters - contract = cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - entries = contract.events.LogNewQuestion.create_filter( - fromBlock=from_block, - toBlock=to_block, - argument_filters=dict(question_id=question_ids), - ).get_all_entries() - events = list( - dict( - tx_hash=entry.transactionHash.hex(), - block_number=entry.blockNumber, - question_id=entry["args"]["question_id"], - user=entry["args"]["user"], - template_id=entry["args"]["template_id"], - question=entry["args"]["question"], - content_hash=entry["args"]["content_hash"], - arbitrator=entry["args"]["arbitrator"], - timeout=entry["args"]["timeout"], - opening_ts=entry["args"]["opening_ts"], - nonce=entry["args"]["nonce"], - created=entry["args"]["created"], - ) - for entry in entries - ) - return dict(data=events) - - @classmethod - def get_submit_answer_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: bytes, - answer: bytes, - max_previous: int, - ) -> JSONLike: - """Get submit answer transaction.""" - contract = cls.get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - data = contract.encodeABI( - fn_name="submitAnswer", - args=[ - question_id, - answer, - max_previous, - ], - ) - return dict(data=data) - - @classmethod - def balance_of( - cls, - ledger_api: LedgerApi, - contract_address: str, - address: str, - ) -> JSONLike: - """Get balance for an address""" - contract = cls.get_instance(ledger_api, contract_address) - data = contract.functions.balanceOf(address).call() - return dict(data=data) - - @classmethod - def build_withdraw_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Build `withdraw` transaction.""" - contract = cls.get_instance(ledger_api, contract_address) - data = contract.encodeABI( - fn_name="withdraw", - ) - return dict(data=data) diff --git a/trader_old/vendor/valory/contracts/realitio/contract.yaml b/trader_old/vendor/valory/contracts/realitio/contract.yaml deleted file mode 100644 index beb6290ca..000000000 --- a/trader_old/vendor/valory/contracts/realitio/contract.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: realitio -author: valory -version: 0.1.0 -type: contract -description: Realitio_v2_1 contract. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeictahkgfmlqv5kksvj6klmxtmjdpeq4sp3x7dp2yr5x4kmzbcihse - build/Realitio.json: bafybeiagi7zoeoy5s7duhg4oeuekj2s6z5mad2z6g2pn3n5elsvze25qiu - contract.py: bafybeih7u7cpfqn3htwribajjfhka6ilhww7lx4w5qqls6b3gxevaevfoa -fingerprint_ignore_patterns: [] -class_name: RealitioContract -contract_interface_paths: - ethereum: build/Realitio.json -dependencies: - eth_typing: {} - hexbytes: {} - web3: - version: <7,>=6.0.0 - requests: - version: ==2.28.1 - urllib3: - version: ==1.26.16 -contracts: [] diff --git a/trader_old/vendor/valory/contracts/realitio_proxy/__init__.py b/trader_old/vendor/valory/contracts/realitio_proxy/__init__.py deleted file mode 100644 index 7b0d92450..000000000 --- a/trader_old/vendor/valory/contracts/realitio_proxy/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for the RealitioProxy contract.""" diff --git a/trader_old/vendor/valory/contracts/realitio_proxy/build/Realitio.json b/trader_old/vendor/valory/contracts/realitio_proxy/build/Realitio.json deleted file mode 100644 index 66c972926..000000000 --- a/trader_old/vendor/valory/contracts/realitio_proxy/build/Realitio.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "abi": [ - { - "inputs": [ - { - "internalType": "contract IConditionalTokens", - "name": "_conditionalTokens", - "type": "address" - }, - { - "internalType": "contract IRealitio", - "name": "_realitio", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nuancedBinaryTemplateId", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "constant": true, - "inputs": [], - "name": "conditionalTokens", - "outputs": [ - { - "internalType": "contract IConditionalTokens", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "nuancedBinaryTemplateId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "realitio", - "outputs": [ - { - "internalType": "contract IRealitio", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "bytes32", - "name": "questionId", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "templateId", - "type": "uint256" - }, - { - "internalType": "string", - "name": "question", - "type": "string" - }, - { - "internalType": "uint256", - "name": "numOutcomes", - "type": "uint256" - } - ], - "name": "resolve", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "608060405234801561001057600080fd5b50604051610b3a380380610b3a8339818101604052606081101561003357600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600281905550505050610a48806100f26000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80635bd9e29914610051578063bc8802a21461009b578063d41f2556146100e5578063dbc0e6351461017c575b600080fd5b61005961019a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100a36101bf565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61017a600480360360808110156100fb57600080fd5b8101908080359060200190929190803590602001909291908035906020019064010000000081111561012c57600080fd5b82018360208201111561013e57600080fd5b8035906020019184600183028401116401000000008311171561016057600080fd5b9091929391929390803590602001909291905050506101e5565b005b610184610596565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600084600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639e63fa6a886040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561025b57600080fd5b505afa15801561026f573d6000803e3d6000fd5b505050506040513d602081101561028557600080fd5b81019080805190602001909291905050508585604051602001808581526020018463ffffffff1663ffffffff1660e01b815260040183838082843780830192505050945050505050604051602081830303815290604052805190602001209050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166351577ea9876040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561035857600080fd5b505afa15801561036c573d6000803e3d6000fd5b505050506040513d602081101561038257600080fd5b81019080805190602001909291905050508114610407576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f436f6e74656e742068617368206d69736d61746368000000000000000000000081525060200191505060405180910390fd5b606060008614806104185750600286145b1561042e57610427878461059c565b90506104b8565b600254861415610449576104428784610767565b90506104b7565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f556e6b6e6f776e2074656d706c6174654964000000000000000000000000000081525060200191505060405180910390fd5b5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c49298ac88836040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019060200280838360005b8381101561054f578082015181840152602081019050610534565b505050509050019350505050600060405180830381600087803b15801561057557600080fd5b505af1158015610589573d6000803e3d6000fd5b5050505050505050505050565b60025481565b606080826040519080825280602002602001820160405280156105ce5781602001602082028038833980820191505090505b5090506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d09cc57e866040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561064657600080fd5b505afa15801561065a573d6000803e3d6000fd5b505050506040513d602081101561067057600080fd5b810190808051906020019092919050505060001c90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114156106e95760008090505b848110156106e35760018382815181106106ca57fe5b60200260200101818152505080806001019150506106b4565b5061075c565b838110610741576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806109ec6028913960400191505060405180910390fd5b600182828151811061074f57fe5b6020026020010181815250505b819250505092915050565b6060600282146107c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806109c96023913960400191505060405180910390fd5b606060026040519080825280602002602001820160405280156107f45781602001602082028038833980820191505090505b5090506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d09cc57e866040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561086c57600080fd5b505afa158015610880573d6000803e3d6000fd5b505050506040513d602081101561089657600080fd5b810190808051906020019092919050505060001c90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81141561090f576001826000815181106108e357fe5b6020026020010181815250506001826001815181106108fe57fe5b6020026020010181815250506109bd565b60058110610985576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f416e73776572206d757374206265206265747765656e203020616e642034000081525060200191505060405180910390fd5b806004038260008151811061099657fe5b60200260200101818152505080826001815181106109b057fe5b6020026020010181815250505b81925050509291505056fe4e756d626572206f66206f7574636f6d657320657870656374656420746f2062652032416e73776572206d757374206265206265747765656e203020616e64206e756d4f7574636f6d6573a265627a7a72315820abd52a8d5d3ccb67c384524197507ac525c640d009250c3a5e4721fd1a7b6ef864736f6c634300050c0032000000000000000000000000ceafdd6bc0bef976fdcd1112955828e00543c0ce00000000000000000000000079e32ae03fb27b07c89c0c568f80287c01ca2e570000000000000000000000000000000000000000000000000000000000000005" -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/realitio_proxy/contract.py b/trader_old/vendor/valory/contracts/realitio_proxy/contract.py deleted file mode 100644 index c7f40aec9..000000000 --- a/trader_old/vendor/valory/contracts/realitio_proxy/contract.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- 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 the realitio proxy contract definition.""" - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi - - -class RealitioProxyContract(Contract): - """The RealitioProxy smart contract.""" - - contract_id = PublicId.from_str("valory/realitio_proxy:0.1.0") - - @classmethod - def build_resolve_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - question_id: bytes, - template_id: int, - question: str, - num_outcomes: int, - ) -> JSONLike: - """Build a `resolve` tx.""" - contract = cls.get_instance(ledger_api, contract_address) - data = contract.encodeABI( - fn_name="resolve", - args=[ - question_id, - template_id, - question, - num_outcomes, - ], - ) - return dict(data=data) diff --git a/trader_old/vendor/valory/contracts/realitio_proxy/contract.yaml b/trader_old/vendor/valory/contracts/realitio_proxy/contract.yaml deleted file mode 100644 index 3adbb2eea..000000000 --- a/trader_old/vendor/valory/contracts/realitio_proxy/contract.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: realitio_proxy -author: valory -version: 0.1.0 -type: contract -description: RealitioProxy contract. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeickfnpykdx2ffgrrza6yhn7gfr2plis354oohzljhlnpwnp4kpe2u - build/Realitio.json: bafybeiaqw4aid7mitc4vfzhlcxhbncei4hd3ywok2ugzs3zkhcx3pliatm - contract.py: bafybeidcouc7xpdcntmzi5dgv5qwnp23dmctdzvof7kwsmzsk27iguaa2e -fingerprint_ignore_patterns: [] -class_name: RealitioProxyContract -contract_interface_paths: - ethereum: build/Realitio.json -dependencies: - web3: - version: <7,>=6.0.0 -contracts: [] diff --git a/trader_old/vendor/valory/contracts/service_registry/__init__.py b/trader_old/vendor/valory/contracts/service_registry/__init__.py deleted file mode 100644 index d616d9211..000000000 --- a/trader_old/vendor/valory/contracts/service_registry/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 the support resources for the service registry contract.""" diff --git a/trader_old/vendor/valory/contracts/service_registry/build/ServiceRegistry.json b/trader_old/vendor/valory/contracts/service_registry/build/ServiceRegistry.json deleted file mode 100644 index cfb4e9391..000000000 --- a/trader_old/vendor/valory/contracts/service_registry/build/ServiceRegistry.json +++ /dev/null @@ -1,1988 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ServiceRegistry", - "sourceName": "contracts/ServiceRegistry.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - }, - { - "internalType": "string", - "name": "_baseURI", - "type": "string" - }, - { - "internalType": "address", - "name": "_agentRegistry", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "AgentInstanceRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentInstancesSlotsFilled", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "AgentNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentNotInService", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "componentId", - "type": "uint256" - } - ], - "name": "ComponentNotFound", - "type": "error" - }, - { - "inputs": [], - "name": "HashExists", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectAgentBondingValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectRegistrationDepositValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "provided", - "type": "address" - }, - { - "internalType": "address", - "name": "expected", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OnlyOwnServiceMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorHasNoInstances", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "Overflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerOnly", - "type": "error" - }, - { - "inputs": [], - "name": "Paused", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrancyGuard", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceMustBeInactive", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "TransferFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "UnauthorizedMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "WrongAgentId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "numValues1", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numValues2", - "type": "uint256" - } - ], - "name": "WrongArrayLength", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongOperator", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "state", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceState", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "currentThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxThreshold", - "type": "uint256" - } - ], - "name": "WrongThreshold", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ActivateRegistration", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "string", - "name": "baseURI", - "type": "string" - } - ], - "name": "BaseURIChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "CreateMultisigWithAgents", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "CreateService", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "DeployService", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "drainer", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Drain", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "drainer", - "type": "address" - } - ], - "name": "DrainerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorSlashed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorUnbond", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "receiver", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Refund", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "agentInstance", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "RegisterInstance", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "TerminateService", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - } - ], - "name": "UpdateService", - "type": "event" - }, - { - "inputs": [], - "name": "CID_PREFIX", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "activateRegistration", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "agentRegistry", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newDrainer", - "type": "address" - } - ], - "name": "changeDrainer", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newManager", - "type": "address" - } - ], - "name": "changeManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "bool", - "name": "permission", - "type": "bool" - } - ], - "name": "changeMultisigPermission", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "changeOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "internalType": "struct AgentParams[]", - "name": "agentParams", - "type": "tuple[]" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - } - ], - "name": "create", - "outputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "multisigImplementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "deploy", - "outputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "drain", - "outputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "drainer", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "name": "exists", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getAgentInstances", - "outputs": [ - { - "internalType": "uint256", - "name": "numAgentInstances", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getAgentParams", - "outputs": [ - { - "internalType": "uint256", - "name": "numAgentIds", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "internalType": "struct AgentParams[]", - "name": "agentParams", - "type": "tuple[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "getInstancesForAgentId", - "outputs": [ - { - "internalType": "uint256", - "name": "numAgentInstances", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getOperatorBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getPreviousHashes", - "outputs": [ - { - "internalType": "uint256", - "name": "numHashes", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "configHashes", - "type": "bytes32[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getService", - "outputs": [ - { - "components": [ - { - "internalType": "uint96", - "name": "securityDeposit", - "type": "uint96" - }, - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "maxNumAgentInstances", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "numAgentInstances", - "type": "uint32" - }, - { - "internalType": "enum ServiceRegistry.ServiceState", - "name": "state", - "type": "uint8" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - } - ], - "internalType": "struct ServiceRegistry.Service", - "name": "service", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "enum IRegistry.UnitType", - "name": "unitType", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getUnitIdsOfService", - "outputs": [ - { - "internalType": "uint256", - "name": "numUnitIds", - "type": "uint256" - }, - { - "internalType": "uint32[]", - "name": "unitIds", - "type": "uint32[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "manager", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapAgentInstanceOperators", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapConfigHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapMultisigs", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapOperatorAndServiceIdAgentInstances", - "outputs": [ - { - "internalType": "address", - "name": "instance", - "type": "address" - }, - { - "internalType": "uint32", - "name": "agentId", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapOperatorAndServiceIdOperatorBalances", - "outputs": [ - { - "internalType": "uint96", - "name": "", - "type": "uint96" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceAndAgentIdAgentInstances", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceAndAgentIdAgentParams", - "outputs": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceIdSetAgentIds", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceIdSetComponentIds", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServices", - "outputs": [ - { - "internalType": "uint96", - "name": "securityDeposit", - "type": "uint96" - }, - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "maxNumAgentInstances", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "numAgentInstances", - "type": "uint32" - }, - { - "internalType": "enum ServiceRegistry.ServiceState", - "name": "state", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - } - ], - "name": "registerAgents", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "bURI", - "type": "string" - } - ], - "name": "setBaseURI", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - }, - { - "internalType": "uint96[]", - "name": "amounts", - "type": "uint96[]" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "slash", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "slashedFunds", - "outputs": [ - { - "internalType": "uint96", - "name": "", - "type": "uint96" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "terminate", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "refund", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "tokenByIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "unbond", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "refund", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "internalType": "struct AgentParams[]", - "name": "agentParams", - "type": "tuple[]" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "update", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x60a06040526001600a553480156200001657600080fd5b506040516200636638038062006366833981016040819052620000399162000160565b83836000620000498382620002a2565b506001620000588282620002a2565b50600891506200006b90508382620002a2565b506001600160a01b03166080525050600680546001600160a01b03191633179055506200036e565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000bb57600080fd5b81516001600160401b0380821115620000d857620000d862000093565b604051601f8301601f19908116603f0116810190828211818310171562000103576200010362000093565b816040528381526020925086838588010111156200012057600080fd5b600091505b8382101562000144578582018301518183018401529082019062000125565b83821115620001565760008385830101525b9695505050505050565b600080600080608085870312156200017757600080fd5b84516001600160401b03808211156200018f57600080fd5b6200019d88838901620000a9565b95506020870151915080821115620001b457600080fd5b620001c288838901620000a9565b94506040870151915080821115620001d957600080fd5b50620001e887828801620000a9565b606087015190935090506001600160a01b03811681146200020857600080fd5b939692955090935050565b600181811c908216806200022857607f821691505b6020821081036200024957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200029d57600081815260208120601f850160051c81016020861015620002785750805b601f850160051c820191505b81811015620002995782815560010162000284565b5050505b505050565b81516001600160401b03811115620002be57620002be62000093565b620002d681620002cf845462000213565b846200024f565b602080601f8311600181146200030e5760008415620002f55750858301515b600019600386901b1c1916600185901b17855562000299565b600085815260208120601f198616915b828110156200033f578886015182559484019460019091019084016200031e565b50858210156200035e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051615fce620003986000396000818161043e01528181613e9e01526146600152615fce6000f3fe6080604052600436106103605760003560e01c80636f99f15c116101c6578063a5d059ca116100f7578063dff7672411610095578063ef0e239b1161006f578063ef0e239b14610bda578063f908bc7714610c07578063fbdeb3d714610c27578063ffa1ad7414610c4757600080fd5b8063dff7672414610b79578063e23f6fb414610b8c578063e985e9c514610b9f57600080fd5b8063b88d4fde116100d1578063b88d4fde14610af9578063c87b56dd14610b19578063cbf994f814610b39578063ccc9305d14610b5957600080fd5b8063a5d059ca14610a74578063a60e4c3c14610aab578063a6f9dae114610ad957600080fd5b80638a2bd86f1161016457806395d89b411161013e57806395d89b4114610a0a5780639890220b14610a1f578063a22cb46514610a34578063a3fbbaae14610a5457600080fd5b80638a2bd86f146109775780638da5cb5b146109bc57806392080b23146109dc57600080fd5b806373b8b6a2116101a057806373b8b6a2146108e25780637c5e63e01461090257806382694b1d1461093757806386a2bdd41461095757600080fd5b80636f99f15c1461085e57806370a082311461087e578063718934d81461089e57600080fd5b806342144854116102a05780634f6ccce71161023e5780635e4507fa116102185780635e4507fa1461079f5780636352211e146107bf57806363dd7615146107df5780636c0360eb1461084957600080fd5b80634f6ccce71461073857806355f804b31461075857806357838e851461077857600080fd5b8063481c6a751161027a578063481c6a75146106a25780634d486f85146106c25780634eb780da146106e25780634f558e791461071857600080fd5b806342144854146105a55780634236aff8146105f357806342842e0e1461068257600080fd5b806317351f7e1161030d57806321e4f7bb116102e757806321e4f7bb1461050257806323b872dd14610530578063323e010714610550578063406f14ad1461058557600080fd5b806317351f7e1461048057806318160ddd146104b05780631de286ba146104d457600080fd5b8063095ea7b31161033e578063095ea7b31461040a5780630d1cfcae1461042c57806310c6aa191461046057600080fd5b806301ffc9a71461036557806306fdde031461039a578063081812fc146103bc575b600080fd5b34801561037157600080fd5b50610385610380366004614e43565b610c78565b60405190151581526020015b60405180910390f35b3480156103a657600080fd5b506103af610cca565b6040516103919190614ec3565b3480156103c857600080fd5b506103f26103d7366004614ed6565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610391565b34801561041657600080fd5b5061042a610425366004614f04565b610d58565b005b34801561043857600080fd5b506103f27f000000000000000000000000000000000000000000000000000000000000000081565b34801561046c57600080fd5b5061042a61047b366004614f30565b610e3f565b34801561048c57600080fd5b5061038561049b366004614f30565b60146020526000908152604090205460ff1681565b3480156104bc57600080fd5b506104c660095481565b604051908152602001610391565b3480156104e057600080fd5b506104f46104ef366004614ed6565b610ef8565b604051610391929190614f4d565b34801561050e57600080fd5b5061052261051d366004614fb4565b61114e565b60405161039192919061501a565b34801561053c57600080fd5b5061042a61054b36600461503b565b61123c565b34801561055c57600080fd5b5061057061056b366004614fb4565b611416565b60405163ffffffff9091168152602001610391565b34801561059157600080fd5b506105706105a0366004614fb4565b61145f565b3480156105b157600080fd5b506105db6105c0366004614ed6565b6010602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610391565b3480156105ff57600080fd5b5061066f61060e366004614ed6565b6015602052600090815260409020805460018201546002909201546001600160601b03821692600160601b928390046001600160a01b031692909163ffffffff808216926401000000008304821692600160401b8104909216910460ff1687565b60405161039197969594939291906150b4565b34801561068e57600080fd5b5061042a61069d36600461503b565b61147b565b3480156106ae57600080fd5b506007546103f2906001600160a01b031681565b3480156106ce57600080fd5b506105226106dd366004614ed6565b611570565b3480156106ee57600080fd5b506103f26106fd366004614f30565b6011602052600090815260409020546001600160a01b031681565b34801561072457600080fd5b50610385610733366004614ed6565b6116c2565b34801561074457600080fd5b506104c6610753366004614ed6565b6116e4565b34801561076457600080fd5b5061042a6107733660046151d7565b611729565b34801561078457600080fd5b50600b546103f290600160601b90046001600160a01b031681565b3480156107ab57600080fd5b506103f26107ba366004614fb4565b6117d2565b3480156107cb57600080fd5b506103f26107da366004614ed6565b61180a565b3480156107eb57600080fd5b506108256107fa366004614ed6565b600e6020526000908152604090205463ffffffff81169064010000000090046001600160601b031682565b6040805163ffffffff90931683526001600160601b03909116602083015201610391565b34801561085557600080fd5b506103af61186f565b34801561086a57600080fd5b50600b546105db906001600160601b031681565b34801561088a57600080fd5b506104c6610899366004614f30565b61187c565b3480156108aa57600080fd5b506108be6108b9366004614fb4565b6118f0565b604080516001600160a01b03909316835263ffffffff909116602083015201610391565b3480156108ee57600080fd5b506103856108fd3660046152cf565b611936565b34801561090e57600080fd5b506103af6040518060400160405280600981526020016806630313730313232360bc1b81525081565b34801561094357600080fd5b50610385610952366004615399565b611d8b565b34801561096357600080fd5b506104c6610972366004614fb4565b611e24565b34801561098357600080fd5b506104c6610992366004614f04565b60a01b6001600160a01b03909116176000908152601060205260409020546001600160601b031690565b3480156109c857600080fd5b506006546103f2906001600160a01b031681565b3480156109e857600080fd5b506109fc6109f73660046153d7565b611e55565b60405161039192919061542f565b348015610a1657600080fd5b506103af611f90565b348015610a2b57600080fd5b506104c6611f9d565b348015610a4057600080fd5b5061042a610a4f366004615399565b6120fb565b348015610a6057600080fd5b5061042a610a6f366004614f30565b612167565b348015610a8057600080fd5b50610a94610a8f366004614f04565b612218565b604080519215158352602083019190915201610391565b348015610ab757600080fd5b50610acb610ac6366004614ed6565b6126b4565b604051610391929190615448565b348015610ae557600080fd5b5061042a610af4366004614f30565b612718565b348015610b0557600080fd5b5061042a610b14366004615496565b6127c9565b348015610b2557600080fd5b506103af610b34366004614ed6565b6128ae565b348015610b4557600080fd5b50610385610b5436600461563a565b612928565b348015610b6557600080fd5b50610a94610b74366004614f04565b612eb6565b610385610b873660046156d7565b613246565b610385610b9a366004614f04565b613841565b348015610bab57600080fd5b50610385610bba366004615757565b600560209081526000928352604080842090915290825290205460ff1681565b348015610be657600080fd5b50610bfa610bf5366004614ed6565b6139c0565b6040516103919190615785565b348015610c1357600080fd5b506103f2610c22366004615821565b613b40565b348015610c3357600080fd5b506104c6610c42366004615895565b613fe6565b348015610c5357600080fd5b506103af604051806040016040528060058152602001640312e302e360dc1b81525081565b60006301ffc9a760e01b6001600160e01b031983161480610ca957506380ac58cd60e01b6001600160e01b03198316145b80610cc45750635b5e139f60e01b6001600160e01b03198316145b92915050565b60008054610cd79061592a565b80601f0160208091040260200160405190810160405280929190818152602001828054610d039061592a565b8015610d505780601f10610d2557610100808354040283529160200191610d50565b820191906000526020600020905b815481529060010190602001808311610d3357829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b031633811480610da157506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b610de35760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6006546001600160a01b03163314610e7f5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b038116610ea65760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160601b0316600160601b6001600160a01b038416908102919091179091556040517f8d1e8547016120917daad7f81c42b48f7fee379badc48f1889f0f43bb619472590600090a250565b600081815260156020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff9104166005811115610f9957610f9961507c565b6005811115610faa57610faa61507c565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561102957602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411610fec5790505b50505050508152505090508060e001515192508267ffffffffffffffff8111156110555761105561510f565b60405190808252806020026020018201604052801561109a57816020015b60408051808201909152600080825260208201528152602001906001900390816110735790505b50915060005b8381101561114757600085905060208360e0015183815181106110c5576110c5615964565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260409081902081518083019092525492831681526401000000009092046001600160601b031692820192909252845185908490811061112a5761112a615964565b6020026020010181905250508061114090615990565b90506110a0565b5050915091565b602081811b83176000818152600f909252604090912054906060908267ffffffffffffffff8111156111825761118261510f565b6040519080825280602002602001820160405280156111ab578160200160208202803683370190505b50915060005b83811015611233576000828152600f602052604090208054829081106111d9576111d9615964565b9060005260206000200160009054906101000a90046001600160a01b031683828151811061120957611209615964565b6001600160a01b03909216602092830291909101909101528061122b81615990565b9150506111b1565b50509250929050565b6000818152600260205260409020546001600160a01b038481169116146112a55760405162461bcd60e51b815260206004820152600a60248201527f57524f4e475f46524f4d000000000000000000000000000000000000000000006044820152606401610dda565b6001600160a01b0382166112ef5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610dda565b336001600160a01b038416148061132957506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061134a57506000818152600460205260409020546001600160a01b031633145b6113875760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610dda565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6012602052816000526040600020818154811061143257600080fd5b9060005260206000209060089182820401919006600402915091509054906101000a900463ffffffff1681565b6013602052816000526040600020818154811061143257600080fd5b61148683838361123c565b6001600160a01b0382163b1561156b57604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af11580156114fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152191906159a9565b6001600160e01b0319161461156b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610dda565b505050565b600081815260156020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff91041660058111156116115761161161507c565b60058111156116225761162261507c565b8152602001600382018054806020026020016040519081016040528092919081815260200182805480156116a157602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116116645790505b50505050508152505090506116b681856142de565b91508151925050915091565b60008082118015610cc457506009546116dc9060016159c6565b821092915050565b60006116f18260016159c6565b905060095481111561172457600954604051637ae5968560e01b8152610dda918391600401918252602082015260400190565b919050565b6006546001600160a01b031633146117695760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b805160000361178b57604051637c946ed760e01b815260040160405180910390fd5b60086117978282615a24565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf6816040516117c79190614ec3565b60405180910390a150565b600f60205281600052604060002081815481106117ee57600080fd5b6000918252602090912001546001600160a01b03169150829050565b6000818152600260205260409020546001600160a01b0316806117245760405162461bcd60e51b815260206004820152600a60248201527f4e4f545f4d494e544544000000000000000000000000000000000000000000006044820152606401610dda565b60088054610cd79061592a565b60006001600160a01b0382166118d45760405162461bcd60e51b815260206004820152600c60248201527f5a45524f5f4144445245535300000000000000000000000000000000000000006044820152606401610dda565b506001600160a01b031660009081526003602052604090205490565b600d602052816000526040600020818154811061190c57600080fd5b6000918252602090912001546001600160a01b0381169250600160a01b900463ffffffff16905082565b600081815260156020908152604080832081516101008101835281546001600160601b0381168252600160601b908190046001600160a01b031694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a0840152849360c08401910460ff1660058111156119cd576119cd61507c565b60058111156119de576119de61507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015611a5d57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611a205790505b505050505081525050905060046005811115611a7b57611a7b61507c565b8160c001516005811115611a9157611a9161507c565b14611ad0578060c001516005811115611aac57611aac61507c565b604051633c053f9d60e21b8152600481019190915260248101849052604401610dda565b8351855114611aff57845184516040516308151c1160e41b815260048101929092526024820152604401610dda565b80602001516001600160a01b0316336001600160a01b031614611b535760208101516040516379f91cd360e01b81523360048201526001600160a01b03909116602482015260448101849052606401610dda565b845160005b81811015611d7e57600060116000898481518110611b7857611b78615964565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081205490931660a08a901b81178085526010909252919092205489519193506001600160601b03169081908a9086908110611bdd57611bdd615964565b60200260200101516001611bf19190615ae4565b6001600160601b03161115611c4b57600b8054829190600090611c1e9084906001600160601b0316615ae4565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060009050611ccf565b888481518110611c5d57611c5d615964565b6020908102919091010151600b8054600090611c839084906001600160601b0316615ae4565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550888481518110611cb957611cb9615964565b602002602001015181611ccc9190615b0f565b90505b600082815260106020526040902080546bffffffffffffffffffffffff19166001600160601b038316179055885188906001600160a01b038516907fa2e524bd0f71903485fbb3d6d50cb305f61005ceea2047c3ac92aa7e0d104306908c9088908110611d3e57611d3e615964565b6020026020010151604051611d6291906001600160601b0391909116815260200190565b60405180910390a350505080611d7790615990565b9050611b58565b5060019695505050505050565b6006546000906001600160a01b03163314611dce5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b038316611df55760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b03919091166000908152601460205260409020805460ff1916911515919091179055600190565b600c6020528160005260406000208181548110611e4057600080fd5b90600052602060002001600091509150505481565b6000606081846001811115611e6c57611e6c61507c565b03611efd5760008381526012602090815260409182902080548351818402810184019094528084529091830182828015611ef157602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611eb45790505b50505050509050611f85565b60008381526013602090815260409182902080548351818402810184019094528084529091830182828015611f7d57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611f405790505b505050505090505b805191509250929050565b60018054610cd79061592a565b60006001600a541115611fc3576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a55600b54600160601b90046001600160a01b0316331461201557600b5460405163312d21ff60e11b8152336004820152600160601b9091046001600160a01b03166024820152604401610dda565b50600b546001600160601b031680156120f357600b80546bffffffffffffffffffffffff19169055604051600090339083908381818185875af1925050503d806000811461207f576040519150601f19603f3d011682016040523d82523d6000602084013e612084565b606091505b50509050806120bc5760405163cd3f165960e01b81526000600482015230602482015233604482015260648101839052608401610dda565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2505b6001600a5590565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6006546001600160a01b031633146121a75760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b0381166121ce5760405163d92e233d60e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f2c1c11af44aa5608f1dca38c00275c30ea091e02417d36e70e9a1538689c433d90600090a250565b6000806001600a54111561223f576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146122845760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b0384166122ab5760405163d92e233d60e01b815260040160405180910390fd5b600083815260156020526040902060056002820154600160601b900460ff1660058111156122db576122db61507c565b14612324576002810154600160601b900460ff1660058111156123005761230061507c565b604051633c053f9d60e21b8152600481019190915260248101859052604401610dda565b60a084901b6001600160a01b038616176000818152600d6020908152604080832080548251818502810185019093528083529192909190849084015b828210156123ac57600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900463ffffffff1681830152825260019092019101612360565b50508251929350505060008190036123e95760405163df2ddd7360e01b81526001600160a01b038916600482015260248101889052604401610dda565b808460020160088282829054906101000a900463ffffffff1661240c9190615b37565b92506101000a81548163ffffffff021916908363ffffffff1602179055508360020160089054906101000a900463ffffffff1663ffffffff166000036124625760028401805460ff60601b1916600160601b1790555b60005b8181101561252a576000889050602084838151811061248657612486615964565b60209081029190910181015181015163ffffffff1690911b919091176000818152600e9092526040909120546124cd9064010000000090046001600160601b0316886159c6565b9650601160008584815181106124e5576124e5615964565b602090810291909101810151516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055508061252281615990565b915050612465565b506000838152600d6020526040812061254291614c87565b6000838152601060205260409020546001600160601b03168086111561256f57806001600160601b031695505b85156126685760008481526010602052604080822080546bffffffffffffffffffffffff19169055516001600160a01b038b169088908381818185875af1925050503d80600081146125dd576040519150601f19603f3d011682016040523d82523d6000602084013e6125e2565b606091505b50509050806126235760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038b16604482015260648101889052608401610dda565b896001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d8860405161265e91815260200190565b60405180910390a2505b60405188906001600160a01b038b16907f5ebf7fe30be09f0f03b9195632508d95c8b67bf010c93abda67f70d5d9599d1e90600090a350506001600a8190559793965092945050505050565b6000818152600c60209081526040808320805482518185028101850190935280835260609383018282801561270857602002820191906000526020600020905b8154815260200190600101908083116126f4575b5050505050905080519150915091565b6006546001600160a01b031633146127585760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b03811661277f5760405163d92e233d60e01b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b90600090a250565b6127d485858561123c565b6001600160a01b0384163b156128a757604051630a85bd0160e11b808252906001600160a01b0386169063150b7a029061281a9033908a90899089908990600401615b54565b6020604051808303816000875af1158015612839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285d91906159a9565b6001600160e01b031916146128a75760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610dda565b5050505050565b6000818152601560205260408120600101546060915060086040518060400160405280600981526020016806630313730313232360bc1b8152506128f18361442f565b6128fe608085901b61442f565b6040516020016129119493929190615ba8565b604051602081830303815290604052915050919050565b6007546000906001600160a01b0316331461296b5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b60006129768361180a565b9050876001600160a01b0316816001600160a01b0316146129bd5760405163521eb56d60e11b81526001600160a01b03808a16600483015282166024820152604401610dda565b600083815260156020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a08401529192909160c084019160ff9104166005811115612a5757612a5761507c565b6005811115612a6857612a6861507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015612ae757602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612aaa5790505b505050505081525050905060016005811115612b0557612b0561507c565b8160c001516005811115612b1b57612b1b61507c565b14612b36578060c0015160058111156123005761230061507c565b612b418888886145ff565b63ffffffff85166060820152600060808201819052875167ffffffffffffffff811115612b7057612b7061510f565b604051908082528060200260200182016040528015612b99578160200160208202803683370190505b5090506000885167ffffffffffffffff811115612bb857612bb861510f565b604051908082528060200260200182016040528015612bfd57816020015b6040805180820190915260008082526020820152815260200190600190039081612bd65790505b5090506000805b8a51811015612d3257898181518110612c1f57612c1f615964565b60200260200101516000015163ffffffff16600003612c9457600088905060208c8381518110612c5157612c51615964565b60209081029190910181015163ffffffff1690911b919091176000908152600e9091526040902080546fffffffffffffffffffffffffffffffff19169055612d20565b8a8181518110612ca657612ca6615964565b6020026020010151848381518110612cc057612cc0615964565b602002602001019063ffffffff16908163ffffffff1681525050898181518110612cec57612cec615964565b6020026020010151838381518110612d0657612d06615964565b60200260200101819052508180612d1c90615990565b9250505b80612d2a81615990565b915050612c04565b5060408401518b8114612d69576000888152600c602090815260408083208054600181018255908452919092200182905585018c90525b612d76858585858c6147c6565b6000888152601560209081526040918290208751918801516001600160a01b0316600160601b9081026001600160601b03909316929092178155918701516001830155606087015160028301805460808a015160a08b015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c08a01518a9594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115612e4b57612e4b61507c565b021790555060e08201518051612e6b916003840191602090910190614ca8565b50506040518d81528991507fff312ce131c4d73ac90ece91266be7090486c5e15f78b7ea2b108c36dfd475299060200160405180910390a25060019c9b505050505050505050505050565b6000806001600a541115612edd576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314612f225760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6000612f2d8461180a565b9050846001600160a01b0316816001600160a01b031614612f745760405163521eb56d60e11b81526001600160a01b03808716600483015282166024820152604401610dda565b600084815260156020526040902060016002820154600160601b900460ff166005811115612fa457612fa461507c565b1480612fcf575060056002820154600160601b900460ff166005811115612fcd57612fcd61507c565b145b15613018576002810154600160601b900460ff166005811115612ff457612ff461507c565b604051633c053f9d60e21b8152600481019190915260248101869052604401610dda565b6002810154600160401b900463ffffffff16156130525760028101805460ff60601b19166c05000000000000000000000000179055613068565b60028101805460ff60601b1916600160601b1790555b600085815260126020526040812061307f91614d57565b600085815260136020526040812061309691614d57565b60005b600382015481101561312357600086905060208360030183815481106130c1576130c1615964565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff16901b81179050600f600082815260200190815260200160002060006131129190614d7c565b5061311c81615990565b9050613099565b5080546040516001600160601b0390911693506000906001600160a01b0388169085908381818185875af1925050503d806000811461317e576040519150601f19603f3d011682016040523d82523d6000602084013e613183565b606091505b50509050806131c45760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038816604482015260648101859052608401610dda565b866001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d856040516131ff91815260200190565b60405180910390a260405186907fe45f5b9540df4f71b7e044809fa318806328c1ea2388a70c7373d97ccf8a0faa90600090a250506001600a819055959194509092505050565b6007546000906001600160a01b031633146132895760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b81518351146132b857825182516040516308151c1160e41b815260048101929092526024820152604401610dda565b6000848152601560205260409020600280820154600160601b900460ff1660058111156132e7576132e761507c565b1461330c576002810154600160601b900460ff166005811115612ff457612ff461507c565b83516000805b82811015613401576000889050602087838151811061333357613333615964565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260408082208151808301909252549384168082526401000000009094046001600160601b03169481019490945290929190036133d45787838151811061339f5761339f615964565b60200260200101518a6040516332832be560e21b8152600401610dda92919063ffffffff929092168252602082015260400190565b60208101516133ec906001600160601b0316856159c6565b93505050806133fa90615990565b9050613312565b5080341461343257604051637ebbcab960e11b81523460048201526024810182905260448101889052606401610dda565b6001600160a01b03888116600090815260116020526040902054161561346e576040516322ddebd960e21b815260048101889052602401610dda565b60a087901b6001600160a01b0389161760005b8381101561376257600088828151811061349d5761349d615964565b6020026020010151905060008883815181106134bb576134bb615964565b60200260200101519050816001600160a01b03168c6001600160a01b0316036134fa576040516322ddebd960e21b8152600481018c9052602401610dda565b6001600160a01b038281166000908152601160205260409020541615613551576001600160a01b038281166000908152601160205260409081902054905163631695bd60e01b815291166004820152602401610dda565b60008b905060208a858151811061356a5761356a615964565b60209081029190910181015163ffffffff90811690921b929092176000818152600e8452604080822054600f909552902054909290911690036135c3576040516304ad100760e21b8152600481018d9052602401610dda565b6000818152600f602090815260408083208054600181810183559185528385200180546001600160a01b03808a166001600160a01b031990921682179092558a8652600d8552838620845180860190955290845263ffffffff8089168587019081528254948501835591875294909520925192909101805494518416600160a01b0277ffffffffffffffffffffffffffffffffffffffffffffffff19909516929091169190911792909217909155600289018054600160401b900490911690600861368d83615c3a565b91906101000a81548163ffffffff021916908363ffffffff160217905550508c60116000856001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001600160a01b03168c8e6001600160a01b03167f6835389a6da5341647f18cbe0a89c56f473f4c17bfaee6e6d07d61f1928e0b7c85604051613746919063ffffffff91909116815260200190565b60405180910390a45050508061375b90615990565b9050613481565b50600284015463ffffffff64010000000082048116600160401b90920416036137a45760028401805460ff60601b19166c030000000000000000000000001790555b600081815260106020526040812080543492906137cb9084906001600160601b0316615ae4565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550886001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161382a91815260200190565b60405180910390a250600198975050505050505050565b6007546000906001600160a01b031633146138845760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b600061388f8361180a565b9050836001600160a01b0316816001600160a01b0316146138d65760405163521eb56d60e11b81526001600160a01b03808616600483015282166024820152604401610dda565b600083815260156020526040902060016002820154600160601b900460ff1660058111156139065761390661507c565b1461392757604051635960d22f60e11b815260048101859052602401610dda565b80546001600160601b0316341461396c578054604051631c30abbb60e31b81523460048201526001600160601b03909116602482015260448101859052606401610dda565b60028101805460ff60601b19166c0200000000000000000000000017905560405184907fa48b531f972c0e4aca57afcc5c099c52a7bd21bc5e2a1b733eec3be9e88da97a90600090a2506001949350505050565b613a086040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b60008281526015602090815260409182902082516101008101845281546001600160601b0381168252600160601b908190046001600160a01b031693820193909352600182015493810193909352600281015463ffffffff8082166060860152640100000000820481166080860152600160401b82041660a0850152909160c08401910460ff166005811115613aa057613aa061507c565b6005811115613ab157613ab161507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613b3057602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613af35790505b5050505050815250509050919050565b60006001600a541115613b66576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314613bab5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6000613bb68561180a565b9050856001600160a01b0316816001600160a01b031614613bfd5760405163521eb56d60e11b81526001600160a01b03808816600483015282166024820152604401610dda565b6001600160a01b03841660009081526014602052604090205460ff16613c405760405162a2307960e51b81526001600160a01b0385166004820152602401610dda565b600085815260156020526040902060036002820154600160601b900460ff166005811115613c7057613c7061507c565b14613cb9576002810154600160601b900460ff166005811115613c9557613c9561507c565b604051633c053f9d60e21b8152600481019190915260248101879052604401610dda565b604080516101008101825282546001600160601b0381168252600160601b908190046001600160a01b03166020830152600184015492820192909252600283015463ffffffff8082166060840152640100000000820481166080840152600160401b82041660a0830152600092613de69291859160c08401910460ff166005811115613d4757613d4761507c565b6005811115613d5857613d5861507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613dd757602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613d9a5790505b505050505081525050886142de565b6002830154604051631e731b7560e31b81529192506001600160a01b0388169163f398dba891613e2391859163ffffffff16908a90600401615c5d565b6020604051808303816000875af1158015613e42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e669190615c98565b6000888152601360205260409020600384018054929650613e8692614d9a565b506040516304d9dc3f60e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906309b3b87e90613ed6906003860190600401615cb5565b600060405180830381865afa158015613ef3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613f1b9190810190615e3d565b60008881526012602090815260409091208251613f3e9391929190910190614ca8565b5081546001600160601b0316600160601b6001600160a01b03861690810291909117835560028301805460ff60601b19166c0400000000000000000000000017905560405188907f2d53f895cd5faf3cddba94a25c2ced2105885b5b37450ff430ffa3cbdf332c7490600090a360405187907fa133ed72c03a7d008deaae618a61613c4fd41c67bba1cad1a6bc0a1c5a9c156e90600090a250506001600a5550949350505050565b60006001600a54111561400c576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146140515760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b0386166140785760405163d92e233d60e01b815260040160405180910390fd5b6140838585856145ff565b60005b8451811015614117578381815181106140a1576140a1615964565b60200260200101516000015163ffffffff16600014806140e757508381815181106140ce576140ce615964565b6020026020010151602001516001600160601b03166000145b1561410557604051637c946ed760e01b815260040160405180910390fd5b8061410f81615990565b915050614086565b50506009548061412681615990565b9150506141716040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b63ffffffff8316606082015260408101869052600160c08201818152505061419d8186868851866147c6565b6000828152601560209081526040918290208351918401516001600160a01b0316600160601b9081026001600160601b039093169290921781559183015160018301556060830151600283018054608086015160a087015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c0860151869594909360ff60601b19166cffffffffff00000000000000001990921691909117908360058111156142725761427261507c565b021790555060e08201518051614292916003840191602090910190614ca8565b50505060098290556142a48783614a7d565b60405182907f9169d45eacd63571e315a0504da919b7c89de505493e7b34051802dd0816a06990600090a2506001600a5595945050505050565b60608260a0015163ffffffff1667ffffffffffffffff8111156143035761430361510f565b60405190808252806020026020018201604052801561432c578160200160208202803683370190505b5090506000805b8460e001515181101561442757600084905060208660e00151838151811061435d5761435d615964565b602002602001015163ffffffff16901b8117905060005b6000828152600f6020526040902054811015614412576000828152600f602052604090208054829081106143aa576143aa615964565b9060005260206000200160009054906101000a90046001600160a01b03168585815181106143da576143da615964565b6001600160a01b0390921660209283029190910190910152836143fc81615990565b945050808061440a90615990565b915050614374565b5050808061441f90615990565b915050614333565b505092915050565b7aff00000000000000ff00000000000000ff00000000000000ff00006bffffffff0000000000000000604083901c9081167bffffffff00000000000000000000000000000000000000000000000084161760201c6fffffffff000000000000000000000000919091166001600160e01b031984161717601081901c9182167eff00000000000000ff00000000000000ff00000000000000ff000000000000821617600890811c7bff00000000000000ff00000000000000ff00000000000000ff000000939093167fff00000000000000ff00000000000000ff00000000000000ff000000000000009290921691909117919091179081901c7e0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f167f0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f00600492831c16179061459b827f06060606060606060606060606060606060606060606060606060606060606066159c6565b901c7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f1660276145cb9190615ed7565b6145f5827f30303030303030303030303030303030303030303030303030303030303030306159c6565b610cc491906159c6565b600083900361462157604051637c946ed760e01b815260040160405180910390fd5b8151158061463157508051825114155b1561465c57815181516040516308151c1160e41b815260048101929092526024820152604401610dda565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156146bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146e09190615ef6565b90506000805b84518110156147be576146fa8260016159c6565b85828151811061470c5761470c615964565b602002602001015163ffffffff16108061474457508285828151811061473457614734615964565b602002602001015163ffffffff16115b156147895784818151811061475b5761475b615964565b6020026020010151604051632ab10b0b60e21b8152600401610dda919063ffffffff91909116815260200190565b84818151811061479b5761479b615964565b602002602001015163ffffffff16915080806147b690615990565b9150506146e6565b505050505050565b60008267ffffffffffffffff8111156147e1576147e161510f565b60405190808252806020026020018201604052801561480a578160200160208202803683370190505b5060e087015260005b8381101561499a5785818151811061482d5761482d615964565b60200260200101518760e00151828151811061484b5761484b615964565b63ffffffff909216602092830291909101820152865184919088908490811061487657614876615964565b602002602001015163ffffffff16901b8117905085828151811061489c5761489c615964565b6020908102919091018101516000838152600e8352604090208151815492909301516001600160601b0316640100000000026fffffffffffffffffffffffffffffffff1990921663ffffffff90931692909217179055855186908390811061490657614906615964565b602002602001015160000151886080018181516149239190615f0f565b63ffffffff1690525085516001600160601b0384169087908490811061494b5761494b615964565b6020026020010151602001516001600160601b031611156149875785828151811061497857614978615964565b60200260200101516020015192505b508061499281615990565b915050614813565b506001600160601b038116865260808601516000906149ba906002615f2e565b6149c5906001615f0f565b63ffffffff1690506149d8600382615f70565b6000036149f1576149ea600382615f84565b9050614a0a565b6149fc600382615f84565b614a079060016159c6565b90505b80876060015163ffffffff161080614a355750866080015163ffffffff16876060015163ffffffff16115b15614a74576060870151608088015160405163eb3a8ba360e01b815263ffffffff92831660048201526024810184905291166044820152606401610dda565b50505050505050565b614a878282614b6d565b6001600160a01b0382163b15614b6957604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af1158015614afb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b1f91906159a9565b6001600160e01b03191614614b695760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610dda565b5050565b6001600160a01b038216614bb75760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610dda565b6000818152600260205260409020546001600160a01b031615614c1c5760405162461bcd60e51b815260206004820152600e60248201527f414c52454144595f4d494e5445440000000000000000000000000000000000006044820152606401610dda565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b5080546000825590600052602060002090810190614ca59190614de8565b50565b82805482825590600052602060002090600701600890048101928215614d475791602002820160005b83821115614d1557835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614cd1565b8015614d455782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614d15565b505b50614d53929150614e18565b5090565b508054600082556007016008900490600052602060002090810190614ca59190614e18565b5080546000825590600052602060002090810190614ca59190614e18565b82805482825590600052602060002090600701600890048101928215614d47576000526020600020916007016008900482015b82811115614d47578254825591600101919060010190614dcd565b5b80821115614d5357805477ffffffffffffffffffffffffffffffffffffffffffffffff19168155600101614de9565b5b80821115614d535760008155600101614e19565b6001600160e01b031981168114614ca557600080fd5b600060208284031215614e5557600080fd5b8135614e6081614e2d565b9392505050565b60005b83811015614e82578181015183820152602001614e6a565b83811115614e91576000848401525b50505050565b60008151808452614eaf816020860160208601614e67565b601f01601f19169290920160200192915050565b602081526000614e606020830184614e97565b600060208284031215614ee857600080fd5b5035919050565b6001600160a01b0381168114614ca557600080fd5b60008060408385031215614f1757600080fd5b8235614f2281614eef565b946020939093013593505050565b600060208284031215614f4257600080fd5b8135614e6081614eef565b6000604080830185845260208281860152818651808452606087019150828801935060005b81811015614fa6578451805163ffffffff1684528401516001600160601b0316848401529383019391850191600101614f72565b509098975050505050505050565b60008060408385031215614fc757600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b8381101561500f5781516001600160a01b031687529582019590820190600101614fea565b509495945050505050565b8281526040602082015260006150336040830184614fd6565b949350505050565b60008060006060848603121561505057600080fd5b833561505b81614eef565b9250602084013561506b81614eef565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b600681106150b057634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03881681526001600160a01b03871660208201526040810186905263ffffffff85811660608301528481166080830152831660a082015260e0810161510360c0830184615092565b98975050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156151485761514861510f565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156151775761517761510f565b604052919050565b600067ffffffffffffffff8311156151995761519961510f565b6151ac601f8401601f191660200161514e565b90508281528383830111156151c057600080fd5b828260208301376000602084830101529392505050565b6000602082840312156151e957600080fd5b813567ffffffffffffffff81111561520057600080fd5b8201601f8101841361521157600080fd5b6150338482356020840161517f565b600067ffffffffffffffff82111561523a5761523a61510f565b5060051b60200190565b600082601f83011261525557600080fd5b8135602061526a61526583615220565b61514e565b82815260059290921b8401810191818101908684111561528957600080fd5b8286015b848110156152ad5780356152a081614eef565b835291830191830161528d565b509695505050505050565b80356001600160601b038116811461172457600080fd5b6000806000606084860312156152e457600080fd5b833567ffffffffffffffff808211156152fc57600080fd5b61530887838801615244565b945060209150818601358181111561531f57600080fd5b86019050601f8101871361533257600080fd5b803561534061526582615220565b81815260059190911b8201830190838101908983111561535f57600080fd5b928401925b8284101561538457615375846152b8565b82529284019290840190615364565b96999698505050506040949094013593505050565b600080604083850312156153ac57600080fd5b82356153b781614eef565b9150602083013580151581146153cc57600080fd5b809150509250929050565b600080604083850312156153ea57600080fd5b823560028110614f2257600080fd5b600081518084526020808501945080840160005b8381101561500f57815163ffffffff168752958201959082019060010161540d565b82815260406020820152600061503360408301846153f9565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156154895784518352938301939183019160010161546d565b5090979650505050505050565b6000806000806000608086880312156154ae57600080fd5b85356154b981614eef565b945060208601356154c981614eef565b935060408601359250606086013567ffffffffffffffff808211156154ed57600080fd5b818801915088601f83011261550157600080fd5b81358181111561551057600080fd5b89602082850101111561552257600080fd5b9699959850939650602001949392505050565b63ffffffff81168114614ca557600080fd5b600082601f83011261555857600080fd5b8135602061556861526583615220565b82815260059290921b8401810191818101908684111561558757600080fd5b8286015b848110156152ad57803561559e81615535565b835291830191830161558b565b600082601f8301126155bc57600080fd5b813560206155cc61526583615220565b82815260069290921b840181019181810190868411156155eb57600080fd5b8286015b848110156152ad57604081890312156156085760008081fd5b615610615125565b813561561b81615535565b81526156288286016152b8565b818601528352918301916040016155ef565b60008060008060008060c0878903121561565357600080fd5b863561565e81614eef565b955060208701359450604087013567ffffffffffffffff8082111561568257600080fd5b61568e8a838b01615547565b955060608901359150808211156156a457600080fd5b506156b189828a016155ab565b93505060808701356156c281615535565b8092505060a087013590509295509295509295565b600080600080608085870312156156ed57600080fd5b84356156f881614eef565b935060208501359250604085013567ffffffffffffffff8082111561571c57600080fd5b61572888838901615244565b9350606087013591508082111561573e57600080fd5b5061574b87828801615547565b91505092959194509250565b6000806040838503121561576a57600080fd5b823561577581614eef565b915060208301356153cc81614eef565b602081526001600160601b0382511660208201526001600160a01b03602083015116604082015260408201516060820152600060608301516157cf608084018263ffffffff169052565b50608083015163ffffffff811660a08401525060a083015163ffffffff811660c08401525060c083015161580660e0840182615092565b5060e0830151610100838101526150336101208401826153f9565b6000806000806080858703121561583757600080fd5b843561584281614eef565b935060208501359250604085013561585981614eef565b9150606085013567ffffffffffffffff81111561587557600080fd5b8501601f8101871361588657600080fd5b61574b8782356020840161517f565b600080600080600060a086880312156158ad57600080fd5b85356158b881614eef565b945060208601359350604086013567ffffffffffffffff808211156158dc57600080fd5b6158e889838a01615547565b945060608801359150808211156158fe57600080fd5b5061590b888289016155ab565b925050608086013561591c81615535565b809150509295509295909350565b600181811c9082168061593e57607f821691505b60208210810361595e57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016159a2576159a261597a565b5060010190565b6000602082840312156159bb57600080fd5b8151614e6081614e2d565b600082198211156159d9576159d961597a565b500190565b601f82111561156b57600081815260208120601f850160051c81016020861015615a055750805b601f850160051c820191505b818110156147be57828155600101615a11565b815167ffffffffffffffff811115615a3e57615a3e61510f565b615a5281615a4c845461592a565b846159de565b602080601f831160018114615a875760008415615a6f5750858301515b600019600386901b1c1916600185901b1785556147be565b600085815260208120601f198616915b82811015615ab657888601518255948401946001909101908401615a97565b5085821015615ad45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006001600160601b03808316818516808303821115615b0657615b0661597a565b01949350505050565b60006001600160601b0383811690831681811015615b2f57615b2f61597a565b039392505050565b600063ffffffff83811690831681811015615b2f57615b2f61597a565b60006001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b6000808654615bb68161592a565b60018281168015615bce5760018114615be357615c12565b60ff1984168752821515830287019450615c12565b8a60005260208060002060005b85811015615c095781548a820152908401908201615bf0565b50505082870194505b505050508551615c26818360208a01614e67565b019384525050602082015260400192915050565b600063ffffffff808316818103615c5357615c5361597a565b6001019392505050565b606081526000615c706060830186614fd6565b63ffffffff851660208401528281036040840152615c8e8185614e97565b9695505050505050565b600060208284031215615caa57600080fd5b8151614e6081614eef565b60006020808301818452808554615cd0818490815260200190565b60008881526020812094509092505b81600782011015615d5557835463ffffffff808216855281871c811687860152604082811c821690860152606082811c821690860152608082811c82169086015260a082811c82169086015260c082811c9091169085015260e090811c9084015260019093019261010090920191600801615cdf565b92549281811015615d715763ffffffff84168352918401916001015b81811015615d8c5783851c63ffffffff168352918401916001015b81811015615da957604084901c63ffffffff168352918401916001015b81811015615dc657606084901c63ffffffff168352918401916001015b81811015615de357608084901c63ffffffff168352918401916001015b81811015615e005760a084901c63ffffffff168352918401916001015b81811015615e1d5760c084901c63ffffffff168352918401916001015b81811015615e315760e084901c8352918401915b50909695505050505050565b60006020808385031215615e5057600080fd5b825167ffffffffffffffff811115615e6757600080fd5b8301601f81018513615e7857600080fd5b8051615e8661526582615220565b81815260059190911b82018301908381019087831115615ea557600080fd5b928401925b82841015615ecc578351615ebd81615535565b82529284019290840190615eaa565b979650505050505050565b6000816000190483118215151615615ef157615ef161597a565b500290565b600060208284031215615f0857600080fd5b5051919050565b600063ffffffff808316818516808303821115615b0657615b0661597a565b600063ffffffff80831681851681830481118215151615615f5157615f5161597a565b02949350505050565b634e487b7160e01b600052601260045260246000fd5b600082615f7f57615f7f615f5a565b500690565b600082615f9357615f93615f5a565b50049056fea2646970667358221220c6f47c49865f99357fc7f3a83dfde648490b39975e4ec4242e3bcab08caabf3664736f6c634300080f0033", - "deployedBytecode": "0x6080604052600436106103605760003560e01c80636f99f15c116101c6578063a5d059ca116100f7578063dff7672411610095578063ef0e239b1161006f578063ef0e239b14610bda578063f908bc7714610c07578063fbdeb3d714610c27578063ffa1ad7414610c4757600080fd5b8063dff7672414610b79578063e23f6fb414610b8c578063e985e9c514610b9f57600080fd5b8063b88d4fde116100d1578063b88d4fde14610af9578063c87b56dd14610b19578063cbf994f814610b39578063ccc9305d14610b5957600080fd5b8063a5d059ca14610a74578063a60e4c3c14610aab578063a6f9dae114610ad957600080fd5b80638a2bd86f1161016457806395d89b411161013e57806395d89b4114610a0a5780639890220b14610a1f578063a22cb46514610a34578063a3fbbaae14610a5457600080fd5b80638a2bd86f146109775780638da5cb5b146109bc57806392080b23146109dc57600080fd5b806373b8b6a2116101a057806373b8b6a2146108e25780637c5e63e01461090257806382694b1d1461093757806386a2bdd41461095757600080fd5b80636f99f15c1461085e57806370a082311461087e578063718934d81461089e57600080fd5b806342144854116102a05780634f6ccce71161023e5780635e4507fa116102185780635e4507fa1461079f5780636352211e146107bf57806363dd7615146107df5780636c0360eb1461084957600080fd5b80634f6ccce71461073857806355f804b31461075857806357838e851461077857600080fd5b8063481c6a751161027a578063481c6a75146106a25780634d486f85146106c25780634eb780da146106e25780634f558e791461071857600080fd5b806342144854146105a55780634236aff8146105f357806342842e0e1461068257600080fd5b806317351f7e1161030d57806321e4f7bb116102e757806321e4f7bb1461050257806323b872dd14610530578063323e010714610550578063406f14ad1461058557600080fd5b806317351f7e1461048057806318160ddd146104b05780631de286ba146104d457600080fd5b8063095ea7b31161033e578063095ea7b31461040a5780630d1cfcae1461042c57806310c6aa191461046057600080fd5b806301ffc9a71461036557806306fdde031461039a578063081812fc146103bc575b600080fd5b34801561037157600080fd5b50610385610380366004614e43565b610c78565b60405190151581526020015b60405180910390f35b3480156103a657600080fd5b506103af610cca565b6040516103919190614ec3565b3480156103c857600080fd5b506103f26103d7366004614ed6565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610391565b34801561041657600080fd5b5061042a610425366004614f04565b610d58565b005b34801561043857600080fd5b506103f27f000000000000000000000000000000000000000000000000000000000000000081565b34801561046c57600080fd5b5061042a61047b366004614f30565b610e3f565b34801561048c57600080fd5b5061038561049b366004614f30565b60146020526000908152604090205460ff1681565b3480156104bc57600080fd5b506104c660095481565b604051908152602001610391565b3480156104e057600080fd5b506104f46104ef366004614ed6565b610ef8565b604051610391929190614f4d565b34801561050e57600080fd5b5061052261051d366004614fb4565b61114e565b60405161039192919061501a565b34801561053c57600080fd5b5061042a61054b36600461503b565b61123c565b34801561055c57600080fd5b5061057061056b366004614fb4565b611416565b60405163ffffffff9091168152602001610391565b34801561059157600080fd5b506105706105a0366004614fb4565b61145f565b3480156105b157600080fd5b506105db6105c0366004614ed6565b6010602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610391565b3480156105ff57600080fd5b5061066f61060e366004614ed6565b6015602052600090815260409020805460018201546002909201546001600160601b03821692600160601b928390046001600160a01b031692909163ffffffff808216926401000000008304821692600160401b8104909216910460ff1687565b60405161039197969594939291906150b4565b34801561068e57600080fd5b5061042a61069d36600461503b565b61147b565b3480156106ae57600080fd5b506007546103f2906001600160a01b031681565b3480156106ce57600080fd5b506105226106dd366004614ed6565b611570565b3480156106ee57600080fd5b506103f26106fd366004614f30565b6011602052600090815260409020546001600160a01b031681565b34801561072457600080fd5b50610385610733366004614ed6565b6116c2565b34801561074457600080fd5b506104c6610753366004614ed6565b6116e4565b34801561076457600080fd5b5061042a6107733660046151d7565b611729565b34801561078457600080fd5b50600b546103f290600160601b90046001600160a01b031681565b3480156107ab57600080fd5b506103f26107ba366004614fb4565b6117d2565b3480156107cb57600080fd5b506103f26107da366004614ed6565b61180a565b3480156107eb57600080fd5b506108256107fa366004614ed6565b600e6020526000908152604090205463ffffffff81169064010000000090046001600160601b031682565b6040805163ffffffff90931683526001600160601b03909116602083015201610391565b34801561085557600080fd5b506103af61186f565b34801561086a57600080fd5b50600b546105db906001600160601b031681565b34801561088a57600080fd5b506104c6610899366004614f30565b61187c565b3480156108aa57600080fd5b506108be6108b9366004614fb4565b6118f0565b604080516001600160a01b03909316835263ffffffff909116602083015201610391565b3480156108ee57600080fd5b506103856108fd3660046152cf565b611936565b34801561090e57600080fd5b506103af6040518060400160405280600981526020016806630313730313232360bc1b81525081565b34801561094357600080fd5b50610385610952366004615399565b611d8b565b34801561096357600080fd5b506104c6610972366004614fb4565b611e24565b34801561098357600080fd5b506104c6610992366004614f04565b60a01b6001600160a01b03909116176000908152601060205260409020546001600160601b031690565b3480156109c857600080fd5b506006546103f2906001600160a01b031681565b3480156109e857600080fd5b506109fc6109f73660046153d7565b611e55565b60405161039192919061542f565b348015610a1657600080fd5b506103af611f90565b348015610a2b57600080fd5b506104c6611f9d565b348015610a4057600080fd5b5061042a610a4f366004615399565b6120fb565b348015610a6057600080fd5b5061042a610a6f366004614f30565b612167565b348015610a8057600080fd5b50610a94610a8f366004614f04565b612218565b604080519215158352602083019190915201610391565b348015610ab757600080fd5b50610acb610ac6366004614ed6565b6126b4565b604051610391929190615448565b348015610ae557600080fd5b5061042a610af4366004614f30565b612718565b348015610b0557600080fd5b5061042a610b14366004615496565b6127c9565b348015610b2557600080fd5b506103af610b34366004614ed6565b6128ae565b348015610b4557600080fd5b50610385610b5436600461563a565b612928565b348015610b6557600080fd5b50610a94610b74366004614f04565b612eb6565b610385610b873660046156d7565b613246565b610385610b9a366004614f04565b613841565b348015610bab57600080fd5b50610385610bba366004615757565b600560209081526000928352604080842090915290825290205460ff1681565b348015610be657600080fd5b50610bfa610bf5366004614ed6565b6139c0565b6040516103919190615785565b348015610c1357600080fd5b506103f2610c22366004615821565b613b40565b348015610c3357600080fd5b506104c6610c42366004615895565b613fe6565b348015610c5357600080fd5b506103af604051806040016040528060058152602001640312e302e360dc1b81525081565b60006301ffc9a760e01b6001600160e01b031983161480610ca957506380ac58cd60e01b6001600160e01b03198316145b80610cc45750635b5e139f60e01b6001600160e01b03198316145b92915050565b60008054610cd79061592a565b80601f0160208091040260200160405190810160405280929190818152602001828054610d039061592a565b8015610d505780601f10610d2557610100808354040283529160200191610d50565b820191906000526020600020905b815481529060010190602001808311610d3357829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b031633811480610da157506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b610de35760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6006546001600160a01b03163314610e7f5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b038116610ea65760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160601b0316600160601b6001600160a01b038416908102919091179091556040517f8d1e8547016120917daad7f81c42b48f7fee379badc48f1889f0f43bb619472590600090a250565b600081815260156020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff9104166005811115610f9957610f9961507c565b6005811115610faa57610faa61507c565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561102957602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411610fec5790505b50505050508152505090508060e001515192508267ffffffffffffffff8111156110555761105561510f565b60405190808252806020026020018201604052801561109a57816020015b60408051808201909152600080825260208201528152602001906001900390816110735790505b50915060005b8381101561114757600085905060208360e0015183815181106110c5576110c5615964565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260409081902081518083019092525492831681526401000000009092046001600160601b031692820192909252845185908490811061112a5761112a615964565b6020026020010181905250508061114090615990565b90506110a0565b5050915091565b602081811b83176000818152600f909252604090912054906060908267ffffffffffffffff8111156111825761118261510f565b6040519080825280602002602001820160405280156111ab578160200160208202803683370190505b50915060005b83811015611233576000828152600f602052604090208054829081106111d9576111d9615964565b9060005260206000200160009054906101000a90046001600160a01b031683828151811061120957611209615964565b6001600160a01b03909216602092830291909101909101528061122b81615990565b9150506111b1565b50509250929050565b6000818152600260205260409020546001600160a01b038481169116146112a55760405162461bcd60e51b815260206004820152600a60248201527f57524f4e475f46524f4d000000000000000000000000000000000000000000006044820152606401610dda565b6001600160a01b0382166112ef5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610dda565b336001600160a01b038416148061132957506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061134a57506000818152600460205260409020546001600160a01b031633145b6113875760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610dda565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6012602052816000526040600020818154811061143257600080fd5b9060005260206000209060089182820401919006600402915091509054906101000a900463ffffffff1681565b6013602052816000526040600020818154811061143257600080fd5b61148683838361123c565b6001600160a01b0382163b1561156b57604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af11580156114fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152191906159a9565b6001600160e01b0319161461156b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610dda565b505050565b600081815260156020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff91041660058111156116115761161161507c565b60058111156116225761162261507c565b8152602001600382018054806020026020016040519081016040528092919081815260200182805480156116a157602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116116645790505b50505050508152505090506116b681856142de565b91508151925050915091565b60008082118015610cc457506009546116dc9060016159c6565b821092915050565b60006116f18260016159c6565b905060095481111561172457600954604051637ae5968560e01b8152610dda918391600401918252602082015260400190565b919050565b6006546001600160a01b031633146117695760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b805160000361178b57604051637c946ed760e01b815260040160405180910390fd5b60086117978282615a24565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf6816040516117c79190614ec3565b60405180910390a150565b600f60205281600052604060002081815481106117ee57600080fd5b6000918252602090912001546001600160a01b03169150829050565b6000818152600260205260409020546001600160a01b0316806117245760405162461bcd60e51b815260206004820152600a60248201527f4e4f545f4d494e544544000000000000000000000000000000000000000000006044820152606401610dda565b60088054610cd79061592a565b60006001600160a01b0382166118d45760405162461bcd60e51b815260206004820152600c60248201527f5a45524f5f4144445245535300000000000000000000000000000000000000006044820152606401610dda565b506001600160a01b031660009081526003602052604090205490565b600d602052816000526040600020818154811061190c57600080fd5b6000918252602090912001546001600160a01b0381169250600160a01b900463ffffffff16905082565b600081815260156020908152604080832081516101008101835281546001600160601b0381168252600160601b908190046001600160a01b031694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a0840152849360c08401910460ff1660058111156119cd576119cd61507c565b60058111156119de576119de61507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015611a5d57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611a205790505b505050505081525050905060046005811115611a7b57611a7b61507c565b8160c001516005811115611a9157611a9161507c565b14611ad0578060c001516005811115611aac57611aac61507c565b604051633c053f9d60e21b8152600481019190915260248101849052604401610dda565b8351855114611aff57845184516040516308151c1160e41b815260048101929092526024820152604401610dda565b80602001516001600160a01b0316336001600160a01b031614611b535760208101516040516379f91cd360e01b81523360048201526001600160a01b03909116602482015260448101849052606401610dda565b845160005b81811015611d7e57600060116000898481518110611b7857611b78615964565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081205490931660a08a901b81178085526010909252919092205489519193506001600160601b03169081908a9086908110611bdd57611bdd615964565b60200260200101516001611bf19190615ae4565b6001600160601b03161115611c4b57600b8054829190600090611c1e9084906001600160601b0316615ae4565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060009050611ccf565b888481518110611c5d57611c5d615964565b6020908102919091010151600b8054600090611c839084906001600160601b0316615ae4565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550888481518110611cb957611cb9615964565b602002602001015181611ccc9190615b0f565b90505b600082815260106020526040902080546bffffffffffffffffffffffff19166001600160601b038316179055885188906001600160a01b038516907fa2e524bd0f71903485fbb3d6d50cb305f61005ceea2047c3ac92aa7e0d104306908c9088908110611d3e57611d3e615964565b6020026020010151604051611d6291906001600160601b0391909116815260200190565b60405180910390a350505080611d7790615990565b9050611b58565b5060019695505050505050565b6006546000906001600160a01b03163314611dce5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b038316611df55760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b03919091166000908152601460205260409020805460ff1916911515919091179055600190565b600c6020528160005260406000208181548110611e4057600080fd5b90600052602060002001600091509150505481565b6000606081846001811115611e6c57611e6c61507c565b03611efd5760008381526012602090815260409182902080548351818402810184019094528084529091830182828015611ef157602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611eb45790505b50505050509050611f85565b60008381526013602090815260409182902080548351818402810184019094528084529091830182828015611f7d57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611f405790505b505050505090505b805191509250929050565b60018054610cd79061592a565b60006001600a541115611fc3576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a55600b54600160601b90046001600160a01b0316331461201557600b5460405163312d21ff60e11b8152336004820152600160601b9091046001600160a01b03166024820152604401610dda565b50600b546001600160601b031680156120f357600b80546bffffffffffffffffffffffff19169055604051600090339083908381818185875af1925050503d806000811461207f576040519150601f19603f3d011682016040523d82523d6000602084013e612084565b606091505b50509050806120bc5760405163cd3f165960e01b81526000600482015230602482015233604482015260648101839052608401610dda565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2505b6001600a5590565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6006546001600160a01b031633146121a75760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b0381166121ce5760405163d92e233d60e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f2c1c11af44aa5608f1dca38c00275c30ea091e02417d36e70e9a1538689c433d90600090a250565b6000806001600a54111561223f576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146122845760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b0384166122ab5760405163d92e233d60e01b815260040160405180910390fd5b600083815260156020526040902060056002820154600160601b900460ff1660058111156122db576122db61507c565b14612324576002810154600160601b900460ff1660058111156123005761230061507c565b604051633c053f9d60e21b8152600481019190915260248101859052604401610dda565b60a084901b6001600160a01b038616176000818152600d6020908152604080832080548251818502810185019093528083529192909190849084015b828210156123ac57600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900463ffffffff1681830152825260019092019101612360565b50508251929350505060008190036123e95760405163df2ddd7360e01b81526001600160a01b038916600482015260248101889052604401610dda565b808460020160088282829054906101000a900463ffffffff1661240c9190615b37565b92506101000a81548163ffffffff021916908363ffffffff1602179055508360020160089054906101000a900463ffffffff1663ffffffff166000036124625760028401805460ff60601b1916600160601b1790555b60005b8181101561252a576000889050602084838151811061248657612486615964565b60209081029190910181015181015163ffffffff1690911b919091176000818152600e9092526040909120546124cd9064010000000090046001600160601b0316886159c6565b9650601160008584815181106124e5576124e5615964565b602090810291909101810151516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055508061252281615990565b915050612465565b506000838152600d6020526040812061254291614c87565b6000838152601060205260409020546001600160601b03168086111561256f57806001600160601b031695505b85156126685760008481526010602052604080822080546bffffffffffffffffffffffff19169055516001600160a01b038b169088908381818185875af1925050503d80600081146125dd576040519150601f19603f3d011682016040523d82523d6000602084013e6125e2565b606091505b50509050806126235760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038b16604482015260648101889052608401610dda565b896001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d8860405161265e91815260200190565b60405180910390a2505b60405188906001600160a01b038b16907f5ebf7fe30be09f0f03b9195632508d95c8b67bf010c93abda67f70d5d9599d1e90600090a350506001600a8190559793965092945050505050565b6000818152600c60209081526040808320805482518185028101850190935280835260609383018282801561270857602002820191906000526020600020905b8154815260200190600101908083116126f4575b5050505050905080519150915091565b6006546001600160a01b031633146127585760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b03811661277f5760405163d92e233d60e01b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b90600090a250565b6127d485858561123c565b6001600160a01b0384163b156128a757604051630a85bd0160e11b808252906001600160a01b0386169063150b7a029061281a9033908a90899089908990600401615b54565b6020604051808303816000875af1158015612839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285d91906159a9565b6001600160e01b031916146128a75760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610dda565b5050505050565b6000818152601560205260408120600101546060915060086040518060400160405280600981526020016806630313730313232360bc1b8152506128f18361442f565b6128fe608085901b61442f565b6040516020016129119493929190615ba8565b604051602081830303815290604052915050919050565b6007546000906001600160a01b0316331461296b5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b60006129768361180a565b9050876001600160a01b0316816001600160a01b0316146129bd5760405163521eb56d60e11b81526001600160a01b03808a16600483015282166024820152604401610dda565b600083815260156020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a08401529192909160c084019160ff9104166005811115612a5757612a5761507c565b6005811115612a6857612a6861507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015612ae757602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612aaa5790505b505050505081525050905060016005811115612b0557612b0561507c565b8160c001516005811115612b1b57612b1b61507c565b14612b36578060c0015160058111156123005761230061507c565b612b418888886145ff565b63ffffffff85166060820152600060808201819052875167ffffffffffffffff811115612b7057612b7061510f565b604051908082528060200260200182016040528015612b99578160200160208202803683370190505b5090506000885167ffffffffffffffff811115612bb857612bb861510f565b604051908082528060200260200182016040528015612bfd57816020015b6040805180820190915260008082526020820152815260200190600190039081612bd65790505b5090506000805b8a51811015612d3257898181518110612c1f57612c1f615964565b60200260200101516000015163ffffffff16600003612c9457600088905060208c8381518110612c5157612c51615964565b60209081029190910181015163ffffffff1690911b919091176000908152600e9091526040902080546fffffffffffffffffffffffffffffffff19169055612d20565b8a8181518110612ca657612ca6615964565b6020026020010151848381518110612cc057612cc0615964565b602002602001019063ffffffff16908163ffffffff1681525050898181518110612cec57612cec615964565b6020026020010151838381518110612d0657612d06615964565b60200260200101819052508180612d1c90615990565b9250505b80612d2a81615990565b915050612c04565b5060408401518b8114612d69576000888152600c602090815260408083208054600181018255908452919092200182905585018c90525b612d76858585858c6147c6565b6000888152601560209081526040918290208751918801516001600160a01b0316600160601b9081026001600160601b03909316929092178155918701516001830155606087015160028301805460808a015160a08b015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c08a01518a9594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115612e4b57612e4b61507c565b021790555060e08201518051612e6b916003840191602090910190614ca8565b50506040518d81528991507fff312ce131c4d73ac90ece91266be7090486c5e15f78b7ea2b108c36dfd475299060200160405180910390a25060019c9b505050505050505050505050565b6000806001600a541115612edd576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314612f225760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6000612f2d8461180a565b9050846001600160a01b0316816001600160a01b031614612f745760405163521eb56d60e11b81526001600160a01b03808716600483015282166024820152604401610dda565b600084815260156020526040902060016002820154600160601b900460ff166005811115612fa457612fa461507c565b1480612fcf575060056002820154600160601b900460ff166005811115612fcd57612fcd61507c565b145b15613018576002810154600160601b900460ff166005811115612ff457612ff461507c565b604051633c053f9d60e21b8152600481019190915260248101869052604401610dda565b6002810154600160401b900463ffffffff16156130525760028101805460ff60601b19166c05000000000000000000000000179055613068565b60028101805460ff60601b1916600160601b1790555b600085815260126020526040812061307f91614d57565b600085815260136020526040812061309691614d57565b60005b600382015481101561312357600086905060208360030183815481106130c1576130c1615964565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff16901b81179050600f600082815260200190815260200160002060006131129190614d7c565b5061311c81615990565b9050613099565b5080546040516001600160601b0390911693506000906001600160a01b0388169085908381818185875af1925050503d806000811461317e576040519150601f19603f3d011682016040523d82523d6000602084013e613183565b606091505b50509050806131c45760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038816604482015260648101859052608401610dda565b866001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d856040516131ff91815260200190565b60405180910390a260405186907fe45f5b9540df4f71b7e044809fa318806328c1ea2388a70c7373d97ccf8a0faa90600090a250506001600a819055959194509092505050565b6007546000906001600160a01b031633146132895760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b81518351146132b857825182516040516308151c1160e41b815260048101929092526024820152604401610dda565b6000848152601560205260409020600280820154600160601b900460ff1660058111156132e7576132e761507c565b1461330c576002810154600160601b900460ff166005811115612ff457612ff461507c565b83516000805b82811015613401576000889050602087838151811061333357613333615964565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260408082208151808301909252549384168082526401000000009094046001600160601b03169481019490945290929190036133d45787838151811061339f5761339f615964565b60200260200101518a6040516332832be560e21b8152600401610dda92919063ffffffff929092168252602082015260400190565b60208101516133ec906001600160601b0316856159c6565b93505050806133fa90615990565b9050613312565b5080341461343257604051637ebbcab960e11b81523460048201526024810182905260448101889052606401610dda565b6001600160a01b03888116600090815260116020526040902054161561346e576040516322ddebd960e21b815260048101889052602401610dda565b60a087901b6001600160a01b0389161760005b8381101561376257600088828151811061349d5761349d615964565b6020026020010151905060008883815181106134bb576134bb615964565b60200260200101519050816001600160a01b03168c6001600160a01b0316036134fa576040516322ddebd960e21b8152600481018c9052602401610dda565b6001600160a01b038281166000908152601160205260409020541615613551576001600160a01b038281166000908152601160205260409081902054905163631695bd60e01b815291166004820152602401610dda565b60008b905060208a858151811061356a5761356a615964565b60209081029190910181015163ffffffff90811690921b929092176000818152600e8452604080822054600f909552902054909290911690036135c3576040516304ad100760e21b8152600481018d9052602401610dda565b6000818152600f602090815260408083208054600181810183559185528385200180546001600160a01b03808a166001600160a01b031990921682179092558a8652600d8552838620845180860190955290845263ffffffff8089168587019081528254948501835591875294909520925192909101805494518416600160a01b0277ffffffffffffffffffffffffffffffffffffffffffffffff19909516929091169190911792909217909155600289018054600160401b900490911690600861368d83615c3a565b91906101000a81548163ffffffff021916908363ffffffff160217905550508c60116000856001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001600160a01b03168c8e6001600160a01b03167f6835389a6da5341647f18cbe0a89c56f473f4c17bfaee6e6d07d61f1928e0b7c85604051613746919063ffffffff91909116815260200190565b60405180910390a45050508061375b90615990565b9050613481565b50600284015463ffffffff64010000000082048116600160401b90920416036137a45760028401805460ff60601b19166c030000000000000000000000001790555b600081815260106020526040812080543492906137cb9084906001600160601b0316615ae4565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550886001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161382a91815260200190565b60405180910390a250600198975050505050505050565b6007546000906001600160a01b031633146138845760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b600061388f8361180a565b9050836001600160a01b0316816001600160a01b0316146138d65760405163521eb56d60e11b81526001600160a01b03808616600483015282166024820152604401610dda565b600083815260156020526040902060016002820154600160601b900460ff1660058111156139065761390661507c565b1461392757604051635960d22f60e11b815260048101859052602401610dda565b80546001600160601b0316341461396c578054604051631c30abbb60e31b81523460048201526001600160601b03909116602482015260448101859052606401610dda565b60028101805460ff60601b19166c0200000000000000000000000017905560405184907fa48b531f972c0e4aca57afcc5c099c52a7bd21bc5e2a1b733eec3be9e88da97a90600090a2506001949350505050565b613a086040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b60008281526015602090815260409182902082516101008101845281546001600160601b0381168252600160601b908190046001600160a01b031693820193909352600182015493810193909352600281015463ffffffff8082166060860152640100000000820481166080860152600160401b82041660a0850152909160c08401910460ff166005811115613aa057613aa061507c565b6005811115613ab157613ab161507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613b3057602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613af35790505b5050505050815250509050919050565b60006001600a541115613b66576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314613bab5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6000613bb68561180a565b9050856001600160a01b0316816001600160a01b031614613bfd5760405163521eb56d60e11b81526001600160a01b03808816600483015282166024820152604401610dda565b6001600160a01b03841660009081526014602052604090205460ff16613c405760405162a2307960e51b81526001600160a01b0385166004820152602401610dda565b600085815260156020526040902060036002820154600160601b900460ff166005811115613c7057613c7061507c565b14613cb9576002810154600160601b900460ff166005811115613c9557613c9561507c565b604051633c053f9d60e21b8152600481019190915260248101879052604401610dda565b604080516101008101825282546001600160601b0381168252600160601b908190046001600160a01b03166020830152600184015492820192909252600283015463ffffffff8082166060840152640100000000820481166080840152600160401b82041660a0830152600092613de69291859160c08401910460ff166005811115613d4757613d4761507c565b6005811115613d5857613d5861507c565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613dd757602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613d9a5790505b505050505081525050886142de565b6002830154604051631e731b7560e31b81529192506001600160a01b0388169163f398dba891613e2391859163ffffffff16908a90600401615c5d565b6020604051808303816000875af1158015613e42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e669190615c98565b6000888152601360205260409020600384018054929650613e8692614d9a565b506040516304d9dc3f60e11b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906309b3b87e90613ed6906003860190600401615cb5565b600060405180830381865afa158015613ef3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613f1b9190810190615e3d565b60008881526012602090815260409091208251613f3e9391929190910190614ca8565b5081546001600160601b0316600160601b6001600160a01b03861690810291909117835560028301805460ff60601b19166c0400000000000000000000000017905560405188907f2d53f895cd5faf3cddba94a25c2ced2105885b5b37450ff430ffa3cbdf332c7490600090a360405187907fa133ed72c03a7d008deaae618a61613c4fd41c67bba1cad1a6bc0a1c5a9c156e90600090a250506001600a5550949350505050565b60006001600a54111561400c576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146140515760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610dda565b6001600160a01b0386166140785760405163d92e233d60e01b815260040160405180910390fd5b6140838585856145ff565b60005b8451811015614117578381815181106140a1576140a1615964565b60200260200101516000015163ffffffff16600014806140e757508381815181106140ce576140ce615964565b6020026020010151602001516001600160601b03166000145b1561410557604051637c946ed760e01b815260040160405180910390fd5b8061410f81615990565b915050614086565b50506009548061412681615990565b9150506141716040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b63ffffffff8316606082015260408101869052600160c08201818152505061419d8186868851866147c6565b6000828152601560209081526040918290208351918401516001600160a01b0316600160601b9081026001600160601b039093169290921781559183015160018301556060830151600283018054608086015160a087015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c0860151869594909360ff60601b19166cffffffffff00000000000000001990921691909117908360058111156142725761427261507c565b021790555060e08201518051614292916003840191602090910190614ca8565b50505060098290556142a48783614a7d565b60405182907f9169d45eacd63571e315a0504da919b7c89de505493e7b34051802dd0816a06990600090a2506001600a5595945050505050565b60608260a0015163ffffffff1667ffffffffffffffff8111156143035761430361510f565b60405190808252806020026020018201604052801561432c578160200160208202803683370190505b5090506000805b8460e001515181101561442757600084905060208660e00151838151811061435d5761435d615964565b602002602001015163ffffffff16901b8117905060005b6000828152600f6020526040902054811015614412576000828152600f602052604090208054829081106143aa576143aa615964565b9060005260206000200160009054906101000a90046001600160a01b03168585815181106143da576143da615964565b6001600160a01b0390921660209283029190910190910152836143fc81615990565b945050808061440a90615990565b915050614374565b5050808061441f90615990565b915050614333565b505092915050565b7aff00000000000000ff00000000000000ff00000000000000ff00006bffffffff0000000000000000604083901c9081167bffffffff00000000000000000000000000000000000000000000000084161760201c6fffffffff000000000000000000000000919091166001600160e01b031984161717601081901c9182167eff00000000000000ff00000000000000ff00000000000000ff000000000000821617600890811c7bff00000000000000ff00000000000000ff00000000000000ff000000939093167fff00000000000000ff00000000000000ff00000000000000ff000000000000009290921691909117919091179081901c7e0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f167f0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f00600492831c16179061459b827f06060606060606060606060606060606060606060606060606060606060606066159c6565b901c7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f1660276145cb9190615ed7565b6145f5827f30303030303030303030303030303030303030303030303030303030303030306159c6565b610cc491906159c6565b600083900361462157604051637c946ed760e01b815260040160405180910390fd5b8151158061463157508051825114155b1561465c57815181516040516308151c1160e41b815260048101929092526024820152604401610dda565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156146bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146e09190615ef6565b90506000805b84518110156147be576146fa8260016159c6565b85828151811061470c5761470c615964565b602002602001015163ffffffff16108061474457508285828151811061473457614734615964565b602002602001015163ffffffff16115b156147895784818151811061475b5761475b615964565b6020026020010151604051632ab10b0b60e21b8152600401610dda919063ffffffff91909116815260200190565b84818151811061479b5761479b615964565b602002602001015163ffffffff16915080806147b690615990565b9150506146e6565b505050505050565b60008267ffffffffffffffff8111156147e1576147e161510f565b60405190808252806020026020018201604052801561480a578160200160208202803683370190505b5060e087015260005b8381101561499a5785818151811061482d5761482d615964565b60200260200101518760e00151828151811061484b5761484b615964565b63ffffffff909216602092830291909101820152865184919088908490811061487657614876615964565b602002602001015163ffffffff16901b8117905085828151811061489c5761489c615964565b6020908102919091018101516000838152600e8352604090208151815492909301516001600160601b0316640100000000026fffffffffffffffffffffffffffffffff1990921663ffffffff90931692909217179055855186908390811061490657614906615964565b602002602001015160000151886080018181516149239190615f0f565b63ffffffff1690525085516001600160601b0384169087908490811061494b5761494b615964565b6020026020010151602001516001600160601b031611156149875785828151811061497857614978615964565b60200260200101516020015192505b508061499281615990565b915050614813565b506001600160601b038116865260808601516000906149ba906002615f2e565b6149c5906001615f0f565b63ffffffff1690506149d8600382615f70565b6000036149f1576149ea600382615f84565b9050614a0a565b6149fc600382615f84565b614a079060016159c6565b90505b80876060015163ffffffff161080614a355750866080015163ffffffff16876060015163ffffffff16115b15614a74576060870151608088015160405163eb3a8ba360e01b815263ffffffff92831660048201526024810184905291166044820152606401610dda565b50505050505050565b614a878282614b6d565b6001600160a01b0382163b15614b6957604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af1158015614afb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b1f91906159a9565b6001600160e01b03191614614b695760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610dda565b5050565b6001600160a01b038216614bb75760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610dda565b6000818152600260205260409020546001600160a01b031615614c1c5760405162461bcd60e51b815260206004820152600e60248201527f414c52454144595f4d494e5445440000000000000000000000000000000000006044820152606401610dda565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b5080546000825590600052602060002090810190614ca59190614de8565b50565b82805482825590600052602060002090600701600890048101928215614d475791602002820160005b83821115614d1557835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614cd1565b8015614d455782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614d15565b505b50614d53929150614e18565b5090565b508054600082556007016008900490600052602060002090810190614ca59190614e18565b5080546000825590600052602060002090810190614ca59190614e18565b82805482825590600052602060002090600701600890048101928215614d47576000526020600020916007016008900482015b82811115614d47578254825591600101919060010190614dcd565b5b80821115614d5357805477ffffffffffffffffffffffffffffffffffffffffffffffff19168155600101614de9565b5b80821115614d535760008155600101614e19565b6001600160e01b031981168114614ca557600080fd5b600060208284031215614e5557600080fd5b8135614e6081614e2d565b9392505050565b60005b83811015614e82578181015183820152602001614e6a565b83811115614e91576000848401525b50505050565b60008151808452614eaf816020860160208601614e67565b601f01601f19169290920160200192915050565b602081526000614e606020830184614e97565b600060208284031215614ee857600080fd5b5035919050565b6001600160a01b0381168114614ca557600080fd5b60008060408385031215614f1757600080fd5b8235614f2281614eef565b946020939093013593505050565b600060208284031215614f4257600080fd5b8135614e6081614eef565b6000604080830185845260208281860152818651808452606087019150828801935060005b81811015614fa6578451805163ffffffff1684528401516001600160601b0316848401529383019391850191600101614f72565b509098975050505050505050565b60008060408385031215614fc757600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b8381101561500f5781516001600160a01b031687529582019590820190600101614fea565b509495945050505050565b8281526040602082015260006150336040830184614fd6565b949350505050565b60008060006060848603121561505057600080fd5b833561505b81614eef565b9250602084013561506b81614eef565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b600681106150b057634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03881681526001600160a01b03871660208201526040810186905263ffffffff85811660608301528481166080830152831660a082015260e0810161510360c0830184615092565b98975050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156151485761514861510f565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156151775761517761510f565b604052919050565b600067ffffffffffffffff8311156151995761519961510f565b6151ac601f8401601f191660200161514e565b90508281528383830111156151c057600080fd5b828260208301376000602084830101529392505050565b6000602082840312156151e957600080fd5b813567ffffffffffffffff81111561520057600080fd5b8201601f8101841361521157600080fd5b6150338482356020840161517f565b600067ffffffffffffffff82111561523a5761523a61510f565b5060051b60200190565b600082601f83011261525557600080fd5b8135602061526a61526583615220565b61514e565b82815260059290921b8401810191818101908684111561528957600080fd5b8286015b848110156152ad5780356152a081614eef565b835291830191830161528d565b509695505050505050565b80356001600160601b038116811461172457600080fd5b6000806000606084860312156152e457600080fd5b833567ffffffffffffffff808211156152fc57600080fd5b61530887838801615244565b945060209150818601358181111561531f57600080fd5b86019050601f8101871361533257600080fd5b803561534061526582615220565b81815260059190911b8201830190838101908983111561535f57600080fd5b928401925b8284101561538457615375846152b8565b82529284019290840190615364565b96999698505050506040949094013593505050565b600080604083850312156153ac57600080fd5b82356153b781614eef565b9150602083013580151581146153cc57600080fd5b809150509250929050565b600080604083850312156153ea57600080fd5b823560028110614f2257600080fd5b600081518084526020808501945080840160005b8381101561500f57815163ffffffff168752958201959082019060010161540d565b82815260406020820152600061503360408301846153f9565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156154895784518352938301939183019160010161546d565b5090979650505050505050565b6000806000806000608086880312156154ae57600080fd5b85356154b981614eef565b945060208601356154c981614eef565b935060408601359250606086013567ffffffffffffffff808211156154ed57600080fd5b818801915088601f83011261550157600080fd5b81358181111561551057600080fd5b89602082850101111561552257600080fd5b9699959850939650602001949392505050565b63ffffffff81168114614ca557600080fd5b600082601f83011261555857600080fd5b8135602061556861526583615220565b82815260059290921b8401810191818101908684111561558757600080fd5b8286015b848110156152ad57803561559e81615535565b835291830191830161558b565b600082601f8301126155bc57600080fd5b813560206155cc61526583615220565b82815260069290921b840181019181810190868411156155eb57600080fd5b8286015b848110156152ad57604081890312156156085760008081fd5b615610615125565b813561561b81615535565b81526156288286016152b8565b818601528352918301916040016155ef565b60008060008060008060c0878903121561565357600080fd5b863561565e81614eef565b955060208701359450604087013567ffffffffffffffff8082111561568257600080fd5b61568e8a838b01615547565b955060608901359150808211156156a457600080fd5b506156b189828a016155ab565b93505060808701356156c281615535565b8092505060a087013590509295509295509295565b600080600080608085870312156156ed57600080fd5b84356156f881614eef565b935060208501359250604085013567ffffffffffffffff8082111561571c57600080fd5b61572888838901615244565b9350606087013591508082111561573e57600080fd5b5061574b87828801615547565b91505092959194509250565b6000806040838503121561576a57600080fd5b823561577581614eef565b915060208301356153cc81614eef565b602081526001600160601b0382511660208201526001600160a01b03602083015116604082015260408201516060820152600060608301516157cf608084018263ffffffff169052565b50608083015163ffffffff811660a08401525060a083015163ffffffff811660c08401525060c083015161580660e0840182615092565b5060e0830151610100838101526150336101208401826153f9565b6000806000806080858703121561583757600080fd5b843561584281614eef565b935060208501359250604085013561585981614eef565b9150606085013567ffffffffffffffff81111561587557600080fd5b8501601f8101871361588657600080fd5b61574b8782356020840161517f565b600080600080600060a086880312156158ad57600080fd5b85356158b881614eef565b945060208601359350604086013567ffffffffffffffff808211156158dc57600080fd5b6158e889838a01615547565b945060608801359150808211156158fe57600080fd5b5061590b888289016155ab565b925050608086013561591c81615535565b809150509295509295909350565b600181811c9082168061593e57607f821691505b60208210810361595e57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016159a2576159a261597a565b5060010190565b6000602082840312156159bb57600080fd5b8151614e6081614e2d565b600082198211156159d9576159d961597a565b500190565b601f82111561156b57600081815260208120601f850160051c81016020861015615a055750805b601f850160051c820191505b818110156147be57828155600101615a11565b815167ffffffffffffffff811115615a3e57615a3e61510f565b615a5281615a4c845461592a565b846159de565b602080601f831160018114615a875760008415615a6f5750858301515b600019600386901b1c1916600185901b1785556147be565b600085815260208120601f198616915b82811015615ab657888601518255948401946001909101908401615a97565b5085821015615ad45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006001600160601b03808316818516808303821115615b0657615b0661597a565b01949350505050565b60006001600160601b0383811690831681811015615b2f57615b2f61597a565b039392505050565b600063ffffffff83811690831681811015615b2f57615b2f61597a565b60006001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b6000808654615bb68161592a565b60018281168015615bce5760018114615be357615c12565b60ff1984168752821515830287019450615c12565b8a60005260208060002060005b85811015615c095781548a820152908401908201615bf0565b50505082870194505b505050508551615c26818360208a01614e67565b019384525050602082015260400192915050565b600063ffffffff808316818103615c5357615c5361597a565b6001019392505050565b606081526000615c706060830186614fd6565b63ffffffff851660208401528281036040840152615c8e8185614e97565b9695505050505050565b600060208284031215615caa57600080fd5b8151614e6081614eef565b60006020808301818452808554615cd0818490815260200190565b60008881526020812094509092505b81600782011015615d5557835463ffffffff808216855281871c811687860152604082811c821690860152606082811c821690860152608082811c82169086015260a082811c82169086015260c082811c9091169085015260e090811c9084015260019093019261010090920191600801615cdf565b92549281811015615d715763ffffffff84168352918401916001015b81811015615d8c5783851c63ffffffff168352918401916001015b81811015615da957604084901c63ffffffff168352918401916001015b81811015615dc657606084901c63ffffffff168352918401916001015b81811015615de357608084901c63ffffffff168352918401916001015b81811015615e005760a084901c63ffffffff168352918401916001015b81811015615e1d5760c084901c63ffffffff168352918401916001015b81811015615e315760e084901c8352918401915b50909695505050505050565b60006020808385031215615e5057600080fd5b825167ffffffffffffffff811115615e6757600080fd5b8301601f81018513615e7857600080fd5b8051615e8661526582615220565b81815260059190911b82018301908381019087831115615ea557600080fd5b928401925b82841015615ecc578351615ebd81615535565b82529284019290840190615eaa565b979650505050505050565b6000816000190483118215151615615ef157615ef161597a565b500290565b600060208284031215615f0857600080fd5b5051919050565b600063ffffffff808316818516808303821115615b0657615b0661597a565b600063ffffffff80831681851681830481118215151615615f5157615f5161597a565b02949350505050565b634e487b7160e01b600052601260045260246000fd5b600082615f7f57615f7f615f5a565b500690565b600082615f9357615f93615f5a565b50049056fea2646970667358221220c6f47c49865f99357fc7f3a83dfde648490b39975e4ec4242e3bcab08caabf3664736f6c634300080f0033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/service_registry/build/ServiceRegistryL2.json b/trader_old/vendor/valory/contracts/service_registry/build/ServiceRegistryL2.json deleted file mode 100644 index 0054fd27a..000000000 --- a/trader_old/vendor/valory/contracts/service_registry/build/ServiceRegistryL2.json +++ /dev/null @@ -1,1899 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ServiceRegistryL2", - "sourceName": "contracts/ServiceRegistryL2.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_symbol", - "type": "string" - }, - { - "internalType": "string", - "name": "_baseURI", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "AgentInstanceRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentInstancesSlotsFilled", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "AgentNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentNotInService", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "componentId", - "type": "uint256" - } - ], - "name": "ComponentNotFound", - "type": "error" - }, - { - "inputs": [], - "name": "HashExists", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectAgentBondingValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectRegistrationDepositValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "provided", - "type": "address" - }, - { - "internalType": "address", - "name": "expected", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OnlyOwnServiceMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorHasNoInstances", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "Overflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerOnly", - "type": "error" - }, - { - "inputs": [], - "name": "Paused", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrancyGuard", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceMustBeInactive", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "TransferFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "UnauthorizedMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "WrongAgentId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "numValues1", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numValues2", - "type": "uint256" - } - ], - "name": "WrongArrayLength", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongOperator", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "state", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceState", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "currentThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxThreshold", - "type": "uint256" - } - ], - "name": "WrongThreshold", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ActivateRegistration", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "string", - "name": "baseURI", - "type": "string" - } - ], - "name": "BaseURIChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "CreateMultisigWithAgents", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - } - ], - "name": "CreateService", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "DeployService", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "drainer", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Drain", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "drainer", - "type": "address" - } - ], - "name": "DrainerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorSlashed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorUnbond", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "receiver", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Refund", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "agentInstance", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "RegisterInstance", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "TerminateService", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - } - ], - "name": "UpdateService", - "type": "event" - }, - { - "inputs": [], - "name": "CID_PREFIX", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "activateRegistration", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newDrainer", - "type": "address" - } - ], - "name": "changeDrainer", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newManager", - "type": "address" - } - ], - "name": "changeManager", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "bool", - "name": "permission", - "type": "bool" - } - ], - "name": "changeMultisigPermission", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "changeOwner", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "internalType": "struct AgentParams[]", - "name": "agentParams", - "type": "tuple[]" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - } - ], - "name": "create", - "outputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "multisigImplementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "deploy", - "outputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "drain", - "outputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "drainer", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "name": "exists", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getAgentInstances", - "outputs": [ - { - "internalType": "uint256", - "name": "numAgentInstances", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getAgentParams", - "outputs": [ - { - "internalType": "uint256", - "name": "numAgentIds", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "internalType": "struct AgentParams[]", - "name": "agentParams", - "type": "tuple[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "getInstancesForAgentId", - "outputs": [ - { - "internalType": "uint256", - "name": "numAgentInstances", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getOperatorBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getPreviousHashes", - "outputs": [ - { - "internalType": "uint256", - "name": "numHashes", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "configHashes", - "type": "bytes32[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getService", - "outputs": [ - { - "components": [ - { - "internalType": "uint96", - "name": "securityDeposit", - "type": "uint96" - }, - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "maxNumAgentInstances", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "numAgentInstances", - "type": "uint32" - }, - { - "internalType": "enum ServiceRegistryL2.ServiceState", - "name": "state", - "type": "uint8" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - } - ], - "internalType": "struct ServiceRegistryL2.Service", - "name": "service", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "manager", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapAgentInstanceOperators", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapConfigHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "mapMultisigs", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapOperatorAndServiceIdAgentInstances", - "outputs": [ - { - "internalType": "address", - "name": "instance", - "type": "address" - }, - { - "internalType": "uint32", - "name": "agentId", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapOperatorAndServiceIdOperatorBalances", - "outputs": [ - { - "internalType": "uint96", - "name": "", - "type": "uint96" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceAndAgentIdAgentInstances", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceAndAgentIdAgentParams", - "outputs": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServices", - "outputs": [ - { - "internalType": "uint96", - "name": "securityDeposit", - "type": "uint96" - }, - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "maxNumAgentInstances", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "numAgentInstances", - "type": "uint32" - }, - { - "internalType": "enum ServiceRegistryL2.ServiceState", - "name": "state", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - } - ], - "name": "registerAgents", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "bURI", - "type": "string" - } - ], - "name": "setBaseURI", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "agentInstances", - "type": "address[]" - }, - { - "internalType": "uint96[]", - "name": "amounts", - "type": "uint96[]" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "slash", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "slashedFunds", - "outputs": [ - { - "internalType": "uint96", - "name": "", - "type": "uint96" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "terminate", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "refund", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "tokenByIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "unitId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "unbond", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "refund", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "serviceOwner", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "uint32[]", - "name": "agentIds", - "type": "uint32[]" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "slots", - "type": "uint32" - }, - { - "internalType": "uint96", - "name": "bond", - "type": "uint96" - } - ], - "internalType": "struct AgentParams[]", - "name": "agentParams", - "type": "tuple[]" - }, - { - "internalType": "uint32", - "name": "threshold", - "type": "uint32" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "update", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x60806040526001600a553480156200001657600080fd5b5060405162005bcb38038062005bcb83398101604081905262000039916200014d565b828260006200004983826200026d565b5060016200005882826200026d565b50600891506200006b905082826200026d565b5050600680546001600160a01b0319163317905550620003399050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000b057600080fd5b81516001600160401b0380821115620000cd57620000cd62000088565b604051601f8301601f19908116603f01168101908282118183101715620000f857620000f862000088565b816040528381526020925086838588010111156200011557600080fd5b600091505b838210156200013957858201830151818301840152908201906200011a565b600093810190920192909252949350505050565b6000806000606084860312156200016357600080fd5b83516001600160401b03808211156200017b57600080fd5b62000189878388016200009e565b94506020860151915080821115620001a057600080fd5b620001ae878388016200009e565b93506040860151915080821115620001c557600080fd5b50620001d4868287016200009e565b9150509250925092565b600181811c90821680620001f357607f821691505b6020821081036200021457634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200026857600081815260208120601f850160051c81016020861015620002435750805b601f850160051c820191505b8181101562000264578281556001016200024f565b5050505b505050565b81516001600160401b0381111562000289576200028962000088565b620002a1816200029a8454620001de565b846200021a565b602080601f831160018114620002d95760008415620002c05750858301515b600019600386901b1c1916600185901b17855562000264565b600085815260208120601f198616915b828110156200030a57888601518255948401946001909101908401620002e9565b5085821015620003295787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61588280620003496000396000f3fe6080604052600436106103345760003560e01c806370a08231116101b0578063a60e4c3c116100ec578063dff7672411610095578063ef0e239b1161006f578063ef0e239b14610af7578063f908bc7714610b24578063fbdeb3d714610b44578063ffa1ad7414610b6457600080fd5b8063dff7672414610a96578063e23f6fb414610aa9578063e985e9c514610abc57600080fd5b8063c87b56dd116100c6578063c87b56dd14610a36578063cbf994f814610a56578063ccc9305d14610a7657600080fd5b8063a60e4c3c146109c8578063a6f9dae1146109f6578063b88d4fde14610a1657600080fd5b80638a2bd86f116101595780639890220b116101335780639890220b1461093c578063a22cb46514610951578063a3fbbaae14610971578063a5d059ca1461099157600080fd5b80638a2bd86f146108c25780638da5cb5b1461090757806395d89b411461092757600080fd5b80637c5e63e01161018a5780637c5e63e01461084d57806382694b1d1461088257806386a2bdd4146108a257600080fd5b806370a08231146107c9578063718934d8146107e957806373b8b6a21461082d57600080fd5b806342842e0e1161027f57806355f804b3116102285780636352211e116102025780636352211e1461070a57806363dd76151461072a5780636c0360eb146107945780636f99f15c146107a957600080fd5b806355f804b3146106a357806357838e85146106c35780635e4507fa146106ea57600080fd5b80634eb780da116102595780634eb780da1461062d5780634f558e79146106635780634f6ccce71461068357600080fd5b806342842e0e146105cd578063481c6a75146105ed5780634d486f851461060d57600080fd5b806318160ddd116102e157806323b872dd116102bb57806323b872dd146104d057806342144854146104f05780634236aff81461053e57600080fd5b806318160ddd146104505780631de286ba1461047457806321e4f7bb146104a257600080fd5b8063095ea7b311610312578063095ea7b3146103de57806310c6aa191461040057806317351f7e1461042057600080fd5b806301ffc9a71461033957806306fdde031461036e578063081812fc14610390575b600080fd5b34801561034557600080fd5b506103596103543660046149a2565b610b95565b60405190151581526020015b60405180910390f35b34801561037a57600080fd5b50610383610be7565b6040516103659190614a16565b34801561039c57600080fd5b506103c66103ab366004614a29565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610365565b3480156103ea57600080fd5b506103fe6103f9366004614a57565b610c75565b005b34801561040c57600080fd5b506103fe61041b366004614a83565b610d5c565b34801561042c57600080fd5b5061035961043b366004614a83565b60126020526000908152604090205460ff1681565b34801561045c57600080fd5b5061046660095481565b604051908152602001610365565b34801561048057600080fd5b5061049461048f366004614a29565b610e15565b604051610365929190614aa0565b3480156104ae57600080fd5b506104c26104bd366004614b07565b61106b565b604051610365929190614b6d565b3480156104dc57600080fd5b506103fe6104eb366004614b8e565b611159565b3480156104fc57600080fd5b5061052661050b366004614a29565b6010602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610365565b34801561054a57600080fd5b506105ba610559366004614a29565b6013602052600090815260409020805460018201546002909201546001600160601b03821692600160601b928390046001600160a01b031692909163ffffffff808216926401000000008304821692600160401b8104909216910460ff1687565b6040516103659796959493929190614c07565b3480156105d957600080fd5b506103fe6105e8366004614b8e565b611333565b3480156105f957600080fd5b506007546103c6906001600160a01b031681565b34801561061957600080fd5b506104c2610628366004614a29565b611428565b34801561063957600080fd5b506103c6610648366004614a83565b6011602052600090815260409020546001600160a01b031681565b34801561066f57600080fd5b5061035961067e366004614a29565b61157a565b34801561068f57600080fd5b5061046661069e366004614a29565b61159c565b3480156106af57600080fd5b506103fe6106be366004614d2a565b6115e1565b3480156106cf57600080fd5b50600b546103c690600160601b90046001600160a01b031681565b3480156106f657600080fd5b506103c6610705366004614b07565b61168a565b34801561071657600080fd5b506103c6610725366004614a29565b6116c2565b34801561073657600080fd5b50610770610745366004614a29565b600e6020526000908152604090205463ffffffff81169064010000000090046001600160601b031682565b6040805163ffffffff90931683526001600160601b03909116602083015201610365565b3480156107a057600080fd5b50610383611727565b3480156107b557600080fd5b50600b54610526906001600160601b031681565b3480156107d557600080fd5b506104666107e4366004614a83565b611734565b3480156107f557600080fd5b50610809610804366004614b07565b6117a8565b604080516001600160a01b03909316835263ffffffff909116602083015201610365565b34801561083957600080fd5b50610359610848366004614e22565b6117ee565b34801561085957600080fd5b506103836040518060400160405280600981526020016806630313730313232360bc1b81525081565b34801561088e57600080fd5b5061035961089d366004614eec565b611c43565b3480156108ae57600080fd5b506104666108bd366004614b07565b611cdc565b3480156108ce57600080fd5b506104666108dd366004614a57565b60a01b6001600160a01b03909116176000908152601060205260409020546001600160601b031690565b34801561091357600080fd5b506006546103c6906001600160a01b031681565b34801561093357600080fd5b50610383611d0d565b34801561094857600080fd5b50610466611d1a565b34801561095d57600080fd5b506103fe61096c366004614eec565b611e78565b34801561097d57600080fd5b506103fe61098c366004614a83565b611ee4565b34801561099d57600080fd5b506109b16109ac366004614a57565b611f95565b604080519215158352602083019190915201610365565b3480156109d457600080fd5b506109e86109e3366004614a29565b612431565b604051610365929190614f2a565b348015610a0257600080fd5b506103fe610a11366004614a83565b612495565b348015610a2257600080fd5b506103fe610a31366004614f78565b612546565b348015610a4257600080fd5b50610383610a51366004614a29565b61262b565b348015610a6257600080fd5b50610359610a7136600461511a565b6126a5565b348015610a8257600080fd5b506109b1610a91366004614a57565b612c33565b610359610aa43660046151b3565b612f95565b610359610ab7366004614a57565b613590565b348015610ac857600080fd5b50610359610ad7366004615233565b600560209081526000928352604080842090915290825290205460ff1681565b348015610b0357600080fd5b50610b17610b12366004614a29565b61370f565b6040516103659190615297565b348015610b3057600080fd5b506103c6610b3f366004615333565b61388f565b348015610b5057600080fd5b50610466610b5f3660046153a7565b613c60565b348015610b7057600080fd5b50610383604051806040016040528060058152602001640312e302e360dc1b81525081565b60006301ffc9a760e01b6001600160e01b031983161480610bc657506380ac58cd60e01b6001600160e01b03198316145b80610be15750635b5e139f60e01b6001600160e01b03198316145b92915050565b60008054610bf490615438565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2090615438565b8015610c6d5780601f10610c4257610100808354040283529160200191610c6d565b820191906000526020600020905b815481529060010190602001808311610c5057829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b031633811480610cbe57506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b610d005760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6006546001600160a01b03163314610d9c5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038116610dc35760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160601b0316600160601b6001600160a01b038416908102919091179091556040517f8d1e8547016120917daad7f81c42b48f7fee379badc48f1889f0f43bb619472590600090a250565b600081815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff9104166005811115610eb657610eb6614bcf565b6005811115610ec757610ec7614bcf565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015610f4657602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411610f095790505b50505050508152505090508060e001515192508267ffffffffffffffff811115610f7257610f72614c62565b604051908082528060200260200182016040528015610fb757816020015b6040805180820190915260008082526020820152815260200190600190039081610f905790505b50915060005b8381101561106457600085905060208360e001518381518110610fe257610fe2615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260409081902081518083019092525492831681526401000000009092046001600160601b031692820192909252845185908490811061104757611047615472565b6020026020010181905250508061105d9061549e565b9050610fbd565b5050915091565b602081811b83176000818152600f909252604090912054906060908267ffffffffffffffff81111561109f5761109f614c62565b6040519080825280602002602001820160405280156110c8578160200160208202803683370190505b50915060005b83811015611150576000828152600f602052604090208054829081106110f6576110f6615472565b9060005260206000200160009054906101000a90046001600160a01b031683828151811061112657611126615472565b6001600160a01b0390921660209283029190910190910152806111488161549e565b9150506110ce565b50509250929050565b6000818152600260205260409020546001600160a01b038481169116146111c25760405162461bcd60e51b815260206004820152600a60248201527f57524f4e475f46524f4d000000000000000000000000000000000000000000006044820152606401610cf7565b6001600160a01b03821661120c5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610cf7565b336001600160a01b038416148061124657506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061126757506000818152600460205260409020546001600160a01b031633145b6112a45760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610cf7565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61133e838383611159565b6001600160a01b0382163b1561142357604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af11580156113b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d991906154b7565b6001600160e01b031916146114235760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b505050565b600081815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff91041660058111156114c9576114c9614bcf565b60058111156114da576114da614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561155957602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff168152602001906004019060208260030104928301926001038202915080841161151c5790505b505050505081525050905061156e8185613f67565b91508151925050915091565b60008082118015610be157506009546115949060016154d4565b821092915050565b60006115a98260016154d4565b90506009548111156115dc57600954604051637ae5968560e01b8152610cf7918391600401918252602082015260400190565b919050565b6006546001600160a01b031633146116215760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b805160000361164357604051637c946ed760e01b815260040160405180910390fd5b600861164f8282615535565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf68160405161167f9190614a16565b60405180910390a150565b600f60205281600052604060002081815481106116a657600080fd5b6000918252602090912001546001600160a01b03169150829050565b6000818152600260205260409020546001600160a01b0316806115dc5760405162461bcd60e51b815260206004820152600a60248201527f4e4f545f4d494e544544000000000000000000000000000000000000000000006044820152606401610cf7565b60088054610bf490615438565b60006001600160a01b03821661178c5760405162461bcd60e51b815260206004820152600c60248201527f5a45524f5f4144445245535300000000000000000000000000000000000000006044820152606401610cf7565b506001600160a01b031660009081526003602052604090205490565b600d60205281600052604060002081815481106117c457600080fd5b6000918252602090912001546001600160a01b0381169250600160a01b900463ffffffff16905082565b600081815260136020908152604080832081516101008101835281546001600160601b0381168252600160601b908190046001600160a01b031694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a0840152849360c08401910460ff16600581111561188557611885614bcf565b600581111561189657611896614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561191557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116118d85790505b50505050508152505090506004600581111561193357611933614bcf565b8160c00151600581111561194957611949614bcf565b14611988578060c00151600581111561196457611964614bcf565b604051633c053f9d60e21b8152600481019190915260248101849052604401610cf7565b83518551146119b757845184516040516308151c1160e41b815260048101929092526024820152604401610cf7565b80602001516001600160a01b0316336001600160a01b031614611a0b5760208101516040516379f91cd360e01b81523360048201526001600160a01b03909116602482015260448101849052606401610cf7565b845160005b81811015611c3657600060116000898481518110611a3057611a30615472565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081205490931660a08a901b81178085526010909252919092205489519193506001600160601b03169081908a9086908110611a9557611a95615472565b60200260200101516001611aa991906155f5565b6001600160601b03161115611b0357600b8054829190600090611ad69084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060009050611b87565b888481518110611b1557611b15615472565b6020908102919091010151600b8054600090611b3b9084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550888481518110611b7157611b71615472565b602002602001015181611b84919061561c565b90505b600082815260106020526040902080546bffffffffffffffffffffffff19166001600160601b038316179055885188906001600160a01b038516907fa2e524bd0f71903485fbb3d6d50cb305f61005ceea2047c3ac92aa7e0d104306908c9088908110611bf657611bf6615472565b6020026020010151604051611c1a91906001600160601b0391909116815260200190565b60405180910390a350505080611c2f9061549e565b9050611a10565b5060019695505050505050565b6006546000906001600160a01b03163314611c865760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038316611cad5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b03919091166000908152601260205260409020805460ff1916911515919091179055600190565b600c6020528160005260406000208181548110611cf857600080fd5b90600052602060002001600091509150505481565b60018054610bf490615438565b60006001600a541115611d40576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a55600b54600160601b90046001600160a01b03163314611d9257600b5460405163312d21ff60e11b8152336004820152600160601b9091046001600160a01b03166024820152604401610cf7565b50600b546001600160601b03168015611e7057600b80546bffffffffffffffffffffffff19169055604051600090339083908381818185875af1925050503d8060008114611dfc576040519150601f19603f3d011682016040523d82523d6000602084013e611e01565b606091505b5050905080611e395760405163cd3f165960e01b81526000600482015230602482015233604482015260648101839052608401610cf7565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2505b6001600a5590565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6006546001600160a01b03163314611f245760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038116611f4b5760405163d92e233d60e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f2c1c11af44aa5608f1dca38c00275c30ea091e02417d36e70e9a1538689c433d90600090a250565b6000806001600a541115611fbc576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146120015760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b0384166120285760405163d92e233d60e01b815260040160405180910390fd5b600083815260136020526040902060056002820154600160601b900460ff16600581111561205857612058614bcf565b146120a1576002810154600160601b900460ff16600581111561207d5761207d614bcf565b604051633c053f9d60e21b8152600481019190915260248101859052604401610cf7565b60a084901b6001600160a01b038616176000818152600d6020908152604080832080548251818502810185019093528083529192909190849084015b8282101561212957600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900463ffffffff16818301528252600190920191016120dd565b50508251929350505060008190036121665760405163df2ddd7360e01b81526001600160a01b038916600482015260248101889052604401610cf7565b808460020160088282829054906101000a900463ffffffff16612189919061563c565b92506101000a81548163ffffffff021916908363ffffffff1602179055508360020160089054906101000a900463ffffffff1663ffffffff166000036121df5760028401805460ff60601b1916600160601b1790555b60005b818110156122a7576000889050602084838151811061220357612203615472565b60209081029190910181015181015163ffffffff1690911b919091176000818152600e90925260409091205461224a9064010000000090046001600160601b0316886154d4565b96506011600085848151811061226257612262615472565b602090810291909101810151516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055508061229f8161549e565b9150506121e2565b506000838152600d602052604081206122bf91614859565b6000838152601060205260409020546001600160601b0316808611156122ec57806001600160601b031695505b85156123e55760008481526010602052604080822080546bffffffffffffffffffffffff19169055516001600160a01b038b169088908381818185875af1925050503d806000811461235a576040519150601f19603f3d011682016040523d82523d6000602084013e61235f565b606091505b50509050806123a05760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038b16604482015260648101889052608401610cf7565b896001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d886040516123db91815260200190565b60405180910390a2505b60405188906001600160a01b038b16907f5ebf7fe30be09f0f03b9195632508d95c8b67bf010c93abda67f70d5d9599d1e90600090a350506001600a8190559793965092945050505050565b6000818152600c60209081526040808320805482518185028101850190935280835260609383018282801561248557602002820191906000526020600020905b815481526020019060010190808311612471575b5050505050905080519150915091565b6006546001600160a01b031633146124d55760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b0381166124fc5760405163d92e233d60e01b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b90600090a250565b612551858585611159565b6001600160a01b0384163b1561262457604051630a85bd0160e11b808252906001600160a01b0386169063150b7a02906125979033908a90899089908990600401615659565b6020604051808303816000875af11580156125b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125da91906154b7565b6001600160e01b031916146126245760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b5050505050565b6000818152601360205260408120600101546060915060086040518060400160405280600981526020016806630313730313232360bc1b81525061266e836140b8565b61267b608085901b6140b8565b60405160200161268e94939291906156ad565b604051602081830303815290604052915050919050565b6007546000906001600160a01b031633146126e85760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b60006126f3836116c2565b9050876001600160a01b0316816001600160a01b03161461273a5760405163521eb56d60e11b81526001600160a01b03808a16600483015282166024820152604401610cf7565b600083815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a08401529192909160c084019160ff91041660058111156127d4576127d4614bcf565b60058111156127e5576127e5614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561286457602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116128275790505b50505050508152505090506001600581111561288257612882614bcf565b8160c00151600581111561289857612898614bcf565b146128b3578060c00151600581111561207d5761207d614bcf565b6128be888888614288565b63ffffffff85166060820152600060808201819052875167ffffffffffffffff8111156128ed576128ed614c62565b604051908082528060200260200182016040528015612916578160200160208202803683370190505b5090506000885167ffffffffffffffff81111561293557612935614c62565b60405190808252806020026020018201604052801561297a57816020015b60408051808201909152600080825260208201528152602001906001900390816129535790505b5090506000805b8a51811015612aaf5789818151811061299c5761299c615472565b60200260200101516000015163ffffffff16600003612a1157600088905060208c83815181106129ce576129ce615472565b60209081029190910181015163ffffffff1690911b919091176000908152600e9091526040902080546fffffffffffffffffffffffffffffffff19169055612a9d565b8a8181518110612a2357612a23615472565b6020026020010151848381518110612a3d57612a3d615472565b602002602001019063ffffffff16908163ffffffff1681525050898181518110612a6957612a69615472565b6020026020010151838381518110612a8357612a83615472565b60200260200101819052508180612a999061549e565b9250505b80612aa78161549e565b915050612981565b5060408401518b8114612ae6576000888152600c602090815260408083208054600181018255908452919092200182905585018c90525b612af3858585858c614398565b6000888152601360209081526040918290208751918801516001600160a01b0316600160601b9081026001600160601b03909316929092178155918701516001830155606087015160028301805460808a015160a08b015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c08a01518a9594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115612bc857612bc8614bcf565b021790555060e08201518051612be891600384019160209091019061487a565b50506040518d81528991507fff312ce131c4d73ac90ece91266be7090486c5e15f78b7ea2b108c36dfd475299060200160405180910390a25060019c9b505050505050505050505050565b6000806001600a541115612c5a576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314612c9f5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6000612caa846116c2565b9050846001600160a01b0316816001600160a01b031614612cf15760405163521eb56d60e11b81526001600160a01b03808716600483015282166024820152604401610cf7565b600084815260136020526040902060016002820154600160601b900460ff166005811115612d2157612d21614bcf565b1480612d4c575060056002820154600160601b900460ff166005811115612d4a57612d4a614bcf565b145b15612d95576002810154600160601b900460ff166005811115612d7157612d71614bcf565b604051633c053f9d60e21b8152600481019190915260248101869052604401610cf7565b6002810154600160401b900463ffffffff1615612dcf5760028101805460ff60601b19166c05000000000000000000000000179055612de5565b60028101805460ff60601b1916600160601b1790555b60005b6003820154811015612e725760008690506020836003018381548110612e1057612e10615472565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff16901b81179050600f60008281526020019081526020016000206000612e619190614929565b50612e6b8161549e565b9050612de8565b5080546040516001600160601b0390911693506000906001600160a01b0388169085908381818185875af1925050503d8060008114612ecd576040519150601f19603f3d011682016040523d82523d6000602084013e612ed2565b606091505b5050905080612f135760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038816604482015260648101859052608401610cf7565b866001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d85604051612f4e91815260200190565b60405180910390a260405186907fe45f5b9540df4f71b7e044809fa318806328c1ea2388a70c7373d97ccf8a0faa90600090a250506001600a819055959194509092505050565b6007546000906001600160a01b03163314612fd85760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b815183511461300757825182516040516308151c1160e41b815260048101929092526024820152604401610cf7565b6000848152601360205260409020600280820154600160601b900460ff16600581111561303657613036614bcf565b1461305b576002810154600160601b900460ff166005811115612d7157612d71614bcf565b83516000805b82811015613150576000889050602087838151811061308257613082615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260408082208151808301909252549384168082526401000000009094046001600160601b0316948101949094529092919003613123578783815181106130ee576130ee615472565b60200260200101518a6040516332832be560e21b8152600401610cf792919063ffffffff929092168252602082015260400190565b602081015161313b906001600160601b0316856154d4565b93505050806131499061549e565b9050613061565b5080341461318157604051637ebbcab960e11b81523460048201526024810182905260448101889052606401610cf7565b6001600160a01b0388811660009081526011602052604090205416156131bd576040516322ddebd960e21b815260048101889052602401610cf7565b60a087901b6001600160a01b0389161760005b838110156134b15760008882815181106131ec576131ec615472565b60200260200101519050600088838151811061320a5761320a615472565b60200260200101519050816001600160a01b03168c6001600160a01b031603613249576040516322ddebd960e21b8152600481018c9052602401610cf7565b6001600160a01b0382811660009081526011602052604090205416156132a0576001600160a01b038281166000908152601160205260409081902054905163631695bd60e01b815291166004820152602401610cf7565b60008b905060208a85815181106132b9576132b9615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e8452604080822054600f90955290205490929091169003613312576040516304ad100760e21b8152600481018d9052602401610cf7565b6000818152600f602090815260408083208054600181810183559185528385200180546001600160a01b03808a166001600160a01b031990921682179092558a8652600d8552838620845180860190955290845263ffffffff8089168587019081528254948501835591875294909520925192909101805494518416600160a01b0277ffffffffffffffffffffffffffffffffffffffffffffffff19909516929091169190911792909217909155600289018054600160401b90049091169060086133dc8361573f565b91906101000a81548163ffffffff021916908363ffffffff160217905550508c60116000856001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001600160a01b03168c8e6001600160a01b03167f6835389a6da5341647f18cbe0a89c56f473f4c17bfaee6e6d07d61f1928e0b7c85604051613495919063ffffffff91909116815260200190565b60405180910390a4505050806134aa9061549e565b90506131d0565b50600284015463ffffffff64010000000082048116600160401b90920416036134f35760028401805460ff60601b19166c030000000000000000000000001790555b6000818152601060205260408120805434929061351a9084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550886001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161357991815260200190565b60405180910390a250600198975050505050505050565b6007546000906001600160a01b031633146135d35760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b60006135de836116c2565b9050836001600160a01b0316816001600160a01b0316146136255760405163521eb56d60e11b81526001600160a01b03808616600483015282166024820152604401610cf7565b600083815260136020526040902060016002820154600160601b900460ff16600581111561365557613655614bcf565b1461367657604051635960d22f60e11b815260048101859052602401610cf7565b80546001600160601b031634146136bb578054604051631c30abbb60e31b81523460048201526001600160601b03909116602482015260448101859052606401610cf7565b60028101805460ff60601b19166c0200000000000000000000000017905560405184907fa48b531f972c0e4aca57afcc5c099c52a7bd21bc5e2a1b733eec3be9e88da97a90600090a2506001949350505050565b6137576040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b60008281526013602090815260409182902082516101008101845281546001600160601b0381168252600160601b908190046001600160a01b031693820193909352600182015493810193909352600281015463ffffffff8082166060860152640100000000820481166080860152600160401b82041660a0850152909160c08401910460ff1660058111156137ef576137ef614bcf565b600581111561380057613800614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561387f57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116138425790505b5050505050815250509050919050565b60006001600a5411156138b5576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146138fa5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6000613905856116c2565b9050856001600160a01b0316816001600160a01b03161461394c5760405163521eb56d60e11b81526001600160a01b03808816600483015282166024820152604401610cf7565b6001600160a01b03841660009081526012602052604090205460ff1661398f5760405162a2307960e51b81526001600160a01b0385166004820152602401610cf7565b600085815260136020526040902060036002820154600160601b900460ff1660058111156139bf576139bf614bcf565b14613a08576002810154600160601b900460ff1660058111156139e4576139e4614bcf565b604051633c053f9d60e21b8152600481019190915260248101879052604401610cf7565b604080516101008101825282546001600160601b0381168252600160601b908190046001600160a01b03166020830152600184015492820192909252600283015463ffffffff8082166060840152640100000000820481166080840152600160401b82041660a0830152600092613b359291859160c08401910460ff166005811115613a9657613a96614bcf565b6005811115613aa757613aa7614bcf565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613b2657602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613ae95790505b50505050508152505088613f67565b6002830154604051631e731b7560e31b81529192506001600160a01b0388169163f398dba891613b7291859163ffffffff16908a90600401615762565b6020604051808303816000875af1158015613b91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb5919061579d565b82546001600160601b0316600160601b6001600160a01b03831690810291909117845560028401805460ff60601b19166c040000000000000000000000001790556040519195509088907f2d53f895cd5faf3cddba94a25c2ced2105885b5b37450ff430ffa3cbdf332c7490600090a360405187907fa133ed72c03a7d008deaae618a61613c4fd41c67bba1cad1a6bc0a1c5a9c156e90600090a250506001600a5550949350505050565b60006001600a541115613c86576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314613ccb5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038616613cf25760405163d92e233d60e01b815260040160405180910390fd5b613cfd858585614288565b60005b8451811015613d9157838181518110613d1b57613d1b615472565b60200260200101516000015163ffffffff1660001480613d615750838181518110613d4857613d48615472565b6020026020010151602001516001600160601b03166000145b15613d7f57604051637c946ed760e01b815260040160405180910390fd5b80613d898161549e565b915050613d00565b505060095480613da08161549e565b915050613deb6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b63ffffffff8316606082015260408101869052600160c082018181525050613e17818686885186614398565b6000828152601360209081526040918290208351918401516001600160a01b0316600160601b9081026001600160601b039093169290921781559183015160018301556060830151600283018054608086015160a087015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c0860151869594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115613eec57613eec614bcf565b021790555060e08201518051613f0c91600384019160209091019061487a565b5050506009829055613f1e878361464f565b817fb34c1e02384201736eb4693b9b173306cb41bff12f15894dea5773088e9a3b1c87604051613f5091815260200190565b60405180910390a2506001600a5595945050505050565b60608260a0015163ffffffff1667ffffffffffffffff811115613f8c57613f8c614c62565b604051908082528060200260200182016040528015613fb5578160200160208202803683370190505b5090506000805b8460e00151518110156140b057600084905060208660e001518381518110613fe657613fe6615472565b602002602001015163ffffffff16901b8117905060005b6000828152600f602052604090205481101561409b576000828152600f6020526040902080548290811061403357614033615472565b9060005260206000200160009054906101000a90046001600160a01b031685858151811061406357614063615472565b6001600160a01b0390921660209283029190910190910152836140858161549e565b94505080806140939061549e565b915050613ffd565b505080806140a89061549e565b915050613fbc565b505092915050565b7aff00000000000000ff00000000000000ff00000000000000ff00006bffffffff0000000000000000604083901c9081167bffffffff00000000000000000000000000000000000000000000000084161760201c6fffffffff000000000000000000000000919091166001600160e01b031984161717601081901c9182167eff00000000000000ff00000000000000ff00000000000000ff000000000000821617600890811c7bff00000000000000ff00000000000000ff00000000000000ff000000939093167fff00000000000000ff00000000000000ff00000000000000ff000000000000009290921691909117919091179081901c7e0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f167f0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f00600492831c161790614224827f06060606060606060606060606060606060606060606060606060606060606066154d4565b901c7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f16602761425491906157ba565b61427e827f30303030303030303030303030303030303030303030303030303030303030306154d4565b610be191906154d4565b60008390036142aa57604051637c946ed760e01b815260040160405180910390fd5b815115806142ba57508051825114155b156142e557815181516040516308151c1160e41b815260048101929092526024820152604401610cf7565b6000805b8351811015612624576142fd8260016154d4565b84828151811061430f5761430f615472565b602002602001015163ffffffff1610156143635783818151811061433557614335615472565b6020026020010151604051632ab10b0b60e21b8152600401610cf7919063ffffffff91909116815260200190565b83818151811061437557614375615472565b602002602001015163ffffffff16915080806143909061549e565b9150506142e9565b60008267ffffffffffffffff8111156143b3576143b3614c62565b6040519080825280602002602001820160405280156143dc578160200160208202803683370190505b5060e087015260005b8381101561456c578581815181106143ff576143ff615472565b60200260200101518760e00151828151811061441d5761441d615472565b63ffffffff909216602092830291909101820152865184919088908490811061444857614448615472565b602002602001015163ffffffff16901b8117905085828151811061446e5761446e615472565b6020908102919091018101516000838152600e8352604090208151815492909301516001600160601b0316640100000000026fffffffffffffffffffffffffffffffff1990921663ffffffff9093169290921717905585518690839081106144d8576144d8615472565b602002602001015160000151886080018181516144f591906157d1565b63ffffffff1690525085516001600160601b0384169087908490811061451d5761451d615472565b6020026020010151602001516001600160601b031611156145595785828151811061454a5761454a615472565b60200260200101516020015192505b50806145648161549e565b9150506143e5565b506001600160601b0381168652608086015160009061458c9060026157ee565b6145979060016157d1565b63ffffffff1690506145aa600382615824565b6000036145c3576145bc600382615838565b90506145dc565b6145ce600382615838565b6145d99060016154d4565b90505b80876060015163ffffffff1610806146075750866080015163ffffffff16876060015163ffffffff16115b15614646576060870151608088015160405163eb3a8ba360e01b815263ffffffff92831660048201526024810184905291166044820152606401610cf7565b50505050505050565b614659828261473f565b6001600160a01b0382163b1561473b57604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af11580156146cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146f191906154b7565b6001600160e01b0319161461473b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b5050565b6001600160a01b0382166147895760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610cf7565b6000818152600260205260409020546001600160a01b0316156147ee5760405162461bcd60e51b815260206004820152600e60248201527f414c52454144595f4d494e5445440000000000000000000000000000000000006044820152606401610cf7565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b50805460008255906000526020600020908101906148779190614947565b50565b828054828255906000526020600020906007016008900481019282156149195791602002820160005b838211156148e757835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026148a3565b80156149175782816101000a81549063ffffffff02191690556004016020816003010492830192600103026148e7565b505b50614925929150614977565b5090565b50805460008255906000526020600020908101906148779190614977565b5b8082111561492557805477ffffffffffffffffffffffffffffffffffffffffffffffff19168155600101614948565b5b808211156149255760008155600101614978565b6001600160e01b03198116811461487757600080fd5b6000602082840312156149b457600080fd5b81356149bf8161498c565b9392505050565b60005b838110156149e15781810151838201526020016149c9565b50506000910152565b60008151808452614a028160208601602086016149c6565b601f01601f19169290920160200192915050565b6020815260006149bf60208301846149ea565b600060208284031215614a3b57600080fd5b5035919050565b6001600160a01b038116811461487757600080fd5b60008060408385031215614a6a57600080fd5b8235614a7581614a42565b946020939093013593505050565b600060208284031215614a9557600080fd5b81356149bf81614a42565b6000604080830185845260208281860152818651808452606087019150828801935060005b81811015614af9578451805163ffffffff1684528401516001600160601b0316848401529383019391850191600101614ac5565b509098975050505050505050565b60008060408385031215614b1a57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015614b625781516001600160a01b031687529582019590820190600101614b3d565b509495945050505050565b828152604060208201526000614b866040830184614b29565b949350505050565b600080600060608486031215614ba357600080fd5b8335614bae81614a42565b92506020840135614bbe81614a42565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b60068110614c0357634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03881681526001600160a01b03871660208201526040810186905263ffffffff85811660608301528481166080830152831660a082015260e08101614c5660c0830184614be5565b98975050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715614c9b57614c9b614c62565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614cca57614cca614c62565b604052919050565b600067ffffffffffffffff831115614cec57614cec614c62565b614cff601f8401601f1916602001614ca1565b9050828152838383011115614d1357600080fd5b828260208301376000602084830101529392505050565b600060208284031215614d3c57600080fd5b813567ffffffffffffffff811115614d5357600080fd5b8201601f81018413614d6457600080fd5b614b8684823560208401614cd2565b600067ffffffffffffffff821115614d8d57614d8d614c62565b5060051b60200190565b600082601f830112614da857600080fd5b81356020614dbd614db883614d73565b614ca1565b82815260059290921b84018101918181019086841115614ddc57600080fd5b8286015b84811015614e00578035614df381614a42565b8352918301918301614de0565b509695505050505050565b80356001600160601b03811681146115dc57600080fd5b600080600060608486031215614e3757600080fd5b833567ffffffffffffffff80821115614e4f57600080fd5b614e5b87838801614d97565b9450602091508186013581811115614e7257600080fd5b86019050601f81018713614e8557600080fd5b8035614e93614db882614d73565b81815260059190911b82018301908381019089831115614eb257600080fd5b928401925b82841015614ed757614ec884614e0b565b82529284019290840190614eb7565b96999698505050506040949094013593505050565b60008060408385031215614eff57600080fd5b8235614f0a81614a42565b915060208301358015158114614f1f57600080fd5b809150509250929050565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015614f6b57845183529383019391830191600101614f4f565b5090979650505050505050565b600080600080600060808688031215614f9057600080fd5b8535614f9b81614a42565b94506020860135614fab81614a42565b935060408601359250606086013567ffffffffffffffff80821115614fcf57600080fd5b818801915088601f830112614fe357600080fd5b813581811115614ff257600080fd5b89602082850101111561500457600080fd5b9699959850939650602001949392505050565b803563ffffffff811681146115dc57600080fd5b600082601f83011261503c57600080fd5b8135602061504c614db883614d73565b82815260059290921b8401810191818101908684111561506b57600080fd5b8286015b84811015614e005761508081615017565b835291830191830161506f565b600082601f83011261509e57600080fd5b813560206150ae614db883614d73565b82815260069290921b840181019181810190868411156150cd57600080fd5b8286015b84811015614e0057604081890312156150ea5760008081fd5b6150f2614c78565b6150fb82615017565b8152615108858301614e0b565b818601528352918301916040016150d1565b60008060008060008060c0878903121561513357600080fd5b863561513e81614a42565b955060208701359450604087013567ffffffffffffffff8082111561516257600080fd5b61516e8a838b0161502b565b9550606089013591508082111561518457600080fd5b5061519189828a0161508d565b9350506151a060808801615017565b915060a087013590509295509295509295565b600080600080608085870312156151c957600080fd5b84356151d481614a42565b935060208501359250604085013567ffffffffffffffff808211156151f857600080fd5b61520488838901614d97565b9350606087013591508082111561521a57600080fd5b506152278782880161502b565b91505092959194509250565b6000806040838503121561524657600080fd5b823561525181614a42565b91506020830135614f1f81614a42565b600081518084526020808501945080840160005b83811015614b6257815163ffffffff1687529582019590820190600101615275565b602081526001600160601b0382511660208201526001600160a01b03602083015116604082015260408201516060820152600060608301516152e1608084018263ffffffff169052565b50608083015163ffffffff811660a08401525060a083015163ffffffff811660c08401525060c083015161531860e0840182614be5565b5060e083015161010083810152614b86610120840182615261565b6000806000806080858703121561534957600080fd5b843561535481614a42565b935060208501359250604085013561536b81614a42565b9150606085013567ffffffffffffffff81111561538757600080fd5b8501601f8101871361539857600080fd5b61522787823560208401614cd2565b600080600080600060a086880312156153bf57600080fd5b85356153ca81614a42565b945060208601359350604086013567ffffffffffffffff808211156153ee57600080fd5b6153fa89838a0161502b565b9450606088013591508082111561541057600080fd5b5061541d8882890161508d565b92505061542c60808701615017565b90509295509295909350565b600181811c9082168061544c57607f821691505b60208210810361546c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016154b0576154b0615488565b5060010190565b6000602082840312156154c957600080fd5b81516149bf8161498c565b80820180821115610be157610be1615488565b601f82111561142357600081815260208120601f850160051c8101602086101561550e5750805b601f850160051c820191505b8181101561552d5782815560010161551a565b505050505050565b815167ffffffffffffffff81111561554f5761554f614c62565b6155638161555d8454615438565b846154e7565b602080601f83116001811461559857600084156155805750858301515b600019600386901b1c1916600185901b17855561552d565b600085815260208120601f198616915b828110156155c7578886015182559484019460019091019084016155a8565b50858210156155e55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160601b0381811683821601908082111561561557615615615488565b5092915050565b6001600160601b0382811682821603908082111561561557615615615488565b63ffffffff82811682821603908082111561561557615615615488565b60006001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b60008086546156bb81615438565b600182811680156156d357600181146156e857615717565b60ff1984168752821515830287019450615717565b8a60005260208060002060005b8581101561570e5781548a8201529084019082016156f5565b50505082870194505b50505050855161572b818360208a016149c6565b019384525050602082015260400192915050565b600063ffffffff80831681810361575857615758615488565b6001019392505050565b6060815260006157756060830186614b29565b63ffffffff85166020840152828103604084015261579381856149ea565b9695505050505050565b6000602082840312156157af57600080fd5b81516149bf81614a42565b8082028115828204841417610be157610be1615488565b63ffffffff81811683821601908082111561561557615615615488565b63ffffffff8181168382160280821691908281146140b0576140b0615488565b634e487b7160e01b600052601260045260246000fd5b6000826158335761583361580e565b500690565b6000826158475761584761580e565b50049056fea2646970667358221220ee3dd136eb9c3aaae80969db0d981f4555af6520415662932908c79dee30e48b64736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106103345760003560e01c806370a08231116101b0578063a60e4c3c116100ec578063dff7672411610095578063ef0e239b1161006f578063ef0e239b14610af7578063f908bc7714610b24578063fbdeb3d714610b44578063ffa1ad7414610b6457600080fd5b8063dff7672414610a96578063e23f6fb414610aa9578063e985e9c514610abc57600080fd5b8063c87b56dd116100c6578063c87b56dd14610a36578063cbf994f814610a56578063ccc9305d14610a7657600080fd5b8063a60e4c3c146109c8578063a6f9dae1146109f6578063b88d4fde14610a1657600080fd5b80638a2bd86f116101595780639890220b116101335780639890220b1461093c578063a22cb46514610951578063a3fbbaae14610971578063a5d059ca1461099157600080fd5b80638a2bd86f146108c25780638da5cb5b1461090757806395d89b411461092757600080fd5b80637c5e63e01161018a5780637c5e63e01461084d57806382694b1d1461088257806386a2bdd4146108a257600080fd5b806370a08231146107c9578063718934d8146107e957806373b8b6a21461082d57600080fd5b806342842e0e1161027f57806355f804b3116102285780636352211e116102025780636352211e1461070a57806363dd76151461072a5780636c0360eb146107945780636f99f15c146107a957600080fd5b806355f804b3146106a357806357838e85146106c35780635e4507fa146106ea57600080fd5b80634eb780da116102595780634eb780da1461062d5780634f558e79146106635780634f6ccce71461068357600080fd5b806342842e0e146105cd578063481c6a75146105ed5780634d486f851461060d57600080fd5b806318160ddd116102e157806323b872dd116102bb57806323b872dd146104d057806342144854146104f05780634236aff81461053e57600080fd5b806318160ddd146104505780631de286ba1461047457806321e4f7bb146104a257600080fd5b8063095ea7b311610312578063095ea7b3146103de57806310c6aa191461040057806317351f7e1461042057600080fd5b806301ffc9a71461033957806306fdde031461036e578063081812fc14610390575b600080fd5b34801561034557600080fd5b506103596103543660046149a2565b610b95565b60405190151581526020015b60405180910390f35b34801561037a57600080fd5b50610383610be7565b6040516103659190614a16565b34801561039c57600080fd5b506103c66103ab366004614a29565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610365565b3480156103ea57600080fd5b506103fe6103f9366004614a57565b610c75565b005b34801561040c57600080fd5b506103fe61041b366004614a83565b610d5c565b34801561042c57600080fd5b5061035961043b366004614a83565b60126020526000908152604090205460ff1681565b34801561045c57600080fd5b5061046660095481565b604051908152602001610365565b34801561048057600080fd5b5061049461048f366004614a29565b610e15565b604051610365929190614aa0565b3480156104ae57600080fd5b506104c26104bd366004614b07565b61106b565b604051610365929190614b6d565b3480156104dc57600080fd5b506103fe6104eb366004614b8e565b611159565b3480156104fc57600080fd5b5061052661050b366004614a29565b6010602052600090815260409020546001600160601b031681565b6040516001600160601b039091168152602001610365565b34801561054a57600080fd5b506105ba610559366004614a29565b6013602052600090815260409020805460018201546002909201546001600160601b03821692600160601b928390046001600160a01b031692909163ffffffff808216926401000000008304821692600160401b8104909216910460ff1687565b6040516103659796959493929190614c07565b3480156105d957600080fd5b506103fe6105e8366004614b8e565b611333565b3480156105f957600080fd5b506007546103c6906001600160a01b031681565b34801561061957600080fd5b506104c2610628366004614a29565b611428565b34801561063957600080fd5b506103c6610648366004614a83565b6011602052600090815260409020546001600160a01b031681565b34801561066f57600080fd5b5061035961067e366004614a29565b61157a565b34801561068f57600080fd5b5061046661069e366004614a29565b61159c565b3480156106af57600080fd5b506103fe6106be366004614d2a565b6115e1565b3480156106cf57600080fd5b50600b546103c690600160601b90046001600160a01b031681565b3480156106f657600080fd5b506103c6610705366004614b07565b61168a565b34801561071657600080fd5b506103c6610725366004614a29565b6116c2565b34801561073657600080fd5b50610770610745366004614a29565b600e6020526000908152604090205463ffffffff81169064010000000090046001600160601b031682565b6040805163ffffffff90931683526001600160601b03909116602083015201610365565b3480156107a057600080fd5b50610383611727565b3480156107b557600080fd5b50600b54610526906001600160601b031681565b3480156107d557600080fd5b506104666107e4366004614a83565b611734565b3480156107f557600080fd5b50610809610804366004614b07565b6117a8565b604080516001600160a01b03909316835263ffffffff909116602083015201610365565b34801561083957600080fd5b50610359610848366004614e22565b6117ee565b34801561085957600080fd5b506103836040518060400160405280600981526020016806630313730313232360bc1b81525081565b34801561088e57600080fd5b5061035961089d366004614eec565b611c43565b3480156108ae57600080fd5b506104666108bd366004614b07565b611cdc565b3480156108ce57600080fd5b506104666108dd366004614a57565b60a01b6001600160a01b03909116176000908152601060205260409020546001600160601b031690565b34801561091357600080fd5b506006546103c6906001600160a01b031681565b34801561093357600080fd5b50610383611d0d565b34801561094857600080fd5b50610466611d1a565b34801561095d57600080fd5b506103fe61096c366004614eec565b611e78565b34801561097d57600080fd5b506103fe61098c366004614a83565b611ee4565b34801561099d57600080fd5b506109b16109ac366004614a57565b611f95565b604080519215158352602083019190915201610365565b3480156109d457600080fd5b506109e86109e3366004614a29565b612431565b604051610365929190614f2a565b348015610a0257600080fd5b506103fe610a11366004614a83565b612495565b348015610a2257600080fd5b506103fe610a31366004614f78565b612546565b348015610a4257600080fd5b50610383610a51366004614a29565b61262b565b348015610a6257600080fd5b50610359610a7136600461511a565b6126a5565b348015610a8257600080fd5b506109b1610a91366004614a57565b612c33565b610359610aa43660046151b3565b612f95565b610359610ab7366004614a57565b613590565b348015610ac857600080fd5b50610359610ad7366004615233565b600560209081526000928352604080842090915290825290205460ff1681565b348015610b0357600080fd5b50610b17610b12366004614a29565b61370f565b6040516103659190615297565b348015610b3057600080fd5b506103c6610b3f366004615333565b61388f565b348015610b5057600080fd5b50610466610b5f3660046153a7565b613c60565b348015610b7057600080fd5b50610383604051806040016040528060058152602001640312e302e360dc1b81525081565b60006301ffc9a760e01b6001600160e01b031983161480610bc657506380ac58cd60e01b6001600160e01b03198316145b80610be15750635b5e139f60e01b6001600160e01b03198316145b92915050565b60008054610bf490615438565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2090615438565b8015610c6d5780601f10610c4257610100808354040283529160200191610c6d565b820191906000526020600020905b815481529060010190602001808311610c5057829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b031633811480610cbe57506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b610d005760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6006546001600160a01b03163314610d9c5760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038116610dc35760405163d92e233d60e01b815260040160405180910390fd5b600b80546001600160601b0316600160601b6001600160a01b038416908102919091179091556040517f8d1e8547016120917daad7f81c42b48f7fee379badc48f1889f0f43bb619472590600090a250565b600081815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff9104166005811115610eb657610eb6614bcf565b6005811115610ec757610ec7614bcf565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015610f4657602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411610f095790505b50505050508152505090508060e001515192508267ffffffffffffffff811115610f7257610f72614c62565b604051908082528060200260200182016040528015610fb757816020015b6040805180820190915260008082526020820152815260200190600190039081610f905790505b50915060005b8381101561106457600085905060208360e001518381518110610fe257610fe2615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260409081902081518083019092525492831681526401000000009092046001600160601b031692820192909252845185908490811061104757611047615472565b6020026020010181905250508061105d9061549e565b9050610fbd565b5050915091565b602081811b83176000818152600f909252604090912054906060908267ffffffffffffffff81111561109f5761109f614c62565b6040519080825280602002602001820160405280156110c8578160200160208202803683370190505b50915060005b83811015611150576000828152600f602052604090208054829081106110f6576110f6615472565b9060005260206000200160009054906101000a90046001600160a01b031683828151811061112657611126615472565b6001600160a01b0390921660209283029190910190910152806111488161549e565b9150506110ce565b50509250929050565b6000818152600260205260409020546001600160a01b038481169116146111c25760405162461bcd60e51b815260206004820152600a60248201527f57524f4e475f46524f4d000000000000000000000000000000000000000000006044820152606401610cf7565b6001600160a01b03821661120c5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610cf7565b336001600160a01b038416148061124657506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061126757506000818152600460205260409020546001600160a01b031633145b6112a45760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610cf7565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61133e838383611159565b6001600160a01b0382163b1561142357604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af11580156113b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d991906154b7565b6001600160e01b031916146114235760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b505050565b600081815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff808216606085810191909152640100000000830482166080860152600160401b830490911660a0850152938593929160c084019160ff91041660058111156114c9576114c9614bcf565b60058111156114da576114da614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561155957602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff168152602001906004019060208260030104928301926001038202915080841161151c5790505b505050505081525050905061156e8185613f67565b91508151925050915091565b60008082118015610be157506009546115949060016154d4565b821092915050565b60006115a98260016154d4565b90506009548111156115dc57600954604051637ae5968560e01b8152610cf7918391600401918252602082015260400190565b919050565b6006546001600160a01b031633146116215760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b805160000361164357604051637c946ed760e01b815260040160405180910390fd5b600861164f8282615535565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf68160405161167f9190614a16565b60405180910390a150565b600f60205281600052604060002081815481106116a657600080fd5b6000918252602090912001546001600160a01b03169150829050565b6000818152600260205260409020546001600160a01b0316806115dc5760405162461bcd60e51b815260206004820152600a60248201527f4e4f545f4d494e544544000000000000000000000000000000000000000000006044820152606401610cf7565b60088054610bf490615438565b60006001600160a01b03821661178c5760405162461bcd60e51b815260206004820152600c60248201527f5a45524f5f4144445245535300000000000000000000000000000000000000006044820152606401610cf7565b506001600160a01b031660009081526003602052604090205490565b600d60205281600052604060002081815481106117c457600080fd5b6000918252602090912001546001600160a01b0381169250600160a01b900463ffffffff16905082565b600081815260136020908152604080832081516101008101835281546001600160601b0381168252600160601b908190046001600160a01b031694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a0840152849360c08401910460ff16600581111561188557611885614bcf565b600581111561189657611896614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561191557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116118d85790505b50505050508152505090506004600581111561193357611933614bcf565b8160c00151600581111561194957611949614bcf565b14611988578060c00151600581111561196457611964614bcf565b604051633c053f9d60e21b8152600481019190915260248101849052604401610cf7565b83518551146119b757845184516040516308151c1160e41b815260048101929092526024820152604401610cf7565b80602001516001600160a01b0316336001600160a01b031614611a0b5760208101516040516379f91cd360e01b81523360048201526001600160a01b03909116602482015260448101849052606401610cf7565b845160005b81811015611c3657600060116000898481518110611a3057611a30615472565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081205490931660a08a901b81178085526010909252919092205489519193506001600160601b03169081908a9086908110611a9557611a95615472565b60200260200101516001611aa991906155f5565b6001600160601b03161115611b0357600b8054829190600090611ad69084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060009050611b87565b888481518110611b1557611b15615472565b6020908102919091010151600b8054600090611b3b9084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550888481518110611b7157611b71615472565b602002602001015181611b84919061561c565b90505b600082815260106020526040902080546bffffffffffffffffffffffff19166001600160601b038316179055885188906001600160a01b038516907fa2e524bd0f71903485fbb3d6d50cb305f61005ceea2047c3ac92aa7e0d104306908c9088908110611bf657611bf6615472565b6020026020010151604051611c1a91906001600160601b0391909116815260200190565b60405180910390a350505080611c2f9061549e565b9050611a10565b5060019695505050505050565b6006546000906001600160a01b03163314611c865760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038316611cad5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b03919091166000908152601260205260409020805460ff1916911515919091179055600190565b600c6020528160005260406000208181548110611cf857600080fd5b90600052602060002001600091509150505481565b60018054610bf490615438565b60006001600a541115611d40576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a55600b54600160601b90046001600160a01b03163314611d9257600b5460405163312d21ff60e11b8152336004820152600160601b9091046001600160a01b03166024820152604401610cf7565b50600b546001600160601b03168015611e7057600b80546bffffffffffffffffffffffff19169055604051600090339083908381818185875af1925050503d8060008114611dfc576040519150601f19603f3d011682016040523d82523d6000602084013e611e01565b606091505b5050905080611e395760405163cd3f165960e01b81526000600482015230602482015233604482015260648101839052608401610cf7565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2505b6001600a5590565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6006546001600160a01b03163314611f245760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038116611f4b5760405163d92e233d60e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0383169081179091556040517f2c1c11af44aa5608f1dca38c00275c30ea091e02417d36e70e9a1538689c433d90600090a250565b6000806001600a541115611fbc576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146120015760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b0384166120285760405163d92e233d60e01b815260040160405180910390fd5b600083815260136020526040902060056002820154600160601b900460ff16600581111561205857612058614bcf565b146120a1576002810154600160601b900460ff16600581111561207d5761207d614bcf565b604051633c053f9d60e21b8152600481019190915260248101859052604401610cf7565b60a084901b6001600160a01b038616176000818152600d6020908152604080832080548251818502810185019093528083529192909190849084015b8282101561212957600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900463ffffffff16818301528252600190920191016120dd565b50508251929350505060008190036121665760405163df2ddd7360e01b81526001600160a01b038916600482015260248101889052604401610cf7565b808460020160088282829054906101000a900463ffffffff16612189919061563c565b92506101000a81548163ffffffff021916908363ffffffff1602179055508360020160089054906101000a900463ffffffff1663ffffffff166000036121df5760028401805460ff60601b1916600160601b1790555b60005b818110156122a7576000889050602084838151811061220357612203615472565b60209081029190910181015181015163ffffffff1690911b919091176000818152600e90925260409091205461224a9064010000000090046001600160601b0316886154d4565b96506011600085848151811061226257612262615472565b602090810291909101810151516001600160a01b0316825281019190915260400160002080546001600160a01b0319169055508061229f8161549e565b9150506121e2565b506000838152600d602052604081206122bf91614859565b6000838152601060205260409020546001600160601b0316808611156122ec57806001600160601b031695505b85156123e55760008481526010602052604080822080546bffffffffffffffffffffffff19169055516001600160a01b038b169088908381818185875af1925050503d806000811461235a576040519150601f19603f3d011682016040523d82523d6000602084013e61235f565b606091505b50509050806123a05760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038b16604482015260648101889052608401610cf7565b896001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d886040516123db91815260200190565b60405180910390a2505b60405188906001600160a01b038b16907f5ebf7fe30be09f0f03b9195632508d95c8b67bf010c93abda67f70d5d9599d1e90600090a350506001600a8190559793965092945050505050565b6000818152600c60209081526040808320805482518185028101850190935280835260609383018282801561248557602002820191906000526020600020905b815481526020019060010190808311612471575b5050505050905080519150915091565b6006546001600160a01b031633146124d55760065460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b0381166124fc5760405163d92e233d60e01b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b90600090a250565b612551858585611159565b6001600160a01b0384163b1561262457604051630a85bd0160e11b808252906001600160a01b0386169063150b7a02906125979033908a90899089908990600401615659565b6020604051808303816000875af11580156125b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125da91906154b7565b6001600160e01b031916146126245760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b5050505050565b6000818152601360205260408120600101546060915060086040518060400160405280600981526020016806630313730313232360bc1b81525061266e836140b8565b61267b608085901b6140b8565b60405160200161268e94939291906156ad565b604051602081830303815290604052915050919050565b6007546000906001600160a01b031633146126e85760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b60006126f3836116c2565b9050876001600160a01b0316816001600160a01b03161461273a5760405163521eb56d60e11b81526001600160a01b03808a16600483015282166024820152604401610cf7565b600083815260136020908152604080832081516101008101835281546001600160601b03811682526001600160a01b03600160601b918290041694820194909452600182015492810192909252600281015463ffffffff8082166060850152640100000000820481166080850152600160401b82041660a08401529192909160c084019160ff91041660058111156127d4576127d4614bcf565b60058111156127e5576127e5614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561286457602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116128275790505b50505050508152505090506001600581111561288257612882614bcf565b8160c00151600581111561289857612898614bcf565b146128b3578060c00151600581111561207d5761207d614bcf565b6128be888888614288565b63ffffffff85166060820152600060808201819052875167ffffffffffffffff8111156128ed576128ed614c62565b604051908082528060200260200182016040528015612916578160200160208202803683370190505b5090506000885167ffffffffffffffff81111561293557612935614c62565b60405190808252806020026020018201604052801561297a57816020015b60408051808201909152600080825260208201528152602001906001900390816129535790505b5090506000805b8a51811015612aaf5789818151811061299c5761299c615472565b60200260200101516000015163ffffffff16600003612a1157600088905060208c83815181106129ce576129ce615472565b60209081029190910181015163ffffffff1690911b919091176000908152600e9091526040902080546fffffffffffffffffffffffffffffffff19169055612a9d565b8a8181518110612a2357612a23615472565b6020026020010151848381518110612a3d57612a3d615472565b602002602001019063ffffffff16908163ffffffff1681525050898181518110612a6957612a69615472565b6020026020010151838381518110612a8357612a83615472565b60200260200101819052508180612a999061549e565b9250505b80612aa78161549e565b915050612981565b5060408401518b8114612ae6576000888152600c602090815260408083208054600181018255908452919092200182905585018c90525b612af3858585858c614398565b6000888152601360209081526040918290208751918801516001600160a01b0316600160601b9081026001600160601b03909316929092178155918701516001830155606087015160028301805460808a015160a08b015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c08a01518a9594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115612bc857612bc8614bcf565b021790555060e08201518051612be891600384019160209091019061487a565b50506040518d81528991507fff312ce131c4d73ac90ece91266be7090486c5e15f78b7ea2b108c36dfd475299060200160405180910390a25060019c9b505050505050505050505050565b6000806001600a541115612c5a576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314612c9f5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6000612caa846116c2565b9050846001600160a01b0316816001600160a01b031614612cf15760405163521eb56d60e11b81526001600160a01b03808716600483015282166024820152604401610cf7565b600084815260136020526040902060016002820154600160601b900460ff166005811115612d2157612d21614bcf565b1480612d4c575060056002820154600160601b900460ff166005811115612d4a57612d4a614bcf565b145b15612d95576002810154600160601b900460ff166005811115612d7157612d71614bcf565b604051633c053f9d60e21b8152600481019190915260248101869052604401610cf7565b6002810154600160401b900463ffffffff1615612dcf5760028101805460ff60601b19166c05000000000000000000000000179055612de5565b60028101805460ff60601b1916600160601b1790555b60005b6003820154811015612e725760008690506020836003018381548110612e1057612e10615472565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff16901b81179050600f60008281526020019081526020016000206000612e619190614929565b50612e6b8161549e565b9050612de8565b5080546040516001600160601b0390911693506000906001600160a01b0388169085908381818185875af1925050503d8060008114612ecd576040519150601f19603f3d011682016040523d82523d6000602084013e612ed2565b606091505b5050905080612f135760405163cd3f165960e01b8152600060048201523060248201526001600160a01b038816604482015260648101859052608401610cf7565b866001600160a01b03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d85604051612f4e91815260200190565b60405180910390a260405186907fe45f5b9540df4f71b7e044809fa318806328c1ea2388a70c7373d97ccf8a0faa90600090a250506001600a819055959194509092505050565b6007546000906001600160a01b03163314612fd85760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b815183511461300757825182516040516308151c1160e41b815260048101929092526024820152604401610cf7565b6000848152601360205260409020600280820154600160601b900460ff16600581111561303657613036614bcf565b1461305b576002810154600160601b900460ff166005811115612d7157612d71614bcf565b83516000805b82811015613150576000889050602087838151811061308257613082615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e845260408082208151808301909252549384168082526401000000009094046001600160601b0316948101949094529092919003613123578783815181106130ee576130ee615472565b60200260200101518a6040516332832be560e21b8152600401610cf792919063ffffffff929092168252602082015260400190565b602081015161313b906001600160601b0316856154d4565b93505050806131499061549e565b9050613061565b5080341461318157604051637ebbcab960e11b81523460048201526024810182905260448101889052606401610cf7565b6001600160a01b0388811660009081526011602052604090205416156131bd576040516322ddebd960e21b815260048101889052602401610cf7565b60a087901b6001600160a01b0389161760005b838110156134b15760008882815181106131ec576131ec615472565b60200260200101519050600088838151811061320a5761320a615472565b60200260200101519050816001600160a01b03168c6001600160a01b031603613249576040516322ddebd960e21b8152600481018c9052602401610cf7565b6001600160a01b0382811660009081526011602052604090205416156132a0576001600160a01b038281166000908152601160205260409081902054905163631695bd60e01b815291166004820152602401610cf7565b60008b905060208a85815181106132b9576132b9615472565b60209081029190910181015163ffffffff90811690921b929092176000818152600e8452604080822054600f90955290205490929091169003613312576040516304ad100760e21b8152600481018d9052602401610cf7565b6000818152600f602090815260408083208054600181810183559185528385200180546001600160a01b03808a166001600160a01b031990921682179092558a8652600d8552838620845180860190955290845263ffffffff8089168587019081528254948501835591875294909520925192909101805494518416600160a01b0277ffffffffffffffffffffffffffffffffffffffffffffffff19909516929091169190911792909217909155600289018054600160401b90049091169060086133dc8361573f565b91906101000a81548163ffffffff021916908363ffffffff160217905550508c60116000856001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001600160a01b03168c8e6001600160a01b03167f6835389a6da5341647f18cbe0a89c56f473f4c17bfaee6e6d07d61f1928e0b7c85604051613495919063ffffffff91909116815260200190565b60405180910390a4505050806134aa9061549e565b90506131d0565b50600284015463ffffffff64010000000082048116600160401b90920416036134f35760028401805460ff60601b19166c030000000000000000000000001790555b6000818152601060205260408120805434929061351a9084906001600160601b03166155f5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550886001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161357991815260200190565b60405180910390a250600198975050505050505050565b6007546000906001600160a01b031633146135d35760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b60006135de836116c2565b9050836001600160a01b0316816001600160a01b0316146136255760405163521eb56d60e11b81526001600160a01b03808616600483015282166024820152604401610cf7565b600083815260136020526040902060016002820154600160601b900460ff16600581111561365557613655614bcf565b1461367657604051635960d22f60e11b815260048101859052602401610cf7565b80546001600160601b031634146136bb578054604051631c30abbb60e31b81523460048201526001600160601b03909116602482015260448101859052606401610cf7565b60028101805460ff60601b19166c0200000000000000000000000017905560405184907fa48b531f972c0e4aca57afcc5c099c52a7bd21bc5e2a1b733eec3be9e88da97a90600090a2506001949350505050565b6137576040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b60008281526013602090815260409182902082516101008101845281546001600160601b0381168252600160601b908190046001600160a01b031693820193909352600182015493810193909352600281015463ffffffff8082166060860152640100000000820481166080860152600160401b82041660a0850152909160c08401910460ff1660058111156137ef576137ef614bcf565b600581111561380057613800614bcf565b81526020016003820180548060200260200160405190810160405280929190818152602001828054801561387f57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116138425790505b5050505050815250509050919050565b60006001600a5411156138b5576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b031633146138fa5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6000613905856116c2565b9050856001600160a01b0316816001600160a01b03161461394c5760405163521eb56d60e11b81526001600160a01b03808816600483015282166024820152604401610cf7565b6001600160a01b03841660009081526012602052604090205460ff1661398f5760405162a2307960e51b81526001600160a01b0385166004820152602401610cf7565b600085815260136020526040902060036002820154600160601b900460ff1660058111156139bf576139bf614bcf565b14613a08576002810154600160601b900460ff1660058111156139e4576139e4614bcf565b604051633c053f9d60e21b8152600481019190915260248101879052604401610cf7565b604080516101008101825282546001600160601b0381168252600160601b908190046001600160a01b03166020830152600184015492820192909252600283015463ffffffff8082166060840152640100000000820481166080840152600160401b82041660a0830152600092613b359291859160c08401910460ff166005811115613a9657613a96614bcf565b6005811115613aa757613aa7614bcf565b815260200160038201805480602002602001604051908101604052809291908181526020018280548015613b2657602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411613ae95790505b50505050508152505088613f67565b6002830154604051631e731b7560e31b81529192506001600160a01b0388169163f398dba891613b7291859163ffffffff16908a90600401615762565b6020604051808303816000875af1158015613b91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb5919061579d565b82546001600160601b0316600160601b6001600160a01b03831690810291909117845560028401805460ff60601b19166c040000000000000000000000001790556040519195509088907f2d53f895cd5faf3cddba94a25c2ced2105885b5b37450ff430ffa3cbdf332c7490600090a360405187907fa133ed72c03a7d008deaae618a61613c4fd41c67bba1cad1a6bc0a1c5a9c156e90600090a250506001600a5550949350505050565b60006001600a541115613c86576040516345f5ce8b60e11b815260040160405180910390fd5b6002600a556007546001600160a01b03163314613ccb5760075460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610cf7565b6001600160a01b038616613cf25760405163d92e233d60e01b815260040160405180910390fd5b613cfd858585614288565b60005b8451811015613d9157838181518110613d1b57613d1b615472565b60200260200101516000015163ffffffff1660001480613d615750838181518110613d4857613d48615472565b6020026020010151602001516001600160601b03166000145b15613d7f57604051637c946ed760e01b815260040160405180910390fd5b80613d898161549e565b915050613d00565b505060095480613da08161549e565b915050613deb6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a081018290529060c08201908152602001606081525090565b63ffffffff8316606082015260408101869052600160c082018181525050613e17818686885186614398565b6000828152601360209081526040918290208351918401516001600160a01b0316600160601b9081026001600160601b039093169290921781559183015160018301556060830151600283018054608086015160a087015163ffffffff908116600160401b026bffffffff0000000000000000199282166401000000000267ffffffffffffffff199094169190951617919091179081168317825560c0860151869594909360ff60601b19166cffffffffff0000000000000000199092169190911790836005811115613eec57613eec614bcf565b021790555060e08201518051613f0c91600384019160209091019061487a565b5050506009829055613f1e878361464f565b817fb34c1e02384201736eb4693b9b173306cb41bff12f15894dea5773088e9a3b1c87604051613f5091815260200190565b60405180910390a2506001600a5595945050505050565b60608260a0015163ffffffff1667ffffffffffffffff811115613f8c57613f8c614c62565b604051908082528060200260200182016040528015613fb5578160200160208202803683370190505b5090506000805b8460e00151518110156140b057600084905060208660e001518381518110613fe657613fe6615472565b602002602001015163ffffffff16901b8117905060005b6000828152600f602052604090205481101561409b576000828152600f6020526040902080548290811061403357614033615472565b9060005260206000200160009054906101000a90046001600160a01b031685858151811061406357614063615472565b6001600160a01b0390921660209283029190910190910152836140858161549e565b94505080806140939061549e565b915050613ffd565b505080806140a89061549e565b915050613fbc565b505092915050565b7aff00000000000000ff00000000000000ff00000000000000ff00006bffffffff0000000000000000604083901c9081167bffffffff00000000000000000000000000000000000000000000000084161760201c6fffffffff000000000000000000000000919091166001600160e01b031984161717601081901c9182167eff00000000000000ff00000000000000ff00000000000000ff000000000000821617600890811c7bff00000000000000ff00000000000000ff00000000000000ff000000939093167fff00000000000000ff00000000000000ff00000000000000ff000000000000009290921691909117919091179081901c7e0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f167f0f000f000f000f000f000f000f000f000f000f000f000f000f000f000f000f00600492831c161790614224827f06060606060606060606060606060606060606060606060606060606060606066154d4565b901c7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f16602761425491906157ba565b61427e827f30303030303030303030303030303030303030303030303030303030303030306154d4565b610be191906154d4565b60008390036142aa57604051637c946ed760e01b815260040160405180910390fd5b815115806142ba57508051825114155b156142e557815181516040516308151c1160e41b815260048101929092526024820152604401610cf7565b6000805b8351811015612624576142fd8260016154d4565b84828151811061430f5761430f615472565b602002602001015163ffffffff1610156143635783818151811061433557614335615472565b6020026020010151604051632ab10b0b60e21b8152600401610cf7919063ffffffff91909116815260200190565b83818151811061437557614375615472565b602002602001015163ffffffff16915080806143909061549e565b9150506142e9565b60008267ffffffffffffffff8111156143b3576143b3614c62565b6040519080825280602002602001820160405280156143dc578160200160208202803683370190505b5060e087015260005b8381101561456c578581815181106143ff576143ff615472565b60200260200101518760e00151828151811061441d5761441d615472565b63ffffffff909216602092830291909101820152865184919088908490811061444857614448615472565b602002602001015163ffffffff16901b8117905085828151811061446e5761446e615472565b6020908102919091018101516000838152600e8352604090208151815492909301516001600160601b0316640100000000026fffffffffffffffffffffffffffffffff1990921663ffffffff9093169290921717905585518690839081106144d8576144d8615472565b602002602001015160000151886080018181516144f591906157d1565b63ffffffff1690525085516001600160601b0384169087908490811061451d5761451d615472565b6020026020010151602001516001600160601b031611156145595785828151811061454a5761454a615472565b60200260200101516020015192505b50806145648161549e565b9150506143e5565b506001600160601b0381168652608086015160009061458c9060026157ee565b6145979060016157d1565b63ffffffff1690506145aa600382615824565b6000036145c3576145bc600382615838565b90506145dc565b6145ce600382615838565b6145d99060016154d4565b90505b80876060015163ffffffff1610806146075750866080015163ffffffff16876060015163ffffffff16115b15614646576060870151608088015160405163eb3a8ba360e01b815263ffffffff92831660048201526024810184905291166044820152606401610cf7565b50505050505050565b614659828261473f565b6001600160a01b0382163b1561473b57604051630a85bd0160e11b80825233600483015260006024830181905260448301849052608060648401526084830152906001600160a01b0384169063150b7a029060a4016020604051808303816000875af11580156146cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146f191906154b7565b6001600160e01b0319161461473b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610cf7565b5050565b6001600160a01b0382166147895760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610cf7565b6000818152600260205260409020546001600160a01b0316156147ee5760405162461bcd60e51b815260206004820152600e60248201527f414c52454144595f4d494e5445440000000000000000000000000000000000006044820152606401610cf7565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b50805460008255906000526020600020908101906148779190614947565b50565b828054828255906000526020600020906007016008900481019282156149195791602002820160005b838211156148e757835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026148a3565b80156149175782816101000a81549063ffffffff02191690556004016020816003010492830192600103026148e7565b505b50614925929150614977565b5090565b50805460008255906000526020600020908101906148779190614977565b5b8082111561492557805477ffffffffffffffffffffffffffffffffffffffffffffffff19168155600101614948565b5b808211156149255760008155600101614978565b6001600160e01b03198116811461487757600080fd5b6000602082840312156149b457600080fd5b81356149bf8161498c565b9392505050565b60005b838110156149e15781810151838201526020016149c9565b50506000910152565b60008151808452614a028160208601602086016149c6565b601f01601f19169290920160200192915050565b6020815260006149bf60208301846149ea565b600060208284031215614a3b57600080fd5b5035919050565b6001600160a01b038116811461487757600080fd5b60008060408385031215614a6a57600080fd5b8235614a7581614a42565b946020939093013593505050565b600060208284031215614a9557600080fd5b81356149bf81614a42565b6000604080830185845260208281860152818651808452606087019150828801935060005b81811015614af9578451805163ffffffff1684528401516001600160601b0316848401529383019391850191600101614ac5565b509098975050505050505050565b60008060408385031215614b1a57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015614b625781516001600160a01b031687529582019590820190600101614b3d565b509495945050505050565b828152604060208201526000614b866040830184614b29565b949350505050565b600080600060608486031215614ba357600080fd5b8335614bae81614a42565b92506020840135614bbe81614a42565b929592945050506040919091013590565b634e487b7160e01b600052602160045260246000fd5b60068110614c0357634e487b7160e01b600052602160045260246000fd5b9052565b6001600160601b03881681526001600160a01b03871660208201526040810186905263ffffffff85811660608301528481166080830152831660a082015260e08101614c5660c0830184614be5565b98975050505050505050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715614c9b57614c9b614c62565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614cca57614cca614c62565b604052919050565b600067ffffffffffffffff831115614cec57614cec614c62565b614cff601f8401601f1916602001614ca1565b9050828152838383011115614d1357600080fd5b828260208301376000602084830101529392505050565b600060208284031215614d3c57600080fd5b813567ffffffffffffffff811115614d5357600080fd5b8201601f81018413614d6457600080fd5b614b8684823560208401614cd2565b600067ffffffffffffffff821115614d8d57614d8d614c62565b5060051b60200190565b600082601f830112614da857600080fd5b81356020614dbd614db883614d73565b614ca1565b82815260059290921b84018101918181019086841115614ddc57600080fd5b8286015b84811015614e00578035614df381614a42565b8352918301918301614de0565b509695505050505050565b80356001600160601b03811681146115dc57600080fd5b600080600060608486031215614e3757600080fd5b833567ffffffffffffffff80821115614e4f57600080fd5b614e5b87838801614d97565b9450602091508186013581811115614e7257600080fd5b86019050601f81018713614e8557600080fd5b8035614e93614db882614d73565b81815260059190911b82018301908381019089831115614eb257600080fd5b928401925b82841015614ed757614ec884614e0b565b82529284019290840190614eb7565b96999698505050506040949094013593505050565b60008060408385031215614eff57600080fd5b8235614f0a81614a42565b915060208301358015158114614f1f57600080fd5b809150509250929050565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015614f6b57845183529383019391830191600101614f4f565b5090979650505050505050565b600080600080600060808688031215614f9057600080fd5b8535614f9b81614a42565b94506020860135614fab81614a42565b935060408601359250606086013567ffffffffffffffff80821115614fcf57600080fd5b818801915088601f830112614fe357600080fd5b813581811115614ff257600080fd5b89602082850101111561500457600080fd5b9699959850939650602001949392505050565b803563ffffffff811681146115dc57600080fd5b600082601f83011261503c57600080fd5b8135602061504c614db883614d73565b82815260059290921b8401810191818101908684111561506b57600080fd5b8286015b84811015614e005761508081615017565b835291830191830161506f565b600082601f83011261509e57600080fd5b813560206150ae614db883614d73565b82815260069290921b840181019181810190868411156150cd57600080fd5b8286015b84811015614e0057604081890312156150ea5760008081fd5b6150f2614c78565b6150fb82615017565b8152615108858301614e0b565b818601528352918301916040016150d1565b60008060008060008060c0878903121561513357600080fd5b863561513e81614a42565b955060208701359450604087013567ffffffffffffffff8082111561516257600080fd5b61516e8a838b0161502b565b9550606089013591508082111561518457600080fd5b5061519189828a0161508d565b9350506151a060808801615017565b915060a087013590509295509295509295565b600080600080608085870312156151c957600080fd5b84356151d481614a42565b935060208501359250604085013567ffffffffffffffff808211156151f857600080fd5b61520488838901614d97565b9350606087013591508082111561521a57600080fd5b506152278782880161502b565b91505092959194509250565b6000806040838503121561524657600080fd5b823561525181614a42565b91506020830135614f1f81614a42565b600081518084526020808501945080840160005b83811015614b6257815163ffffffff1687529582019590820190600101615275565b602081526001600160601b0382511660208201526001600160a01b03602083015116604082015260408201516060820152600060608301516152e1608084018263ffffffff169052565b50608083015163ffffffff811660a08401525060a083015163ffffffff811660c08401525060c083015161531860e0840182614be5565b5060e083015161010083810152614b86610120840182615261565b6000806000806080858703121561534957600080fd5b843561535481614a42565b935060208501359250604085013561536b81614a42565b9150606085013567ffffffffffffffff81111561538757600080fd5b8501601f8101871361539857600080fd5b61522787823560208401614cd2565b600080600080600060a086880312156153bf57600080fd5b85356153ca81614a42565b945060208601359350604086013567ffffffffffffffff808211156153ee57600080fd5b6153fa89838a0161502b565b9450606088013591508082111561541057600080fd5b5061541d8882890161508d565b92505061542c60808701615017565b90509295509295909350565b600181811c9082168061544c57607f821691505b60208210810361546c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016154b0576154b0615488565b5060010190565b6000602082840312156154c957600080fd5b81516149bf8161498c565b80820180821115610be157610be1615488565b601f82111561142357600081815260208120601f850160051c8101602086101561550e5750805b601f850160051c820191505b8181101561552d5782815560010161551a565b505050505050565b815167ffffffffffffffff81111561554f5761554f614c62565b6155638161555d8454615438565b846154e7565b602080601f83116001811461559857600084156155805750858301515b600019600386901b1c1916600185901b17855561552d565b600085815260208120601f198616915b828110156155c7578886015182559484019460019091019084016155a8565b50858210156155e55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160601b0381811683821601908082111561561557615615615488565b5092915050565b6001600160601b0382811682821603908082111561561557615615615488565b63ffffffff82811682821603908082111561561557615615615488565b60006001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b60008086546156bb81615438565b600182811680156156d357600181146156e857615717565b60ff1984168752821515830287019450615717565b8a60005260208060002060005b8581101561570e5781548a8201529084019082016156f5565b50505082870194505b50505050855161572b818360208a016149c6565b019384525050602082015260400192915050565b600063ffffffff80831681810361575857615758615488565b6001019392505050565b6060815260006157756060830186614b29565b63ffffffff85166020840152828103604084015261579381856149ea565b9695505050505050565b6000602082840312156157af57600080fd5b81516149bf81614a42565b8082028115828204841417610be157610be1615488565b63ffffffff81811683821601908082111561561557615615615488565b63ffffffff8181168382160280821691908281146140b0576140b0615488565b634e487b7160e01b600052601260045260246000fd5b6000826158335761583361580e565b500690565b6000826158475761584761580e565b50049056fea2646970667358221220ee3dd136eb9c3aaae80969db0d981f4555af6520415662932908c79dee30e48b64736f6c63430008130033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/service_registry/contract.py b/trader_old/vendor/valory/contracts/service_registry/contract.py deleted file mode 100644 index 20e21888a..000000000 --- a/trader_old/vendor/valory/contracts/service_registry/contract.py +++ /dev/null @@ -1,402 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 the class to connect to the Service Registry contract.""" - -import hashlib -import json -import logging -from pathlib import Path -from typing import Any, Dict, FrozenSet, List, Optional, Tuple, Union, cast - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from web3.types import BlockData, EventData, TxReceipt - - -PUBLIC_ID = PublicId.from_str("valory/service_registry:0.1.0") -ETHEREUM_IDENTIFIER = "ethereum" -UNIT_HASH_PREFIX = "0x{metadata_hash}" -EXPECTED_CONTRACT_ADDRESS_BY_CHAIN_ID = { - 1: "0x48b6af7B12C71f09e2fC8aF4855De4Ff54e775cA", - 5: "0x1cEe30D08943EB58EFF84DD1AB44a6ee6FEff63a", - 100: "0x9338b5153AE39BB89f50468E608eD9d764B755fD", - 137: "0xE3607b00E75f6405248323A9417ff6b39B244b50", - 31337: "0x998abeb3E57409262aE5b751f60747921B33613E", -} -DEPLOYED_BYTECODE_MD5_HASH_BY_CHAIN_ID = { - 1: "6f9fc7f3c2348801737120e6b5f8fa8e9670c65152c66d128ff4cddb465b4d705340c559e352f5e7f29bda3b84a8d36d4a9448b791cfe2d370e31c01276e0244", - 5: "d4a860f21f17762c99d93359244b39a878dd5bac9ea6056c0ff29c7558d6653aa0d5962aa819fc9f05f237d068845125cfc37a7fd7761b11c29a709ad5c48157", - 100: "10e2cfb500481d6c5a3b6b90507e4ac04d8b0d88741cea5568306ed4115f24e8b9747055423da5fca05838d5ccefebf41fb47d2ba1fb45215b6b21c0a27823be", - 137: "10e2cfb500481d6c5a3b6b90507e4ac04d8b0d88741cea5568306ed4115f24e8b9747055423da5fca05838d5ccefebf41fb47d2ba1fb45215b6b21c0a27823be", - 31337: "41ab54d43fd4bdfdc929658a0dc9bedd970c7339eecafbefda9892ab54c02c396bceedaa3a84a0f4690bee03dc11195a3267a264de7859c420efbf4291f1fef0", -} -L1_CHAINS = ( - 1, - 5, - 31337, -) -L2_BUILD_FILENAME = "ServiceRegistryL2.json" - -ServiceInfo = Tuple[int, str, bytes, int, int, int, int, List[int]] - -_logger = logging.getLogger( - f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" -) - - -class ServiceRegistryContract(Contract): - """The Service Registry contract.""" - - contract_id = PUBLIC_ID - - @classmethod - def get_raw_transaction( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get the Safe transaction.""" - raise NotImplementedError # pragma: nocover - - @classmethod - def get_raw_message( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[bytes]: - """Get raw message.""" - raise NotImplementedError # pragma: nocover - - @classmethod - def get_state( - cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any - ) -> Optional[JSONLike]: - """Get state.""" - raise NotImplementedError # pragma: nocover - - @staticmethod - def is_l1_chain(ledger_api: LedgerApi) -> bool: - """Check if we're interecting with an L1 chain""" - return ledger_api.api.eth.chain_id in L1_CHAINS - - @staticmethod - def load_l2_build() -> JSONLike: - """Load L2 ABI""" - path = Path(__file__).parent / "build" / L2_BUILD_FILENAME - return json.loads(path.read_text(encoding="utf-8")) - - @classmethod - def get_instance( - cls, - ledger_api: LedgerApi, - contract_address: Optional[str] = None, - ) -> Any: - """Get contract instance.""" - if ledger_api.identifier != ETHEREUM_IDENTIFIER: - return super().get_instance( - ledger_api=ledger_api, contract_address=contract_address - ) - if cls.is_l1_chain(ledger_api=ledger_api): - contract_interface = cls.contract_interface.get(ledger_api.identifier, {}) - else: - contract_interface = cls.load_l2_build() - instance = ledger_api.get_contract_instance( - contract_interface, contract_address - ) - return instance - - @classmethod - def verify_contract( - cls, ledger_api: LedgerApi, contract_address: str - ) -> Dict[str, Union[bool, str]]: - """ - Verify the contract's bytecode - - :param ledger_api: the ledger API object - :param contract_address: the contract address - :return: the verified status - """ - verified = False - chain_id = ledger_api.api.eth.chain_id - expected_address = EXPECTED_CONTRACT_ADDRESS_BY_CHAIN_ID[chain_id] - if contract_address != expected_address: - _logger.error( - f"For chain_id {chain_id} expected {expected_address} and got {contract_address}." - ) - return dict(verified=verified) - deployed_bytecode = ledger_api.api.eth.get_code(contract_address).hex() - sha512_hash = hashlib.sha512(deployed_bytecode.encode("utf-8")).hexdigest() - verified = DEPLOYED_BYTECODE_MD5_HASH_BY_CHAIN_ID[chain_id] == sha512_hash - if not verified: # pragma: nocover - _logger.error( - f"CONTRACT NOT VERIFIED! Contract address: {contract_address}, chain_id: {chain_id}." - ) - return dict(verified=verified) - - @classmethod - def exists( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> bool: - """Check if the service id exists""" - - contract_instance = cls.get_instance(ledger_api, contract_address) - exists = ledger_api.contract_method_call( - contract_instance=contract_instance, - method_name="exists", - unitId=service_id, - ) - - return cast(bool, exists) - - @classmethod - def get_agent_instances( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> Dict[str, Any]: - """Retrieve on-chain agent instances.""" - - contract_instance = cls.get_instance(ledger_api, contract_address) - service_info = ledger_api.contract_method_call( - contract_instance=contract_instance, - method_name="getAgentInstances", - serviceId=service_id, - ) - - return dict( - numAgentInstances=service_info[0], - agentInstances=service_info[1], - ) - - @classmethod - def get_service_owner( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> Dict[str, Any]: - """Retrieve the service owner.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - service_owner = contract_instance.functions.ownerOf(service_id).call() - checksum_service_owner = ledger_api.api.to_checksum_address(service_owner) - return dict( - service_owner=checksum_service_owner, - ) - - @classmethod - def get_service_information( - cls, - ledger_api: LedgerApi, - contract_address: str, - token_id: int, - ) -> ServiceInfo: - """Retrieve service information""" - - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - return contract_interface.functions.getService(token_id).call() - - @classmethod - def get_token_uri( - cls, - ledger_api: LedgerApi, - contract_address: str, - token_id: int, - ) -> str: - """Returns the latest metadata URI for a component.""" - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - return contract_interface.functions.tokenURI(token_id).call() - - @classmethod - def get_create_events( # pragma: nocover - cls, - ledger_api: LedgerApi, - contract_address: str, - receipt: JSONLike, - ) -> Optional[int]: - """Returns `CreateUnit` event filter.""" - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - return contract_interface.events.CreateService().process_receipt(receipt) - - @classmethod - def get_update_events( # pragma: nocover - cls, - ledger_api: LedgerApi, - contract_address: str, - receipt: JSONLike, - ) -> Optional[int]: - """Returns `CreateUnit` event filter.""" - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - return contract_interface.events.UpdateService().process_receipt(receipt) - - @classmethod - def get_update_hash_events( # pragma: nocover - cls, - ledger_api: LedgerApi, - contract_address: str, - receipt: JSONLike, - ) -> Optional[int]: - """Returns `CreateUnit` event filter.""" - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - return contract_interface.events.UpdateUnitHash().process_receipt(receipt) - - @classmethod - def get_events( # pragma: nocover - cls, - ledger_api: LedgerApi, - contract_address: str, - event: str, - receipt: JSONLike, - ) -> Dict: - """Process receipt for events.""" - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - Event = getattr(contract_interface.events, event, None) - if Event is None: - return {"events": []} - return {"events": Event().process_receipt(receipt)} - - @classmethod - def process_receipt( - cls, - ledger_api: LedgerApi, - contract_address: str, - event: str, - receipt: JSONLike, - ) -> JSONLike: - """Checks for a successful service registration event in the latest block""" - contract_interface = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - Event = getattr(contract_interface.events, event, None) - if Event is None: - return {"events": []} - return {"events": Event().process_receipt(receipt)} - - @classmethod - def get_slash_data( - cls, - ledger_api: LedgerApi, - contract_address: str, - agent_instances: List[str], - amounts: List[int], - service_id: int, - ) -> Dict[str, bytes]: - """Gets the encoded arguments for a slashing tx, which should only be called via the multisig.""" - - contract_instance = cls.get_instance( - ledger_api=ledger_api, - contract_address=contract_address, - ) - - slash_kwargs = dict( - agentInstances=agent_instances, - amounts=amounts, - serviceId=service_id, - ) - - data = contract_instance.encodeABI(fn_name="slash", kwargs=slash_kwargs) - return {"data": bytes.fromhex(data[2:])} - - @classmethod - def process_slash_receipt( - cls, - ledger_api: LedgerApi, - contract_address: str, - tx_hash: str, - ) -> Optional[JSONLike]: - """ - Process the slash receipt. - - :param ledger_api: the ledger apis. - :param contract_address: the contract address. - :param tx_hash: the hash of a slash tx to be processed. - :return: a dictionary with the timestamp of the slashing and the `OperatorSlashed` events. - """ - contract = cls.get_instance(ledger_api, contract_address) - receipt: TxReceipt = ledger_api.api.eth.get_transaction_receipt(tx_hash) - logs: List[EventData] = list( - contract.events.OperatorSlashed().process_receipt(receipt) - ) - - if len(logs) == 0: - _logger.error(f"No `OperatorSlashed` event was emitted in tx {tx_hash}.") - return None - - block: BlockData = ledger_api.api.eth.get_block(receipt["blockNumber"]) - - return { - "slash_timestamp": block["timestamp"], - "events": [log["args"] for log in logs], - } - - @classmethod - def _get_operator( - cls, - ledger_api: LedgerApi, - contract_address: str, - agent_instance: str, - ) -> str: - """Retrieve an operator given its agent instance.""" - - contract_instance = cls.get_instance(ledger_api, contract_address) - map_fn = contract_instance.functions.mapAgentInstanceOperators - return map_fn(agent_instance).call() - - @classmethod - def get_operators_mapping( - cls, - ledger_api: LedgerApi, - contract_address: str, - agent_instances: FrozenSet[str], - ) -> Dict[str, str]: - """ - Retrieve a mapping of the given agent instances to their operators. - - Please keep in mind that this method performs a call for each agent instance. - - :param ledger_api: the ledger api. - :param contract_address: the contract address. - :param agent_instances: the agent instances to be mapped. - :return: a mapping of the given agent instances to their operators. - """ - return { - agent: cls._get_operator(ledger_api, contract_address, agent) - for agent in agent_instances - } diff --git a/trader_old/vendor/valory/contracts/service_registry/contract.yaml b/trader_old/vendor/valory/contracts/service_registry/contract.yaml deleted file mode 100644 index 5158c37ff..000000000 --- a/trader_old/vendor/valory/contracts/service_registry/contract.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: service_registry -author: valory -version: 0.1.0 -type: contract -description: Service Registry contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeidey4syohls5hxmso6qsp5p4uhtzle5txv2mlbym6ktjzknich6oa - build/ServiceRegistry.json: bafybeia4qi2vstrutejzrxfpbb6eift7va5cjs7bparaal2fafiiczuiyy - build/ServiceRegistryL2.json: bafybeic2jylwfod4nmdtbs4izyxyi246pd3f35aoqyahnmyrvzn7j3sv4e - contract.py: bafybeihaixq3vettolpxspv6nog6vltqwshug7ltbpvb2i3rw2mps5o2li - tests/__init__.py: bafybeicl2oklx774jomlt6wwwegfdzrxh6iazjxwcyc7h4gepjljkpl4ji - tests/test_contract.py: bafybeicj535veqf35zb3ycu5iqjvqgj4a2kdmogmx5ba7fiolt5chah42a -fingerprint_ignore_patterns: [] -contracts: [] -class_name: ServiceRegistryContract -contract_interface_paths: - ethereum: build/ServiceRegistry.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - web3: - version: <7,>=6.0.0 diff --git a/trader_old/vendor/valory/contracts/service_registry/tests/__init__.py b/trader_old/vendor/valory/contracts/service_registry/tests/__init__.py deleted file mode 100644 index 230ef096b..000000000 --- a/trader_old/vendor/valory/contracts/service_registry/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/service_registry contract.""" diff --git a/trader_old/vendor/valory/contracts/service_registry/tests/test_contract.py b/trader_old/vendor/valory/contracts/service_registry/tests/test_contract.py deleted file mode 100644 index a54e84143..000000000 --- a/trader_old/vendor/valory/contracts/service_registry/tests/test_contract.py +++ /dev/null @@ -1,239 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/service_registry contract.""" -from pathlib import Path -from typing import Any -from unittest import mock - -import pytest -from aea_ledger_ethereum import EthereumCrypto -from aea_test_autonomy.base_test_classes.contracts import BaseRegistriesContractsTest -from aea_test_autonomy.docker.base import skip_docker_tests - -from packages.valory.contracts.service_registry.contract import ( - DEPLOYED_BYTECODE_MD5_HASH_BY_CHAIN_ID, - EXPECTED_CONTRACT_ADDRESS_BY_CHAIN_ID, - ServiceRegistryContract, -) - - -PACKAGE_DIR = Path(__file__).parent.parent - -SERVICE_REGISTRY_INVALID = "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed" -VALID_SERVICE_ID = 1 -INVALID_SERVICE_ID = 0 -CHAIN_ID = 31337 -AGENT_INSTANCES = [ - "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", - "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", - "0x90F79bf6EB2c4f870365E785982E1f101E93b906", -] -OPERATOR = "0xBcd4042DE499D14e55001CcbB24a551F3b954096" -OPERATORS_MAPPING = dict.fromkeys(AGENT_INSTANCES, OPERATOR) - - -def event_filter_patch(event: str, return_value: Any) -> mock._patch: - """Returns an event filter patch for the given event name.""" - return mock.patch.object( - ServiceRegistryContract, - "get_instance", - return_value=mock.MagicMock( - events=mock.MagicMock( - **{ - event: mock.MagicMock( - create_filter=lambda **_: mock.MagicMock( - get_all_entries=lambda *_: return_value - ) - ) - } - ) - ), - ) - - -class BaseServiceRegistryContractTest(BaseRegistriesContractsTest): - """Base class for Service Registry contract tests""" - - contract: ServiceRegistryContract - contract_address = EXPECTED_CONTRACT_ADDRESS_BY_CHAIN_ID[CHAIN_ID] - invalid_contract_address = SERVICE_REGISTRY_INVALID - path_to_contract = PACKAGE_DIR - ledger_identifier = EthereumCrypto.identifier - contract_directory = PACKAGE_DIR - - -@skip_docker_tests -class TestServiceRegistryContract(BaseServiceRegistryContractTest): - """Test Service Registry Contract""" - - @pytest.mark.parametrize("valid_address", (True, False)) - def test_verify_contract(self, valid_address: bool) -> None: - """Run verify test. If abi file is updated tests + addresses need updating""" - bytecode = DEPLOYED_BYTECODE_MD5_HASH_BY_CHAIN_ID[CHAIN_ID] - - if valid_address: - contract_address = self.contract_address - else: - contract_address = self.invalid_contract_address - bytecode += "invalid" - - result = self.contract.verify_contract( - self.ledger_api, - contract_address, - ) - - assert result["verified"] is valid_address, result - - @pytest.mark.parametrize( - "service_id, expected", [(INVALID_SERVICE_ID, False), (VALID_SERVICE_ID, True)] - ) - def test_exists(self, service_id: int, expected: int) -> None: - """Test whether service id exists""" - exists = self.contract.exists( - self.ledger_api, - self.contract_address, - service_id, - ) - - assert exists is expected - - def test_get_agent_instances(self) -> None: - """Test agent instances retrieval""" - - return_value = { - "numAgentInstances": 4, - "agentInstances": AGENT_INSTANCES, - } - - assert self.contract_address is not None - - result = self.contract.get_agent_instances( - self.ledger_api, - self.contract_address, - VALID_SERVICE_ID, - ) - - assert result == return_value - - def test_get_service_owner(self) -> None: - """Test service owner retrieval.""" - service_owner = AGENT_INSTANCES[0] - assert self.contract_address is not None - - actual = self.contract.get_service_owner( - self.ledger_api, - self.contract_address, - VALID_SERVICE_ID, - ) - - expected = dict(service_owner=service_owner) - assert expected == actual - - def test_get_token_uri(self) -> None: - """Test `get_token_uri` method.""" - - token_uri = self.contract.get_token_uri( - self.ledger_api, - self.contract_address, - VALID_SERVICE_ID, - ) - - assert ( - token_uri - == "https://gateway.autonolas.tech/ipfs/f017012205555555555555555555555555555555555555555555555555555555555555555" # nosec - ) - - def test_get_service_information(self) -> None: - """Test `test_get_service_information` method.""" - - ( - security_deposit, - multisig_address, - ipfs_hash_for_config, - threshold, - max_number_of_agent_instances, - number_of_agent_instances, - service_state, - list_of_cannonical_agents, - ) = self.contract.get_service_information( - self.ledger_api, - self.contract_address, - VALID_SERVICE_ID, - ) - - assert security_deposit == 10000000000000000 - assert multisig_address == "0x77b783e911F4398D75908Cc60C7138Bd1eFe35Fd" - assert ipfs_hash_for_config == b"UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" - assert threshold == 3 - assert max_number_of_agent_instances == 4 - assert number_of_agent_instances == 4 - assert service_state == 4 - assert list_of_cannonical_agents == [1] - - def test_get_slash_data(self) -> None: - """Test the `get_slash_data`.""" - result = self.contract.get_slash_data( - self.ledger_api, - self.contract_address, - AGENT_INSTANCES, - [0, 0, 0, 1], - service_id=1, - ) - - assert result.get("data", b"") == ( - b"s\xb8\xb6\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" - b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf3\x9f\xd6\xe5\x1a\xad\x88\xf6\xf4\xcej\xb8\x82ry\xcf" - b'\xff\xb9"f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x99yp\xc5\x18\x12\xdc:\x01\x0c}\x01\xb5\x0e\r' - b"\x17\xdcy\xc8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 None: - """Test `get_operator` method.""" - for agent_instance, expected_operator in OPERATORS_MAPPING.items(): - actual_operator = ( - self.contract._get_operator( # pylint: disable=protected-access - self.ledger_api, - self.contract_address, - agent_instance, - ) - ) - assert actual_operator == expected_operator - - def test_get_operators_mapping(self) -> None: - """Test `get_operator` method.""" - actual_mapping = self.contract.get_operators_mapping( - self.ledger_api, - self.contract_address, - frozenset(OPERATORS_MAPPING.keys()), - ) - assert actual_mapping == OPERATORS_MAPPING diff --git a/trader_old/vendor/valory/contracts/service_staking_token/__init__.py b/trader_old/vendor/valory/contracts/service_staking_token/__init__.py deleted file mode 100644 index cf1e8467e..000000000 --- a/trader_old/vendor/valory/contracts/service_staking_token/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 the support resources for the agent registry contract.""" diff --git a/trader_old/vendor/valory/contracts/service_staking_token/build/ServiceStakingToken.json b/trader_old/vendor/valory/contracts/service_staking_token/build/ServiceStakingToken.json deleted file mode 100644 index e1405c0bf..000000000 --- a/trader_old/vendor/valory/contracts/service_staking_token/build/ServiceStakingToken.json +++ /dev/null @@ -1,1355 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ServiceStakingToken", - "sourceName": "contracts/staking/ServiceStakingToken.sol", - "abi": [ - { - "inputs": [ - { - "components": [ - { - "internalType": "uint256", - "name": "maxNumServices", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "rewardsPerSecond", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minStakingDeposit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minNumStakingPeriods", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxNumInactivityPeriods", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "livenessPeriod", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "livenessRatio", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numAgentInstances", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "agentIds", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - } - ], - "internalType": "struct ServiceStakingBase.StakingParams", - "name": "_stakingParams", - "type": "tuple" - }, - { - "internalType": "address", - "name": "_serviceRegistry", - "type": "address" - }, - { - "internalType": "address", - "name": "_serviceRegistryTokenUtility", - "type": "address" - }, - { - "internalType": "address", - "name": "_stakingToken", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "_proxyHash", - "type": "bytes32" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "AgentInstanceRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentInstancesSlotsFilled", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "AgentNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "AgentNotInService", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "componentId", - "type": "uint256" - } - ], - "name": "ComponentNotFound", - "type": "error" - }, - { - "inputs": [], - "name": "HashExists", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectAgentBondingValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "sent", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "IncorrectRegistrationDepositValue", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "LowerThan", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "manager", - "type": "address" - } - ], - "name": "ManagerOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "maxNumServices", - "type": "uint256" - } - ], - "name": "MaxNumServicesReached", - "type": "error" - }, - { - "inputs": [], - "name": "NoRewardsAvailable", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "tsProvided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "tsExpected", - "type": "uint256" - } - ], - "name": "NotEnoughTimeStaked", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "provided", - "type": "address" - }, - { - "internalType": "address", - "name": "expected", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OnlyOwnServiceMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "OperatorHasNoInstances", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "max", - "type": "uint256" - } - ], - "name": "Overflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerOnly", - "type": "error" - }, - { - "inputs": [], - "name": "Paused", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrancyGuard", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceMustBeInactive", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceNotUnstaked", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "TokenTransferFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "TransferFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "UnauthorizedMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "ValueLowerThan", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "WrongAgentId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "numValues1", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numValues2", - "type": "uint256" - } - ], - "name": "WrongArrayLength", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongOperator", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceConfiguration", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "state", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceState", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "expected", - "type": "address" - }, - { - "internalType": "address", - "name": "provided", - "type": "address" - } - ], - "name": "WrongStakingToken", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "currentThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minThreshold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxThreshold", - "type": "uint256" - } - ], - "name": "WrongThreshold", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "availableRewards", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "serviceIds", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "rewards", - "type": "uint256[]" - } - ], - "name": "Checkpoint", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "balance", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "availableRewards", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - } - ], - "name": "ServiceStaked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "reward", - "type": "uint256" - } - ], - "name": "ServiceUnstaked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "serviceIds", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "owners", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "multisigs", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "serviceInactivity", - "type": "uint256[]" - } - ], - "name": "ServicesEvicted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Withdraw", - "type": "event" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "agentIds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "availableRewards", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "balance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "calculateServiceStakingLastReward", - "outputs": [ - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "calculateServiceStakingReward", - "outputs": [ - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "checkpoint", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[][]", - "name": "", - "type": "uint256[][]" - }, - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "evictServiceIds", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "configHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "deposit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "epochCounter", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getAgentIds", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNextRewardCheckpointTimestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "tsNext", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getServiceIds", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getServiceInfo", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "tsStart", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "inactivity", - "type": "uint256" - } - ], - "internalType": "struct ServiceInfo", - "name": "sInfo", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getServiceStakingState", - "outputs": [ - { - "internalType": "enum ServiceStakingBase.ServiceStakingState", - "name": "stakingState", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "livenessPeriod", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "livenessRatio", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceInfo", - "outputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tsStart", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "inactivity", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxInactivityDuration", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxNumInactivityPeriods", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxNumServices", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minStakingDeposit", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minStakingDuration", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "numAgentInstances", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC721Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "proxyHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "rewardsPerSecond", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "serviceRegistry", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "serviceRegistryTokenUtility", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "setServiceIds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "stake", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "stakingToken", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "threshold", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "tsCheckpoint", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "unstake", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x6102606040523480156200001257600080fd5b506040516200383a3803806200383a833981016040819052620000359162000453565b8484828260000151600014806200004e57506020830151155b806200005c575060a0830151155b806200006a575060c0830151155b8062000078575060e0830151155b806200008657506060830151155b806200009457506080830151155b15620000b357604051637c946ed760e01b815260040160405180910390fd5b826080015183606001511015620000f5576060830151608084015160405163491a2bb160e01b8152600481019290925260248201526044015b60405180910390fd5b6002836040015110156200012d57604080840151905163491a2bb160e01b8152600481019190915260026024820152604401620000ec565b6001600160a01b038216620001555760405163d92e233d60e01b815260040160405180910390fd5b82516080908152602084015160a0908152604085015160c09081529185015160e0908152908501516101005290840151610120908152908401516101409081526001600160a01b0384166101a0529084015161016052830151610180526000805b846101000151518110156200029257818561010001518281518110620001e057620001e062000576565b6020026020010151116200022d57846101000151818151811062000208576200020862000576565b6020026020010151604051632ab10b0b60e21b8152600401620000ec91815260200190565b846101000151818151811062000247576200024762000576565b602090810291909101015160048054600181810183556000929092527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0182905590925001620001b6565b5081620002b257604051637c946ed760e01b815260040160405180910390fd5b6101c0829052610100516060850151620002cd91906200058c565b6101e052610100516080850151620002e691906200058c565b6102005250504260035550506001600160a01b03821615806200031057506001600160a01b038316155b156200032f5760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b0390811661024052166102205250620005b89050565b634e487b7160e01b600052604160045260246000fd5b60405161016081016001600160401b03811182821017156200038957620003896200034d565b60405290565b600082601f830112620003a157600080fd5b815160206001600160401b0380831115620003c057620003c06200034d565b8260051b604051601f19603f83011681018181108482111715620003e857620003e86200034d565b60405293845260208187018101949081019250878511156200040957600080fd5b6020870191505b848210156200042b5781518352918301919083019062000410565b979650505050505050565b80516001600160a01b03811681146200044e57600080fd5b919050565b600080600080600060a086880312156200046c57600080fd5b85516001600160401b03808211156200048457600080fd5b90870190610160828a0312156200049a57600080fd5b620004a462000363565b825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010080840151838111156200050357600080fd5b620005118c8287016200038f565b918301919091525061012083810151908201526101409283015192810192909252509450620005436020870162000436565b9350620005536040870162000436565b9250620005636060870162000436565b9150608086015190509295509295909350565b634e487b7160e01b600052603260045260246000fd5b8082028115828204841417620005b257634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161311962000721600039600081816104110152818161130901528181611c1401528181611d1e0152611d6201526000818161030501528181611ca40152611e0e01526000818161068e015281816118a50152611b1401526000818161024b0152818161074d015261079f01526000818161044b0152610fca0152600081816105cf01528181610a0101528181610d8601526111bd0152600081816105f601528181610e4e0152610e7d01526000818161036201528181610ec40152610ef80152600081816103c30152610e0c0152600081816103ea015261294a01526000818161038901528181611bc60152611fb80152600061049b01526000818161061d0152611d9901526000818161064401526122ae0152600081816102de01528181610d0d0152610d4101526131196000f3fe608060405234801561001057600080fd5b50600436106102415760003560e01c8063a0ed60e011610145578063cbcf252a116100bd578063eb338c961161008c578063f4dce71411610071578063f4dce71414610681578063f86ad2b614610689578063ffa1ad74146106b057600080fd5b8063eb338c9614610666578063f189e85a1461067957600080fd5b8063cbcf252a146105ca578063e1f1176d146105f1578063e77cdcc914610618578063eacdaabc1461063f57600080fd5b8063b69ef8a811610114578063c2c4c5c1116100f9578063c2c4c5c11461057e578063c889921d14610597578063cae2a5f0146105aa57600080fd5b8063b69ef8a814610562578063b6b55f251461056b57600080fd5b8063a0ed60e014610496578063a694fc3a146104bd578063a74466ad146104d0578063b15087601461054d57600080fd5b806352c824f5116101d857806372f702f3116101a7578063809cee2f1161018c578063809cee2f1461044657806382a8ea581461046d578063879d90901461048d57600080fd5b806372f702f31461040c57806378e061361461043357600080fd5b806352c824f51461038457806356e76058146103ab5780635829c5ec146103be578063592cf3fb146103e557600080fd5b8063287140511161021457806328714051146103005780632e17de781461033f5780633e7329971461035457806342cde4e81461035d57600080fd5b806308ae7e541461024657806314b19c5a14610280578063150b7a021461028957806316a75172146102d9575b600080fd5b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61026d60005481565b6102a8610297366004612a0a565b630a85bd0160e11b95945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610277565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b61035261034d366004612aa9565b6106e1565b005b61026d60035481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d6103b9366004612aa9565b610acf565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d610441366004612aa9565b610af0565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61048061047b366004612aa9565b610bba565b6040516102779190612afe565b61026d60025481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103526104cb366004612aa9565b610cb1565b61051a6104de366004612aa9565b6005602081905260009182526040909120805460018201546003830154600484015493909401546001600160a01b039283169492909116929085565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610277565b61055561127e565b6040516102779190612b65565b61026d60015481565b610352610579366004612aa9565b6112d6565b610586611378565b604051610277959493929190612b78565b61026d6105a5366004612aa9565b6119ad565b6105bd6105b8366004612aa9565b611a69565b6040516102779190612c3d565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d610674366004612aa9565b611b5c565b610555611b6c565b61026d611bc2565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6106d4604051806040016040528060058152602001640302e312e360dc1b81525081565b6040516102779190612c65565b600081815260056020526040902060018101546001600160a01b0316331461073857600181015460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b600381015460006107498242612cca565b90507f0000000000000000000000000000000000000000000000000000000000000000811115801561077d57506000600254115b156107cb5760405163ba2bbc6b60e01b815260048101859052602481018290527f0000000000000000000000000000000000000000000000000000000000000000604482015260640161072f565b6000806107d6611378565b945050505091508151600003610837576107ee611b6c565b9150815167ffffffffffffffff81111561080a5761080a612cdd565b604051908082528060200260200182016040528015610833578160200160208202803683370190505b5090505b6000805b8351821015610898578783838151811061085757610857612cf3565b60200260200101510315610898578784838151811061087857610878612cf3565b60200260200101510361088d57506001610898565b81600101915061083b565b600487015460028801805460408051602080840282018101909252828152600093909290918301828280156108ec57602002820191906000526020600020905b8154815260200190600101908083116108d8575b50508c5460008f8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff19908116825560018201805490911690559596506001600160a01b03909116949350915061094890506002830182612974565b506000600382018190556004820181905560059091015583156109d7576006805461097590600190612cca565b8154811061098557610985612cf3565b9060005260206000200154600686815481106109a3576109a3612cf3565b60009182526020909120015560068054806109c0576109c0612d09565b600190038181906000526020600020016000905590555b604051632142170760e11b8152306004820152336024820152604481018c90526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342842e0e90606401600060405180830381600087803b158015610a4557600080fd5b505af1158015610a59573d6000803e3d6000fd5b505050506000831115610a7057610a708184611bf7565b806001600160a01b0316336001600160a01b03168c7f950733f4c0bf951b8e770f3cc619a4288e7b59b1236d59aeaf2c238488e8ae816000548688604051610aba93929190612d1f565b60405180910390a45050505050505050505050565b60048181548110610adf57600080fd5b600091825260209091200154905081565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015610b7057602002820191906000526020600020905b815481526020019060010190808311610b5c575b505050505081526020016003820154815260200160048201548152602001600582015481525050905080608001519150610ba9836119ad565b610bb39083612d48565b9392505050565b610c056040518060c0016040528060006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016000815260200160008152602001600081525090565b600082815260056020908152604091829020825160c08101845281546001600160a01b0390811682526001830154168184015260028201805485518186028101860187528181529295939493860193830182828015610c8357602002820191906000526020600020905b815481526020019060010190808311610c6f575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050919050565b600254600003610cd45760405163afb0be3360e01b815260040160405180910390fd5b6000818152600560205260409020600381015415610d085760405163b4817ce760e01b81526004810183905260240161072f565b6006547f00000000000000000000000000000000000000000000000000000000000000008103610d6d5760405163fd20861560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260240161072f565b60405163ef0e239b60e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ef0e239b90602401600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dfd9190810190612e79565b9050806080015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014610e4c57604051637ad404bf60e11b81526004810185905260240161072f565b7f000000000000000000000000000000000000000000000000000000000000000015801590610e9f575080604001517f000000000000000000000000000000000000000000000000000000000000000014155b15610ec057604051637ad404bf60e11b81526004810185905260240161072f565b60007f0000000000000000000000000000000000000000000000000000000000000000118015610f1a5750806060015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014155b15610f3b57604051637ad404bf60e11b81526004810185905260240161072f565b60048160c001516005811115610f5357610f53612c27565b14610f92578060c001516005811115610f6e57610f6e612c27565b604051633c053f9d60e21b815260048101919091526024810185905260440161072f565b600081602001516001600160a01b0316803b806020016040519081016040528181526000908060200190933c805190602001209050807f00000000000000000000000000000000000000000000000000000000000000001461101757602082015160405162a2307960e51b81526001600160a01b03909116600482015260240161072f565b60045480156110e05760e08301515181811461104957604051637ad404bf60e11b81526004810188905260240161072f565b60005b818110156110dd578460e00151818151811061106a5761106a612cf3565b602002602001015163ffffffff166004828154811061108b5761108b612cf3565b9060005260206000200154146110d557600481815481106110ae576110ae612cf3565b9060005260206000200154604051632ab10b0b60e21b815260040161072f91815260200190565b60010161104c565b50505b6111018684600001516bffffffffffffffffffffffff168560e00151611c81565b602083015185546001600160a01b03821673ffffffffffffffffffffffffffffffffffffffff199182161787556001870180549091163317905560009061114790611f02565b805190915061115f9060028801906020840190612995565b50426003870155600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01879055604051632142170760e11b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342842e0e90606401600060405180830381600087803b15801561120957600080fd5b505af115801561121d573d6000803e3d6000fd5b5050505083602001516001600160a01b0316336001600160a01b0316887faa6b005b4958114a0c90492461c24af6525ae0178db7fbf44125ae9217c69ccb6000548560405161126d929190612f57565b60405180910390a450505050505050565b606060048054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020905b8154815260200190600101908083116112b8575b5050505050905090565b6000816001546112e69190612d48565b90506000826002546112f89190612d48565b6001839055600281905590506113307f0000000000000000000000000000000000000000000000000000000000000000333086611f13565b604080518481526020810184905290810182905233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9060600160405180910390a2505050565b6060806060806060600080600080600080600080611394611f9d565b97509750975097509750975097509750606080845167ffffffffffffffff8111156113c1576113c1612cdd565b6040519080825280602002602001820160405280156113ea578160200160208202803683370190505b509a506000891561177d578967ffffffffffffffff81111561140e5761140e612cdd565b604051908082528060200260200182016040528015611437578160200160208202803683370190505b5092508967ffffffffffffffff81111561145357611453612cdd565b60405190808252806020026020018201604052801561147c578160200160208202803683370190505b5091508a8911156116865760008060015b8c811015611579578b8e8b83815181106114a9576114a9612cf3565b60200260200101516114bb9190612f70565b6114c59190612f87565b92506114d18383612d48565b91508a81815181106114e5576114e5612cf3565b602002602001015193508a818151811061150157611501612cf3565b602002602001015186828151811061151b5761151b612cf3565b6020026020010181815250508285828151811061153a5761153a612cf3565b6020026020010181815250508260056000868152602001908152602001600020600401600082825461156c9190612d48565b909155505060010161148d565b508a8d8a60008151811061158f5761158f612cf3565b60200260200101516115a19190612f70565b6115ab9190612f87565b91506115b78282612d48565b9050896000815181106115cc576115cc612cf3565b60200260200101519250896000815181106115e9576115e9612cf3565b60200260200101518560008151811061160457611604612cf3565b602002602001018181525050808d111561162f57611622818e612cca565b61162c9083612d48565b91505b818460008151811061164357611643612cf3565b602002602001018181525050816005600085815260200190815260200160002060040160008282546116759190612d48565b9091555060009d5061177792505050565b60005b8a811015611769578881815181106116a3576116a3612cf3565b602002602001015191508881815181106116bf576116bf612cf3565b60200260200101518482815181106116d9576116d9612cf3565b6020026020010181815250508781815181106116f7576116f7612cf3565b602002602001015183828151811061171157611711612cf3565b60200260200101818152505087818151811061172f5761172f612cf3565b602002602001015160056000848152602001908152602001600020600401600082825461175c9190612d48565b9091555050600101611689565b50611774898c612cca565b9a505b60028b90555b855115611997576000995060005b8651811015611930578681815181106117a6576117a6612cf3565b602002602001015191508581815181106117c2576117c2612cf3565b60200260200101516005600084815260200190815260200160002060020190805190602001906117f3929190612995565b50600085828151811061180857611808612cf3565b602002602001015111156119155784818151811061182857611828612cf3565b602002602001015160056000848152602001908152602001600020600501546118519190612d48565b85828151811061186357611863612cf3565b60200260200101818152505084818151811061188157611881612cf3565b602002602001015160056000848152602001908152602001600020600501819055507f00000000000000000000000000000000000000000000000000000000000000008582815181106118d6576118d6612cf3565b6020026020010151111561191057818d82815181106118f7576118f7612cf3565b60209081029190910101528a61190c81612fa9565b9b50505b611928565b6000828152600560208190526040822001555b60010161178b565b508915611942576119428c858c61239b565b42600355600054611954816001612d48565b60005560405181907f06a98bdd4732811ab3214800ed1ada2dce66a2bce301d250c3ca7d6b461ee6669061198d908f9088908890612fc2565b60405180910390a2505b50939e929d509b50919950969750505050505050565b6000806000806000806119be611f9d565b5050509450945094509450945060005b84811015611a5e57878382815181106119e9576119e9612cf3565b602002602001015103611a565785841115611a35578386838381518110611a1257611a12612cf3565b6020026020010151611a249190612f70565b611a2e9190612f87565b9650611a5e565b818181518110611a4757611a47612cf3565b60200260200101519650611a5e565b6001016119ce565b505050505050919050565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015611ae957602002820191906000526020600020905b815481526020019060010190808311611ad5575b50505050508152602001600382015481526020016004820154815260200160058201548152505090507f00000000000000000000000000000000000000000000000000000000000000008160a001511115611b475760029150611b56565b606081015115611b5657600191505b50919050565b60068181548110610adf57600080fd5b606060068054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020908154815260200190600101908083116112b8575050505050905090565b60007f0000000000000000000000000000000000000000000000000000000000000000600354611bf29190612d48565b905090565b8060016000828254611c099190612cca565b90915550611c3a90507f00000000000000000000000000000000000000000000000000000000000000008383612760565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051611c7591815260200190565b60405180910390a25050565b604051633cebfa4f60e01b81526004810184905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633cebfa4f906024016040805180830381865afa158015611cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0e9190612ff7565b91509150816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611d9757604051630b80380d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161072f565b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff8216811115611dfe57604051632b30b24760e21b81526bffffffffffffffffffffffff831660048201526024810182905260440161072f565b60005b8451811015611ef95760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166375c1f93489888581518110611e4e57611e4e612cf3565b60200260200101516040518363ffffffff1660e01b8152600401611e8292919091825263ffffffff16602082015260400190565b602060405180830381865afa158015611e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec3919061302c565b905082811015611ef057604051632b30b24760e21b8152600481018290526024810184905260440161072f565b50600101611e01565b50505050505050565b6060611f0d826127e3565b92915050565b60006040516323b872dd60e01b6000528460045283602452826044526020600060646000808a5af13d15601f3d1160016000511416171691506000606052806040525080611f965760405163abae3d6d60e01b81526001600160a01b0380871660048301528086166024830152841660448201526064810183905260840161072f565b5050505050565b600080600060608060608060606000600354905060025498507f00000000000000000000000000000000000000000000000000000000000000008142611fe39190612cca565b10158015611ff15750600089115b15612390576006548067ffffffffffffffff81111561201257612012612cdd565b60405190808252806020026020018201604052801561203b578160200160208202803683370190505b5094508067ffffffffffffffff81111561205757612057612cdd565b604051908082528060200260200182016040528015612080578160200160208202803683370190505b5096508067ffffffffffffffff81111561209c5761209c612cdd565b6040519080825280602002602001820160405280156120c5578160200160208202803683370190505b5095508067ffffffffffffffff8111156120e1576120e1612cdd565b60405190808252806020026020018201604052801561211457816020015b60608152602001906001900390816120ff5790505b5093508067ffffffffffffffff81111561213057612130612cdd565b604051908082528060200260200182016040528015612159578160200160208202803683370190505b50925060005b8181101561238d576006818154811061217a5761217a612cf3565b906000526020600020015486828151811061219757612197612cf3565b6020026020010181815250506000600560008884815181106121bb576121bb612cf3565b602090810291909101810151825281019190915260400160002080549091506121ec906001600160a01b0316611f02565b8683815181106121fe576121fe612cf3565b6020908102919091010152600381015484908181111561221c578091505b6122268242612cca565b905060006122a089868151811061223f5761223f612cf3565b60200260200101518560020180548060200260200160405190810160405280929190818152602001828054801561229557602002820191906000526020600020905b815481526020019060010190808311612281575b50505050508461288b565b9050801561235e576122d2827f0000000000000000000000000000000000000000000000000000000000000000612f70565b8b8f815181106122e4576122e4612cf3565b6020026020010181815250508a8e8151811061230257612302612cf3565b60200260200101518d6123159190612d48565b9c5089858151811061232957612329612cf3565b60200260200101518c8f8151811061234357612343612cf3565b60209081029190910101526123578e612fa9565b9d5061237e565b8188868151811061237157612371612cf3565b6020026020010181815250505b5050505080600101905061215f565b50505b509091929394959697565b825160008267ffffffffffffffff8111156123b8576123b8612cdd565b6040519080825280602002602001820160405280156123e1578160200160208202803683370190505b50905060008367ffffffffffffffff8111156123ff576123ff612cdd565b604051908082528060200260200182016040528015612428578160200160208202803683370190505b50905060008467ffffffffffffffff81111561244657612446612cdd565b60405190808252806020026020018201604052801561246f578160200160208202803683370190505b50905060008567ffffffffffffffff81111561248d5761248d612cdd565b6040519080825280602002602001820160405280156124b6578160200160208202803683370190505b50905060008667ffffffffffffffff8111156124d4576124d4612cdd565b6040519080825280602002602001820160405280156124fd578160200160208202803683370190505b50905060008060005b8881101561265d5760008c828151811061252257612522612cf3565b60200260200101511115612655578b818151811061254257612542612cf3565b602002602001015191508188848151811061255f5761255f612cf3565b6020908102919091018101919091526000838152600590915260409020600181015488516001600160a01b03909116908990869081106125a1576125a1612cf3565b6001600160a01b039283166020918202929092010152815488519116908890869081106125d0576125d0612cf3565b60200260200101906001600160a01b031690816001600160a01b0316815250508b828151811061260257612602612cf3565b602002602001015186858151811061261c5761261c612cf3565b6020026020010181815250508185858151811061263b5761263b612cf3565b60209081029190910101528361265081612fa9565b945050505b600101612506565b50885b8015612712578861267081613045565b99506000905084612682600184612cca565b8151811061269257612692612cf3565b6020026020010151905060068a815481106126af576126af612cf3565b9060005260206000200154600682815481106126cd576126cd612cf3565b60009182526020909120015560068054806126ea576126ea612d09565b60019003818190600052602060002001600090559055508061270b90613045565b9050612660565b506000547fd19a3d42ed383465e4058c322d9411aeac76ddb8454d22e139fc99808bd569528888888860405161274b9493929190613096565b60405180910390a25050505050505050505050565b600060405163a9059cbb60e01b6000528360045282602452602060006044600080895af13d15601f3d11600160005114161716915060006060528060405250806127dd5760405163abae3d6d60e01b81526001600160a01b038086166004830152306024830152841660448201526064810183905260840161072f565b50505050565b60408051600180825281830190925260609160208083019080368337019050509050816001600160a01b031663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612843573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612867919061302c565b8160008151811061287a5761287a612cf3565b602002602001018181525050919050565b60006128988484846128a0565b949350505050565b600080821180156128e45750826000815181106128bf576128bf612cf3565b6020026020010151846000815181106128da576128da612cf3565b6020026020010151115b15610bb357600082846000815181106128ff576128ff612cf3565b60200260200101518660008151811061291a5761291a612cf3565b602002602001015161292c9190612cca565b61293e90670de0b6b3a7640000612f70565b6129489190612f87565b7f0000000000000000000000000000000000000000000000000000000000000000111595945050505050565b508054600082559060005260206000209081019061299291906129e0565b50565b8280548282559060005260206000209081019282156129d0579160200282015b828111156129d05782518255916020019190600101906129b5565b506129dc9291506129e0565b5090565b5b808211156129dc57600081556001016129e1565b6001600160a01b038116811461299257600080fd5b600080600080600060808688031215612a2257600080fd5b8535612a2d816129f5565b94506020860135612a3d816129f5565b935060408601359250606086013567ffffffffffffffff80821115612a6157600080fd5b818801915088601f830112612a7557600080fd5b813581811115612a8457600080fd5b896020828501011115612a9657600080fd5b9699959850939650602001949392505050565b600060208284031215612abb57600080fd5b5035919050565b60008151808452602080850194506020840160005b83811015612af357815187529582019590820190600101612ad7565b509495945050505050565b6020815260006001600160a01b0380845116602084015280602085015116604084015250604083015160c06060840152612b3b60e0840182612ac2565b905060608401516080840152608084015160a084015260a084015160c08401528091505092915050565b602081526000610bb36020830184612ac2565b60a081526000612b8b60a0830188612ac2565b6020838203818501528188518084528284019150828160051b850101838b0160005b83811015612bdb57601f19878403018552612bc9838351612ac2565b94860194925090850190600101612bad565b50508681036040880152612bef818b612ac2565b9450505050508281036060840152612c078186612ac2565b90508281036080840152612c1b8185612ac2565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6020810160038310612c5f57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020808352835180602085015260005b81811015612c9357858101830151858201604001528201612c77565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115611f0d57611f0d612cb4565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b838152606060208201526000612d386060830185612ac2565b9050826040830152949350505050565b80820180821115611f0d57611f0d612cb4565b604051610100810167ffffffffffffffff81118282101715612d7f57612d7f612cdd565b60405290565b80516bffffffffffffffffffffffff81168114612da157600080fd5b919050565b8051612da1816129f5565b805163ffffffff81168114612da157600080fd5b805160068110612da157600080fd5b600082601f830112612de557600080fd5b8151602067ffffffffffffffff80831115612e0257612e02612cdd565b8260051b604051601f19603f83011681018181108482111715612e2757612e27612cdd565b6040529384526020818701810194908101925087851115612e4757600080fd5b6020870191505b84821015612e6e57612e5f82612db1565b83529183019190830190612e4e565b979650505050505050565b600060208284031215612e8b57600080fd5b815167ffffffffffffffff80821115612ea357600080fd5b908301906101008286031215612eb857600080fd5b612ec0612d5b565b612ec983612d85565b8152612ed760208401612da6565b602082015260408301516040820152612ef260608401612db1565b6060820152612f0360808401612db1565b6080820152612f1460a08401612db1565b60a0820152612f2560c08401612dc5565b60c082015260e083015182811115612f3c57600080fd5b612f4887828601612dd4565b60e08301525095945050505050565b8281526040602082015260006128986040830184612ac2565b8082028115828204841417611f0d57611f0d612cb4565b600082612fa457634e487b7160e01b600052601260045260246000fd5b500490565b600060018201612fbb57612fbb612cb4565b5060010190565b838152606060208201526000612fdb6060830185612ac2565b8281036040840152612fed8185612ac2565b9695505050505050565b6000806040838503121561300a57600080fd5b8251613015816129f5565b915061302360208401612d85565b90509250929050565b60006020828403121561303e57600080fd5b5051919050565b60008161305457613054612cb4565b506000190190565b60008151808452602080850194506020840160005b83811015612af35781516001600160a01b031687529582019590820190600101613071565b6080815260006130a96080830187612ac2565b82810360208401526130bb818761305c565b905082810360408401526130cf818661305c565b90508281036060840152612e6e8185612ac256fea26469706673582212201cbb3243bdf2246a74a754c4b24385dc52b256b192f67778a3b3a76648374a5864736f6c63430008170033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102415760003560e01c8063a0ed60e011610145578063cbcf252a116100bd578063eb338c961161008c578063f4dce71411610071578063f4dce71414610681578063f86ad2b614610689578063ffa1ad74146106b057600080fd5b8063eb338c9614610666578063f189e85a1461067957600080fd5b8063cbcf252a146105ca578063e1f1176d146105f1578063e77cdcc914610618578063eacdaabc1461063f57600080fd5b8063b69ef8a811610114578063c2c4c5c1116100f9578063c2c4c5c11461057e578063c889921d14610597578063cae2a5f0146105aa57600080fd5b8063b69ef8a814610562578063b6b55f251461056b57600080fd5b8063a0ed60e014610496578063a694fc3a146104bd578063a74466ad146104d0578063b15087601461054d57600080fd5b806352c824f5116101d857806372f702f3116101a7578063809cee2f1161018c578063809cee2f1461044657806382a8ea581461046d578063879d90901461048d57600080fd5b806372f702f31461040c57806378e061361461043357600080fd5b806352c824f51461038457806356e76058146103ab5780635829c5ec146103be578063592cf3fb146103e557600080fd5b8063287140511161021457806328714051146103005780632e17de781461033f5780633e7329971461035457806342cde4e81461035d57600080fd5b806308ae7e541461024657806314b19c5a14610280578063150b7a021461028957806316a75172146102d9575b600080fd5b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b61026d60005481565b6102a8610297366004612a0a565b630a85bd0160e11b95945050505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610277565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b61035261034d366004612aa9565b6106e1565b005b61026d60035481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d6103b9366004612aa9565b610acf565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d610441366004612aa9565b610af0565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61048061047b366004612aa9565b610bba565b6040516102779190612afe565b61026d60025481565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6103526104cb366004612aa9565b610cb1565b61051a6104de366004612aa9565b6005602081905260009182526040909120805460018201546003830154600484015493909401546001600160a01b039283169492909116929085565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a001610277565b61055561127e565b6040516102779190612b65565b61026d60015481565b610352610579366004612aa9565b6112d6565b610586611378565b604051610277959493929190612b78565b61026d6105a5366004612aa9565b6119ad565b6105bd6105b8366004612aa9565b611a69565b6040516102779190612c3d565b6103277f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b61026d610674366004612aa9565b611b5c565b610555611b6c565b61026d611bc2565b61026d7f000000000000000000000000000000000000000000000000000000000000000081565b6106d4604051806040016040528060058152602001640302e312e360dc1b81525081565b6040516102779190612c65565b600081815260056020526040902060018101546001600160a01b0316331461073857600181015460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b600381015460006107498242612cca565b90507f0000000000000000000000000000000000000000000000000000000000000000811115801561077d57506000600254115b156107cb5760405163ba2bbc6b60e01b815260048101859052602481018290527f0000000000000000000000000000000000000000000000000000000000000000604482015260640161072f565b6000806107d6611378565b945050505091508151600003610837576107ee611b6c565b9150815167ffffffffffffffff81111561080a5761080a612cdd565b604051908082528060200260200182016040528015610833578160200160208202803683370190505b5090505b6000805b8351821015610898578783838151811061085757610857612cf3565b60200260200101510315610898578784838151811061087857610878612cf3565b60200260200101510361088d57506001610898565b81600101915061083b565b600487015460028801805460408051602080840282018101909252828152600093909290918301828280156108ec57602002820191906000526020600020905b8154815260200190600101908083116108d8575b50508c5460008f8152600560205260408120805473ffffffffffffffffffffffffffffffffffffffff19908116825560018201805490911690559596506001600160a01b03909116949350915061094890506002830182612974565b506000600382018190556004820181905560059091015583156109d7576006805461097590600190612cca565b8154811061098557610985612cf3565b9060005260206000200154600686815481106109a3576109a3612cf3565b60009182526020909120015560068054806109c0576109c0612d09565b600190038181906000526020600020016000905590555b604051632142170760e11b8152306004820152336024820152604481018c90526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342842e0e90606401600060405180830381600087803b158015610a4557600080fd5b505af1158015610a59573d6000803e3d6000fd5b505050506000831115610a7057610a708184611bf7565b806001600160a01b0316336001600160a01b03168c7f950733f4c0bf951b8e770f3cc619a4288e7b59b1236d59aeaf2c238488e8ae816000548688604051610aba93929190612d1f565b60405180910390a45050505050505050505050565b60048181548110610adf57600080fd5b600091825260209091200154905081565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015610b7057602002820191906000526020600020905b815481526020019060010190808311610b5c575b505050505081526020016003820154815260200160048201548152602001600582015481525050905080608001519150610ba9836119ad565b610bb39083612d48565b9392505050565b610c056040518060c0016040528060006001600160a01b0316815260200160006001600160a01b03168152602001606081526020016000815260200160008152602001600081525090565b600082815260056020908152604091829020825160c08101845281546001600160a01b0390811682526001830154168184015260028201805485518186028101860187528181529295939493860193830182828015610c8357602002820191906000526020600020905b815481526020019060010190808311610c6f575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050919050565b600254600003610cd45760405163afb0be3360e01b815260040160405180910390fd5b6000818152600560205260409020600381015415610d085760405163b4817ce760e01b81526004810183905260240161072f565b6006547f00000000000000000000000000000000000000000000000000000000000000008103610d6d5760405163fd20861560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260240161072f565b60405163ef0e239b60e01b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ef0e239b90602401600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610dfd9190810190612e79565b9050806080015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014610e4c57604051637ad404bf60e11b81526004810185905260240161072f565b7f000000000000000000000000000000000000000000000000000000000000000015801590610e9f575080604001517f000000000000000000000000000000000000000000000000000000000000000014155b15610ec057604051637ad404bf60e11b81526004810185905260240161072f565b60007f0000000000000000000000000000000000000000000000000000000000000000118015610f1a5750806060015163ffffffff167f000000000000000000000000000000000000000000000000000000000000000014155b15610f3b57604051637ad404bf60e11b81526004810185905260240161072f565b60048160c001516005811115610f5357610f53612c27565b14610f92578060c001516005811115610f6e57610f6e612c27565b604051633c053f9d60e21b815260048101919091526024810185905260440161072f565b600081602001516001600160a01b0316803b806020016040519081016040528181526000908060200190933c805190602001209050807f00000000000000000000000000000000000000000000000000000000000000001461101757602082015160405162a2307960e51b81526001600160a01b03909116600482015260240161072f565b60045480156110e05760e08301515181811461104957604051637ad404bf60e11b81526004810188905260240161072f565b60005b818110156110dd578460e00151818151811061106a5761106a612cf3565b602002602001015163ffffffff166004828154811061108b5761108b612cf3565b9060005260206000200154146110d557600481815481106110ae576110ae612cf3565b9060005260206000200154604051632ab10b0b60e21b815260040161072f91815260200190565b60010161104c565b50505b6111018684600001516bffffffffffffffffffffffff168560e00151611c81565b602083015185546001600160a01b03821673ffffffffffffffffffffffffffffffffffffffff199182161787556001870180549091163317905560009061114790611f02565b805190915061115f9060028801906020840190612995565b50426003870155600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01879055604051632142170760e11b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342842e0e90606401600060405180830381600087803b15801561120957600080fd5b505af115801561121d573d6000803e3d6000fd5b5050505083602001516001600160a01b0316336001600160a01b0316887faa6b005b4958114a0c90492461c24af6525ae0178db7fbf44125ae9217c69ccb6000548560405161126d929190612f57565b60405180910390a450505050505050565b606060048054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020905b8154815260200190600101908083116112b8575b5050505050905090565b6000816001546112e69190612d48565b90506000826002546112f89190612d48565b6001839055600281905590506113307f0000000000000000000000000000000000000000000000000000000000000000333086611f13565b604080518481526020810184905290810182905233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9060600160405180910390a2505050565b6060806060806060600080600080600080600080611394611f9d565b97509750975097509750975097509750606080845167ffffffffffffffff8111156113c1576113c1612cdd565b6040519080825280602002602001820160405280156113ea578160200160208202803683370190505b509a506000891561177d578967ffffffffffffffff81111561140e5761140e612cdd565b604051908082528060200260200182016040528015611437578160200160208202803683370190505b5092508967ffffffffffffffff81111561145357611453612cdd565b60405190808252806020026020018201604052801561147c578160200160208202803683370190505b5091508a8911156116865760008060015b8c811015611579578b8e8b83815181106114a9576114a9612cf3565b60200260200101516114bb9190612f70565b6114c59190612f87565b92506114d18383612d48565b91508a81815181106114e5576114e5612cf3565b602002602001015193508a818151811061150157611501612cf3565b602002602001015186828151811061151b5761151b612cf3565b6020026020010181815250508285828151811061153a5761153a612cf3565b6020026020010181815250508260056000868152602001908152602001600020600401600082825461156c9190612d48565b909155505060010161148d565b508a8d8a60008151811061158f5761158f612cf3565b60200260200101516115a19190612f70565b6115ab9190612f87565b91506115b78282612d48565b9050896000815181106115cc576115cc612cf3565b60200260200101519250896000815181106115e9576115e9612cf3565b60200260200101518560008151811061160457611604612cf3565b602002602001018181525050808d111561162f57611622818e612cca565b61162c9083612d48565b91505b818460008151811061164357611643612cf3565b602002602001018181525050816005600085815260200190815260200160002060040160008282546116759190612d48565b9091555060009d5061177792505050565b60005b8a811015611769578881815181106116a3576116a3612cf3565b602002602001015191508881815181106116bf576116bf612cf3565b60200260200101518482815181106116d9576116d9612cf3565b6020026020010181815250508781815181106116f7576116f7612cf3565b602002602001015183828151811061171157611711612cf3565b60200260200101818152505087818151811061172f5761172f612cf3565b602002602001015160056000848152602001908152602001600020600401600082825461175c9190612d48565b9091555050600101611689565b50611774898c612cca565b9a505b60028b90555b855115611997576000995060005b8651811015611930578681815181106117a6576117a6612cf3565b602002602001015191508581815181106117c2576117c2612cf3565b60200260200101516005600084815260200190815260200160002060020190805190602001906117f3929190612995565b50600085828151811061180857611808612cf3565b602002602001015111156119155784818151811061182857611828612cf3565b602002602001015160056000848152602001908152602001600020600501546118519190612d48565b85828151811061186357611863612cf3565b60200260200101818152505084818151811061188157611881612cf3565b602002602001015160056000848152602001908152602001600020600501819055507f00000000000000000000000000000000000000000000000000000000000000008582815181106118d6576118d6612cf3565b6020026020010151111561191057818d82815181106118f7576118f7612cf3565b60209081029190910101528a61190c81612fa9565b9b50505b611928565b6000828152600560208190526040822001555b60010161178b565b508915611942576119428c858c61239b565b42600355600054611954816001612d48565b60005560405181907f06a98bdd4732811ab3214800ed1ada2dce66a2bce301d250c3ca7d6b461ee6669061198d908f9088908890612fc2565b60405180910390a2505b50939e929d509b50919950969750505050505050565b6000806000806000806119be611f9d565b5050509450945094509450945060005b84811015611a5e57878382815181106119e9576119e9612cf3565b602002602001015103611a565785841115611a35578386838381518110611a1257611a12612cf3565b6020026020010151611a249190612f70565b611a2e9190612f87565b9650611a5e565b818181518110611a4757611a47612cf3565b60200260200101519650611a5e565b6001016119ce565b505050505050919050565b6000818152600560209081526040808320815160c08101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181528796939586019390929190830182828015611ae957602002820191906000526020600020905b815481526020019060010190808311611ad5575b50505050508152602001600382015481526020016004820154815260200160058201548152505090507f00000000000000000000000000000000000000000000000000000000000000008160a001511115611b475760029150611b56565b606081015115611b5657600191505b50919050565b60068181548110610adf57600080fd5b606060068054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020908154815260200190600101908083116112b8575050505050905090565b60007f0000000000000000000000000000000000000000000000000000000000000000600354611bf29190612d48565b905090565b8060016000828254611c099190612cca565b90915550611c3a90507f00000000000000000000000000000000000000000000000000000000000000008383612760565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436482604051611c7591815260200190565b60405180910390a25050565b604051633cebfa4f60e01b81526004810184905260009081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633cebfa4f906024016040805180830381865afa158015611cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0e9190612ff7565b91509150816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614611d9757604051630b80380d60e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301528316602482015260440161072f565b7f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff8216811115611dfe57604051632b30b24760e21b81526bffffffffffffffffffffffff831660048201526024810182905260440161072f565b60005b8451811015611ef95760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166375c1f93489888581518110611e4e57611e4e612cf3565b60200260200101516040518363ffffffff1660e01b8152600401611e8292919091825263ffffffff16602082015260400190565b602060405180830381865afa158015611e9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec3919061302c565b905082811015611ef057604051632b30b24760e21b8152600481018290526024810184905260440161072f565b50600101611e01565b50505050505050565b6060611f0d826127e3565b92915050565b60006040516323b872dd60e01b6000528460045283602452826044526020600060646000808a5af13d15601f3d1160016000511416171691506000606052806040525080611f965760405163abae3d6d60e01b81526001600160a01b0380871660048301528086166024830152841660448201526064810183905260840161072f565b5050505050565b600080600060608060608060606000600354905060025498507f00000000000000000000000000000000000000000000000000000000000000008142611fe39190612cca565b10158015611ff15750600089115b15612390576006548067ffffffffffffffff81111561201257612012612cdd565b60405190808252806020026020018201604052801561203b578160200160208202803683370190505b5094508067ffffffffffffffff81111561205757612057612cdd565b604051908082528060200260200182016040528015612080578160200160208202803683370190505b5096508067ffffffffffffffff81111561209c5761209c612cdd565b6040519080825280602002602001820160405280156120c5578160200160208202803683370190505b5095508067ffffffffffffffff8111156120e1576120e1612cdd565b60405190808252806020026020018201604052801561211457816020015b60608152602001906001900390816120ff5790505b5093508067ffffffffffffffff81111561213057612130612cdd565b604051908082528060200260200182016040528015612159578160200160208202803683370190505b50925060005b8181101561238d576006818154811061217a5761217a612cf3565b906000526020600020015486828151811061219757612197612cf3565b6020026020010181815250506000600560008884815181106121bb576121bb612cf3565b602090810291909101810151825281019190915260400160002080549091506121ec906001600160a01b0316611f02565b8683815181106121fe576121fe612cf3565b6020908102919091010152600381015484908181111561221c578091505b6122268242612cca565b905060006122a089868151811061223f5761223f612cf3565b60200260200101518560020180548060200260200160405190810160405280929190818152602001828054801561229557602002820191906000526020600020905b815481526020019060010190808311612281575b50505050508461288b565b9050801561235e576122d2827f0000000000000000000000000000000000000000000000000000000000000000612f70565b8b8f815181106122e4576122e4612cf3565b6020026020010181815250508a8e8151811061230257612302612cf3565b60200260200101518d6123159190612d48565b9c5089858151811061232957612329612cf3565b60200260200101518c8f8151811061234357612343612cf3565b60209081029190910101526123578e612fa9565b9d5061237e565b8188868151811061237157612371612cf3565b6020026020010181815250505b5050505080600101905061215f565b50505b509091929394959697565b825160008267ffffffffffffffff8111156123b8576123b8612cdd565b6040519080825280602002602001820160405280156123e1578160200160208202803683370190505b50905060008367ffffffffffffffff8111156123ff576123ff612cdd565b604051908082528060200260200182016040528015612428578160200160208202803683370190505b50905060008467ffffffffffffffff81111561244657612446612cdd565b60405190808252806020026020018201604052801561246f578160200160208202803683370190505b50905060008567ffffffffffffffff81111561248d5761248d612cdd565b6040519080825280602002602001820160405280156124b6578160200160208202803683370190505b50905060008667ffffffffffffffff8111156124d4576124d4612cdd565b6040519080825280602002602001820160405280156124fd578160200160208202803683370190505b50905060008060005b8881101561265d5760008c828151811061252257612522612cf3565b60200260200101511115612655578b818151811061254257612542612cf3565b602002602001015191508188848151811061255f5761255f612cf3565b6020908102919091018101919091526000838152600590915260409020600181015488516001600160a01b03909116908990869081106125a1576125a1612cf3565b6001600160a01b039283166020918202929092010152815488519116908890869081106125d0576125d0612cf3565b60200260200101906001600160a01b031690816001600160a01b0316815250508b828151811061260257612602612cf3565b602002602001015186858151811061261c5761261c612cf3565b6020026020010181815250508185858151811061263b5761263b612cf3565b60209081029190910101528361265081612fa9565b945050505b600101612506565b50885b8015612712578861267081613045565b99506000905084612682600184612cca565b8151811061269257612692612cf3565b6020026020010151905060068a815481106126af576126af612cf3565b9060005260206000200154600682815481106126cd576126cd612cf3565b60009182526020909120015560068054806126ea576126ea612d09565b60019003818190600052602060002001600090559055508061270b90613045565b9050612660565b506000547fd19a3d42ed383465e4058c322d9411aeac76ddb8454d22e139fc99808bd569528888888860405161274b9493929190613096565b60405180910390a25050505050505050505050565b600060405163a9059cbb60e01b6000528360045282602452602060006044600080895af13d15601f3d11600160005114161716915060006060528060405250806127dd5760405163abae3d6d60e01b81526001600160a01b038086166004830152306024830152841660448201526064810183905260840161072f565b50505050565b60408051600180825281830190925260609160208083019080368337019050509050816001600160a01b031663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa158015612843573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612867919061302c565b8160008151811061287a5761287a612cf3565b602002602001018181525050919050565b60006128988484846128a0565b949350505050565b600080821180156128e45750826000815181106128bf576128bf612cf3565b6020026020010151846000815181106128da576128da612cf3565b6020026020010151115b15610bb357600082846000815181106128ff576128ff612cf3565b60200260200101518660008151811061291a5761291a612cf3565b602002602001015161292c9190612cca565b61293e90670de0b6b3a7640000612f70565b6129489190612f87565b7f0000000000000000000000000000000000000000000000000000000000000000111595945050505050565b508054600082559060005260206000209081019061299291906129e0565b50565b8280548282559060005260206000209081019282156129d0579160200282015b828111156129d05782518255916020019190600101906129b5565b506129dc9291506129e0565b5090565b5b808211156129dc57600081556001016129e1565b6001600160a01b038116811461299257600080fd5b600080600080600060808688031215612a2257600080fd5b8535612a2d816129f5565b94506020860135612a3d816129f5565b935060408601359250606086013567ffffffffffffffff80821115612a6157600080fd5b818801915088601f830112612a7557600080fd5b813581811115612a8457600080fd5b896020828501011115612a9657600080fd5b9699959850939650602001949392505050565b600060208284031215612abb57600080fd5b5035919050565b60008151808452602080850194506020840160005b83811015612af357815187529582019590820190600101612ad7565b509495945050505050565b6020815260006001600160a01b0380845116602084015280602085015116604084015250604083015160c06060840152612b3b60e0840182612ac2565b905060608401516080840152608084015160a084015260a084015160c08401528091505092915050565b602081526000610bb36020830184612ac2565b60a081526000612b8b60a0830188612ac2565b6020838203818501528188518084528284019150828160051b850101838b0160005b83811015612bdb57601f19878403018552612bc9838351612ac2565b94860194925090850190600101612bad565b50508681036040880152612bef818b612ac2565b9450505050508281036060840152612c078186612ac2565b90508281036080840152612c1b8185612ac2565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6020810160038310612c5f57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020808352835180602085015260005b81811015612c9357858101830151858201604001528201612c77565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b81810381811115611f0d57611f0d612cb4565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b838152606060208201526000612d386060830185612ac2565b9050826040830152949350505050565b80820180821115611f0d57611f0d612cb4565b604051610100810167ffffffffffffffff81118282101715612d7f57612d7f612cdd565b60405290565b80516bffffffffffffffffffffffff81168114612da157600080fd5b919050565b8051612da1816129f5565b805163ffffffff81168114612da157600080fd5b805160068110612da157600080fd5b600082601f830112612de557600080fd5b8151602067ffffffffffffffff80831115612e0257612e02612cdd565b8260051b604051601f19603f83011681018181108482111715612e2757612e27612cdd565b6040529384526020818701810194908101925087851115612e4757600080fd5b6020870191505b84821015612e6e57612e5f82612db1565b83529183019190830190612e4e565b979650505050505050565b600060208284031215612e8b57600080fd5b815167ffffffffffffffff80821115612ea357600080fd5b908301906101008286031215612eb857600080fd5b612ec0612d5b565b612ec983612d85565b8152612ed760208401612da6565b602082015260408301516040820152612ef260608401612db1565b6060820152612f0360808401612db1565b6080820152612f1460a08401612db1565b60a0820152612f2560c08401612dc5565b60c082015260e083015182811115612f3c57600080fd5b612f4887828601612dd4565b60e08301525095945050505050565b8281526040602082015260006128986040830184612ac2565b8082028115828204841417611f0d57611f0d612cb4565b600082612fa457634e487b7160e01b600052601260045260246000fd5b500490565b600060018201612fbb57612fbb612cb4565b5060010190565b838152606060208201526000612fdb6060830185612ac2565b8281036040840152612fed8185612ac2565b9695505050505050565b6000806040838503121561300a57600080fd5b8251613015816129f5565b915061302360208401612d85565b90509250929050565b60006020828403121561303e57600080fd5b5051919050565b60008161305457613054612cb4565b506000190190565b60008151808452602080850194506020840160005b83811015612af35781516001600160a01b031687529582019590820190600101613071565b6080815260006130a96080830187612ac2565b82810360208401526130bb818761305c565b905082810360408401526130cf818661305c565b90508281036060840152612e6e8185612ac256fea26469706673582212201cbb3243bdf2246a74a754c4b24385dc52b256b192f67778a3b3a76648374a5864736f6c63430008170033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/trader_old/vendor/valory/contracts/service_staking_token/contract.py b/trader_old/vendor/valory/contracts/service_staking_token/contract.py deleted file mode 100644 index 3817febe4..000000000 --- a/trader_old/vendor/valory/contracts/service_staking_token/contract.py +++ /dev/null @@ -1,192 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the class to connect to the `ServiceStakingTokenMechUsage` contract.""" - -from enum import Enum - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi - - -class ServiceStakingTokenContract(Contract): - """The Service Staking contract.""" - - contract_id = PublicId.from_str("valory/service_staking_token:0.1.0") - - @classmethod - def get_service_staking_state( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Check whether the service is staked.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - res = contract_instance.functions.getServiceStakingState(service_id).call() - return dict(data=res) - - @classmethod - def build_stake_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Build stake tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("stake", args=[service_id]) - return dict(data=bytes.fromhex(data[2:])) - - @classmethod - def build_checkpoint_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Build checkpoint tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("checkpoint") - return dict(data=bytes.fromhex(data[2:])) - - @classmethod - def build_unstake_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Build unstake tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("unstake", args=[service_id]) - return dict(data=bytes.fromhex(data[2:])) - - @classmethod - def available_rewards( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Get the available rewards.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - res = contract_instance.functions.availableRewards().call() - return dict(data=res) - - @classmethod - def get_staking_rewards( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Get the service's staking rewards.""" - contract = cls.get_instance(ledger_api, contract_address) - reward = contract.functions.calculateServiceStakingReward(service_id).call() - return dict(data=reward) - - @classmethod - def get_next_checkpoint_ts( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Get the next checkpoint's timestamp.""" - contract = cls.get_instance(ledger_api, contract_address) - ts = contract.functions.getNextRewardCheckpointTimestamp().call() - return dict(data=ts) - - @classmethod - def ts_checkpoint( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the checkpoint's timestamp.""" - contract = cls.get_instance(ledger_api, contract_address) - ts_checkpoint = contract.functions.tsCheckpoint().call() - return dict(data=ts_checkpoint) - - @classmethod - def liveness_ratio( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the liveness ratio.""" - contract = cls.get_instance(ledger_api, contract_address) - liveness_ratio = contract.functions.livenessRatio().call() - return dict(data=liveness_ratio) - - @classmethod - def get_liveness_period( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the liveness period.""" - contract = cls.get_instance(ledger_api, contract_address) - liveness_period = contract.functions.livenessPeriod().call() - return dict(data=liveness_period) - - @classmethod - def get_service_info( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Retrieve the service info for a service.""" - contract = cls.get_instance(ledger_api, contract_address) - info = contract.functions.getServiceInfo(service_id).call() - return dict(data=info) - - @classmethod - def max_num_services( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the max number of services.""" - contract = cls.get_instance(ledger_api, contract_address) - max_num_services = contract.functions.maxNumServices().call() - return dict(data=max_num_services) - - @classmethod - def get_service_ids( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the service IDs.""" - contract = cls.get_instance(ledger_api, contract_address) - service_ids = contract.functions.getServiceIds().call() - return dict(data=service_ids) - - @classmethod - def get_min_staking_duration( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the service IDs.""" - contract = cls.get_instance(ledger_api, contract_address) - duration = contract.functions.minStakingDuration().call() - return dict(data=duration) diff --git a/trader_old/vendor/valory/contracts/service_staking_token/contract.yaml b/trader_old/vendor/valory/contracts/service_staking_token/contract.yaml deleted file mode 100644 index 70df67a5c..000000000 --- a/trader_old/vendor/valory/contracts/service_staking_token/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: service_staking_token -author: valory -version: 0.1.0 -type: contract -description: Service staking token contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeid3wfzglolebuo6jrrsopswzu4lk77bm76mvw3euizlsjtnt3wmgu - build/ServiceStakingToken.json: bafybeib6frfpqtr4dfyxuylehqmic2iawofydx7u24t7j5zbrsc4m4ijoi - contract.py: bafybeiboxlbmmhnsreimqyrnn3yamzueiucno6v75xjfrvfvbx4pqrnlsy -fingerprint_ignore_patterns: [] -contracts: [] -class_name: ServiceStakingTokenContract -contract_interface_paths: - ethereum: build/ServiceStakingToken.json -dependencies: - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - web3: - version: <7,>=6.0.0 diff --git a/trader_old/vendor/valory/contracts/staking_token/__init__.py b/trader_old/vendor/valory/contracts/staking_token/__init__.py deleted file mode 100644 index 4682f8155..000000000 --- a/trader_old/vendor/valory/contracts/staking_token/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the support resources for the staking contract.""" diff --git a/trader_old/vendor/valory/contracts/staking_token/build/StakingToken.json b/trader_old/vendor/valory/contracts/staking_token/build/StakingToken.json deleted file mode 100644 index 070508dba..000000000 --- a/trader_old/vendor/valory/contracts/staking_token/build/StakingToken.json +++ /dev/null @@ -1,1336 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "StakingToken", - "sourceName": "contracts/staking/StakingToken.sol", - "abi": [ - { - "inputs": [], - "name": "AlreadyInitialized", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "activityChecker", - "type": "address" - } - ], - "name": "ContractOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "LowerThan", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "maxNumServices", - "type": "uint256" - } - ], - "name": "MaxNumServicesReached", - "type": "error" - }, - { - "inputs": [], - "name": "NoRewardsAvailable", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "tsProvided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "tsExpected", - "type": "uint256" - } - ], - "name": "NotEnoughTimeStaked", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnerOnly", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "ServiceNotUnstaked", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "TokenTransferFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - } - ], - "name": "UnauthorizedMultisig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "ValueLowerThan", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "agentId", - "type": "uint256" - } - ], - "name": "WrongAgentId", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceConfiguration", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "state", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "WrongServiceState", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "expected", - "type": "address" - }, - { - "internalType": "address", - "name": "provided", - "type": "address" - } - ], - "name": "WrongStakingToken", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroTokenAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValue", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "availableRewards", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "serviceIds", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "rewards", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "epochLength", - "type": "uint256" - } - ], - "name": "Checkpoint", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "balance", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "availableRewards", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "reward", - "type": "uint256" - } - ], - "name": "RewardClaimed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "reward", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "availableRewards", - "type": "uint256" - } - ], - "name": "ServiceForceUnstaked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "serviceInactivity", - "type": "uint256" - } - ], - "name": "ServiceInactivityWarning", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - } - ], - "name": "ServiceStaked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "reward", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "availableRewards", - "type": "uint256" - } - ], - "name": "ServiceUnstaked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "epoch", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "serviceIds", - "type": "uint256[]" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "owners", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "address[]", - "name": "multisigs", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "serviceInactivity", - "type": "uint256[]" - } - ], - "name": "ServicesEvicted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Withdraw", - "type": "event" - }, - { - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "activityChecker", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "agentIds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "availableRewards", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "balance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "calculateStakingLastReward", - "outputs": [ - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "calculateStakingReward", - "outputs": [ - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "checkpoint", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "evictServiceIds", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "checkpointAndClaim", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "claim", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "configHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "deposit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "emissionsAmount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "epochCounter", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "forcedUnstake", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getAgentIds", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNextRewardCheckpointTimestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "tsNext", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getServiceIds", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getServiceInfo", - "outputs": [ - { - "components": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256[]", - "name": "nonces", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "tsStart", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "inactivity", - "type": "uint256" - } - ], - "internalType": "struct ServiceInfo", - "name": "sInfo", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "getStakingState", - "outputs": [ - { - "internalType": "enum StakingBase.StakingState", - "name": "stakingState", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "metadataHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "maxNumServices", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "rewardsPerSecond", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minStakingDeposit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minNumStakingPeriods", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxNumInactivityPeriods", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "livenessPeriod", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "timeForEmissions", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "numAgentInstances", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "agentIds", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "threshold", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "configHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "proxyHash", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "serviceRegistry", - "type": "address" - }, - { - "internalType": "address", - "name": "activityChecker", - "type": "address" - } - ], - "internalType": "struct StakingBase.StakingParams", - "name": "_stakingParams", - "type": "tuple" - }, - { - "internalType": "address", - "name": "_serviceRegistryTokenUtility", - "type": "address" - }, - { - "internalType": "address", - "name": "_stakingToken", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "livenessPeriod", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "mapServiceInfo", - "outputs": [ - { - "internalType": "address", - "name": "multisig", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tsStart", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "reward", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "inactivity", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxInactivityDuration", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxNumInactivityPeriods", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "maxNumServices", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "metadataHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minStakingDeposit", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "minStakingDuration", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "numAgentInstances", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC721Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "proxyHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "rewardsPerSecond", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "serviceRegistry", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "serviceRegistryTokenUtility", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "setServiceIds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "stake", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "stakingToken", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "threshold", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "timeForEmissions", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "tsCheckpoint", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "serviceId", - "type": "uint256" - } - ], - "name": "unstake", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x608060405234801561000f575f80fd5b50600436106102cd575f3560e01c806393ac752f1161017c578063c5a1d7f0116100dd578063eb338c9611610093578063f86ad2b61161006e578063f86ad2b6146105db578063fd0bba8c146105e4578063ffa1ad7414610604575f80fd5b8063eb338c96146105b8578063f189e85a146105cb578063f4dce714146105d3575f80fd5b8063e1f1176d116100c3578063e1f1176d1461059d578063e77cdcc9146105a6578063eacdaabc146105af575f80fd5b8063c5a1d7f014610582578063cbcf252a1461058a575f80fd5b8063b150876011610132578063b69ef8a811610118578063b69ef8a81461054e578063b6b55f2514610557578063c2c4c5c11461056a575f80fd5b8063b150876014610526578063b267c67b1461053b575f80fd5b8063a0ed60e011610162578063a0ed60e01461048f578063a694fc3a14610498578063a74466ad146104ab575f80fd5b806393ac752f146104715780639573236114610486575f80fd5b806352c824f5116102315780637fbe2833116101e757806383f9eb22116101c257806383f9eb2214610442578063879d9090146104555780638f9e0a621461045e575f80fd5b80637fbe283314610406578063809cee2f1461041957806382a8ea5814610422575f80fd5b806356e760581161021757806356e76058146103d75780635829c5ec146103ea57806372f702f3146103f3575f80fd5b806352c824f5146103bb578063546af2e0146103c4575f80fd5b80632871405111610286578063379607f51161026c578063379607f5146103965780633e732997146103a957806342cde4e8146103b2575f80fd5b806328714051146103585780632e17de7814610383575f80fd5b8063150b7a02116102b6578063150b7a02146102f657806316a75172146103465780631f7794081461034f575f80fd5b806308ae7e54146102d157806314b19c5a146102ed575b5f80fd5b6102da600d5481565b6040519081526020015b60405180910390f35b6102da600f5481565b610315610304366004612c65565b630a85bd0160e11b95945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016102e4565b6102da60015481565b6102da60065481565b60175461036b906001600160a01b031681565b6040516001600160a01b0390911681526020016102e4565b6102da610391366004612cfc565b610635565b6102da6103a4366004612cfc565b610646565b6102da60135481565b6102da60085481565b6102da60055481565b6102da6103d2366004612cfc565b610651565b6102da6103e5366004612cfc565b61065d565b6102da60075481565b60185461036b906001600160a01b031681565b6102da610414366004612cfc565b61067c565b6102da600a5481565b610435610430366004612cfc565b610743565b6040516102e49190612d13565b6102da610450366004612cfc565b610832565b6102da60115481565b600c5461036b906001600160a01b031681565b61048461047f366004612cfc565b6108ea565b005b6102da60125481565b6102da60045481565b6104846104a6366004612cfc565b6108f9565b6104f36104b9366004612cfc565b60156020525f9081526040902080546001820154600383015460048401546005909401546001600160a01b03938416949390921692909185565b604080516001600160a01b039687168152959094166020860152928401919091526060830152608082015260a0016102e4565b61052e610de9565b6040516102e49190612ddf565b610484610549366004612f13565b610e3f565b6102da60105481565b610484610565366004612cfc565b610eb5565b610572610f42565b6040516102e49493929190613047565b6102da5f5481565b600b5461036b906001600160a01b031681565b6102da60095481565b6102da60035481565b6102da60025481565b6102da6105c6366004612cfc565b6115d6565b61052e6115e5565b6102da611639565b6102da600e5481565b6105f76105f2366004612cfc565b61164f565b6040516102e491906130b2565b610628604051806040016040528060058152602001640302e322e360dc1b81525081565b6040516102e491906130d8565b5f610640825f611721565b92915050565b5f610640825f611aa8565b5f610640826001611aa8565b6014818154811061066c575f80fd5b5f91825260209091200154905081565b5f818152601560209081526040808320815160c08101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287969395860193909291908301828280156106f957602002820191905f5260205f20905b8154815260200190600101908083116106e5575b50505050508152602001600382015481526020016004820154815260200160058201548152505090508060800151915061073283610832565b61073c9083613121565b9392505050565b6107896040518060c001604052805f6001600160a01b031681526020015f6001600160a01b03168152602001606081526020015f81526020015f81526020015f81525090565b5f82815260156020908152604091829020825160c08101845281546001600160a01b039081168252600183015416818401526002820180548551818602810186018752818152929593949386019383018282801561080457602002820191905f5260205f20905b8154815260200190600101908083116107f0575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050919050565b5f805f805f80610840611bab565b505050945094509450945094505f5b848110156108df578783828151811061086a5761086a613134565b6020026020010151036108d757858411156108b657838683838151811061089357610893613134565b60200260200101516108a59190613148565b6108af9190613173565b96506108df565b8181815181106108c8576108c8613134565b602002602001015196506108df565b60010161084f565b505050505050919050565b6108f5816001611721565b5050565b610901610f42565b505050506011545f036109275760405163afb0be3360e01b815260040160405180910390fd5b5f81815260156020526040902060038101541561095f5760405163b4817ce760e01b8152600481018390526024015b60405180910390fd5b601654600154810361098a5760015460405163fd20861560e01b815260040161095691815260200190565b600b5460405163ef0e239b60e01b8152600481018590525f916001600160a01b03169063ef0e239b906024015f60405180830381865afa1580156109d0573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526109f79190810190613230565b9050806080015163ffffffff1660075414610a2857604051637ad404bf60e11b815260048101859052602401610956565b60095415801590610a3f5750806040015160095414155b15610a6057604051637ad404bf60e11b815260048101859052602401610956565b5f600854118015610a7d5750806060015163ffffffff1660085414155b15610a9e57604051637ad404bf60e11b815260048101859052602401610956565b60048160c001516005811115610ab657610ab661309e565b14610af5578060c001516005811115610ad157610ad161309e565b604051633c053f9d60e21b8152600481019190915260248101859052604401610956565b5f81602001516001600160a01b0316803b806020016040519081016040528181525f908060200190933c80519060200120905080600a5414610b5a57602082015160405162a2307960e51b81526001600160a01b039091166004820152602401610956565b6014548015610c1e5760e083015151818114610b8c57604051637ad404bf60e11b815260048101889052602401610956565b5f5b81811015610c1b578460e001518181518110610bac57610bac613134565b602002602001015163ffffffff1660148281548110610bcd57610bcd613134565b905f5260205f20015414610c135760148181548110610bee57610bee613134565b905f5260205f200154604051632ab10b0b60e21b815260040161095691815260200190565b600101610b8e565b50505b610c3e86845f01516bffffffffffffffffffffffff168560e00151611f4b565b602083015185546001600160a01b039182166001600160a01b0319918216811788556001880180549092163317909155600c5460405163d564c4bf60e01b815260048101929092525f92169063d564c4bf906024015f60405180830381865afa158015610cad573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610cd49190810190613309565b8051909150610cec9060028801906020840190612bc6565b50426003870155601680546001810182555f919091527fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b512428901879055600b54604051632142170760e11b8152336004820152306024820152604481018990526001600160a01b03909116906342842e0e906064015f604051808303815f87803b158015610d76575f80fd5b505af1158015610d88573d5f803e3d5ffd5b5050505083602001516001600160a01b0316336001600160a01b0316887faa6b005b4958114a0c90492461c24af6525ae0178db7fbf44125ae9217c69ccb600f5485604051610dd892919061338a565b60405180910390a450505050505050565b60606014805480602002602001604051908101604052809291908181526020018280548015610e3557602002820191905f5260205f20905b815481526020019060010190808311610e21575b5050505050905090565b610e4883612134565b6001600160a01b0381161580610e6557506001600160a01b038216155b15610e8357604051636b093aad60e01b815260040160405180910390fd5b601880546001600160a01b039283166001600160a01b0319918216179091556017805493909216921691909117905550565b5f81601054610ec49190613121565b90505f82601154610ed59190613121565b60108390556011819055601854909150610efa906001600160a01b03163330866124b2565b604080518481526020810184905290810182905233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9060600160405180910390a2505050565b6060806060805f805f805f805f80610f58611bab565b97509750975097509750975097509750606080845167ffffffffffffffff811115610f8557610f85612df1565b604051908082528060200260200182016040528015610fae578160200160208202803683370190505b509a505f891561132f578967ffffffffffffffff811115610fd157610fd1612df1565b604051908082528060200260200182016040528015610ffa578160200160208202803683370190505b5092508967ffffffffffffffff81111561101657611016612df1565b60405190808252806020026020018201604052801561103f578160200160208202803683370190505b5091508a89111561123c575f8060015b8c811015611138578b8e8b838151811061106b5761106b613134565b602002602001015161107d9190613148565b6110879190613173565b92506110938383613121565b91508a81815181106110a7576110a7613134565b602002602001015193508a81815181106110c3576110c3613134565b60200260200101518682815181106110dd576110dd613134565b602002602001018181525050828582815181106110fc576110fc613134565b6020026020010181815250508260155f8681526020019081526020015f206004015f82825461112b9190613121565b909155505060010161104f565b508a8d8a5f8151811061114d5761114d613134565b602002602001015161115f9190613148565b6111699190613173565b91506111758282613121565b9050895f8151811061118957611189613134565b60200260200101519250895f815181106111a5576111a5613134565b6020026020010151855f815181106111bf576111bf613134565b602002602001018181525050808d11156111ea576111dd818e6133aa565b6111e79083613121565b91505b81845f815181106111fd576111fd613134565b6020026020010181815250508160155f8581526020019081526020015f206004015f82825461122c9190613121565b909155505f9d5061132992505050565b5f5b8a81101561131b5788818151811061125857611258613134565b6020026020010151915088818151811061127457611274613134565b602002602001015184828151811061128e5761128e613134565b6020026020010181815250508781815181106112ac576112ac613134565b60200260200101518382815181106112c6576112c6613134565b6020026020010181815250508781815181106112e4576112e4613134565b602002602001015160155f8481526020019081526020015f206004015f82825461130e9190613121565b909155505060010161123e565b50611326898c6133aa565b9a505b60118b90555b8551156115a257600f545f9a508a5b875181101561151d5787818151811061135957611359613134565b6020026020010151925086818151811061137557611375613134565b602002602001015160155f8581526020019081526020015f2060020190805190602001906113a4929190612bc6565b505f8682815181106113b8576113b8613134565b60200260200101511115611503578581815181106113d8576113d8613134565b602002602001015160155f8581526020019081526020015f20600501546113ff9190613121565b86828151811061141157611411613134565b60200260200101818152505085818151811061142f5761142f613134565b602002602001015160155f8581526020019081526020015f2060050181905550600e5486828151811061146457611464613134565b602002602001015111156114a257828e828151811061148557611485613134565b60209081029190910101528b61149a816133bd565b9c5050611515565b827f33dc5cdf1e035de8a7fe16ad7a30a441d30ee51719d3f07703ee35d4348f0779838884815181106114d7576114d7613134565b60200260200101516040516114f6929190918252602082015260400190565b60405180910390a2611515565b5f838152601560205260408120600501555b60010161133e565b508a156115365761152f8d868d612536565b9c5061153b565b60609c505b5f6013544261154a91906133aa565b42601355905061155b826001613121565b600f81905550817f48b735a18ed32318d316214e41387be29c52e29df4598f2b8e40fa843be3f9408e87878560405161159794939291906133d5565b60405180910390a250505b855115806115b057505f8c51115b156115c0576115bd6115e5565b95505b50939c509a509198505050505050505090919293565b6016818154811061066c575f80fd5b60606016805480602002602001604051908101604052809291908181526020018280548015610e3557602002820191905f5260205f2090815481526020019060010190808311610e21575050505050905090565b5f60055460135461164a9190613121565b905090565b5f818152601560209081526040808320815160c08101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287969395860193909291908301828280156116cc57602002820191905f5260205f20905b8154815260200190600101908083116116b8575b5050505050815260200160038201548152602001600482015481526020016005820154815250509050600e548160a00151111561170c576002915061171b565b60608101511561171b57600191505b50919050565b5f82815260156020526040812060018101546001600160a01b0316331461177257600181015460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610956565b5f61177b610f42565b505050600483015460115460038501549195509192505f9061179d90426133aa565b9050600d5481111580156117b057505f82115b156117e357600d5460405163ba2bbc6b60e01b815260048101899052602481018390526044810191909152606401610956565b5f805b8451821015611822578885838151811061180257611802613134565b60200260200101510361181757506001611822565b8160010191506117e6565b5f8660020180548060200260200160405190810160405280929190818152602001828054801561186f57602002820191905f5260205f20905b81548152602001906001019080831161185b575b50508a545f8f815260156020526040812080546001600160a01b0319908116825560018201805490911690559596506001600160a01b0390911694935091506118bd90506002830182612c0f565b505f60038201819055600482018190556005909101558215611953576016545f906118ea906001906133aa565b9050801561192d576016818154811061190557611905613134565b905f5260205f2001546016868154811061192157611921613134565b5f918252602090912001555b601680548061193e5761193e613411565b600190038181905f5260205f20015f90559055505b600b546040516323b872dd60e01b8152306004820152336024820152604481018d90526001600160a01b03909116906323b872dd906064015f604051808303815f87803b1580156119a2575f80fd5b505af11580156119b4573d5f803e3d5ffd5b505050505f8911156119e65789156119dc576119d08987613121565b601181905595506119e6565b6119e6818a6128ee565b8915611a4557806001600160a01b0316336001600160a01b03168c7f91c9f7c7f307bcc0ae02ba613bd8d07c29e94952f0a28803ded176fcd7d96d64600f54868e8c604051611a389493929190613425565b60405180910390a4611a9a565b806001600160a01b0316336001600160a01b03168c7f6d789d063e079a4c156e77a20008529fc448dca2cd7e5e7a20abf969fffb9226600f54868e8c604051611a919493929190613425565b60405180910390a45b505050505050505092915050565b5f82815260156020526040812060018101546001600160a01b03163314611af957600181015460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610956565b8215611b0c57611b07610f42565b505050505b80600401549150815f03611b3357604051637c946ed760e01b815260040160405180910390fd5b5f600482015580546001600160a01b0316611b4e81846128ee565b806001600160a01b0316336001600160a01b0316867f31add0166dae59ea66bbc180e4fae85b72fc9b7b5fc7b0f7257e4721a840c96e600f548660020188604051611b9b93929190613450565b60405180910390a4505092915050565b60135460115460165490915f91829160609182918291829182918015801590611bdf5750600554611bdc83426133aa565b10155b8015611bea57505f8a115b15611f3f578067ffffffffffffffff811115611c0857611c08612df1565b604051908082528060200260200182016040528015611c31578160200160208202803683370190505b5094508067ffffffffffffffff811115611c4d57611c4d612df1565b604051908082528060200260200182016040528015611c76578160200160208202803683370190505b5096508067ffffffffffffffff811115611c9257611c92612df1565b604051908082528060200260200182016040528015611cbb578160200160208202803683370190505b5095508067ffffffffffffffff811115611cd757611cd7612df1565b604051908082528060200260200182016040528015611d0a57816020015b6060815260200190600190039081611cf55790505b5093508067ffffffffffffffff811115611d2657611d26612df1565b604051908082528060200260200182016040528015611d4f578160200160208202803683370190505b5092505f5b81811015611f3d5760168181548110611d6f57611d6f613134565b905f5260205f200154868281518110611d8a57611d8a613134565b6020026020010181815250505f60155f888481518110611dac57611dac613134565b602002602001015181526020019081526020015f2090505f8490505f8260030154905081811115611ddb578091505b611de582426133aa565b8354600285018054604080516020808402820181019092528281529495505f94611e4f946001600160a01b03169390929091830182828015611e4457602002820191905f5260205f20905b815481526020019060010190808311611e30575b505050505084612962565b8a8781518110611e6157611e61613134565b602090810291909101015290508015611f0e5781600254611e829190613148565b8b8f81518110611e9457611e94613134565b6020026020010181815250508a8e81518110611eb257611eb2613134565b60200260200101518d611ec59190613121565b9c50898581518110611ed957611ed9613134565b60200260200101518c8f81518110611ef357611ef3613134565b6020908102919091010152611f078e6133bd565b9d50611f2e565b81888681518110611f2157611f21613134565b6020026020010181815250505b50505050806001019050611d54565b505b50509091929394959697565b601754604051633cebfa4f60e01b8152600481018590525f9182916001600160a01b0390911690633cebfa4f906024016040805180830381865afa158015611f95573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fb991906134aa565b60185491935091506001600160a01b0380841691161461200357601854604051630b80380d60e31b81526001600160a01b0391821660048201529083166024820152604401610956565b6003546bffffffffffffffffffffffff821681111561204c57604051632b30b24760e21b81526bffffffffffffffffffffffff8316600482015260248101829052604401610956565b5f5b845181101561212b5760175485515f916001600160a01b0316906375c1f934908a9089908690811061208257612082613134565b60200260200101516040518363ffffffff1660e01b81526004016120b692919091825263ffffffff16602082015260400190565b602060405180830381865afa1580156120d1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120f591906134dd565b90508281101561212257604051632b30b24760e21b81526004810182905260248101849052604401610956565b5060010161204e565b50505050505050565b600b546001600160a01b03161561215d5760405162dc149f60e41b815260040160405180910390fd5b8051158061216d57506020810151155b8061217a57506040810151155b80612187575060c0810151155b806121955750610100810151155b806121a2575060e0810151155b806121af57506080810151155b806121bc575060a0810151155b156121da57604051637c946ed760e01b815260040160405180910390fd5b8060a001518160800151101561221657608081015160a082015160405163491a2bb160e01b815260048101929092526024820152604401610956565b60028160600151101561224c57606081015160405163491a2bb160e01b8152600481019190915260026024820152604401610956565b6101a08101516001600160a01b0316158061227357506101c08101516001600160a01b0316155b156122915760405163d92e233d60e01b815260040160405180910390fd5b806101c001516001600160a01b03163b5f036122d2576101c081015160405163601c0c2160e01b81526001600160a01b039091166004820152602401610956565b80515f90815560208201516001556040820151600255606082015160035560a082015160045560c082015160055560e08201516006556101008201516007556101a0820151600b80546001600160a01b039283166001600160a01b0319918216179091556101c0840151600c8054919093169116179055610140820151600855610160820151600955805b8261012001515181101561242b5781836101200151828151811061238357612383613134565b6020026020010151116123cb5782610120015181815181106123a7576123a7613134565b6020026020010151604051632ab10b0b60e21b815260040161095691815260200190565b82610120015181815181106123e2576123e2613134565b602090810291909101015160148054600181810183555f929092527fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec018290559092500161235d565b506101808201515f0361245157604051637c946ed760e01b815260040160405180910390fd5b610180820151600a55600554608083015161246c9190613148565b600d5560055460a08301516124819190613148565b600e5560e08201516020830151604084015161249d9190613148565b6124a79190613148565b601255505042601355565b5f6040516323b872dd60e01b5f5284600452836024528260445260205f60645f808a5af13d15601f3d1160015f511416171691505f60605280604052508061252f5760405163abae3d6d60e01b81526001600160a01b03808716600483015280861660248301528416604482015260648101839052608401610956565b5050505050565b82516060908267ffffffffffffffff81111561255457612554612df1565b60405190808252806020026020018201604052801561257d578160200160208202803683370190505b5091505f8367ffffffffffffffff81111561259a5761259a612df1565b6040519080825280602002602001820160405280156125c3578160200160208202803683370190505b5090505f8467ffffffffffffffff8111156125e0576125e0612df1565b604051908082528060200260200182016040528015612609578160200160208202803683370190505b5090505f8567ffffffffffffffff81111561262657612626612df1565b60405190808252806020026020018201604052801561264f578160200160208202803683370190505b5090505f8667ffffffffffffffff81111561266c5761266c612df1565b604051908082528060200260200182016040528015612695578160200160208202803683370190505b5090505f805f5b878110156127f1575f8c82815181106126b7576126b7613134565b602002602001015111156127e9578b81815181106126d7576126d7613134565b60200260200101519150818984815181106126f4576126f4613134565b6020908102919091018101919091525f838152601590915260409020600181015488516001600160a01b039091169089908690811061273557612735613134565b6001600160a01b0392831660209182029290920101528154885191169088908690811061276457612764613134565b60200260200101906001600160a01b031690816001600160a01b0316815250508b828151811061279657612796613134565b60200260200101518685815181106127b0576127b0613134565b602002602001018181525050818585815181106127cf576127cf613134565b6020908102919091010152836127e4816133bd565b945050505b60010161269c565b50885b801561289f5787612804816134f4565b98505f9050846128156001846133aa565b8151811061282557612825613134565b602002602001015190506016898154811061284257612842613134565b905f5260205f2001546016828154811061285e5761285e613134565b5f91825260209091200155601680548061287a5761287a613411565b600190038181905f5260205f20015f905590555080612898906134f4565b90506127f4565b50600f547fd19a3d42ed383465e4058c322d9411aeac76ddb8454d22e139fc99808bd56952898888886040516128d89493929190613541565b60405180910390a2505050505050509392505050565b8060105f8282546128ff91906133aa565b909155505060185461291b906001600160a01b03168383612b49565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243648260405161295691815260200190565b60405180910390a25050565b6040516001600160a01b03841660248201525f90606090829060440160408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663d564c4bf60e01b179052600c5490519192505f9182916001600160a01b0316906129de908590613579565b5f60405180830381855afa9150503d805f8114612a16576040519150601f19603f3d011682016040523d82523d5f602084013e612a1b565b606091505b5091509150818015612a2e5750603f8151115b8015612a45575060208151612a43919061358f565b155b15612b3e5780806020019051810190612a5e9190613309565b9350838787604051602401612a75939291906135a2565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663184023a560e01b179052600c5490519194506001600160a01b031690612ad1908590613579565b5f60405180830381855afa9150503d805f8114612b09576040519150601f19603f3d011682016040523d82523d5f602084013e612b0e565b606091505b509092509050818015612b22575080516020145b15612b3e5780806020019051810190612b3b91906135d7565b94505b505050935093915050565b5f60405163a9059cbb60e01b5f52836004528260245260205f60445f80895af13d15601f3d1160015f511416171691505f606052806040525080612bc05760405163abae3d6d60e01b81526001600160a01b0380861660048301523060248301528416604482015260648101839052608401610956565b50505050565b828054828255905f5260205f20908101928215612bff579160200282015b82811115612bff578251825591602001919060010190612be4565b50612c0b929150612c2d565b5090565b5080545f8255905f5260205f2090810190612c2a9190612c2d565b50565b5b80821115612c0b575f8155600101612c2e565b6001600160a01b0381168114612c2a575f80fd5b8035612c6081612c41565b919050565b5f805f805f60808688031215612c79575f80fd5b8535612c8481612c41565b94506020860135612c9481612c41565b935060408601359250606086013567ffffffffffffffff80821115612cb7575f80fd5b818801915088601f830112612cca575f80fd5b813581811115612cd8575f80fd5b896020828501011115612ce9575f80fd5b9699959850939650602001949392505050565b5f60208284031215612d0c575f80fd5b5035919050565b602080825282516001600160a01b0390811683830152838201511660408084019190915283015160c06060840152805160e084018190525f929182019083906101008601905b80831015612d795783518252928401926001929092019190840190612d59565b5060608701516080870152608087015160a087015260a087015160c08701528094505050505092915050565b5f815180845260208085019450602084015f5b83811015612dd457815187529582019590820190600101612db8565b509495945050505050565b602081525f61073c6020830184612da5565b634e487b7160e01b5f52604160045260245ffd5b6040516101e0810167ffffffffffffffff81118282101715612e2957612e29612df1565b60405290565b604051610100810167ffffffffffffffff81118282101715612e2957612e29612df1565b604051601f8201601f1916810167ffffffffffffffff81118282101715612e7c57612e7c612df1565b604052919050565b5f67ffffffffffffffff821115612e9d57612e9d612df1565b5060051b60200190565b5f82601f830112612eb6575f80fd5b81356020612ecb612ec683612e84565b612e53565b8083825260208201915060208460051b870101935086841115612eec575f80fd5b602086015b84811015612f085780358352918301918301612ef1565b509695505050505050565b5f805f60608486031215612f25575f80fd5b833567ffffffffffffffff80821115612f3c575f80fd5b908501906101e08288031215612f50575f80fd5b612f58612e05565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c082015260e083013560e08201526101008084013581830152506101208084013583811115612fc1575f80fd5b612fcd8a828701612ea7565b91830191909152506101408381013590820152610160808401359082015261018080840135908201526101a09150613006828401612c55565b828201526101c0915061301a828401612c55565b8282015280955050505061303060208501612c55565b915061303e60408501612c55565b90509250925092565b608081525f6130596080830187612da5565b828103602084015261306b8187612da5565b9050828103604084015261307f8186612da5565b905082810360608401526130938185612da5565b979650505050505050565b634e487b7160e01b5f52602160045260245ffd5b60208101600383106130d257634e487b7160e01b5f52602160045260245ffd5b91905290565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156106405761064061310d565b634e487b7160e01b5f52603260045260245ffd5b80820281158282048414176106405761064061310d565b634e487b7160e01b5f52601260045260245ffd5b5f826131815761318161315f565b500490565b80516bffffffffffffffffffffffff81168114612c60575f80fd5b8051612c6081612c41565b805163ffffffff81168114612c60575f80fd5b805160068110612c60575f80fd5b5f82601f8301126131dc575f80fd5b815160206131ec612ec683612e84565b8083825260208201915060208460051b87010193508684111561320d575f80fd5b602086015b84811015612f0857613223816131ac565b8352918301918301613212565b5f60208284031215613240575f80fd5b815167ffffffffffffffff80821115613257575f80fd5b90830190610100828603121561326b575f80fd5b613273612e2f565b61327c83613186565b815261328a602084016131a1565b6020820152604083015160408201526132a5606084016131ac565b60608201526132b6608084016131ac565b60808201526132c760a084016131ac565b60a08201526132d860c084016131bf565b60c082015260e0830151828111156132ee575f80fd5b6132fa878286016131cd565b60e08301525095945050505050565b5f602080838503121561331a575f80fd5b825167ffffffffffffffff811115613330575f80fd5b8301601f81018513613340575f80fd5b805161334e612ec682612e84565b81815260059190911b8201830190838101908783111561336c575f80fd5b928401925b8284101561309357835182529284019290840190613371565b828152604060208201525f6133a26040830184612da5565b949350505050565b818103818111156106405761064061310d565b5f600182016133ce576133ce61310d565b5060010190565b848152608060208201525f6133ed6080830186612da5565b82810360408401526133ff8186612da5565b91505082606083015295945050505050565b634e487b7160e01b5f52603160045260245ffd5b848152608060208201525f61343d6080830186612da5565b6040830194909452506060015292915050565b5f60608201858352602060606020850152818654808452608086019150875f5260205f2093505f5b8181101561349457845483526001948501949284019201613478565b5050809350505050826040830152949350505050565b5f80604083850312156134bb575f80fd5b82516134c681612c41565b91506134d460208401613186565b90509250929050565b5f602082840312156134ed575f80fd5b5051919050565b5f816135025761350261310d565b505f190190565b5f815180845260208085019450602084015f5b83811015612dd45781516001600160a01b03168752958201959082019060010161351c565b608081525f6135536080830187612da5565b82810360208401526135658187613509565b9050828103604084015261307f8186613509565b5f82518060208501845e5f920191825250919050565b5f8261359d5761359d61315f565b500690565b606081525f6135b46060830186612da5565b82810360208401526135c68186612da5565b915050826040830152949350505050565b5f602082840312156135e7575f80fd5b8151801515811461073c575f80fdfea26469706673582212205776961a63fdaa13bebe3a0b2e71165c50721be211795e8926959409ae3d540364736f6c63430008190033", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/staking_token/contract.py b/trader_old/vendor/valory/contracts/staking_token/contract.py deleted file mode 100644 index 8bc883783..000000000 --- a/trader_old/vendor/valory/contracts/staking_token/contract.py +++ /dev/null @@ -1,192 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the class to connect to the `StakingToken` contract.""" - -from enum import Enum - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi - - -class StakingTokenContract(Contract): - """The Staking Token contract.""" - - contract_id = PublicId.from_str("valory/staking_token:0.1.0") - - @classmethod - def get_service_staking_state( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Check whether the service is staked.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - res = contract_instance.functions.getStakingState(service_id).call() - return dict(data=res) - - @classmethod - def build_stake_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Build stake tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("stake", args=[service_id]) - return dict(data=bytes.fromhex(data[2:])) - - @classmethod - def build_checkpoint_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Build checkpoint tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("checkpoint") - return dict(data=bytes.fromhex(data[2:])) - - @classmethod - def build_unstake_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Build unstake tx.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("unstake", args=[service_id]) - return dict(data=bytes.fromhex(data[2:])) - - @classmethod - def available_rewards( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Get the available rewards.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - res = contract_instance.functions.availableRewards().call() - return dict(data=res) - - @classmethod - def get_staking_rewards( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Get the service's staking rewards.""" - contract = cls.get_instance(ledger_api, contract_address) - reward = contract.functions.calculateStakingReward(service_id).call() - return dict(data=reward) - - @classmethod - def get_next_checkpoint_ts( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Get the next checkpoint's timestamp.""" - contract = cls.get_instance(ledger_api, contract_address) - ts = contract.functions.getNextRewardCheckpointTimestamp().call() - return dict(data=ts) - - @classmethod - def ts_checkpoint( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the checkpoint's timestamp.""" - contract = cls.get_instance(ledger_api, contract_address) - ts_checkpoint = contract.functions.tsCheckpoint().call() - return dict(data=ts_checkpoint) - - @classmethod - def liveness_ratio( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the liveness ratio.""" - contract = cls.get_instance(ledger_api, contract_address) - liveness_ratio = contract.functions.livenessRatio().call() - return dict(data=liveness_ratio) - - @classmethod - def get_liveness_period( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the liveness period.""" - contract = cls.get_instance(ledger_api, contract_address) - liveness_period = contract.functions.livenessPeriod().call() - return dict(data=liveness_period) - - @classmethod - def get_service_info( - cls, - ledger_api: LedgerApi, - contract_address: str, - service_id: int, - ) -> JSONLike: - """Retrieve the service info for a service.""" - contract = cls.get_instance(ledger_api, contract_address) - info = contract.functions.getServiceInfo(service_id).call() - return dict(data=info) - - @classmethod - def max_num_services( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the max number of services.""" - contract = cls.get_instance(ledger_api, contract_address) - max_num_services = contract.functions.maxNumServices().call() - return dict(data=max_num_services) - - @classmethod - def get_service_ids( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the service IDs.""" - contract = cls.get_instance(ledger_api, contract_address) - service_ids = contract.functions.getServiceIds().call() - return dict(data=service_ids) - - @classmethod - def get_min_staking_duration( - cls, - ledger_api: LedgerApi, - contract_address: str, - ) -> JSONLike: - """Retrieve the service IDs.""" - contract = cls.get_instance(ledger_api, contract_address) - duration = contract.functions.minStakingDuration().call() - return dict(data=duration) diff --git a/trader_old/vendor/valory/contracts/staking_token/contract.yaml b/trader_old/vendor/valory/contracts/staking_token/contract.yaml deleted file mode 100644 index e1a858361..000000000 --- a/trader_old/vendor/valory/contracts/staking_token/contract.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: staking_token -author: valory -version: 0.1.0 -type: contract -description: Service staking token contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeicmgkagyhgwn2ktcdjbprijalbdyj26cvza4d3b7uvmehvy4mmr3i - build/StakingToken.json: bafybeibhcwyawq377innrpq4ytpw5kotufjqo7cyd2rjhyit34mnbks5b4 - contract.py: bafybeigjt7a2biiorp4vmj4d3qkm3xbbohnawoetywojye5akhavlvkrxm -fingerprint_ignore_patterns: [] -contracts: [] -class_name: StakingTokenContract -contract_interface_paths: - ethereum: build/StakingToken.json -dependencies: - open-aea-ledger-ethereum: - version: <2,>=1.53.0 - open-aea-test-autonomy: - version: <1,>=0.14.14.post1 - web3: - version: <7,>=6.0.0 diff --git a/trader_old/vendor/valory/contracts/transfer_nft_condition/README.md b/trader_old/vendor/valory/contracts/transfer_nft_condition/README.md deleted file mode 100644 index e4d57e82f..000000000 --- a/trader_old/vendor/valory/contracts/transfer_nft_condition/README.md +++ /dev/null @@ -1 +0,0 @@ -# TRANSFER_NFT_CONDITION token contract diff --git a/trader_old/vendor/valory/contracts/transfer_nft_condition/__init__.py b/trader_old/vendor/valory/contracts/transfer_nft_condition/__init__.py deleted file mode 100644 index d8773d74b..000000000 --- a/trader_old/vendor/valory/contracts/transfer_nft_condition/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the support resources for TransferNFTCondition.""" diff --git a/trader_old/vendor/valory/contracts/transfer_nft_condition/build/TransferNFTCondition.json b/trader_old/vendor/valory/contracts/transfer_nft_condition/build/TransferNFTCondition.json deleted file mode 100644 index ddfe15e47..000000000 --- a/trader_old/vendor/valory/contracts/transfer_nft_condition/build/TransferNFTCondition.json +++ /dev/null @@ -1,1148 +0,0 @@ -{ - "_format": "", - "contractName": "", - "sourceName": "", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "_receiver", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "_conditionId", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "_contract", - "type": "address" - } - ], - "name": "Fulfilled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "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": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } - ], - "name": "RoleAdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleGranted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleRevoked", - "type": "event" - }, - { - "inputs": [], - "name": "DEFAULT_ADMIN_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_id", - "type": "bytes32" - } - ], - "name": "abortByTimeOut", - "outputs": [ - { - "internalType": "enum ConditionStoreLibrary.ConditionState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_addr", - "type": "address" - } - ], - "name": "addressToBytes32", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_b32", - "type": "bytes32" - } - ], - "name": "bytes32ToAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256[]", - "name": "_amounts", - "type": "uint256[]" - } - ], - "name": "calculateTotalAmount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftHolder", - "type": "address" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockPaymentCondition", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "_transfer", - "type": "bool" - } - ], - "name": "encodeParams", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockPaymentCondition", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "_transfer", - "type": "bool" - } - ], - "name": "fulfill", - "outputs": [ - { - "internalType": "enum ConditionStoreLibrary.ConditionState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockPaymentCondition", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "_transfer", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "_expirationBlock", - "type": "uint256" - } - ], - "name": "fulfill", - "outputs": [ - { - "internalType": "enum ConditionStoreLibrary.ConditionState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockPaymentCondition", - "type": "bytes32" - } - ], - "name": "fulfill", - "outputs": [ - { - "internalType": "enum ConditionStoreLibrary.ConditionState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftHolder", - "type": "address" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockPaymentCondition", - "type": "bytes32" - }, - { - "internalType": "bool", - "name": "_transfer", - "type": "bool" - } - ], - "name": "fulfillForDelegate", - "outputs": [ - { - "internalType": "enum ConditionStoreLibrary.ConditionState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftHolder", - "type": "address" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockPaymentCondition", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "_transfer", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "_expirationBlock", - "type": "uint256" - } - ], - "name": "fulfillForDelegate", - "outputs": [ - { - "internalType": "enum ConditionStoreLibrary.ConditionState", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_account", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "_params", - "type": "bytes" - } - ], - "name": "fulfillProxy", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_agreementId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_valueHash", - "type": "bytes32" - } - ], - "name": "generateId", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getCurrentBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNFTDefaultAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNvmConfigAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } - ], - "name": "getRoleAdmin", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getTrustedForwarder", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - } - ], - "name": "grantMarketRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_address", - "type": "address" - } - ], - "name": "grantProxyRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "grantRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "a", - "type": "address" - } - ], - "name": "hasNVMOperatorRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "hasRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftHolder", - "type": "address" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockCondition", - "type": "bytes32" - } - ], - "name": "hashValues", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_did", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftHolder", - "type": "address" - }, - { - "internalType": "address", - "name": "_nftReceiver", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_nftAmount", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_lockCondition", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "_transfer", - "type": "bool" - } - ], - "name": "hashValues", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "internalType": "address", - "name": "_conditionStoreManagerAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "_didRegistryAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "_ercAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "isContract", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "forwarder", - "type": "address" - } - ], - "name": "isTrustedForwarder", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "renounceRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_nftContractAddress", - "type": "address" - } - ], - "name": "revokeMarketRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_address", - "type": "address" - } - ], - "name": "revokeProxyRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "revokeRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_id", - "type": "bytes32" - }, - { - "name": "_did", - "type": "bytes32" - }, - { - "name": "_conditionIds", - "type": "bytes32[]" - }, - { - "name": "_timeLocks", - "type": "uint256[]" - }, - { - "name": "_timeOuts", - "type": "uint256[]" - }, - { - "name": "_accessConsumer", - "type": "address" - }, - { - "name": "_idx", - "type": "uint256" - }, - { - "name": "_rewardAddress", - "type": "address" - }, - { - "name": "_tokenAddress", - "type": "address" - }, - { - "name": "_amounts", - "type": "uint256[]" - }, - { - "name": "_receivers", - "type": "address[]" - } - ], - "name": "createAgreementAndPayEscrow", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [ - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "", - "deployedBytecode": "", - "linkReferences": {}, - "deployedLinkReferences": {} -} \ No newline at end of file diff --git a/trader_old/vendor/valory/contracts/transfer_nft_condition/contract.py b/trader_old/vendor/valory/contracts/transfer_nft_condition/contract.py deleted file mode 100644 index b20b37ad4..000000000 --- a/trader_old/vendor/valory/contracts/transfer_nft_condition/contract.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the class to connect to an TRANSFER_NFT_CONDITION token contract.""" - -from typing import Dict, List - -from aea.common import JSONLike -from aea.configurations.base import PublicId -from aea.contracts.base import Contract -from aea.crypto.base import LedgerApi -from aea_ledger_ethereum import EthereumApi -from web3 import Web3 - -PUBLIC_ID = PublicId.from_str("valory/transfer_nft_condition:0.1.0") - - -class TransferNftCondition(Contract): - """The TransferNftCondition contract.""" - - contract_id = PUBLIC_ID - - @classmethod - def build_order_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - agreement_id: str, - did: str, - condition_ids: List[str], - time_locks: List[int], - time_outs: List[int], - consumer: str, - index: int, - reward_address: str, - token_address: str, - amounts: List[int], - receives: List[str], - ) -> Dict[str, bytes]: - """Build an TransferNftCondition approval.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("createAgreementAndPayEscrow", args=( - bytes.fromhex(agreement_id[2:]), - bytes.fromhex(did[2:]), - [bytes.fromhex(condition_id[2:]) for condition_id in condition_ids], - time_locks, - time_outs, - Web3.to_checksum_address(consumer), - index, - Web3.to_checksum_address(reward_address), - Web3.to_checksum_address(token_address), - amounts, - [Web3.to_checksum_address(receive) for receive in receives], - )) - return {"data": bytes.fromhex(data[2:])} - - @classmethod - def balance_of( - cls, - ledger_api: LedgerApi, - contract_address: str, - address: str, - did: str, - ) -> JSONLike: - """Get the balance of an address.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - balance = contract_instance.functions.balanceOf( - Web3.to_checksum_address(address), - int(did, 16) - ).call() - return dict(data=balance) - - @classmethod - def is_approved_for_all( - cls, - ledger_api: LedgerApi, - contract_address: str, - account: str, - operator: str, - ) -> JSONLike: - """Get the balance of an address.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - is_approved = contract_instance.functions.isApprovedForAll( - Web3.to_checksum_address(account), - Web3.to_checksum_address(operator), - ).call() - return dict(data=is_approved) - - @classmethod - def build_set_approval_for_all_tx( - cls, - ledger_api: LedgerApi, - contract_address: str, - operator: str, - approved: bool, - ) -> Dict[str, bytes]: - """Build an TransferNftCondition approval.""" - contract_instance = cls.get_instance(ledger_api, contract_address) - data = contract_instance.encodeABI("setApprovalForAll", args=( - Web3.to_checksum_address(operator), - approved, - )) - return {"data": bytes.fromhex(data[2:])} - diff --git a/trader_old/vendor/valory/contracts/transfer_nft_condition/contract.yaml b/trader_old/vendor/valory/contracts/transfer_nft_condition/contract.yaml deleted file mode 100644 index fcc24b09a..000000000 --- a/trader_old/vendor/valory/contracts/transfer_nft_condition/contract.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: transfer_nft_condition -author: valory -version: 0.1.0 -type: contract -description: TRANSFER_NFT_CONDITION token contract -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeidiaep6cpoqlabnajvsgegpt72hqnbtozayicaxclzxzftopvlw5u - __init__.py: bafybeigz4j3ow7nagttswpbrpajnxqtxrl35oznejzxwi6bhfdeltnab5i - build/TransferNFTCondition.json: bafybeigxqddrgr4tuyhxyt5zblgnhwgpn4szjvyu5kvznslw4xfi7x2pp4 - contract.py: bafybeibievlshamdrcanb7rd4625jhmvmdwspovpnyudshahjiq4vzvyrm -fingerprint_ignore_patterns: [] -contracts: [] -class_name: TransferNftCondition -contract_interface_paths: - ethereum: build/TransferNFTCondition.json -dependencies: - ecdsa: - version: '>=0.15' - eth_typing: {} - hexbytes: {} - open-aea-ledger-ethereum: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - packaging: {} - py-eth-sig-utils: {} - requests: - version: ==2.28.1 - web3: - version: <7,>=6.0.0 diff --git a/trader_old/vendor/valory/customs/__init__.py b/trader_old/vendor/valory/customs/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_old/vendor/valory/customs/bet_amount_per_threshold/__init__.py b/trader_old/vendor/valory/customs/bet_amount_per_threshold/__init__.py deleted file mode 100644 index 93e631216..000000000 --- a/trader_old/vendor/valory/customs/bet_amount_per_threshold/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the bet amount per threshold strategy.""" diff --git a/trader_old/vendor/valory/customs/bet_amount_per_threshold/bet_amount_per_threshold.py b/trader_old/vendor/valory/customs/bet_amount_per_threshold/bet_amount_per_threshold.py deleted file mode 100644 index c9bd5a75e..000000000 --- a/trader_old/vendor/valory/customs/bet_amount_per_threshold/bet_amount_per_threshold.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 simple strategy that returns a bet amount based on a mapping.""" - -from typing import Union, List, Dict, Tuple, Any - -REQUIRED_FIELDS = ("confidence", "bet_amount_per_threshold") - - -def check_missing_fields(kwargs: Dict[str, Any]) -> List[str]: - """Check for missing fields and return them, if any.""" - missing = [] - for field in REQUIRED_FIELDS: - if kwargs.get(field, None) is None: - missing.append(field) - return missing - - -def remove_irrelevant_fields(kwargs: Dict[str, Any]) -> Dict[str, Any]: - """Remove the irrelevant fields from the given kwargs.""" - return {key: value for key, value in kwargs.items() if key in REQUIRED_FIELDS} - - -def amount_per_threshold( - confidence: float, bet_amount_per_threshold: Dict[str, int] -) -> Dict[str, Union[int, Tuple[str]]]: - """Get the bet amount per threshold strategy's result.""" - # we need the threshold as a string, because the agent/service overrides cannot be given with `int`s as keys - threshold = str(round(confidence, 1)) - bet_amount = bet_amount_per_threshold.get(threshold, None) - - if bet_amount is None: - return { - "error": ( - f"No amount was found in {bet_amount_per_threshold=} for {confidence=}.", - ) - } - return {"bet_amount": bet_amount} - - -def run(*_args, **kwargs) -> Dict[str, Union[int, Tuple[str]]]: - """Run the strategy.""" - missing = check_missing_fields(kwargs) - if len(missing) > 0: - return {"error": (f"Required kwargs {missing} were not provided.",)} - - kwargs = remove_irrelevant_fields(kwargs) - return amount_per_threshold(**kwargs) diff --git a/trader_old/vendor/valory/customs/bet_amount_per_threshold/component.yaml b/trader_old/vendor/valory/customs/bet_amount_per_threshold/component.yaml deleted file mode 100644 index 31fe6fc32..000000000 --- a/trader_old/vendor/valory/customs/bet_amount_per_threshold/component.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: bet_amount_per_threshold -author: valory -version: 0.1.0 -type: custom -description: A simple strategy that bets a fixed amount when the confidence is of - a given threshold. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeibbn67pnrrm4qm3n3kbelvbs3v7fjlrjniywmw2vbizarippidtvi - bet_amount_per_threshold.py: bafybeih7kv24wtfotp3rskyo4runchu74qf4nlxyq53pzuy5qles545nza -fingerprint_ignore_patterns: [] -entry_point: bet_amount_per_threshold.py -callable: run -dependencies: {} diff --git a/trader_old/vendor/valory/customs/kelly_criterion_no_conf/__init__.py b/trader_old/vendor/valory/customs/kelly_criterion_no_conf/__init__.py deleted file mode 100644 index 3a7196fde..000000000 --- a/trader_old/vendor/valory/customs/kelly_criterion_no_conf/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the kelly criterion strategy without confidence factor in the formula.""" diff --git a/trader_old/vendor/valory/customs/kelly_criterion_no_conf/component.yaml b/trader_old/vendor/valory/customs/kelly_criterion_no_conf/component.yaml deleted file mode 100644 index 66dd77c4b..000000000 --- a/trader_old/vendor/valory/customs/kelly_criterion_no_conf/component.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: kelly_criterion_no_conf -author: valory -version: 0.1.0 -type: custom -description: The kelly criterion trading strategy without confidence factor in the - formula. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeidog73nvs6bfta5pmaxufwly6pc52knbnxqlwcwka4cpnyneeykqi - kelly_criterion_no_conf.py: bafybeifrdnpes4jbhnkesuuk5pktyz2udlx4d5yr73ebgqpzpiqywixhom -fingerprint_ignore_patterns: [] -entry_point: kelly_criterion_no_conf.py -callable: run -dependencies: {} diff --git a/trader_old/vendor/valory/customs/kelly_criterion_no_conf/kelly_criterion_no_conf.py b/trader_old/vendor/valory/customs/kelly_criterion_no_conf/kelly_criterion_no_conf.py deleted file mode 100644 index 71be7fc7d..000000000 --- a/trader_old/vendor/valory/customs/kelly_criterion_no_conf/kelly_criterion_no_conf.py +++ /dev/null @@ -1,186 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the kelly criterion strategy without confidence factor in the formula.""" - -from typing import Dict, Any, List, Union, Optional - -REQUIRED_FIELDS = frozenset( - { - # the fraction of the calculated kelly bet amount to use for placing the bet - "bet_kelly_fraction", - "bankroll", - "win_probability", - "confidence", - "selected_type_tokens_in_pool", - "other_tokens_in_pool", - "bet_fee", - "weighted_accuracy", - "floor_balance", - } -) -OPTIONAL_FIELDS = frozenset({"max_bet"}) -ALL_FIELDS = REQUIRED_FIELDS.union(OPTIONAL_FIELDS) -DEFAULT_MAX_BET = 8e17 - - -def check_missing_fields(kwargs: Dict[str, Any]) -> List[str]: - """Check for missing fields and return them, if any.""" - missing = [] - for field in REQUIRED_FIELDS: - if kwargs.get(field, None) is None: - missing.append(field) - return missing - - -def remove_irrelevant_fields(kwargs: Dict[str, Any]) -> Dict[str, Any]: - """Remove the irrelevant fields from the given kwargs.""" - return {key: value for key, value in kwargs.items() if key in ALL_FIELDS} - - -def get_adjusted_kelly_amount( - kelly_bet_amount: float, - weighted_accuracy: Optional[float], - static_kelly_fraction: float, - error: list, -): - """This function adjusts the kelly bet amount based on the weighted accuracy metric - of the selected tool to make the prediction. Default use-case: it uses the static kelly fraction - """ - if weighted_accuracy is None: - error.append( - f"No weighted accuracy information for this tool. Using static fraction." - ) - return int(kelly_bet_amount * static_kelly_fraction) - # weighted_accuracy must be always between [0, 1] - if not (0 <= weighted_accuracy <= 1): - error.append( - f"Wrong value for the weighted accuracy {weighted_accuracy}. Accepted range [0, 1]. Using static fraction" - ) - return int(kelly_bet_amount * static_kelly_fraction) - dynamic_kelly_fraction = static_kelly_fraction + weighted_accuracy - return int(kelly_bet_amount * dynamic_kelly_fraction) - - -def calculate_kelly_bet_amount_no_conf( - x: int, y: int, p: float, b: int, f: float -) -> int: - """Calculate the Kelly bet amount.""" - if b == 0: - return 0 - numerator = ( - -4 * x**2 * y - + b * y**2 * p * f - + 2 * b * x * y * p * f - + b * x**2 * p * f - - 2 * b * y**2 * f - - 2 * b * x * y * f - + ( - ( - 4 * x**2 * y - - b * y**2 * p * f - - 2 * b * x * y * p * f - - b * x**2 * p * f - + 2 * b * y**2 * f - + 2 * b * x * y * f - ) - ** 2 - - ( - 4 - * (x**2 * f - y**2 * f) - * (-4 * b * x * y**2 * p - 4 * b * x**2 * y * p + 4 * b * x * y**2) - ) - ) - ** (1 / 2) - ) - denominator = 2 * (x**2 * f - y**2 * f) - if denominator == 0: - return 0 - kelly_bet_amount = numerator / denominator - return int(kelly_bet_amount) - - -def wei_to_native(wei: int) -> float: - """Convert WEI to native token.""" - return wei / 10**18 - - -def get_bet_amount_kelly( # pylint: disable=too-many-arguments - bet_kelly_fraction: float, - bankroll: int, - win_probability: float, - confidence: float, - selected_type_tokens_in_pool: int, - other_tokens_in_pool: int, - bet_fee: int, - weighted_accuracy: float, - floor_balance: int, - max_bet: int = DEFAULT_MAX_BET, -) -> Dict[str, Union[int, List[str]]]: - """Calculate the Kelly bet amount.""" - # keep `floor_balance` xDAI in the bankroll - bankroll_adj = bankroll - floor_balance - bankroll_adj = min(bankroll_adj, max_bet) - bankroll_adj_xdai = wei_to_native(bankroll_adj) - info = [f"Adjusted bankroll: {bankroll_adj_xdai} xDAI."] - error = [] - if bankroll_adj <= 0: - error.append( - f"Bankroll ({bankroll_adj}) is less than the floor balance ({floor_balance})." - ) - error.append("Set bet amount to 0.") - error.append("Top up safe with DAI or wait for redeeming.") - return {"bet_amount": 0, "info": info, "error": error} - - fee_fraction = 1 - wei_to_native(bet_fee) - info.append(f"Fee fraction: {fee_fraction}") - kelly_bet_amount = calculate_kelly_bet_amount_no_conf( - selected_type_tokens_in_pool, - other_tokens_in_pool, - win_probability, - bankroll_adj, - fee_fraction, - ) - if kelly_bet_amount < 0: - info.append( - f"Invalid value for kelly bet amount: {kelly_bet_amount}\nSet bet amount to 0." - ) - return {"bet_amount": 0, "info": info, "error": error} - - info.append(f"Kelly bet amount: {wei_to_native(kelly_bet_amount)} xDAI") - info.append(f"Bet kelly fraction: {bet_kelly_fraction}") - info.append( - f"Applying dynamic kelly fraction to all bets. Weighted accuracy of the tool={weighted_accuracy}" - ) - adj_kelly_bet_amount = get_adjusted_kelly_amount( - kelly_bet_amount, weighted_accuracy, bet_kelly_fraction, error - ) - info.append( - f"Adjusted Kelly bet amount: {wei_to_native(adj_kelly_bet_amount)} xDAI" - ) - return {"bet_amount": adj_kelly_bet_amount, "info": info, "error": error} - - -def run(*_args, **kwargs) -> Dict[str, Union[int, List[str]]]: - """Run the strategy.""" - missing = check_missing_fields(kwargs) - if len(missing) > 0: - return {"error": [f"Required kwargs {missing} were not provided."]} - kwargs = remove_irrelevant_fields(kwargs) - return get_bet_amount_kelly(**kwargs) diff --git a/trader_old/vendor/valory/customs/mike_strat/__init__.py b/trader_old/vendor/valory/customs/mike_strat/__init__.py deleted file mode 100644 index 93e631216..000000000 --- a/trader_old/vendor/valory/customs/mike_strat/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the bet amount per threshold strategy.""" diff --git a/trader_old/vendor/valory/customs/mike_strat/component.yaml b/trader_old/vendor/valory/customs/mike_strat/component.yaml deleted file mode 100644 index 12b0baf52..000000000 --- a/trader_old/vendor/valory/customs/mike_strat/component.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: mike_strat -author: valory -version: 0.1.0 -type: custom -description: A simple strategy that bets a fixed amount when the confidence is of - a given threshold. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeibbn67pnrrm4qm3n3kbelvbs3v7fjlrjniywmw2vbizarippidtvi - mike_strat.py: bafybeifbxlcl6kvubdudnjilantbqbghuvhmgheyh35jhiiaqpmq7va6ji -fingerprint_ignore_patterns: [] -entry_point: mike_strat.py -callable: run -dependencies: {} diff --git a/trader_old/vendor/valory/customs/mike_strat/mike_strat.py b/trader_old/vendor/valory/customs/mike_strat/mike_strat.py deleted file mode 100644 index 88790b7bd..000000000 --- a/trader_old/vendor/valory/customs/mike_strat/mike_strat.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 simple strategy that returns a bet amount based on a mapping.""" - -from typing import Union, List, Dict, Tuple, Any - -REQUIRED_FIELDS = ("confidence", "bet_amount_per_threshold") - - -def check_missing_fields(kwargs: Dict[str, Any]) -> List[str]: - """Check for missing fields and return them, if any.""" - missing = [] - for field in REQUIRED_FIELDS: - if kwargs.get(field, None) is None: - missing.append(field) - return missing - - -def remove_irrelevant_fields(kwargs: Dict[str, Any]) -> Dict[str, Any]: - """Remove the irrelevant fields from the given kwargs.""" - return {key: value for key, value in kwargs.items() if key in REQUIRED_FIELDS} - - -def amount_per_threshold( - confidence: float, bet_amount_per_threshold: Dict[str, int] -) -> Dict[str, Union[int, Tuple[str]]]: - """Get the bet amount per threshold strategy's result.""" - # we need the threshold as a string, because the agent/service overrides cannot be given with `int`s as keys - threshold = str(round(confidence, 1)) - bet_amount = bet_amount_per_threshold.get(threshold, None) - - if bet_amount is None: - return { - "error": ( - f"No amount was found in {bet_amount_per_threshold=} for {confidence=}.", - ) - } - return {"bet_amount": bet_amount * confidence} - - -def run(*_args, **kwargs) -> Dict[str, Union[int, Tuple[str]]]: - """Run the strategy.""" - missing = check_missing_fields(kwargs) - if len(missing) > 0: - return {"error": (f"Required kwargs {missing} were not provided.",)} - - kwargs = remove_irrelevant_fields(kwargs) - return amount_per_threshold(**kwargs) diff --git a/trader_old/vendor/valory/protocols/__init__.py b/trader_old/vendor/valory/protocols/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_old/vendor/valory/protocols/abci/README.md b/trader_old/vendor/valory/protocols/abci/README.md deleted file mode 100644 index 63209a74d..000000000 --- a/trader_old/vendor/valory/protocols/abci/README.md +++ /dev/null @@ -1,414 +0,0 @@ -# ABCI Protocol - -## Description - -This is a protocol for interacting with an ABCI client/server requests and responses. - -## Specification - -The specification is inspired from -[the Protobuf file `types.proto` for the ABCI protocol](https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto). - -```yaml ---- -name: abci -author: valory -version: 0.1.0 -description: A protocol for ABCI requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: valory/abci:0.1.0 -speech_acts: - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L42 - request_echo: - message: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L46 - request_flush: {} - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L48 - request_info: - version: pt:str - block_version: pt:int - p2p_version: pt:int - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L55 - request_set_option: - option_key: pt:str - option_value: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L60 - request_init_chain: - time: ct:Timestamp - chain_id: pt:str - consensus_params: pt:optional[ct:ConsensusParams] - validators: ct:ValidatorUpdates - app_state_bytes: pt:bytes - initial_height: pt:int - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L70 - request_query: - query_data: pt:bytes - path: pt:str - height: pt:int - prove: pt:bool - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L77 - request_begin_block: - hash: pt:bytes - header: ct:Header - last_commit_info: ct:LastCommitInfo - byzantine_validators: ct:Evidences - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L89 - request_check_tx: - tx: pt:bytes - type: ct:CheckTxType - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L94 - request_deliver_tx: - tx: pt:bytes - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L98 - request_end_block: - height: pt:int - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L102 - request_commit: {} - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L105 - request_list_snapshots: {} - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L109 - request_offer_snapshot: - snapshot: ct:Snapshot # snapshot offered by peers - app_hash: pt:bytes # light client-verified app hash for snapshot height - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L115 - request_load_snapshot_chunk: - height: pt:int - format: pt:int - chunk_index: pt:int - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L115 - request_apply_snapshot_chunk: - index: pt:int - chunk: pt:bytes - chunk_sender: pt:str # 'sender' conflicts with the attribute of 'Message' - # responses - response_exception: { - error: pt:str - } - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L157 - response_echo: - message: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L161 - response_flush: {} - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L163 - response_info: - info_data: pt:str - version: pt:str - app_version: pt:int - last_block_height: pt:int - last_block_app_hash: pt:bytes - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L174 - response_set_option: - code: pt:int - log: pt:str - info: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L181 - response_init_chain: - consensus_params: pt:optional[ct:ConsensusParams] - validators: ct:ValidatorUpdates - app_hash: pt:bytes - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L187 - response_query: - code: pt:int - log: pt:str - info: pt:str - index: pt:int - key: pt:bytes - value: pt:bytes - proof_ops: ct:ProofOps - height: pt:int - codespace: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L200 - response_begin_block: - events: ct:Events - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L205 - response_check_tx: - code: pt:int - data: pt:bytes - log: pt:str - info: pt:str - gas_wanted: pt:int - gas_used: pt:int - events: ct:Events - codespace: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L217 - response_deliver_tx: - code: pt:int - data: pt:bytes - log: pt:str - info: pt:str - gas_wanted: pt:int - gas_used: pt:int - events: ct:Events - codespace: pt:str - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L229 - response_end_block: - validator_updates: ct:ValidatorUpdates - consensus_param_updates: pt:optional[ct:ConsensusParams] - events: ct:Events - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L237 - response_commit: - data: pt:bytes - retain_height: pt:int - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L243 - response_list_snapshots: - snapshots: ct:SnapShots - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L247 - response_offer_snapshot: - result: ct:Result - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L260 - response_load_snapshot_chunk: - chunk: pt:bytes - # https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L264 - response_apply_snapshot_chunk: - result: ct:Result - refetch_chunks: pt:list[pt:int] # Chunks to refetch and reapply - reject_senders: pt:list[pt:str] # Chunk senders to reject and ban - # dummy performative to make custom types used at least once - dummy: - dummy_consensus_params: ct:ConsensusParams -... ---- -# https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L284 -ct:ConsensusParams: | - message Duration { - int64 seconds = 1; - int32 nanos = 2; - } - message BlockParams { - int64 max_bytes = 1; - int64 max_gas = 2; - } - message EvidenceParams { - int64 max_age_num_blocks = 1; - Duration max_age_duration = 2; - int64 max_bytes = 3; - } - message ValidatorParams { - repeated string pub_key_types = 1; - } - message VersionParams { - uint64 app_version = 1; - } - BlockParams block = 1; - EvidenceParams evidence = 2; - ValidatorParams validator = 3; - VersionParams version = 4; -# https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L343 -ct:ValidatorUpdates: | - message PublicKey { - oneof sum { - bytes ed25519 = 1; - bytes secp256k1 = 2; - } - } - message ValidatorUpdate { - PublicKey pub_key = 1; - int64 power = 2; - } - repeated ValidatorUpdate validators = 1; -# google.protobuf.Timestamp -ct:Timestamp: | - // Represents seconds of UTC time since Unix epoch - // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - // 9999-12-31T23:59:59Z inclusive. - int64 seconds = 1; - // Non-negative fractions of a second at nanosecond resolution. Negative - // second values with fractions must still have non-negative nanos values - // that count forward in time. Must be from 0 to 999,999,999 - // inclusive. - int32 nanos = 2; -# https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/crypto/proof.proto#L39 -ct:ProofOps: | - message ProofOp { - string type = 1; - bytes key = 2; - bytes data = 3; - } - repeated ProofOp ops = 1; -# https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/types/types.proto#L58 -ct:Header: | - message ConsensusVersion { - uint64 block = 1; - uint64 app = 2; - } - message BlockID { - bytes hash = 1; - PartSetHeader part_set_header = 2; - } - message PartSetHeader { - uint32 total = 1; - bytes hash = 2; - } - ConsensusVersion version = 1; - string chain_id = 2; - int64 height = 3; - Timestamp time = 4; - - // prev block info - BlockID last_block_id = 5; - - // hashes of block data - bytes last_commit_hash = 6; // commit from validators from the last block - bytes data_hash = 7; // transactions - - // hashes from the app output from the prev block - bytes validators_hash = 8; // validators for the current block - bytes next_validators_hash = 9; // validators for the next block - bytes consensus_hash = 10; // consensus params for current block - bytes app_hash = 11; // state after txs from the previous block - bytes last_results_hash = 12; // root hash of all results from the txs from the previous block - - // consensus info - bytes evidence_hash = 13; // evidence included in the block - bytes proposer_address = 14; // original proposer of the block -# https://github.com/tendermint/tendermint/blob/v0.34.19/proto/tendermint/abci/types.proto#L299 -ct:LastCommitInfo: | - message Validator { - bytes address = 1; // The first 20 bytes of SHA256(public key) - // PubKey pub_key = 2 [(gogoproto.nullable)=false]; - int64 power = 3; // The voting power - } - message VoteInfo { - Validator validator = 1; - bool signed_last_block = 2; - } - int32 round = 1; - repeated VoteInfo votes = 2; -# https://github.com/tendermint/tendermint/blob/2f231ceb952a2426cf3c0abaf0b455aadd11e5b2/proto/tendermint/abci/types.proto#L360 -ct:Evidences: | - message Evidence { - enum EvidenceType { - UNKNOWN = 0; - DUPLICATE_VOTE = 1; - LIGHT_CLIENT_ATTACK = 2; - } - EvidenceType type = 1; - // The offending validator - LastCommitInfo.Validator validator = 2; - // The height when the offense occurred - int64 height = 3; - // The corresponding time where the offense occurred - Timestamp time = 4; - // Total voting power of the validator set in case the ABCI application does - // not store historical validators. - // https://github.com/tendermint/tendermint/issues/4581 - int64 total_voting_power = 5; - } - repeated Evidence byzantine_validators = 1; -ct:CheckTxType: | - enum _CheckTxType { - NEW = 0; - RECHECK = 1; - } - _CheckTxType type = 1; -# https://github.com/tendermint/tendermint/blob/2f231ceb952a2426cf3c0abaf0b455aadd11e5b2/proto/tendermint/abci/types.proto#L307 -ct:Events: | - message EventAttribute { - bytes key = 1; - bytes value = 2; - bool index = 3; // nondeterministic - } - message Event { - string type = 1; - repeated EventAttribute attributes = 2; - } - repeated Event events = 1; -ct:Result: | - enum ResultType { - UNKNOWN = 0; // Unknown result, abort all snapshot restoration - ACCEPT = 1; // Snapshot accepted, apply chunks - ABORT = 2; // Abort all snapshot restoration - REJECT = 3; // Reject this specific snapshot, try others - REJECT_FORMAT = 4; // Reject all snapshots of this format, try others - REJECT_SENDER = 5; // Reject all snapshots from the sender(s), try others - } - ResultType result_type = 1; -ct:Snapshot: | - // State Sync Types - uint64 height = 1; // The height at which the snapshot was taken - uint32 format = 2; // The application-specific snapshot format - uint32 chunks = 3; // Number of chunks in the snapshot - bytes hash = 4; // Arbitrary snapshot hash, equal only if identical - bytes metadata = 5; // Arbitrary application metadata -ct:SnapShots: | - repeated Snapshot snapshots = 1; -... ---- -initiation: -- request_echo -- request_flush -- request_info -- request_set_option -- request_init_chain -- request_query -- request_begin_block -- request_check_tx -- request_deliver_tx -- request_end_block -- request_commit -- request_list_snapshots -- request_offer_snapshot -- request_apply_snapshot_chunk -- request_load_snapshot_chunk -- dummy -reply: - request_echo: [response_echo, response_exception] - response_echo: [] - response_exception: [] - request_flush: [response_flush, response_exception] - response_flush: [] - request_info: [response_info, response_exception] - response_info: [] - request_set_option: [response_set_option, response_exception] - response_set_option: [] - request_init_chain: [response_init_chain, response_exception] - response_init_chain: [] - request_query: [response_query, response_exception] - response_query: [] - request_begin_block: [response_begin_block, response_exception] - response_begin_block: [] - request_check_tx: [response_check_tx, response_exception] - response_check_tx: [] - request_deliver_tx: [response_deliver_tx, response_exception] - response_deliver_tx: [] - request_end_block: [response_end_block, response_exception] - response_end_block: [] - request_commit: [response_commit, response_exception] - response_commit: [] - request_list_snapshots: [response_list_snapshots, response_exception] - response_list_snapshots: [] - request_offer_snapshot: [response_offer_snapshot, response_exception] - response_offer_snapshot: [] - request_apply_snapshot_chunk: [response_apply_snapshot_chunk, response_exception] - response_apply_snapshot_chunk: [] - request_load_snapshot_chunk: [response_load_snapshot_chunk, response_exception] - response_load_snapshot_chunk: [] - dummy: [] -termination: - - response_exception - - response_echo - - response_flush - - response_info - - response_set_option - - response_init_chain - - response_query - - response_begin_block - - response_check_tx - - response_deliver_tx - - response_end_block - - response_commit - - response_list_snapshots - - response_offer_snapshot - - response_apply_snapshot_chunk - - response_load_snapshot_chunk - - dummy -roles: {client, server} -end_states: [successful] -keep_terminal_state_dialogues: false -... -``` - -## Links - -* HTTP Specification diff --git a/trader_old/vendor/valory/protocols/abci/__init__.py b/trader_old/vendor/valory/protocols/abci/__init__.py deleted file mode 100644 index 79b88d47f..000000000 --- a/trader_old/vendor/valory/protocols/abci/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the abci protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.abci.message import AbciMessage -from packages.valory.protocols.abci.serialization import AbciSerializer - - -AbciMessage.serializer = AbciSerializer diff --git a/trader_old/vendor/valory/protocols/abci/abci.proto b/trader_old/vendor/valory/protocols/abci/abci.proto deleted file mode 100644 index aa5f82878..000000000 --- a/trader_old/vendor/valory/protocols/abci/abci.proto +++ /dev/null @@ -1,407 +0,0 @@ -syntax = "proto3"; - -package aea.valory.abci.v0_1_0; - -message AbciMessage{ - - // Custom Types - message CheckTxType{ - enum _CheckTxType { - NEW = 0; - RECHECK = 1; - } - _CheckTxType type = 1; - } - - message ConsensusParams{ - message Duration { - int64 seconds = 1; - int32 nanos = 2; - } - message BlockParams { - int64 max_bytes = 1; - int64 max_gas = 2; - } - message EvidenceParams { - int64 max_age_num_blocks = 1; - Duration max_age_duration = 2; - int64 max_bytes = 3; - } - message ValidatorParams { - repeated string pub_key_types = 1; - } - message VersionParams { - uint64 app_version = 1; - } - BlockParams block = 1; - EvidenceParams evidence = 2; - ValidatorParams validator = 3; - VersionParams version = 4; - } - - message Events{ - message EventAttribute { - bytes key = 1; - bytes value = 2; - bool index = 3; // nondeterministic - } - message Event { - string type = 1; - repeated EventAttribute attributes = 2; - } - repeated Event events = 1; - } - - message Evidences{ - message Evidence { - enum EvidenceType { - UNKNOWN = 0; - DUPLICATE_VOTE = 1; - LIGHT_CLIENT_ATTACK = 2; - } - EvidenceType type = 1; - // The offending validator - LastCommitInfo.Validator validator = 2; - // The height when the offense occurred - int64 height = 3; - // The corresponding time where the offense occurred - Timestamp time = 4; - // Total voting power of the validator set in case the ABCI application does - // not store historical validators. - // https://github.com/tendermint/tendermint/issues/4581 - int64 total_voting_power = 5; - } - repeated Evidence byzantine_validators = 1; - } - - message Header{ - message ConsensusVersion { - uint64 block = 1; - uint64 app = 2; - } - message BlockID { - bytes hash = 1; - PartSetHeader part_set_header = 2; - } - message PartSetHeader { - uint32 total = 1; - bytes hash = 2; - } - ConsensusVersion version = 1; - string chain_id = 2; - int64 height = 3; - Timestamp time = 4; - - // prev block info - BlockID last_block_id = 5; - - // hashes of block data - bytes last_commit_hash = 6; // commit from validators from the last block - bytes data_hash = 7; // transactions - - // hashes from the app output from the prev block - bytes validators_hash = 8; // validators for the current block - bytes next_validators_hash = 9; // validators for the next block - bytes consensus_hash = 10; // consensus params for current block - bytes app_hash = 11; // state after txs from the previous block - bytes last_results_hash = 12; // root hash of all results from the txs from the previous block - - // consensus info - bytes evidence_hash = 13; // evidence included in the block - bytes proposer_address = 14; // original proposer of the block - } - - message LastCommitInfo{ - message Validator { - bytes address = 1; // The first 20 bytes of SHA256(public key) - // PubKey pub_key = 2 [(gogoproto.nullable)=false]; - int64 power = 3; // The voting power - } - message VoteInfo { - Validator validator = 1; - bool signed_last_block = 2; - } - int32 round = 1; - repeated VoteInfo votes = 2; - } - - message ProofOps{ - message ProofOp { - string type = 1; - bytes key = 2; - bytes data = 3; - } - repeated ProofOp ops = 1; - } - - message Result{ - enum ResultType { - UNKNOWN = 0; // Unknown result, abort all snapshot restoration - ACCEPT = 1; // Snapshot accepted, apply chunks - ABORT = 2; // Abort all snapshot restoration - REJECT = 3; // Reject this specific snapshot, try others - REJECT_FORMAT = 4; // Reject all snapshots of this format, try others - REJECT_SENDER = 5; // Reject all snapshots from the sender(s), try others - } - ResultType result_type = 1; - } - - message SnapShots{ - repeated Snapshot snapshots = 1; - } - - message Snapshot{ - // State Sync Types - uint64 height = 1; // The height at which the snapshot was taken - uint32 format = 2; // The application-specific snapshot format - uint32 chunks = 3; // Number of chunks in the snapshot - bytes hash = 4; // Arbitrary snapshot hash, equal only if identical - bytes metadata = 5; // Arbitrary application metadata - } - - message Timestamp{ - // Represents seconds of UTC time since Unix epoch - // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - // 9999-12-31T23:59:59Z inclusive. - int64 seconds = 1; - // Non-negative fractions of a second at nanosecond resolution. Negative - // second values with fractions must still have non-negative nanos values - // that count forward in time. Must be from 0 to 999,999,999 - // inclusive. - int32 nanos = 2; - } - - message ValidatorUpdates{ - message PublicKey { - oneof sum { - bytes ed25519 = 1; - bytes secp256k1 = 2; - } - } - message ValidatorUpdate { - PublicKey pub_key = 1; - int64 power = 2; - } - repeated ValidatorUpdate validators = 1; - } - - - // Performatives and contents - message Request_Echo_Performative{ - string message = 1; - } - - message Request_Flush_Performative{ - } - - message Request_Info_Performative{ - string version = 1; - int32 block_version = 2; - int32 p2p_version = 3; - } - - message Request_Set_Option_Performative{ - string option_key = 1; - string option_value = 2; - } - - message Request_Init_Chain_Performative{ - Timestamp time = 1; - string chain_id = 2; - ConsensusParams consensus_params = 3; - bool consensus_params_is_set = 4; - ValidatorUpdates validators = 5; - bytes app_state_bytes = 6; - int32 initial_height = 7; - } - - message Request_Query_Performative{ - bytes query_data = 1; - string path = 2; - int32 height = 3; - bool prove = 4; - } - - message Request_Begin_Block_Performative{ - bytes hash = 1; - Header header = 2; - LastCommitInfo last_commit_info = 3; - Evidences byzantine_validators = 4; - } - - message Request_Check_Tx_Performative{ - bytes tx = 1; - CheckTxType type = 2; - } - - message Request_Deliver_Tx_Performative{ - bytes tx = 1; - } - - message Request_End_Block_Performative{ - int32 height = 1; - } - - message Request_Commit_Performative{ - } - - message Request_List_Snapshots_Performative{ - } - - message Request_Offer_Snapshot_Performative{ - Snapshot snapshot = 1; - bytes app_hash = 2; - } - - message Request_Load_Snapshot_Chunk_Performative{ - int32 height = 1; - int32 format = 2; - int32 chunk_index = 3; - } - - message Request_Apply_Snapshot_Chunk_Performative{ - int32 index = 1; - bytes chunk = 2; - string chunk_sender = 3; - } - - message Response_Exception_Performative{ - string error = 1; - } - - message Response_Echo_Performative{ - string message = 1; - } - - message Response_Flush_Performative{ - } - - message Response_Info_Performative{ - string info_data = 1; - string version = 2; - int32 app_version = 3; - int32 last_block_height = 4; - bytes last_block_app_hash = 5; - } - - message Response_Set_Option_Performative{ - int32 code = 1; - string log = 2; - string info = 3; - } - - message Response_Init_Chain_Performative{ - ConsensusParams consensus_params = 1; - bool consensus_params_is_set = 2; - ValidatorUpdates validators = 3; - bytes app_hash = 4; - } - - message Response_Query_Performative{ - int32 code = 1; - string log = 2; - string info = 3; - int32 index = 4; - bytes key = 5; - bytes value = 6; - ProofOps proof_ops = 7; - int32 height = 8; - string codespace = 9; - } - - message Response_Begin_Block_Performative{ - Events events = 1; - } - - message Response_Check_Tx_Performative{ - int32 code = 1; - bytes data = 2; - string log = 3; - string info = 4; - int32 gas_wanted = 5; - int32 gas_used = 6; - Events events = 7; - string codespace = 8; - } - - message Response_Deliver_Tx_Performative{ - int32 code = 1; - bytes data = 2; - string log = 3; - string info = 4; - int32 gas_wanted = 5; - int32 gas_used = 6; - Events events = 7; - string codespace = 8; - } - - message Response_End_Block_Performative{ - ValidatorUpdates validator_updates = 1; - ConsensusParams consensus_param_updates = 2; - bool consensus_param_updates_is_set = 3; - Events events = 4; - } - - message Response_Commit_Performative{ - bytes data = 1; - int32 retain_height = 2; - } - - message Response_List_Snapshots_Performative{ - SnapShots snapshots = 1; - } - - message Response_Offer_Snapshot_Performative{ - Result result = 1; - } - - message Response_Load_Snapshot_Chunk_Performative{ - bytes chunk = 1; - } - - message Response_Apply_Snapshot_Chunk_Performative{ - Result result = 1; - repeated int32 refetch_chunks = 2; - repeated string reject_senders = 3; - } - - message Dummy_Performative{ - ConsensusParams dummy_consensus_params = 1; - } - - - oneof performative{ - Dummy_Performative dummy = 5; - Request_Apply_Snapshot_Chunk_Performative request_apply_snapshot_chunk = 6; - Request_Begin_Block_Performative request_begin_block = 7; - Request_Check_Tx_Performative request_check_tx = 8; - Request_Commit_Performative request_commit = 9; - Request_Deliver_Tx_Performative request_deliver_tx = 10; - Request_Echo_Performative request_echo = 11; - Request_End_Block_Performative request_end_block = 12; - Request_Flush_Performative request_flush = 13; - Request_Info_Performative request_info = 14; - Request_Init_Chain_Performative request_init_chain = 15; - Request_List_Snapshots_Performative request_list_snapshots = 16; - Request_Load_Snapshot_Chunk_Performative request_load_snapshot_chunk = 17; - Request_Offer_Snapshot_Performative request_offer_snapshot = 18; - Request_Query_Performative request_query = 19; - Request_Set_Option_Performative request_set_option = 20; - Response_Apply_Snapshot_Chunk_Performative response_apply_snapshot_chunk = 21; - Response_Begin_Block_Performative response_begin_block = 22; - Response_Check_Tx_Performative response_check_tx = 23; - Response_Commit_Performative response_commit = 24; - Response_Deliver_Tx_Performative response_deliver_tx = 25; - Response_Echo_Performative response_echo = 26; - Response_End_Block_Performative response_end_block = 27; - Response_Exception_Performative response_exception = 28; - Response_Flush_Performative response_flush = 29; - Response_Info_Performative response_info = 30; - Response_Init_Chain_Performative response_init_chain = 31; - Response_List_Snapshots_Performative response_list_snapshots = 32; - Response_Load_Snapshot_Chunk_Performative response_load_snapshot_chunk = 33; - Response_Offer_Snapshot_Performative response_offer_snapshot = 34; - Response_Query_Performative response_query = 35; - Response_Set_Option_Performative response_set_option = 36; - } -} diff --git a/trader_old/vendor/valory/protocols/abci/abci_pb2.py b/trader_old/vendor/valory/protocols/abci/abci_pb2.py deleted file mode 100644 index b1454d434..000000000 --- a/trader_old/vendor/valory/protocols/abci/abci_pb2.py +++ /dev/null @@ -1,177 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: abci.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\nabci.proto\x12\x16\x61\x65\x61.valory.abci.v0_1_0"\x86P\n\x0b\x41\x62\x63iMessage\x12G\n\x05\x64ummy\x18\x05 \x01(\x0b\x32\x36.aea.valory.abci.v0_1_0.AbciMessage.Dummy_PerformativeH\x00\x12u\n\x1crequest_apply_snapshot_chunk\x18\x06 \x01(\x0b\x32M.aea.valory.abci.v0_1_0.AbciMessage.Request_Apply_Snapshot_Chunk_PerformativeH\x00\x12\x63\n\x13request_begin_block\x18\x07 \x01(\x0b\x32\x44.aea.valory.abci.v0_1_0.AbciMessage.Request_Begin_Block_PerformativeH\x00\x12]\n\x10request_check_tx\x18\x08 \x01(\x0b\x32\x41.aea.valory.abci.v0_1_0.AbciMessage.Request_Check_Tx_PerformativeH\x00\x12Y\n\x0erequest_commit\x18\t \x01(\x0b\x32?.aea.valory.abci.v0_1_0.AbciMessage.Request_Commit_PerformativeH\x00\x12\x61\n\x12request_deliver_tx\x18\n \x01(\x0b\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.Request_Deliver_Tx_PerformativeH\x00\x12U\n\x0crequest_echo\x18\x0b \x01(\x0b\x32=.aea.valory.abci.v0_1_0.AbciMessage.Request_Echo_PerformativeH\x00\x12_\n\x11request_end_block\x18\x0c \x01(\x0b\x32\x42.aea.valory.abci.v0_1_0.AbciMessage.Request_End_Block_PerformativeH\x00\x12W\n\rrequest_flush\x18\r \x01(\x0b\x32>.aea.valory.abci.v0_1_0.AbciMessage.Request_Flush_PerformativeH\x00\x12U\n\x0crequest_info\x18\x0e \x01(\x0b\x32=.aea.valory.abci.v0_1_0.AbciMessage.Request_Info_PerformativeH\x00\x12\x61\n\x12request_init_chain\x18\x0f \x01(\x0b\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.Request_Init_Chain_PerformativeH\x00\x12i\n\x16request_list_snapshots\x18\x10 \x01(\x0b\x32G.aea.valory.abci.v0_1_0.AbciMessage.Request_List_Snapshots_PerformativeH\x00\x12s\n\x1brequest_load_snapshot_chunk\x18\x11 \x01(\x0b\x32L.aea.valory.abci.v0_1_0.AbciMessage.Request_Load_Snapshot_Chunk_PerformativeH\x00\x12i\n\x16request_offer_snapshot\x18\x12 \x01(\x0b\x32G.aea.valory.abci.v0_1_0.AbciMessage.Request_Offer_Snapshot_PerformativeH\x00\x12W\n\rrequest_query\x18\x13 \x01(\x0b\x32>.aea.valory.abci.v0_1_0.AbciMessage.Request_Query_PerformativeH\x00\x12\x61\n\x12request_set_option\x18\x14 \x01(\x0b\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.Request_Set_Option_PerformativeH\x00\x12w\n\x1dresponse_apply_snapshot_chunk\x18\x15 \x01(\x0b\x32N.aea.valory.abci.v0_1_0.AbciMessage.Response_Apply_Snapshot_Chunk_PerformativeH\x00\x12\x65\n\x14response_begin_block\x18\x16 \x01(\x0b\x32\x45.aea.valory.abci.v0_1_0.AbciMessage.Response_Begin_Block_PerformativeH\x00\x12_\n\x11response_check_tx\x18\x17 \x01(\x0b\x32\x42.aea.valory.abci.v0_1_0.AbciMessage.Response_Check_Tx_PerformativeH\x00\x12[\n\x0fresponse_commit\x18\x18 \x01(\x0b\x32@.aea.valory.abci.v0_1_0.AbciMessage.Response_Commit_PerformativeH\x00\x12\x63\n\x13response_deliver_tx\x18\x19 \x01(\x0b\x32\x44.aea.valory.abci.v0_1_0.AbciMessage.Response_Deliver_Tx_PerformativeH\x00\x12W\n\rresponse_echo\x18\x1a \x01(\x0b\x32>.aea.valory.abci.v0_1_0.AbciMessage.Response_Echo_PerformativeH\x00\x12\x61\n\x12response_end_block\x18\x1b \x01(\x0b\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.Response_End_Block_PerformativeH\x00\x12\x61\n\x12response_exception\x18\x1c \x01(\x0b\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.Response_Exception_PerformativeH\x00\x12Y\n\x0eresponse_flush\x18\x1d \x01(\x0b\x32?.aea.valory.abci.v0_1_0.AbciMessage.Response_Flush_PerformativeH\x00\x12W\n\rresponse_info\x18\x1e \x01(\x0b\x32>.aea.valory.abci.v0_1_0.AbciMessage.Response_Info_PerformativeH\x00\x12\x63\n\x13response_init_chain\x18\x1f \x01(\x0b\x32\x44.aea.valory.abci.v0_1_0.AbciMessage.Response_Init_Chain_PerformativeH\x00\x12k\n\x17response_list_snapshots\x18 \x01(\x0b\x32H.aea.valory.abci.v0_1_0.AbciMessage.Response_List_Snapshots_PerformativeH\x00\x12u\n\x1cresponse_load_snapshot_chunk\x18! \x01(\x0b\x32M.aea.valory.abci.v0_1_0.AbciMessage.Response_Load_Snapshot_Chunk_PerformativeH\x00\x12k\n\x17response_offer_snapshot\x18" \x01(\x0b\x32H.aea.valory.abci.v0_1_0.AbciMessage.Response_Offer_Snapshot_PerformativeH\x00\x12Y\n\x0eresponse_query\x18# \x01(\x0b\x32?.aea.valory.abci.v0_1_0.AbciMessage.Response_Query_PerformativeH\x00\x12\x63\n\x13response_set_option\x18$ \x01(\x0b\x32\x44.aea.valory.abci.v0_1_0.AbciMessage.Response_Set_Option_PerformativeH\x00\x1a\x7f\n\x0b\x43heckTxType\x12J\n\x04type\x18\x01 \x01(\x0e\x32<.aea.valory.abci.v0_1_0.AbciMessage.CheckTxType._CheckTxType"$\n\x0c_CheckTxType\x12\x07\n\x03NEW\x10\x00\x12\x0b\n\x07RECHECK\x10\x01\x1a\xac\x05\n\x0f\x43onsensusParams\x12N\n\x05\x62lock\x18\x01 \x01(\x0b\x32?.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams.BlockParams\x12T\n\x08\x65vidence\x18\x02 \x01(\x0b\x32\x42.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams.EvidenceParams\x12V\n\tvalidator\x18\x03 \x01(\x0b\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams.ValidatorParams\x12R\n\x07version\x18\x04 \x01(\x0b\x32\x41.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams.VersionParams\x1a*\n\x08\x44uration\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x1a\x31\n\x0b\x42lockParams\x12\x11\n\tmax_bytes\x18\x01 \x01(\x03\x12\x0f\n\x07max_gas\x18\x02 \x01(\x03\x1a\x97\x01\n\x0e\x45videnceParams\x12\x1a\n\x12max_age_num_blocks\x18\x01 \x01(\x03\x12V\n\x10max_age_duration\x18\x02 \x01(\x0b\x32<.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams.Duration\x12\x11\n\tmax_bytes\x18\x03 \x01(\x03\x1a(\n\x0fValidatorParams\x12\x15\n\rpub_key_types\x18\x01 \x03(\t\x1a$\n\rVersionParams\x12\x13\n\x0b\x61pp_version\x18\x01 \x01(\x04\x1a\xed\x01\n\x06\x45vents\x12@\n\x06\x65vents\x18\x01 \x03(\x0b\x32\x30.aea.valory.abci.v0_1_0.AbciMessage.Events.Event\x1a;\n\x0e\x45ventAttribute\x12\x0b\n\x03key\x18\x01 \x01(\x0c\x12\r\n\x05value\x18\x02 \x01(\x0c\x12\r\n\x05index\x18\x03 \x01(\x08\x1a\x64\n\x05\x45vent\x12\x0c\n\x04type\x18\x01 \x01(\t\x12M\n\nattributes\x18\x02 \x03(\x0b\x32\x39.aea.valory.abci.v0_1_0.AbciMessage.Events.EventAttribute\x1a\xc5\x03\n\tEvidences\x12T\n\x14\x62yzantine_validators\x18\x01 \x03(\x0b\x32\x36.aea.valory.abci.v0_1_0.AbciMessage.Evidences.Evidence\x1a\xe1\x02\n\x08\x45vidence\x12Q\n\x04type\x18\x01 \x01(\x0e\x32\x43.aea.valory.abci.v0_1_0.AbciMessage.Evidences.Evidence.EvidenceType\x12O\n\tvalidator\x18\x02 \x01(\x0b\x32<.aea.valory.abci.v0_1_0.AbciMessage.LastCommitInfo.Validator\x12\x0e\n\x06height\x18\x03 \x01(\x03\x12;\n\x04time\x18\x04 \x01(\x0b\x32-.aea.valory.abci.v0_1_0.AbciMessage.Timestamp\x12\x1a\n\x12total_voting_power\x18\x05 \x01(\x03"H\n\x0c\x45videnceType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x12\n\x0e\x44UPLICATE_VOTE\x10\x01\x12\x17\n\x13LIGHT_CLIENT_ATTACK\x10\x02\x1a\xa4\x05\n\x06Header\x12L\n\x07version\x18\x01 \x01(\x0b\x32;.aea.valory.abci.v0_1_0.AbciMessage.Header.ConsensusVersion\x12\x10\n\x08\x63hain_id\x18\x02 \x01(\t\x12\x0e\n\x06height\x18\x03 \x01(\x03\x12;\n\x04time\x18\x04 \x01(\x0b\x32-.aea.valory.abci.v0_1_0.AbciMessage.Timestamp\x12I\n\rlast_block_id\x18\x05 \x01(\x0b\x32\x32.aea.valory.abci.v0_1_0.AbciMessage.Header.BlockID\x12\x18\n\x10last_commit_hash\x18\x06 \x01(\x0c\x12\x11\n\tdata_hash\x18\x07 \x01(\x0c\x12\x17\n\x0fvalidators_hash\x18\x08 \x01(\x0c\x12\x1c\n\x14next_validators_hash\x18\t \x01(\x0c\x12\x16\n\x0e\x63onsensus_hash\x18\n \x01(\x0c\x12\x10\n\x08\x61pp_hash\x18\x0b \x01(\x0c\x12\x19\n\x11last_results_hash\x18\x0c \x01(\x0c\x12\x15\n\revidence_hash\x18\r \x01(\x0c\x12\x18\n\x10proposer_address\x18\x0e \x01(\x0c\x1a.\n\x10\x43onsensusVersion\x12\r\n\x05\x62lock\x18\x01 \x01(\x04\x12\x0b\n\x03\x61pp\x18\x02 \x01(\x04\x1aj\n\x07\x42lockID\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12Q\n\x0fpart_set_header\x18\x02 \x01(\x0b\x32\x38.aea.valory.abci.v0_1_0.AbciMessage.Header.PartSetHeader\x1a,\n\rPartSetHeader\x12\r\n\x05total\x18\x01 \x01(\r\x12\x0c\n\x04hash\x18\x02 \x01(\x0c\x1a\x90\x02\n\x0eLastCommitInfo\x12\r\n\x05round\x18\x01 \x01(\x05\x12J\n\x05votes\x18\x02 \x03(\x0b\x32;.aea.valory.abci.v0_1_0.AbciMessage.LastCommitInfo.VoteInfo\x1a+\n\tValidator\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\x0c\x12\r\n\x05power\x18\x03 \x01(\x03\x1av\n\x08VoteInfo\x12O\n\tvalidator\x18\x01 \x01(\x0b\x32<.aea.valory.abci.v0_1_0.AbciMessage.LastCommitInfo.Validator\x12\x19\n\x11signed_last_block\x18\x02 \x01(\x08\x1a\x81\x01\n\x08ProofOps\x12\x41\n\x03ops\x18\x01 \x03(\x0b\x32\x34.aea.valory.abci.v0_1_0.AbciMessage.ProofOps.ProofOp\x1a\x32\n\x07ProofOp\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\x1a\xb8\x01\n\x06Result\x12J\n\x0bresult_type\x18\x01 \x01(\x0e\x32\x35.aea.valory.abci.v0_1_0.AbciMessage.Result.ResultType"b\n\nResultType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x41\x43\x43\x45PT\x10\x01\x12\t\n\x05\x41\x42ORT\x10\x02\x12\n\n\x06REJECT\x10\x03\x12\x11\n\rREJECT_FORMAT\x10\x04\x12\x11\n\rREJECT_SENDER\x10\x05\x1aL\n\tSnapShots\x12?\n\tsnapshots\x18\x01 \x03(\x0b\x32,.aea.valory.abci.v0_1_0.AbciMessage.Snapshot\x1aZ\n\x08Snapshot\x12\x0e\n\x06height\x18\x01 \x01(\x04\x12\x0e\n\x06\x66ormat\x18\x02 \x01(\r\x12\x0e\n\x06\x63hunks\x18\x03 \x01(\r\x12\x0c\n\x04hash\x18\x04 \x01(\x0c\x12\x10\n\x08metadata\x18\x05 \x01(\x0c\x1a+\n\tTimestamp\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x1a\x9b\x02\n\x10ValidatorUpdates\x12X\n\nvalidators\x18\x01 \x03(\x0b\x32\x44.aea.valory.abci.v0_1_0.AbciMessage.ValidatorUpdates.ValidatorUpdate\x1a:\n\tPublicKey\x12\x11\n\x07\x65\x64\x32\x35\x35\x31\x39\x18\x01 \x01(\x0cH\x00\x12\x13\n\tsecp256k1\x18\x02 \x01(\x0cH\x00\x42\x05\n\x03sum\x1aq\n\x0fValidatorUpdate\x12O\n\x07pub_key\x18\x01 \x01(\x0b\x32>.aea.valory.abci.v0_1_0.AbciMessage.ValidatorUpdates.PublicKey\x12\r\n\x05power\x18\x02 \x01(\x03\x1a,\n\x19Request_Echo_Performative\x12\x0f\n\x07message\x18\x01 \x01(\t\x1a\x1c\n\x1aRequest_Flush_Performative\x1aX\n\x19Request_Info_Performative\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x15\n\rblock_version\x18\x02 \x01(\x05\x12\x13\n\x0bp2p_version\x18\x03 \x01(\x05\x1aK\n\x1fRequest_Set_Option_Performative\x12\x12\n\noption_key\x18\x01 \x01(\t\x12\x14\n\x0coption_value\x18\x02 \x01(\t\x1a\xdb\x02\n\x1fRequest_Init_Chain_Performative\x12;\n\x04time\x18\x01 \x01(\x0b\x32-.aea.valory.abci.v0_1_0.AbciMessage.Timestamp\x12\x10\n\x08\x63hain_id\x18\x02 \x01(\t\x12M\n\x10\x63onsensus_params\x18\x03 \x01(\x0b\x32\x33.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams\x12\x1f\n\x17\x63onsensus_params_is_set\x18\x04 \x01(\x08\x12H\n\nvalidators\x18\x05 \x01(\x0b\x32\x34.aea.valory.abci.v0_1_0.AbciMessage.ValidatorUpdates\x12\x17\n\x0f\x61pp_state_bytes\x18\x06 \x01(\x0c\x12\x16\n\x0einitial_height\x18\x07 \x01(\x05\x1a]\n\x1aRequest_Query_Performative\x12\x12\n\nquery_data\x18\x01 \x01(\x0c\x12\x0c\n\x04path\x18\x02 \x01(\t\x12\x0e\n\x06height\x18\x03 \x01(\x05\x12\r\n\x05prove\x18\x04 \x01(\x08\x1a\x87\x02\n Request_Begin_Block_Performative\x12\x0c\n\x04hash\x18\x01 \x01(\x0c\x12:\n\x06header\x18\x02 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Header\x12L\n\x10last_commit_info\x18\x03 \x01(\x0b\x32\x32.aea.valory.abci.v0_1_0.AbciMessage.LastCommitInfo\x12K\n\x14\x62yzantine_validators\x18\x04 \x01(\x0b\x32-.aea.valory.abci.v0_1_0.AbciMessage.Evidences\x1aj\n\x1dRequest_Check_Tx_Performative\x12\n\n\x02tx\x18\x01 \x01(\x0c\x12=\n\x04type\x18\x02 \x01(\x0b\x32/.aea.valory.abci.v0_1_0.AbciMessage.CheckTxType\x1a-\n\x1fRequest_Deliver_Tx_Performative\x12\n\n\x02tx\x18\x01 \x01(\x0c\x1a\x30\n\x1eRequest_End_Block_Performative\x12\x0e\n\x06height\x18\x01 \x01(\x05\x1a\x1d\n\x1bRequest_Commit_Performative\x1a%\n#Request_List_Snapshots_Performative\x1aw\n#Request_Offer_Snapshot_Performative\x12>\n\x08snapshot\x18\x01 \x01(\x0b\x32,.aea.valory.abci.v0_1_0.AbciMessage.Snapshot\x12\x10\n\x08\x61pp_hash\x18\x02 \x01(\x0c\x1a_\n(Request_Load_Snapshot_Chunk_Performative\x12\x0e\n\x06height\x18\x01 \x01(\x05\x12\x0e\n\x06\x66ormat\x18\x02 \x01(\x05\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\x05\x1a_\n)Request_Apply_Snapshot_Chunk_Performative\x12\r\n\x05index\x18\x01 \x01(\x05\x12\r\n\x05\x63hunk\x18\x02 \x01(\x0c\x12\x14\n\x0c\x63hunk_sender\x18\x03 \x01(\t\x1a\x30\n\x1fResponse_Exception_Performative\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x1a-\n\x1aResponse_Echo_Performative\x12\x0f\n\x07message\x18\x01 \x01(\t\x1a\x1d\n\x1bResponse_Flush_Performative\x1a\x8d\x01\n\x1aResponse_Info_Performative\x12\x11\n\tinfo_data\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12\x13\n\x0b\x61pp_version\x18\x03 \x01(\x05\x12\x19\n\x11last_block_height\x18\x04 \x01(\x05\x12\x1b\n\x13last_block_app_hash\x18\x05 \x01(\x0c\x1aK\n Response_Set_Option_Performative\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0b\n\x03log\x18\x02 \x01(\t\x12\x0c\n\x04info\x18\x03 \x01(\t\x1a\xee\x01\n Response_Init_Chain_Performative\x12M\n\x10\x63onsensus_params\x18\x01 \x01(\x0b\x32\x33.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams\x12\x1f\n\x17\x63onsensus_params_is_set\x18\x02 \x01(\x08\x12H\n\nvalidators\x18\x03 \x01(\x0b\x32\x34.aea.valory.abci.v0_1_0.AbciMessage.ValidatorUpdates\x12\x10\n\x08\x61pp_hash\x18\x04 \x01(\x0c\x1a\xd5\x01\n\x1bResponse_Query_Performative\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0b\n\x03log\x18\x02 \x01(\t\x12\x0c\n\x04info\x18\x03 \x01(\t\x12\r\n\x05index\x18\x04 \x01(\x05\x12\x0b\n\x03key\x18\x05 \x01(\x0c\x12\r\n\x05value\x18\x06 \x01(\x0c\x12?\n\tproof_ops\x18\x07 \x01(\x0b\x32,.aea.valory.abci.v0_1_0.AbciMessage.ProofOps\x12\x0e\n\x06height\x18\x08 \x01(\x05\x12\x11\n\tcodespace\x18\t \x01(\t\x1a_\n!Response_Begin_Block_Performative\x12:\n\x06\x65vents\x18\x01 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Events\x1a\xcc\x01\n\x1eResponse_Check_Tx_Performative\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x0b\n\x03log\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t\x12\x12\n\ngas_wanted\x18\x05 \x01(\x05\x12\x10\n\x08gas_used\x18\x06 \x01(\x05\x12:\n\x06\x65vents\x18\x07 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Events\x12\x11\n\tcodespace\x18\x08 \x01(\t\x1a\xce\x01\n Response_Deliver_Tx_Performative\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12\x0b\n\x03log\x18\x03 \x01(\t\x12\x0c\n\x04info\x18\x04 \x01(\t\x12\x12\n\ngas_wanted\x18\x05 \x01(\x05\x12\x10\n\x08gas_used\x18\x06 \x01(\x05\x12:\n\x06\x65vents\x18\x07 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Events\x12\x11\n\tcodespace\x18\x08 \x01(\t\x1a\xac\x02\n\x1fResponse_End_Block_Performative\x12O\n\x11validator_updates\x18\x01 \x01(\x0b\x32\x34.aea.valory.abci.v0_1_0.AbciMessage.ValidatorUpdates\x12T\n\x17\x63onsensus_param_updates\x18\x02 \x01(\x0b\x32\x33.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParams\x12&\n\x1e\x63onsensus_param_updates_is_set\x18\x03 \x01(\x08\x12:\n\x06\x65vents\x18\x04 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Events\x1a\x43\n\x1cResponse_Commit_Performative\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x12\x15\n\rretain_height\x18\x02 \x01(\x05\x1ah\n$Response_List_Snapshots_Performative\x12@\n\tsnapshots\x18\x01 \x01(\x0b\x32-.aea.valory.abci.v0_1_0.AbciMessage.SnapShots\x1a\x62\n$Response_Offer_Snapshot_Performative\x12:\n\x06result\x18\x01 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Result\x1a:\n)Response_Load_Snapshot_Chunk_Performative\x12\r\n\x05\x63hunk\x18\x01 \x01(\x0c\x1a\x98\x01\n*Response_Apply_Snapshot_Chunk_Performative\x12:\n\x06result\x18\x01 \x01(\x0b\x32*.aea.valory.abci.v0_1_0.AbciMessage.Result\x12\x16\n\x0erefetch_chunks\x18\x02 \x03(\x05\x12\x16\n\x0ereject_senders\x18\x03 \x03(\t\x1ai\n\x12\x44ummy_Performative\x12S\n\x16\x64ummy_consensus_params\x18\x01 \x01(\x0b\x32\x33.aea.valory.abci.v0_1_0.AbciMessage.ConsensusParamsB\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "abci_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals["_ABCIMESSAGE"]._serialized_start = 39 - _globals["_ABCIMESSAGE"]._serialized_end = 10285 - _globals["_ABCIMESSAGE_CHECKTXTYPE"]._serialized_start = 3222 - _globals["_ABCIMESSAGE_CHECKTXTYPE"]._serialized_end = 3349 - _globals["_ABCIMESSAGE_CHECKTXTYPE__CHECKTXTYPE"]._serialized_start = 3313 - _globals["_ABCIMESSAGE_CHECKTXTYPE__CHECKTXTYPE"]._serialized_end = 3349 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS"]._serialized_start = 3352 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS"]._serialized_end = 4036 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_DURATION"]._serialized_start = 3709 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_DURATION"]._serialized_end = 3751 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_BLOCKPARAMS"]._serialized_start = 3753 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_BLOCKPARAMS"]._serialized_end = 3802 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_EVIDENCEPARAMS"]._serialized_start = 3805 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_EVIDENCEPARAMS"]._serialized_end = 3956 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_VALIDATORPARAMS"]._serialized_start = 3958 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_VALIDATORPARAMS"]._serialized_end = 3998 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_VERSIONPARAMS"]._serialized_start = 4000 - _globals["_ABCIMESSAGE_CONSENSUSPARAMS_VERSIONPARAMS"]._serialized_end = 4036 - _globals["_ABCIMESSAGE_EVENTS"]._serialized_start = 4039 - _globals["_ABCIMESSAGE_EVENTS"]._serialized_end = 4276 - _globals["_ABCIMESSAGE_EVENTS_EVENTATTRIBUTE"]._serialized_start = 4115 - _globals["_ABCIMESSAGE_EVENTS_EVENTATTRIBUTE"]._serialized_end = 4174 - _globals["_ABCIMESSAGE_EVENTS_EVENT"]._serialized_start = 4176 - _globals["_ABCIMESSAGE_EVENTS_EVENT"]._serialized_end = 4276 - _globals["_ABCIMESSAGE_EVIDENCES"]._serialized_start = 4279 - _globals["_ABCIMESSAGE_EVIDENCES"]._serialized_end = 4732 - _globals["_ABCIMESSAGE_EVIDENCES_EVIDENCE"]._serialized_start = 4379 - _globals["_ABCIMESSAGE_EVIDENCES_EVIDENCE"]._serialized_end = 4732 - _globals["_ABCIMESSAGE_EVIDENCES_EVIDENCE_EVIDENCETYPE"]._serialized_start = 4660 - _globals["_ABCIMESSAGE_EVIDENCES_EVIDENCE_EVIDENCETYPE"]._serialized_end = 4732 - _globals["_ABCIMESSAGE_HEADER"]._serialized_start = 4735 - _globals["_ABCIMESSAGE_HEADER"]._serialized_end = 5411 - _globals["_ABCIMESSAGE_HEADER_CONSENSUSVERSION"]._serialized_start = 5211 - _globals["_ABCIMESSAGE_HEADER_CONSENSUSVERSION"]._serialized_end = 5257 - _globals["_ABCIMESSAGE_HEADER_BLOCKID"]._serialized_start = 5259 - _globals["_ABCIMESSAGE_HEADER_BLOCKID"]._serialized_end = 5365 - _globals["_ABCIMESSAGE_HEADER_PARTSETHEADER"]._serialized_start = 5367 - _globals["_ABCIMESSAGE_HEADER_PARTSETHEADER"]._serialized_end = 5411 - _globals["_ABCIMESSAGE_LASTCOMMITINFO"]._serialized_start = 5414 - _globals["_ABCIMESSAGE_LASTCOMMITINFO"]._serialized_end = 5686 - _globals["_ABCIMESSAGE_LASTCOMMITINFO_VALIDATOR"]._serialized_start = 5523 - _globals["_ABCIMESSAGE_LASTCOMMITINFO_VALIDATOR"]._serialized_end = 5566 - _globals["_ABCIMESSAGE_LASTCOMMITINFO_VOTEINFO"]._serialized_start = 5568 - _globals["_ABCIMESSAGE_LASTCOMMITINFO_VOTEINFO"]._serialized_end = 5686 - _globals["_ABCIMESSAGE_PROOFOPS"]._serialized_start = 5689 - _globals["_ABCIMESSAGE_PROOFOPS"]._serialized_end = 5818 - _globals["_ABCIMESSAGE_PROOFOPS_PROOFOP"]._serialized_start = 5768 - _globals["_ABCIMESSAGE_PROOFOPS_PROOFOP"]._serialized_end = 5818 - _globals["_ABCIMESSAGE_RESULT"]._serialized_start = 5821 - _globals["_ABCIMESSAGE_RESULT"]._serialized_end = 6005 - _globals["_ABCIMESSAGE_RESULT_RESULTTYPE"]._serialized_start = 5907 - _globals["_ABCIMESSAGE_RESULT_RESULTTYPE"]._serialized_end = 6005 - _globals["_ABCIMESSAGE_SNAPSHOTS"]._serialized_start = 6007 - _globals["_ABCIMESSAGE_SNAPSHOTS"]._serialized_end = 6083 - _globals["_ABCIMESSAGE_SNAPSHOT"]._serialized_start = 6085 - _globals["_ABCIMESSAGE_SNAPSHOT"]._serialized_end = 6175 - _globals["_ABCIMESSAGE_TIMESTAMP"]._serialized_start = 6177 - _globals["_ABCIMESSAGE_TIMESTAMP"]._serialized_end = 6220 - _globals["_ABCIMESSAGE_VALIDATORUPDATES"]._serialized_start = 6223 - _globals["_ABCIMESSAGE_VALIDATORUPDATES"]._serialized_end = 6506 - _globals["_ABCIMESSAGE_VALIDATORUPDATES_PUBLICKEY"]._serialized_start = 6333 - _globals["_ABCIMESSAGE_VALIDATORUPDATES_PUBLICKEY"]._serialized_end = 6391 - _globals["_ABCIMESSAGE_VALIDATORUPDATES_VALIDATORUPDATE"]._serialized_start = 6393 - _globals["_ABCIMESSAGE_VALIDATORUPDATES_VALIDATORUPDATE"]._serialized_end = 6506 - _globals["_ABCIMESSAGE_REQUEST_ECHO_PERFORMATIVE"]._serialized_start = 6508 - _globals["_ABCIMESSAGE_REQUEST_ECHO_PERFORMATIVE"]._serialized_end = 6552 - _globals["_ABCIMESSAGE_REQUEST_FLUSH_PERFORMATIVE"]._serialized_start = 6554 - _globals["_ABCIMESSAGE_REQUEST_FLUSH_PERFORMATIVE"]._serialized_end = 6582 - _globals["_ABCIMESSAGE_REQUEST_INFO_PERFORMATIVE"]._serialized_start = 6584 - _globals["_ABCIMESSAGE_REQUEST_INFO_PERFORMATIVE"]._serialized_end = 6672 - _globals["_ABCIMESSAGE_REQUEST_SET_OPTION_PERFORMATIVE"]._serialized_start = 6674 - _globals["_ABCIMESSAGE_REQUEST_SET_OPTION_PERFORMATIVE"]._serialized_end = 6749 - _globals["_ABCIMESSAGE_REQUEST_INIT_CHAIN_PERFORMATIVE"]._serialized_start = 6752 - _globals["_ABCIMESSAGE_REQUEST_INIT_CHAIN_PERFORMATIVE"]._serialized_end = 7099 - _globals["_ABCIMESSAGE_REQUEST_QUERY_PERFORMATIVE"]._serialized_start = 7101 - _globals["_ABCIMESSAGE_REQUEST_QUERY_PERFORMATIVE"]._serialized_end = 7194 - _globals["_ABCIMESSAGE_REQUEST_BEGIN_BLOCK_PERFORMATIVE"]._serialized_start = 7197 - _globals["_ABCIMESSAGE_REQUEST_BEGIN_BLOCK_PERFORMATIVE"]._serialized_end = 7460 - _globals["_ABCIMESSAGE_REQUEST_CHECK_TX_PERFORMATIVE"]._serialized_start = 7462 - _globals["_ABCIMESSAGE_REQUEST_CHECK_TX_PERFORMATIVE"]._serialized_end = 7568 - _globals["_ABCIMESSAGE_REQUEST_DELIVER_TX_PERFORMATIVE"]._serialized_start = 7570 - _globals["_ABCIMESSAGE_REQUEST_DELIVER_TX_PERFORMATIVE"]._serialized_end = 7615 - _globals["_ABCIMESSAGE_REQUEST_END_BLOCK_PERFORMATIVE"]._serialized_start = 7617 - _globals["_ABCIMESSAGE_REQUEST_END_BLOCK_PERFORMATIVE"]._serialized_end = 7665 - _globals["_ABCIMESSAGE_REQUEST_COMMIT_PERFORMATIVE"]._serialized_start = 7667 - _globals["_ABCIMESSAGE_REQUEST_COMMIT_PERFORMATIVE"]._serialized_end = 7696 - _globals[ - "_ABCIMESSAGE_REQUEST_LIST_SNAPSHOTS_PERFORMATIVE" - ]._serialized_start = 7698 - _globals["_ABCIMESSAGE_REQUEST_LIST_SNAPSHOTS_PERFORMATIVE"]._serialized_end = 7735 - _globals[ - "_ABCIMESSAGE_REQUEST_OFFER_SNAPSHOT_PERFORMATIVE" - ]._serialized_start = 7737 - _globals["_ABCIMESSAGE_REQUEST_OFFER_SNAPSHOT_PERFORMATIVE"]._serialized_end = 7856 - _globals[ - "_ABCIMESSAGE_REQUEST_LOAD_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_start = 7858 - _globals[ - "_ABCIMESSAGE_REQUEST_LOAD_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_end = 7953 - _globals[ - "_ABCIMESSAGE_REQUEST_APPLY_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_start = 7955 - _globals[ - "_ABCIMESSAGE_REQUEST_APPLY_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_end = 8050 - _globals["_ABCIMESSAGE_RESPONSE_EXCEPTION_PERFORMATIVE"]._serialized_start = 8052 - _globals["_ABCIMESSAGE_RESPONSE_EXCEPTION_PERFORMATIVE"]._serialized_end = 8100 - _globals["_ABCIMESSAGE_RESPONSE_ECHO_PERFORMATIVE"]._serialized_start = 8102 - _globals["_ABCIMESSAGE_RESPONSE_ECHO_PERFORMATIVE"]._serialized_end = 8147 - _globals["_ABCIMESSAGE_RESPONSE_FLUSH_PERFORMATIVE"]._serialized_start = 8149 - _globals["_ABCIMESSAGE_RESPONSE_FLUSH_PERFORMATIVE"]._serialized_end = 8178 - _globals["_ABCIMESSAGE_RESPONSE_INFO_PERFORMATIVE"]._serialized_start = 8181 - _globals["_ABCIMESSAGE_RESPONSE_INFO_PERFORMATIVE"]._serialized_end = 8322 - _globals["_ABCIMESSAGE_RESPONSE_SET_OPTION_PERFORMATIVE"]._serialized_start = 8324 - _globals["_ABCIMESSAGE_RESPONSE_SET_OPTION_PERFORMATIVE"]._serialized_end = 8399 - _globals["_ABCIMESSAGE_RESPONSE_INIT_CHAIN_PERFORMATIVE"]._serialized_start = 8402 - _globals["_ABCIMESSAGE_RESPONSE_INIT_CHAIN_PERFORMATIVE"]._serialized_end = 8640 - _globals["_ABCIMESSAGE_RESPONSE_QUERY_PERFORMATIVE"]._serialized_start = 8643 - _globals["_ABCIMESSAGE_RESPONSE_QUERY_PERFORMATIVE"]._serialized_end = 8856 - _globals["_ABCIMESSAGE_RESPONSE_BEGIN_BLOCK_PERFORMATIVE"]._serialized_start = 8858 - _globals["_ABCIMESSAGE_RESPONSE_BEGIN_BLOCK_PERFORMATIVE"]._serialized_end = 8953 - _globals["_ABCIMESSAGE_RESPONSE_CHECK_TX_PERFORMATIVE"]._serialized_start = 8956 - _globals["_ABCIMESSAGE_RESPONSE_CHECK_TX_PERFORMATIVE"]._serialized_end = 9160 - _globals["_ABCIMESSAGE_RESPONSE_DELIVER_TX_PERFORMATIVE"]._serialized_start = 9163 - _globals["_ABCIMESSAGE_RESPONSE_DELIVER_TX_PERFORMATIVE"]._serialized_end = 9369 - _globals["_ABCIMESSAGE_RESPONSE_END_BLOCK_PERFORMATIVE"]._serialized_start = 9372 - _globals["_ABCIMESSAGE_RESPONSE_END_BLOCK_PERFORMATIVE"]._serialized_end = 9672 - _globals["_ABCIMESSAGE_RESPONSE_COMMIT_PERFORMATIVE"]._serialized_start = 9674 - _globals["_ABCIMESSAGE_RESPONSE_COMMIT_PERFORMATIVE"]._serialized_end = 9741 - _globals[ - "_ABCIMESSAGE_RESPONSE_LIST_SNAPSHOTS_PERFORMATIVE" - ]._serialized_start = 9743 - _globals["_ABCIMESSAGE_RESPONSE_LIST_SNAPSHOTS_PERFORMATIVE"]._serialized_end = 9847 - _globals[ - "_ABCIMESSAGE_RESPONSE_OFFER_SNAPSHOT_PERFORMATIVE" - ]._serialized_start = 9849 - _globals["_ABCIMESSAGE_RESPONSE_OFFER_SNAPSHOT_PERFORMATIVE"]._serialized_end = 9947 - _globals[ - "_ABCIMESSAGE_RESPONSE_LOAD_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_start = 9949 - _globals[ - "_ABCIMESSAGE_RESPONSE_LOAD_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_end = 10007 - _globals[ - "_ABCIMESSAGE_RESPONSE_APPLY_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_start = 10010 - _globals[ - "_ABCIMESSAGE_RESPONSE_APPLY_SNAPSHOT_CHUNK_PERFORMATIVE" - ]._serialized_end = 10162 - _globals["_ABCIMESSAGE_DUMMY_PERFORMATIVE"]._serialized_start = 10164 - _globals["_ABCIMESSAGE_DUMMY_PERFORMATIVE"]._serialized_end = 10269 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/protocols/abci/custom_types.py b/trader_old/vendor/valory/protocols/abci/custom_types.py deleted file mode 100644 index ab07951fb..000000000 --- a/trader_old/vendor/valory/protocols/abci/custom_types.py +++ /dev/null @@ -1,1622 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021 valory -# -# 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 class representations corresponding to every custom type in the protocol specification.""" -import datetime -from enum import Enum -from typing import List, Optional - -from aea.exceptions import enforce - -from packages.valory.protocols.abci import abci_pb2 - - -class BlockParams: - """This class represents an instance of BlockParams.""" - - __slots__ = ["max_bytes", "max_gas"] - - def __init__(self, max_bytes: int, max_gas: int): - """Initialise an instance of BlockParams.""" - self.max_bytes = max_bytes - self.max_gas = max_gas - - @staticmethod - def encode( - block_params_protobuf_object, block_params_object: "BlockParams" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the block_params_protobuf_object argument is matched with the instance of this class in the 'block_params_object' argument. - - :param block_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param block_params_object: an instance of this class to be encoded in the protocol buffer object. - """ - block_params_protobuf_object.max_bytes = block_params_object.max_bytes - block_params_protobuf_object.max_gas = block_params_object.max_gas - - @classmethod - def decode(cls, block_params_protobuf_object) -> "BlockParams": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'block_params_protobuf_object' argument. - - :param block_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'block_params_protobuf_object' argument. - """ - return BlockParams( - block_params_protobuf_object.max_bytes, block_params_protobuf_object.max_gas - ) - - def __eq__(self, other) -> bool: - """Compare with another object.""" - return ( - isinstance(other, BlockParams) - and self.max_bytes == other.max_bytes - and self.max_gas == other.max_gas - ) - - -class Duration: - """This class represents an instance of Duration.""" - - __slots__ = ["seconds", "nanos"] - - def __init__(self, seconds: int, nanos: int): - """ - Initialise an instance of Duration. - - :param seconds: Signed seconds of the span of time. - Must be from -315,576,000,000 to +315,576,000,000 inclusive. - :param nanos: Signed fractions of a second at nanosecond resolution of the span of time. - Durations less than one second are represented with a 0 seconds field and - a positive or negative nanos field. For durations of one second or more, - a non-zero value for the nanos field must be of the same sign as the seconds field. - Must be from -999,999,999 to +999,999,999 inclusive. - """ - self.seconds = seconds - self.nanos = nanos - - @staticmethod - def encode(duration_protobuf_object, duration_object: "Duration") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the duration_protobuf_object argument is matched with the instance of this class in the 'duration_object' argument. - - :param duration_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param duration_object: an instance of this class to be encoded in the protocol buffer object. - """ - duration_protobuf_object.seconds = duration_object.seconds - duration_protobuf_object.nanos = duration_object.nanos - - @classmethod - def decode(cls, duration_protobuf_object) -> "Duration": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'duration_protobuf_object' argument. - - :param duration_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'duration_protobuf_object' argument. - """ - return Duration( - duration_protobuf_object.seconds, duration_protobuf_object.nanos - ) - - def __eq__(self, other) -> bool: - """Compare with another object.""" - return ( - isinstance(other, Duration) - and self.seconds == other.seconds - and self.nanos == other.nanos - ) - - -class EvidenceParams: - """This class represents an instance of EvidenceParams.""" - - __slots__ = [ - "max_age_num_blocks", - "max_age_duration", - "max_bytes", - ] - - def __init__( - self, max_age_num_blocks: int, max_age_duration: Duration, max_bytes: int - ): - """Initialise an instance of BlockParams.""" - self.max_age_num_blocks = max_age_num_blocks - self.max_age_duration = max_age_duration - self.max_bytes = max_bytes - - @staticmethod - def encode( - evidence_params_protobuf_object, evidence_params_object: "EvidenceParams" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the evidence_params_protobuf_object argument is matched with the instance of this class in the 'evidence_params_object' argument. - - :param evidence_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param evidence_params_object: an instance of this class to be encoded in the protocol buffer object. - """ - evidence_params_protobuf_object.max_age_num_blocks = ( - evidence_params_object.max_age_num_blocks - ) - Duration.encode( - evidence_params_protobuf_object.max_age_duration, - evidence_params_object.max_age_duration, - ) - evidence_params_protobuf_object.max_bytes = evidence_params_object.max_bytes - - @classmethod - def decode(cls, evidence_params_protobuf_object) -> "EvidenceParams": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'evidence_params_protobuf_object' argument. - - :param evidence_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'evidence_params_protobuf_object' argument. - """ - duration = Duration.decode(evidence_params_protobuf_object.max_age_duration) - return EvidenceParams( - evidence_params_protobuf_object.max_age_num_blocks, - duration, - evidence_params_protobuf_object.max_bytes, - ) - - def __eq__(self, other) -> bool: - """Compare with another object.""" - return ( - isinstance(other, EvidenceParams) - and self.max_age_num_blocks == other.max_age_num_blocks - and self.max_age_duration == other.max_age_duration - and self.max_bytes == other.max_bytes - ) - - -class ValidatorParams: - """This class represents an instance of ValidatorParams.""" - - __slots__ = [ - "pub_key_types", - ] - - def __init__(self, pub_key_types: List[str]): - """Initialise an instance of BlockParams.""" - self.pub_key_types = pub_key_types - - @staticmethod - def encode( - validator_params_protobuf_object, validator_params_object: "ValidatorParams" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the validator_params_protobuf_object argument is matched with the instance of this class in the 'validator_params_object' argument. - - :param validator_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param validator_params_object: an instance of this class to be encoded in the protocol buffer object. - """ - validator_params_protobuf_object.pub_key_types.extend( - validator_params_object.pub_key_types - ) - - @classmethod - def decode(cls, validator_params_protobuf_object) -> "ValidatorParams": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'validator_params_protobuf_object' argument. - - :param validator_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'validator_params_protobuf_object' argument. - """ - pub_key_types = list(validator_params_protobuf_object.pub_key_types) - return ValidatorParams( - pub_key_types, - ) - - def __eq__(self, other) -> bool: - """Compare with another object.""" - return ( - isinstance(other, ValidatorParams) - and self.pub_key_types == other.pub_key_types - ) - - -class VersionParams: - """This class represents an instance of VersionParams.""" - - __slots__ = [ - "app_version", - ] - - def __init__(self, app_version: int): - """Initialise an instance of BlockParams.""" - self.app_version = app_version - - @staticmethod - def encode( - version_params_protobuf_object, version_params_object: "VersionParams" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the version_params_protobuf_object argument is matched with the instance of this class in the 'version_params_object' argument. - - :param version_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param version_params_object: an instance of this class to be encoded in the protocol buffer object. - """ - version_params_protobuf_object.app_version = version_params_object.app_version - - @classmethod - def decode(cls, version_params_protobuf_object) -> "VersionParams": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'version_params_protobuf_object' argument. - - :param version_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'version_params_protobuf_object' argument. - """ - app_version = version_params_protobuf_object.app_version - return VersionParams( - app_version, - ) - - def __eq__(self, other) -> bool: - """Compare with another object.""" - return ( - isinstance(other, VersionParams) and self.app_version == other.app_version - ) - - -class ConsensusParams: - """This class represents an instance of ConsensusParams.""" - - def __init__( - self, - block: "BlockParams", - evidence_params: "EvidenceParams", - validator_params: "ValidatorParams", - version_params: "VersionParams", - ): - """Initialise an instance of ConsensusParams.""" - self.block = block - self.evidence_params = evidence_params - self.validator_params = validator_params - self.version_params = version_params - - @staticmethod - def encode( - consensus_params_protobuf_object, - consensus_params_object: Optional["ConsensusParams"], - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the consensus_params_protobuf_object argument is matched with the instance of this class in the 'consensus_params_object' argument. - - :param consensus_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param consensus_params_object: an instance of this class to be encoded in the protocol buffer object. - """ - BlockParams.encode( - consensus_params_protobuf_object.block, consensus_params_object.block - ) - EvidenceParams.encode( - consensus_params_protobuf_object.evidence, - consensus_params_object.evidence_params, - ) - ValidatorParams.encode( - consensus_params_protobuf_object.validator, - consensus_params_object.validator_params, - ) - VersionParams.encode( - consensus_params_protobuf_object.version, - consensus_params_object.version_params, - ) - - @classmethod - def decode(cls, consensus_params_protobuf_object) -> "ConsensusParams": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'consensus_params_protobuf_object' argument. - - :param consensus_params_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'consensus_params_protobuf_object' argument. - """ - block_params = BlockParams.decode(consensus_params_protobuf_object.block) - evidence_params = EvidenceParams.decode( - consensus_params_protobuf_object.evidence - ) - validator_params = ValidatorParams.decode( - consensus_params_protobuf_object.validator - ) - version_params = VersionParams.decode(consensus_params_protobuf_object.version) - return ConsensusParams( - block_params, evidence_params, validator_params, version_params - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, ConsensusParams) - and self.block == other.block - and self.evidence_params == other.evidence_params - and self.validator_params == other.validator_params - and self.version_params == other.version_params - ) - - -class EventAttribute: - """This class represents an instance of EventAttribute.""" - - def __init__(self, key: bytes, value: bytes, index: bool): - """Initialise an instance of EventAttribute.""" - self.key = key - self.value = value - self.index = index - - @staticmethod - def encode( - event_attribute_protobuf_object, event_attribute_object: "EventAttribute" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the event_attribute_protobuf_object argument is matched with the instance of this class in the 'event_attribute_object' argument. - - :param event_attribute_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param event_attribute_object: an instance of this class to be encoded in the protocol buffer object. - """ - event_attribute_protobuf_object.key = event_attribute_object.key - event_attribute_protobuf_object.value = event_attribute_object.value - event_attribute_protobuf_object.index = event_attribute_object.index - - @classmethod - def decode(cls, event_attribute_protobuf_object) -> "EventAttribute": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'event_attribute_protobuf_object' argument. - - :param event_attribute_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'event_attribute_protobuf_object' argument. - """ - return EventAttribute( - event_attribute_protobuf_object.key, - event_attribute_protobuf_object.value, - event_attribute_protobuf_object.index, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, EventAttribute) - and self.key == other.key - and self.value == other.value - and self.index == other.index - ) - - -class Event: - """This class represents an instance of Event.""" - - def __init__(self, type_: str, attributes: List[EventAttribute]): - """Initialise an instance of Event.""" - self.type_ = type_ - self.attributes = attributes - - @staticmethod - def encode(event_protobuf_object, event_object: "Event") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the event_protobuf_object argument is matched with the instance of this class in the 'event_object' argument. - - :param event_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param event_object: an instance of this class to be encoded in the protocol buffer object. - """ - event_protobuf_object.type = event_object.type_ - - event_attribute_protobuf_objects = [] - for event_attribute_object in event_object.attributes: - event_attribute_protobuf_object = ( - abci_pb2.AbciMessage.Events.EventAttribute() - ) - EventAttribute.encode( - event_attribute_protobuf_object, event_attribute_object - ) - event_attribute_protobuf_objects.append(event_attribute_protobuf_object) - - event_protobuf_object.attributes.extend(event_attribute_protobuf_objects) - - @classmethod - def decode(cls, event_protobuf_object) -> "Event": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'event_protobuf_object' argument. - - :param event_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'event_protobuf_object' argument. - """ - attributes = [] - for event_attribute_protobuf_object in list(event_protobuf_object.attributes): - attribute = EventAttribute.decode(event_attribute_protobuf_object) - attributes.append(attribute) - return Event(event_protobuf_object.type, attributes) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, Event) - and self.type_ == other.type_ - and self.attributes == other.attributes - ) - - -class Events: - """This class represents an instance of Events.""" - - def __init__(self, events: List[Event]): - """Initialise an instance of Events.""" - self.events = events - - @staticmethod - def encode(events_protobuf_object, events_object: "Events") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the events_protobuf_object argument is matched with the instance of this class in the 'events_object' argument. - - :param events_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param events_object: an instance of this class to be encoded in the protocol buffer object. - """ - event_protobuf_objects = [] - for event_object in events_object.events: - event_protobuf_object = abci_pb2.AbciMessage.Events.Event() - Event.encode(event_protobuf_object, event_object) - event_protobuf_objects.append(event_protobuf_object) - events_protobuf_object.events.extend(event_protobuf_objects) - - @classmethod - def decode(cls, events_protobuf_object) -> "Events": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'events_protobuf_object' argument. - - :param events_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'events_protobuf_object' argument. - """ - event_objects = [] - for event_protobuf_object in list(events_protobuf_object.events): - event_object = Event.decode(event_protobuf_object) - event_objects.append(event_object) - return Events(event_objects) - - def __eq__(self, other): - """Compare with another object.""" - return isinstance(other, Events) and self.events == other.events - - -class EvidenceType(Enum): - """This class represent an instance of EvidenceType.""" - - UNKNOWN = 0 - DUPLICATE_VOTE = 1 - LIGHT_CLIENT_ATTACK = 2 - - -class Evidence: - """This class represent an instance of Evidence.""" - - def __init__( - self, - evidence_type: EvidenceType, - validator: "Validator", - height: int, - time: "Timestamp", - total_voting_power: int, - ): - """Initialise an instance of Evidences.""" - self.evidence_type = evidence_type - self.validator = validator - self.height = height - self.time = time - self.total_voting_power = total_voting_power - - @staticmethod - def encode(evidence_protobuf_object, evidence_object: "Evidence") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the evidence_protobuf_object argument is matched with the instance of this class in the 'evidence_object' argument. - - :param evidence_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param evidence_object: an instance of this class to be encoded in the protocol buffer object. - """ - evidence_protobuf_object.type = evidence_object.evidence_type.value - - validator_protobuf_object = abci_pb2.AbciMessage.LastCommitInfo.Validator() - Validator.encode(validator_protobuf_object, evidence_object.validator) - evidence_protobuf_object.validator.CopyFrom(validator_protobuf_object) - - evidence_protobuf_object.height = evidence_object.height - - timestamp_protobuf_object = abci_pb2.AbciMessage.Timestamp() - Timestamp.encode(timestamp_protobuf_object, evidence_object.time) - evidence_protobuf_object.time.CopyFrom(timestamp_protobuf_object) - - evidence_protobuf_object.total_voting_power = evidence_object.total_voting_power - - @classmethod - def decode(cls, evidence_protobuf_object) -> "Evidence": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'evidence_protobuf_object' argument. - - :param evidence_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'evidence_protobuf_object' argument. - """ - evidence_type = EvidenceType(evidence_protobuf_object.type) - validator = Validator.decode(evidence_protobuf_object.validator) - height = evidence_protobuf_object.height - time = Timestamp.decode(evidence_protobuf_object.time) - total_voting_power = evidence_protobuf_object.total_voting_power - return Evidence(evidence_type, validator, height, time, total_voting_power) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, Evidence) - and self.evidence_type == other.evidence_type - and self.validator == other.validator - and self.height == other.height - and self.time == other.time - and self.total_voting_power == other.total_voting_power - ) - - -class Evidences: - """This class represents an instance of Evidences.""" - - def __init__(self, byzantine_validators: List[Evidence]): - """Initialise an instance of Evidences.""" - self.byzantine_validators = byzantine_validators - - @staticmethod - def encode(evidences_protobuf_object, evidences_object: "Evidences") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the evidences_protobuf_object argument is matched with the instance of this class in the 'evidences_object' argument. - - :param evidences_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param evidences_object: an instance of this class to be encoded in the protocol buffer object. - """ - validators_protobuf_objects = [] - for validator in evidences_object.byzantine_validators: - evidence_protobuf_object = abci_pb2.AbciMessage.Evidences.Evidence() - Evidence.encode(evidence_protobuf_object, validator) - validators_protobuf_objects.append(evidence_protobuf_object) - evidences_protobuf_object.byzantine_validators.extend( - validators_protobuf_objects - ) - - @classmethod - def decode(cls, evidences_protobuf_object) -> "Evidences": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'evidences_protobuf_object' argument. - - :param evidences_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'evidences_protobuf_object' argument. - """ - validator_objects = [] - for validator_protobuf_object in list( - evidences_protobuf_object.byzantine_validators - ): - validator_object = Evidence.decode(validator_protobuf_object) - validator_objects.append(validator_object) - return Evidences(validator_objects) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, Evidences) - and self.byzantine_validators == other.byzantine_validators - ) - - -class CheckTxTypeEnum(Enum): - """CheckTxTypeEnum for tx check.""" - - NEW = 0 - RECHECK = 1 - - -class CheckTxType: - """This class represents an instance of CheckTxType.""" - - def __init__(self, check_tx_type: CheckTxTypeEnum): - """Initialise an instance of CheckTxType.""" - self.check_tx_type = check_tx_type - - @staticmethod - def encode( - check_tx_type_protobuf_object, check_tx_type_object: "CheckTxType" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the check_tx_type_protobuf_object argument is matched with the instance of this class in the 'check_tx_type_object' argument. - - :param check_tx_type_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param check_tx_type_object: an instance of this class to be encoded in the protocol buffer object. - """ - check_tx_type_protobuf_object.type = check_tx_type_object.check_tx_type.value - - @classmethod - def decode(cls, check_tx_type_protobuf_object) -> "CheckTxType": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'check_tx_type_protobuf_object' argument. - - :param check_tx_type_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'check_tx_type_protobuf_object' argument. - """ - return CheckTxType(CheckTxTypeEnum(check_tx_type_protobuf_object.type)) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, CheckTxType) and self.check_tx_type == other.check_tx_type - ) - - -class ConsensusVersion: - """This class represents an instance of ConsensusVersion.""" - - def __init__(self, block: int, app: int): - """Initialise an instance of ConsensusVersion.""" - self.block = block - self.app = app - - @staticmethod - def encode( - consensus_version_protobuf_object, consensus_version_object: "ConsensusVersion" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the consensus_version_protobuf_object argument is matched with the instance of this class in the 'consensus_version_object' argument. - - :param consensus_version_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param consensus_version_object: an instance of this class to be encoded in the protocol buffer object. - """ - consensus_version_protobuf_object.block = consensus_version_object.block - consensus_version_protobuf_object.app = consensus_version_object.app - - @classmethod - def decode(cls, consensus_version_protobuf_object) -> "ConsensusVersion": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'consensus_version_protobuf_object' argument. - - :param consensus_version_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'consensus_version_protobuf_object' argument. - """ - return ConsensusVersion( - consensus_version_protobuf_object.block, - consensus_version_protobuf_object.app, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, ConsensusVersion) - and self.block == other.block - and self.app == other.app - ) - - -class PartSetHeader: - """This class represents an instance of PartSetHeader.""" - - def __init__(self, total: int, hash_: bytes): - """Initialise an instance of PartSetHeader.""" - self.total = total - self.hash_ = hash_ - - @staticmethod - def encode( - part_set_header_protobuf_object, part_set_header_object: "PartSetHeader" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the part_set_header_protobuf_object argument is matched with the instance of this class in the 'part_set_header_object' argument. - - :param part_set_header_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param part_set_header_object: an instance of this class to be encoded in the protocol buffer object. - """ - part_set_header_protobuf_object.total = part_set_header_object.total - part_set_header_protobuf_object.hash = part_set_header_object.hash_ - - @classmethod - def decode(cls, part_set_header_protobuf_object) -> "PartSetHeader": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'part_set_header_protobuf_object' argument. - - :param part_set_header_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'part_set_header_protobuf_object' argument. - """ - return PartSetHeader( - part_set_header_protobuf_object.total, - part_set_header_protobuf_object.hash, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, PartSetHeader) - and self.total == other.total - and self.hash_ == other.hash_ - ) - - -class BlockID: - """This class represents an instance of BlockID.""" - - def __init__(self, hash_: bytes, part_set_header: PartSetHeader): - """Initialise an instance of BlockID.""" - self.hash_ = hash_ - self.part_set_header = part_set_header - - @staticmethod - def encode(block_id_protobuf_object, block_id_object: "BlockID") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the block_id_protobuf_object argument is matched with the instance of this class in the 'block_id_object' argument. - - :param block_id_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param block_id_object: an instance of this class to be encoded in the protocol buffer object. - """ - block_id_protobuf_object.hash = block_id_object.hash_ - part_set_header_protobuf_object = abci_pb2.AbciMessage.Header.PartSetHeader() - PartSetHeader.encode( - part_set_header_protobuf_object, block_id_object.part_set_header - ) - block_id_protobuf_object.part_set_header.CopyFrom( - part_set_header_protobuf_object - ) - - @classmethod - def decode(cls, block_id_protobuf_object) -> "BlockID": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'block_id_protobuf_object' argument. - - :param block_id_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'block_id_protobuf_object' argument. - """ - part_set_header = PartSetHeader.decode(block_id_protobuf_object.part_set_header) - return BlockID( - block_id_protobuf_object.hash, - part_set_header, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, BlockID) - and self.hash_ == other.hash_ - and self.part_set_header == other.part_set_header - ) - - -class Header: # pylint: disable=too-many-instance-attributes - """This class represents an instance of Header.""" - - def __init__( # pylint: disable=too-many-arguments - self, - version: ConsensusVersion, - chain_id: str, - height: int, - time: "Timestamp", - last_block_id: BlockID, - last_commit_hash: bytes, - data_hash: bytes, - validators_hash: bytes, - next_validators_hash: bytes, - consensus_hash: bytes, - app_hash: bytes, - last_results_hash: bytes, - evidence_hash: bytes, - proposer_address: bytes, - ): - """Initialise an instance of Header.""" - self.version = version - self.chain_id = chain_id - self.height = height - self.time = time - self.last_block_id = last_block_id - self.last_commit_hash = last_commit_hash - self.data_hash = data_hash - self.validators_hash = validators_hash - self.next_validators_hash = next_validators_hash - self.consensus_hash = consensus_hash - self.app_hash = app_hash - self.last_results_hash = last_results_hash - self.evidence_hash = evidence_hash - self.proposer_address = proposer_address - - @property - def timestamp(self) -> datetime.datetime: - """Get the block timestamp.""" - timestamp: Timestamp = self.time - nanoseconds = timestamp.nanos / 10**9 - seconds = timestamp.seconds - return datetime.datetime.fromtimestamp(seconds + nanoseconds) - - @staticmethod - def encode(header_protobuf_object, header_object: "Header") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the header_protobuf_object argument is matched with the instance of this class in the 'header_object' argument. - - :param header_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param header_object: an instance of this class to be encoded in the protocol buffer object. - """ - consensus_version_protobuf_obj = abci_pb2.AbciMessage.Header.ConsensusVersion() - ConsensusVersion.encode(consensus_version_protobuf_obj, header_object.version) - header_protobuf_object.version.CopyFrom(consensus_version_protobuf_obj) - - header_protobuf_object.chain_id = header_object.chain_id - header_protobuf_object.height = header_object.height - - timestamp_protobuf_obj = abci_pb2.AbciMessage.Timestamp() - Timestamp.encode(timestamp_protobuf_obj, header_object.time) - header_protobuf_object.time.CopyFrom(timestamp_protobuf_obj) - - last_block_id_protobuf_obj = abci_pb2.AbciMessage.Header.BlockID() - BlockID.encode(last_block_id_protobuf_obj, header_object.last_block_id) - header_protobuf_object.last_block_id.CopyFrom(last_block_id_protobuf_obj) - - header_protobuf_object.last_commit_hash = header_object.last_commit_hash - header_protobuf_object.data_hash = header_object.data_hash - header_protobuf_object.validators_hash = header_object.validators_hash - header_protobuf_object.next_validators_hash = header_object.next_validators_hash - header_protobuf_object.consensus_hash = header_object.consensus_hash - header_protobuf_object.app_hash = header_object.app_hash - header_protobuf_object.last_results_hash = header_object.last_results_hash - header_protobuf_object.evidence_hash = header_object.evidence_hash - header_protobuf_object.proposer_address = header_object.proposer_address - - @classmethod - def decode( # pylint: disable=too-many-locals - cls, header_protobuf_object - ) -> "Header": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'header_protobuf_object' argument. - - :param header_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'header_protobuf_object' argument. - """ - consensus_version_obj = ConsensusVersion.decode(header_protobuf_object.version) - chain_id = header_protobuf_object.chain_id - height = header_protobuf_object.height - time = Timestamp.decode(header_protobuf_object.time) - - last_block_id = BlockID.decode(header_protobuf_object.last_block_id) - - last_commit_hash = header_protobuf_object.last_commit_hash - data_hash = header_protobuf_object.data_hash - validators_hash = header_protobuf_object.validators_hash - next_validators_hash = header_protobuf_object.next_validators_hash - consensus_hash = header_protobuf_object.consensus_hash - app_hash = header_protobuf_object.app_hash - last_results_hash = header_protobuf_object.last_results_hash - evidence_hash = header_protobuf_object.evidence_hash - proposer_address = header_protobuf_object.proposer_address - return Header( - consensus_version_obj, - chain_id, - height, - time, - last_block_id, - last_commit_hash, - data_hash, - validators_hash, - next_validators_hash, - consensus_hash, - app_hash, - last_results_hash, - evidence_hash, - proposer_address, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, Header) - and self.version == other.version - and self.chain_id == other.chain_id - and self.height == other.height - and self.time == other.time - and self.last_block_id == other.last_block_id - and self.last_commit_hash == other.last_commit_hash - and self.data_hash == other.data_hash - and self.validators_hash == other.validators_hash - and self.next_validators_hash == other.next_validators_hash - and self.consensus_hash == other.consensus_hash - and self.app_hash == other.app_hash - and self.last_results_hash == other.last_results_hash - and self.evidence_hash == other.evidence_hash - and self.proposer_address == other.proposer_address - ) - - -class Validator: - """This class represents an instance of Validator.""" - - def __init__(self, address: bytes, power: int): - """Initialise an instance of Validator.""" - self.address = address - self.power = power - - @staticmethod - def encode(validator_protobuf_object, validator_object: "Validator") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the validator_protobuf_object argument is matched with the instance of this class in the 'validator_object' argument. - - :param validator_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param validator_object: an instance of this class to be encoded in the protocol buffer object. - """ - validator_protobuf_object.address = validator_object.address - validator_protobuf_object.power = validator_object.power - - @classmethod - def decode(cls, validator_protobuf_object) -> "Validator": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'validator_protobuf_object' argument. - - :param validator_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'validator_protobuf_object' argument. - """ - return Validator( - validator_protobuf_object.address, - validator_protobuf_object.power, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, Validator) - and self.address == other.address - and self.power == other.power - ) - - -class VoteInfo: - """This class represents an instance of VoteInfo.""" - - def __init__(self, validator: Validator, signed_last_block: bool): - """Initialise an instance of Validator.""" - self.validator = validator - self.signed_last_block = signed_last_block - - @staticmethod - def encode(vote_info_protobuf_object, vote_info_object: "VoteInfo") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the vote_info_protobuf_object argument is matched with the instance of this class in the 'vote_info_object' argument. - - :param vote_info_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param vote_info_object: an instance of this class to be encoded in the protocol buffer object. - """ - validator_protobuf_object = abci_pb2.AbciMessage.LastCommitInfo.Validator() - Validator.encode(validator_protobuf_object, vote_info_object.validator) - vote_info_protobuf_object.validator.CopyFrom(validator_protobuf_object) - - vote_info_protobuf_object.signed_last_block = vote_info_object.signed_last_block - - @classmethod - def decode(cls, vote_info_protobuf_object) -> "VoteInfo": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'vote_info_protobuf_object' argument. - - :param vote_info_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'vote_info_protobuf_object' argument. - """ - validator = Validator.decode(vote_info_protobuf_object.validator) - return VoteInfo( - validator, - vote_info_protobuf_object.signed_last_block, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, VoteInfo) - and self.validator == other.validator - and self.signed_last_block == other.signed_last_block - ) - - -class LastCommitInfo: - """This class represents an instance of LastCommitInfo.""" - - def __init__(self, round_: int, votes: List[VoteInfo]): - """Initialise an instance of LastCommitInfo.""" - self.round_ = round_ - self.votes = votes - - @staticmethod - def encode( - last_commit_info_protobuf_object, last_commit_info_object: "LastCommitInfo" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the last_commit_info_protobuf_object argument is matched with the instance of this class in the 'last_commit_info_object' argument. - - :param last_commit_info_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param last_commit_info_object: an instance of this class to be encoded in the protocol buffer object. - """ - last_commit_info_protobuf_object.round = last_commit_info_object.round_ - - votes_protobuf_objects = [] - for vote_info in last_commit_info_object.votes: - vote_info_protobuf_object = abci_pb2.AbciMessage.LastCommitInfo.VoteInfo() - VoteInfo.encode(vote_info_protobuf_object, vote_info) - votes_protobuf_objects.append(vote_info_protobuf_object) - last_commit_info_protobuf_object.votes.extend(votes_protobuf_objects) - - @classmethod - def decode(cls, last_commit_info_protobuf_object) -> "LastCommitInfo": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'last_commit_info_protobuf_object' argument. - - :param last_commit_info_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'last_commit_info_protobuf_object' argument. - """ - vote_info_objects = [] - for vote_info_protobuf_object in list(last_commit_info_protobuf_object.votes): - vote_info = VoteInfo.decode(vote_info_protobuf_object) - vote_info_objects.append(vote_info) - - return LastCommitInfo(last_commit_info_protobuf_object.round, vote_info_objects) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, LastCommitInfo) - and self.round_ == other.round_ - and self.votes == other.votes - ) - - -class ProofOp: - """This class represents an instance of ProofOp.""" - - def __init__(self, type_: str, key: bytes, data: bytes): - """ - Initialise an instance of ProofOp. - - ProofOp defines an operation used for calculating Merkle root - The data could be arbitrary format, providing necessary data - for example neighbouring node hash. - - :param type_: the type - :param key: the key - :param data: the data - """ - self.type_ = type_ - self.key = key - self.data = data - - @staticmethod - def encode(proof_op_protobuf_object, proof_op_object: "ProofOp") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the proof_op_protobuf_object argument is matched with the instance of this class in the 'proof_op_object' argument. - - :param proof_op_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param proof_op_object: an instance of this class to be encoded in the protocol buffer object. - """ - proof_op_protobuf_object.type = proof_op_object.type_ - proof_op_protobuf_object.key = proof_op_object.key - proof_op_protobuf_object.data = proof_op_object.data - - @classmethod - def decode(cls, proof_op_protobuf_object) -> "ProofOp": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'proof_op_protobuf_object' argument. - - :param proof_op_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'proof_op_protobuf_object' argument. - """ - return ProofOp( - proof_op_protobuf_object.type, - proof_op_protobuf_object.key, - proof_op_protobuf_object.data, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, ProofOp) - and self.type_ == other.type_ - and self.key == other.key - and self.data == other.data - ) - - -class ProofOps: - """This class represents an instance of ProofOps.""" - - def __init__(self, proof_ops: List[ProofOp]): - """ - Initialise an instance of ProofOps. - - :param proof_ops: a list of ProofOp instances. - """ - self.proof_ops = proof_ops - - @staticmethod - def encode(proof_ops_protobuf_object, proof_ops_object: "ProofOps") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the proof_ops_protobuf_object argument is matched with the instance of this class in the 'proof_ops_object' argument. - - :param proof_ops_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param proof_ops_object: an instance of this class to be encoded in the protocol buffer object. - """ - proof_ops_protobuf_objects = [] - for proof_op in proof_ops_object.proof_ops: - proof_op_protobuf_object = abci_pb2.AbciMessage.ProofOps.ProofOp() - ProofOp.encode(proof_op_protobuf_object, proof_op) - proof_ops_protobuf_objects.append(proof_op_protobuf_object) - proof_ops_protobuf_object.ops.extend(proof_ops_protobuf_objects) - - @classmethod - def decode(cls, proof_ops_protobuf_object) -> "ProofOps": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'proof_ops_protobuf_object' argument. - - :param proof_ops_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'proof_ops_protobuf_object' argument. - """ - proof_ops_objects = [] - for proof_op_protobuf_object in list(proof_ops_protobuf_object.ops): - proof_ops_objects.append(ProofOp.decode(proof_op_protobuf_object)) - return ProofOps(proof_ops_objects) - - def __eq__(self, other): - """Compare with another object.""" - return isinstance(other, ProofOps) and self.proof_ops == other.proof_ops - - -class ResultType(Enum): - """This class represents an instance of ResultType.""" - - UNKNOWN = 0 # Unknown result, abort all snapshot restoration - ACCEPT = 1 # Snapshot accepted, apply chunks - ABORT = 2 # Abort all snapshot restoration - REJECT = 3 # Reject this specific snapshot, try others - REJECT_FORMAT = 4 # Reject all snapshots of this format, try others - REJECT_SENDER = 5 # Reject all snapshots from the sender(s), try others - - -class Result: - """This class represents an instance of Result.""" - - def __init__(self, result_type: ResultType): - """Initialise an instance of Result.""" - self.result_type = result_type - - @staticmethod - def encode(result_protobuf_object, result_object: "Result") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the result_protobuf_object argument is matched with the instance of this class in the 'result_object' argument. - - :param result_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param result_object: an instance of this class to be encoded in the protocol buffer object. - """ - result_protobuf_object.result_type = result_object.result_type.value - - @classmethod - def decode(cls, result_protobuf_object) -> "Result": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'result_protobuf_object' argument. - - :param result_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'result_protobuf_object' argument. - """ - return Result(ResultType(result_protobuf_object.result_type)) - - def __eq__(self, other): - """Compare with another object.""" - return isinstance(other, Result) and self.result_type == other.result_type - - -class Snapshot: - """This class represents an instance of Snapshot.""" - - def __init__( - self, height: int, format_: int, chunks: int, hash_: bytes, metadata: bytes - ): - """Initialise an instance of Snapshot.""" - self.height = height - self.format_ = format_ - self.chunks = chunks - self.hash_ = hash_ - self.metadata = metadata - - @staticmethod - def encode(snapshot_protobuf_object, snapshot_object: "Snapshot") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the snapshot_protobuf_object argument is matched with the instance of this class in the 'snapshot_object' argument. - - :param snapshot_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param snapshot_object: an instance of this class to be encoded in the protocol buffer object. - """ - snapshot_protobuf_object.height = snapshot_object.height - snapshot_protobuf_object.format = snapshot_object.format_ - snapshot_protobuf_object.chunks = snapshot_object.chunks - snapshot_protobuf_object.hash = snapshot_object.hash_ - snapshot_protobuf_object.metadata = snapshot_object.metadata - - @classmethod - def decode(cls, snapshot_protobuf_object) -> "Snapshot": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'snapshot_protobuf_object' argument. - - :param snapshot_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'snapshot_protobuf_object' argument. - """ - return Snapshot( - snapshot_protobuf_object.height, - snapshot_protobuf_object.format, - snapshot_protobuf_object.chunks, - snapshot_protobuf_object.hash, - snapshot_protobuf_object.metadata, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, Snapshot) - and self.height == other.height - and self.format_ == other.format_ - and self.chunks == other.chunks - and self.hash_ == other.hash_ - and self.metadata == other.metadata - ) - - -class SnapShots: - """This class represents an instance of SnapShots.""" - - def __init__(self, snapshots: List[Snapshot]): - """Initialise an instance of SnapShots.""" - self.snapshots = snapshots - - @staticmethod - def encode(snapshots_protobuf_object, snapshots_object: "SnapShots") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the snapshots_protobuf_object argument is matched with the instance of this class in the 'snapshots_object' argument. - - :param snapshots_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param snapshots_object: an instance of this class to be encoded in the protocol buffer object. - """ - snapshot_protobuf_objects = [] - for snapshot_object in snapshots_object.snapshots: - snapshot_protobuf_object = abci_pb2.AbciMessage.Snapshot() - Snapshot.encode(snapshot_protobuf_object, snapshot_object) - snapshot_protobuf_objects.append(snapshot_protobuf_object) - snapshots_protobuf_object.snapshots.extend(snapshot_protobuf_objects) - - @classmethod - def decode(cls, snapshots_protobuf_object) -> "SnapShots": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'snapshots_protobuf_object' argument. - - :param snapshots_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'snapshots_protobuf_object' argument. - """ - snapshot_objects = [] - for snapshot_protobuf_object in list(snapshots_protobuf_object.snapshots): - snapshot_objects.append(Snapshot.decode(snapshot_protobuf_object)) - return SnapShots(snapshot_objects) - - def __eq__(self, other): - """Compare with another object.""" - return isinstance(other, SnapShots) and self.snapshots == other.snapshots - - -class Timestamp: - """This class represents an instance of Timestamp.""" - - __slots__ = ["seconds", "nanos"] - - def __init__(self, seconds: int, nanos: int): - """ - Initialise an instance of Timestamp. - - :param seconds: Represents seconds of UTC time since Unix epoch - 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - 9999-12-31T23:59:59Z inclusive. - :param nanos: Non-negative fractions of a second at nanosecond resolution. - Negative second values with fractions must still have non-negative nanos values - that count forward in time. Must be from 0 to 999,999,999 inclusive. - """ - self.seconds = seconds - self.nanos = nanos - enforce( - 0 <= nanos < 10**9, - "nanos argument must be from 0 to 999,999,999 inclusive", - exception_class=ValueError, - ) - - @staticmethod - def encode(timestamp_protobuf_object, timestamp_object: "Timestamp") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the timestamp_protobuf_object argument is matched with the instance of this class in the 'timestamp_object' argument. - - :param timestamp_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param timestamp_object: an instance of this class to be encoded in the protocol buffer object. - """ - timestamp_protobuf_object.seconds = timestamp_object.seconds - timestamp_protobuf_object.nanos = timestamp_object.nanos - - @classmethod - def decode(cls, timestamp_protobuf_object) -> "Timestamp": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'timestamp_protobuf_object' argument. - - :param timestamp_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'timestamp_protobuf_object' argument. - """ - return Timestamp( - timestamp_protobuf_object.seconds, timestamp_protobuf_object.nanos - ) - - def __eq__(self, other) -> bool: - """Compare with another object.""" - return ( - isinstance(other, Timestamp) - and self.seconds == other.seconds - and self.nanos == other.nanos - ) - - -class PublicKey: - """This class represents an instance of PublicKey.""" - - class PublicKeyType(Enum): - """Enumeration of public key types supported by Tendermint.""" - - ed25519 = "ed25519" - secp256k1 = "secp256k1" - - def __init__(self, data: bytes, key_type: PublicKeyType) -> None: - """ - Initialize the public key object. - - :param data: the data of the public key. - :param key_type: the type of the public key. - """ - self.data = data - self.key_type = key_type - - @staticmethod - def encode(public_key_protobuf_object, public_key_object: "PublicKey") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the public_key_protobuf_object argument is matched with the instance of this class in the 'public_key_object' argument. - - :param public_key_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param public_key_object: an instance of this class to be encoded in the protocol buffer object. - """ - key_type_name = public_key_object.key_type.value - setattr(public_key_protobuf_object, key_type_name, public_key_object.data) - - @classmethod - def decode(cls, public_key_protobuf_object) -> "PublicKey": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'public_key_protobuf_object' argument. - - :param public_key_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'public_key_protobuf_object' argument. - """ - key_type_name = public_key_protobuf_object.WhichOneof("sum") - key_type = PublicKey.PublicKeyType(key_type_name) - data = getattr(public_key_protobuf_object, key_type_name) - return PublicKey(data, key_type) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, PublicKey) - and self.data == other.data - and self.key_type == other.key_type - ) - - -class ValidatorUpdate: - """This class represents an instance of ValidatorUpdate.""" - - def __init__(self, pub_key: PublicKey, power: int): - """Initialise an instance of ValidatorUpdate.""" - self.pub_key = pub_key - self.power = power - - @staticmethod - def encode( - validator_update_protobuf_object, validator_update_object: "ValidatorUpdate" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the validator_update_protobuf_object argument is matched with the instance of this class in the 'validator_update_object' argument. - - :param validator_update_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param validator_update_object: an instance of this class to be encoded in the protocol buffer object. - """ - PublicKey.encode( - validator_update_protobuf_object.pub_key, validator_update_object.pub_key - ) - validator_update_protobuf_object.power = validator_update_object.power - - @classmethod - def decode(cls, validator_update_protobuf_object) -> "ValidatorUpdate": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'validator_update_protobuf_object' argument. - - :param validator_update_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'validator_update_protobuf_object' argument. - """ - pub_key = PublicKey.decode(validator_update_protobuf_object.pub_key) - return ValidatorUpdate( - pub_key, - validator_update_protobuf_object.power, - ) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, ValidatorUpdate) - and self.pub_key == other.pub_key - and self.power == other.power - ) - - -class ValidatorUpdates: - """This class represents an instance of ValidatorUpdates.""" - - def __init__(self, validator_updates: List[ValidatorUpdate]): - """Initialise an instance of ValidatorUpdates.""" - self.validator_updates = validator_updates - - @staticmethod - def encode( - validator_updates_protobuf_object, validator_updates_object: "ValidatorUpdates" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the validator_updates_protobuf_object argument is matched with the instance of this class in the 'validator_updates_object' argument. - - :param validator_updates_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param validator_updates_object: an instance of this class to be encoded in the protocol buffer object. - """ - validator_updates = [] - for validator_update_object in validator_updates_object.validator_updates: - validator_update_protobuf_object = ( - abci_pb2.AbciMessage.ValidatorUpdates.ValidatorUpdate() - ) - ValidatorUpdate.encode( - validator_update_protobuf_object, validator_update_object - ) - validator_updates.append(validator_update_protobuf_object) - validator_updates_protobuf_object.validators.extend(validator_updates) - - @classmethod - def decode(cls, validator_updates_protobuf_object) -> "ValidatorUpdates": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'validator_updates_protobuf_object' argument. - - :param validator_updates_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'validator_updates_protobuf_object' argument. - """ - validator_updates_objects = [] - validator_updates_protobuf_objects = list( - validator_updates_protobuf_object.validators - ) - for validator_update_protobuf_object in validator_updates_protobuf_objects: - validator_update = ValidatorUpdate.decode(validator_update_protobuf_object) - validator_updates_objects.append(validator_update) - return ValidatorUpdates(validator_updates_objects) - - def __eq__(self, other): - """Compare with another object.""" - return ( - isinstance(other, ValidatorUpdates) - and self.validator_updates == other.validator_updates - ) diff --git a/trader_old/vendor/valory/protocols/abci/dialogues.py b/trader_old/vendor/valory/protocols/abci/dialogues.py deleted file mode 100644 index 3126eef85..000000000 --- a/trader_old/vendor/valory/protocols/abci/dialogues.py +++ /dev/null @@ -1,253 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for abci dialogue management. - -- AbciDialogue: The dialogue class maintains state of a dialogue and manages it. -- AbciDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.abci.message import AbciMessage - - -class AbciDialogue(Dialogue): - """The abci dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - AbciMessage.Performative.REQUEST_ECHO, - AbciMessage.Performative.REQUEST_FLUSH, - AbciMessage.Performative.REQUEST_INFO, - AbciMessage.Performative.REQUEST_SET_OPTION, - AbciMessage.Performative.REQUEST_INIT_CHAIN, - AbciMessage.Performative.REQUEST_QUERY, - AbciMessage.Performative.REQUEST_BEGIN_BLOCK, - AbciMessage.Performative.REQUEST_CHECK_TX, - AbciMessage.Performative.REQUEST_DELIVER_TX, - AbciMessage.Performative.REQUEST_END_BLOCK, - AbciMessage.Performative.REQUEST_COMMIT, - AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS, - AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT, - AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK, - AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK, - AbciMessage.Performative.DUMMY, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - AbciMessage.Performative.RESPONSE_EXCEPTION, - AbciMessage.Performative.RESPONSE_ECHO, - AbciMessage.Performative.RESPONSE_FLUSH, - AbciMessage.Performative.RESPONSE_INFO, - AbciMessage.Performative.RESPONSE_SET_OPTION, - AbciMessage.Performative.RESPONSE_INIT_CHAIN, - AbciMessage.Performative.RESPONSE_QUERY, - AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, - AbciMessage.Performative.RESPONSE_CHECK_TX, - AbciMessage.Performative.RESPONSE_DELIVER_TX, - AbciMessage.Performative.RESPONSE_END_BLOCK, - AbciMessage.Performative.RESPONSE_COMMIT, - AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, - AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, - AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, - AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, - AbciMessage.Performative.DUMMY, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - AbciMessage.Performative.DUMMY: frozenset(), - AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK: frozenset( - { - AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_BEGIN_BLOCK: frozenset( - { - AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_CHECK_TX: frozenset( - { - AbciMessage.Performative.RESPONSE_CHECK_TX, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_COMMIT: frozenset( - { - AbciMessage.Performative.RESPONSE_COMMIT, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_DELIVER_TX: frozenset( - { - AbciMessage.Performative.RESPONSE_DELIVER_TX, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_ECHO: frozenset( - { - AbciMessage.Performative.RESPONSE_ECHO, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_END_BLOCK: frozenset( - { - AbciMessage.Performative.RESPONSE_END_BLOCK, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_FLUSH: frozenset( - { - AbciMessage.Performative.RESPONSE_FLUSH, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_INFO: frozenset( - { - AbciMessage.Performative.RESPONSE_INFO, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_INIT_CHAIN: frozenset( - { - AbciMessage.Performative.RESPONSE_INIT_CHAIN, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS: frozenset( - { - AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK: frozenset( - { - AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT: frozenset( - { - AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_QUERY: frozenset( - { - AbciMessage.Performative.RESPONSE_QUERY, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.REQUEST_SET_OPTION: frozenset( - { - AbciMessage.Performative.RESPONSE_SET_OPTION, - AbciMessage.Performative.RESPONSE_EXCEPTION, - } - ), - AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK: frozenset(), - AbciMessage.Performative.RESPONSE_BEGIN_BLOCK: frozenset(), - AbciMessage.Performative.RESPONSE_CHECK_TX: frozenset(), - AbciMessage.Performative.RESPONSE_COMMIT: frozenset(), - AbciMessage.Performative.RESPONSE_DELIVER_TX: frozenset(), - AbciMessage.Performative.RESPONSE_ECHO: frozenset(), - AbciMessage.Performative.RESPONSE_END_BLOCK: frozenset(), - AbciMessage.Performative.RESPONSE_EXCEPTION: frozenset(), - AbciMessage.Performative.RESPONSE_FLUSH: frozenset(), - AbciMessage.Performative.RESPONSE_INFO: frozenset(), - AbciMessage.Performative.RESPONSE_INIT_CHAIN: frozenset(), - AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS: frozenset(), - AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK: frozenset(), - AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT: frozenset(), - AbciMessage.Performative.RESPONSE_QUERY: frozenset(), - AbciMessage.Performative.RESPONSE_SET_OPTION: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a abci dialogue.""" - - CLIENT = "client" - SERVER = "server" - - class EndState(Dialogue.EndState): - """This class defines the end states of a abci dialogue.""" - - SUCCESSFUL = 0 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[AbciMessage] = AbciMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class AbciDialogues(Dialogues, ABC): - """This class keeps track of all abci dialogues.""" - - END_STATES = frozenset({AbciDialogue.EndState.SUCCESSFUL}) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[AbciDialogue] = AbciDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=AbciMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_old/vendor/valory/protocols/abci/message.py b/trader_old/vendor/valory/protocols/abci/message.py deleted file mode 100644 index 7d0237d8b..000000000 --- a/trader_old/vendor/valory/protocols/abci/message.py +++ /dev/null @@ -1,1273 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 abci's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Optional, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - -from packages.valory.protocols.abci.custom_types import CheckTxType as CustomCheckTxType -from packages.valory.protocols.abci.custom_types import ( - ConsensusParams as CustomConsensusParams, -) -from packages.valory.protocols.abci.custom_types import Events as CustomEvents -from packages.valory.protocols.abci.custom_types import Evidences as CustomEvidences -from packages.valory.protocols.abci.custom_types import Header as CustomHeader -from packages.valory.protocols.abci.custom_types import ( - LastCommitInfo as CustomLastCommitInfo, -) -from packages.valory.protocols.abci.custom_types import ProofOps as CustomProofOps -from packages.valory.protocols.abci.custom_types import Result as CustomResult -from packages.valory.protocols.abci.custom_types import SnapShots as CustomSnapShots -from packages.valory.protocols.abci.custom_types import Snapshot as CustomSnapshot -from packages.valory.protocols.abci.custom_types import Timestamp as CustomTimestamp -from packages.valory.protocols.abci.custom_types import ( - ValidatorUpdates as CustomValidatorUpdates, -) - - -_default_logger = logging.getLogger("aea.packages.valory.protocols.abci.message") - -DEFAULT_BODY_SIZE = 4 - - -class AbciMessage(Message): - """A protocol for ABCI requests and responses.""" - - protocol_id = PublicId.from_str("valory/abci:0.1.0") - protocol_specification_id = PublicId.from_str("valory/abci:0.1.0") - - CheckTxType = CustomCheckTxType - - ConsensusParams = CustomConsensusParams - - Events = CustomEvents - - Evidences = CustomEvidences - - Header = CustomHeader - - LastCommitInfo = CustomLastCommitInfo - - ProofOps = CustomProofOps - - Result = CustomResult - - SnapShots = CustomSnapShots - - Snapshot = CustomSnapshot - - Timestamp = CustomTimestamp - - ValidatorUpdates = CustomValidatorUpdates - - class Performative(Message.Performative): - """Performatives for the abci protocol.""" - - DUMMY = "dummy" - REQUEST_APPLY_SNAPSHOT_CHUNK = "request_apply_snapshot_chunk" - REQUEST_BEGIN_BLOCK = "request_begin_block" - REQUEST_CHECK_TX = "request_check_tx" - REQUEST_COMMIT = "request_commit" - REQUEST_DELIVER_TX = "request_deliver_tx" - REQUEST_ECHO = "request_echo" - REQUEST_END_BLOCK = "request_end_block" - REQUEST_FLUSH = "request_flush" - REQUEST_INFO = "request_info" - REQUEST_INIT_CHAIN = "request_init_chain" - REQUEST_LIST_SNAPSHOTS = "request_list_snapshots" - REQUEST_LOAD_SNAPSHOT_CHUNK = "request_load_snapshot_chunk" - REQUEST_OFFER_SNAPSHOT = "request_offer_snapshot" - REQUEST_QUERY = "request_query" - REQUEST_SET_OPTION = "request_set_option" - RESPONSE_APPLY_SNAPSHOT_CHUNK = "response_apply_snapshot_chunk" - RESPONSE_BEGIN_BLOCK = "response_begin_block" - RESPONSE_CHECK_TX = "response_check_tx" - RESPONSE_COMMIT = "response_commit" - RESPONSE_DELIVER_TX = "response_deliver_tx" - RESPONSE_ECHO = "response_echo" - RESPONSE_END_BLOCK = "response_end_block" - RESPONSE_EXCEPTION = "response_exception" - RESPONSE_FLUSH = "response_flush" - RESPONSE_INFO = "response_info" - RESPONSE_INIT_CHAIN = "response_init_chain" - RESPONSE_LIST_SNAPSHOTS = "response_list_snapshots" - RESPONSE_LOAD_SNAPSHOT_CHUNK = "response_load_snapshot_chunk" - RESPONSE_OFFER_SNAPSHOT = "response_offer_snapshot" - RESPONSE_QUERY = "response_query" - RESPONSE_SET_OPTION = "response_set_option" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = { - "dummy", - "request_apply_snapshot_chunk", - "request_begin_block", - "request_check_tx", - "request_commit", - "request_deliver_tx", - "request_echo", - "request_end_block", - "request_flush", - "request_info", - "request_init_chain", - "request_list_snapshots", - "request_load_snapshot_chunk", - "request_offer_snapshot", - "request_query", - "request_set_option", - "response_apply_snapshot_chunk", - "response_begin_block", - "response_check_tx", - "response_commit", - "response_deliver_tx", - "response_echo", - "response_end_block", - "response_exception", - "response_flush", - "response_info", - "response_init_chain", - "response_list_snapshots", - "response_load_snapshot_chunk", - "response_offer_snapshot", - "response_query", - "response_set_option", - } - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "app_hash", - "app_state_bytes", - "app_version", - "block_version", - "byzantine_validators", - "chain_id", - "chunk", - "chunk_index", - "chunk_sender", - "code", - "codespace", - "consensus_param_updates", - "consensus_params", - "data", - "dialogue_reference", - "dummy_consensus_params", - "error", - "events", - "format", - "gas_used", - "gas_wanted", - "hash", - "header", - "height", - "index", - "info", - "info_data", - "initial_height", - "key", - "last_block_app_hash", - "last_block_height", - "last_commit_info", - "log", - "message", - "message_id", - "option_key", - "option_value", - "p2p_version", - "path", - "performative", - "proof_ops", - "prove", - "query_data", - "refetch_chunks", - "reject_senders", - "result", - "retain_height", - "snapshot", - "snapshots", - "target", - "time", - "tx", - "type", - "validator_updates", - "validators", - "value", - "version", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of AbciMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=AbciMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(AbciMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def app_hash(self) -> bytes: - """Get the 'app_hash' content from the message.""" - enforce(self.is_set("app_hash"), "'app_hash' content is not set.") - return cast(bytes, self.get("app_hash")) - - @property - def app_state_bytes(self) -> bytes: - """Get the 'app_state_bytes' content from the message.""" - enforce(self.is_set("app_state_bytes"), "'app_state_bytes' content is not set.") - return cast(bytes, self.get("app_state_bytes")) - - @property - def app_version(self) -> int: - """Get the 'app_version' content from the message.""" - enforce(self.is_set("app_version"), "'app_version' content is not set.") - return cast(int, self.get("app_version")) - - @property - def block_version(self) -> int: - """Get the 'block_version' content from the message.""" - enforce(self.is_set("block_version"), "'block_version' content is not set.") - return cast(int, self.get("block_version")) - - @property - def byzantine_validators(self) -> CustomEvidences: - """Get the 'byzantine_validators' content from the message.""" - enforce( - self.is_set("byzantine_validators"), - "'byzantine_validators' content is not set.", - ) - return cast(CustomEvidences, self.get("byzantine_validators")) - - @property - def chain_id(self) -> str: - """Get the 'chain_id' content from the message.""" - enforce(self.is_set("chain_id"), "'chain_id' content is not set.") - return cast(str, self.get("chain_id")) - - @property - def chunk(self) -> bytes: - """Get the 'chunk' content from the message.""" - enforce(self.is_set("chunk"), "'chunk' content is not set.") - return cast(bytes, self.get("chunk")) - - @property - def chunk_index(self) -> int: - """Get the 'chunk_index' content from the message.""" - enforce(self.is_set("chunk_index"), "'chunk_index' content is not set.") - return cast(int, self.get("chunk_index")) - - @property - def chunk_sender(self) -> str: - """Get the 'chunk_sender' content from the message.""" - enforce(self.is_set("chunk_sender"), "'chunk_sender' content is not set.") - return cast(str, self.get("chunk_sender")) - - @property - def code(self) -> int: - """Get the 'code' content from the message.""" - enforce(self.is_set("code"), "'code' content is not set.") - return cast(int, self.get("code")) - - @property - def codespace(self) -> str: - """Get the 'codespace' content from the message.""" - enforce(self.is_set("codespace"), "'codespace' content is not set.") - return cast(str, self.get("codespace")) - - @property - def consensus_param_updates(self) -> Optional[CustomConsensusParams]: - """Get the 'consensus_param_updates' content from the message.""" - return cast( - Optional[CustomConsensusParams], self.get("consensus_param_updates") - ) - - @property - def consensus_params(self) -> Optional[CustomConsensusParams]: - """Get the 'consensus_params' content from the message.""" - return cast(Optional[CustomConsensusParams], self.get("consensus_params")) - - @property - def data(self) -> bytes: - """Get the 'data' content from the message.""" - enforce(self.is_set("data"), "'data' content is not set.") - return cast(bytes, self.get("data")) - - @property - def dummy_consensus_params(self) -> CustomConsensusParams: - """Get the 'dummy_consensus_params' content from the message.""" - enforce( - self.is_set("dummy_consensus_params"), - "'dummy_consensus_params' content is not set.", - ) - return cast(CustomConsensusParams, self.get("dummy_consensus_params")) - - @property - def error(self) -> str: - """Get the 'error' content from the message.""" - enforce(self.is_set("error"), "'error' content is not set.") - return cast(str, self.get("error")) - - @property - def events(self) -> CustomEvents: - """Get the 'events' content from the message.""" - enforce(self.is_set("events"), "'events' content is not set.") - return cast(CustomEvents, self.get("events")) - - @property - def format(self) -> int: - """Get the 'format' content from the message.""" - enforce(self.is_set("format"), "'format' content is not set.") - return cast(int, self.get("format")) - - @property - def gas_used(self) -> int: - """Get the 'gas_used' content from the message.""" - enforce(self.is_set("gas_used"), "'gas_used' content is not set.") - return cast(int, self.get("gas_used")) - - @property - def gas_wanted(self) -> int: - """Get the 'gas_wanted' content from the message.""" - enforce(self.is_set("gas_wanted"), "'gas_wanted' content is not set.") - return cast(int, self.get("gas_wanted")) - - @property - def hash(self) -> bytes: - """Get the 'hash' content from the message.""" - enforce(self.is_set("hash"), "'hash' content is not set.") - return cast(bytes, self.get("hash")) - - @property - def header(self) -> CustomHeader: - """Get the 'header' content from the message.""" - enforce(self.is_set("header"), "'header' content is not set.") - return cast(CustomHeader, self.get("header")) - - @property - def height(self) -> int: - """Get the 'height' content from the message.""" - enforce(self.is_set("height"), "'height' content is not set.") - return cast(int, self.get("height")) - - @property - def index(self) -> int: - """Get the 'index' content from the message.""" - enforce(self.is_set("index"), "'index' content is not set.") - return cast(int, self.get("index")) - - @property - def info(self) -> str: - """Get the 'info' content from the message.""" - enforce(self.is_set("info"), "'info' content is not set.") - return cast(str, self.get("info")) - - @property - def info_data(self) -> str: - """Get the 'info_data' content from the message.""" - enforce(self.is_set("info_data"), "'info_data' content is not set.") - return cast(str, self.get("info_data")) - - @property - def initial_height(self) -> int: - """Get the 'initial_height' content from the message.""" - enforce(self.is_set("initial_height"), "'initial_height' content is not set.") - return cast(int, self.get("initial_height")) - - @property - def key(self) -> bytes: - """Get the 'key' content from the message.""" - enforce(self.is_set("key"), "'key' content is not set.") - return cast(bytes, self.get("key")) - - @property - def last_block_app_hash(self) -> bytes: - """Get the 'last_block_app_hash' content from the message.""" - enforce( - self.is_set("last_block_app_hash"), - "'last_block_app_hash' content is not set.", - ) - return cast(bytes, self.get("last_block_app_hash")) - - @property - def last_block_height(self) -> int: - """Get the 'last_block_height' content from the message.""" - enforce( - self.is_set("last_block_height"), "'last_block_height' content is not set." - ) - return cast(int, self.get("last_block_height")) - - @property - def last_commit_info(self) -> CustomLastCommitInfo: - """Get the 'last_commit_info' content from the message.""" - enforce( - self.is_set("last_commit_info"), "'last_commit_info' content is not set." - ) - return cast(CustomLastCommitInfo, self.get("last_commit_info")) - - @property - def log(self) -> str: - """Get the 'log' content from the message.""" - enforce(self.is_set("log"), "'log' content is not set.") - return cast(str, self.get("log")) - - @property - def message(self) -> str: - """Get the 'message' content from the message.""" - enforce(self.is_set("message"), "'message' content is not set.") - return cast(str, self.get("message")) - - @property - def option_key(self) -> str: - """Get the 'option_key' content from the message.""" - enforce(self.is_set("option_key"), "'option_key' content is not set.") - return cast(str, self.get("option_key")) - - @property - def option_value(self) -> str: - """Get the 'option_value' content from the message.""" - enforce(self.is_set("option_value"), "'option_value' content is not set.") - return cast(str, self.get("option_value")) - - @property - def p2p_version(self) -> int: - """Get the 'p2p_version' content from the message.""" - enforce(self.is_set("p2p_version"), "'p2p_version' content is not set.") - return cast(int, self.get("p2p_version")) - - @property - def path(self) -> str: - """Get the 'path' content from the message.""" - enforce(self.is_set("path"), "'path' content is not set.") - return cast(str, self.get("path")) - - @property - def proof_ops(self) -> CustomProofOps: - """Get the 'proof_ops' content from the message.""" - enforce(self.is_set("proof_ops"), "'proof_ops' content is not set.") - return cast(CustomProofOps, self.get("proof_ops")) - - @property - def prove(self) -> bool: - """Get the 'prove' content from the message.""" - enforce(self.is_set("prove"), "'prove' content is not set.") - return cast(bool, self.get("prove")) - - @property - def query_data(self) -> bytes: - """Get the 'query_data' content from the message.""" - enforce(self.is_set("query_data"), "'query_data' content is not set.") - return cast(bytes, self.get("query_data")) - - @property - def refetch_chunks(self) -> Tuple[int, ...]: - """Get the 'refetch_chunks' content from the message.""" - enforce(self.is_set("refetch_chunks"), "'refetch_chunks' content is not set.") - return cast(Tuple[int, ...], self.get("refetch_chunks")) - - @property - def reject_senders(self) -> Tuple[str, ...]: - """Get the 'reject_senders' content from the message.""" - enforce(self.is_set("reject_senders"), "'reject_senders' content is not set.") - return cast(Tuple[str, ...], self.get("reject_senders")) - - @property - def result(self) -> CustomResult: - """Get the 'result' content from the message.""" - enforce(self.is_set("result"), "'result' content is not set.") - return cast(CustomResult, self.get("result")) - - @property - def retain_height(self) -> int: - """Get the 'retain_height' content from the message.""" - enforce(self.is_set("retain_height"), "'retain_height' content is not set.") - return cast(int, self.get("retain_height")) - - @property - def snapshot(self) -> CustomSnapshot: - """Get the 'snapshot' content from the message.""" - enforce(self.is_set("snapshot"), "'snapshot' content is not set.") - return cast(CustomSnapshot, self.get("snapshot")) - - @property - def snapshots(self) -> CustomSnapShots: - """Get the 'snapshots' content from the message.""" - enforce(self.is_set("snapshots"), "'snapshots' content is not set.") - return cast(CustomSnapShots, self.get("snapshots")) - - @property - def time(self) -> CustomTimestamp: - """Get the 'time' content from the message.""" - enforce(self.is_set("time"), "'time' content is not set.") - return cast(CustomTimestamp, self.get("time")) - - @property - def tx(self) -> bytes: - """Get the 'tx' content from the message.""" - enforce(self.is_set("tx"), "'tx' content is not set.") - return cast(bytes, self.get("tx")) - - @property - def type(self) -> CustomCheckTxType: - """Get the 'type' content from the message.""" - enforce(self.is_set("type"), "'type' content is not set.") - return cast(CustomCheckTxType, self.get("type")) - - @property - def validator_updates(self) -> CustomValidatorUpdates: - """Get the 'validator_updates' content from the message.""" - enforce( - self.is_set("validator_updates"), "'validator_updates' content is not set." - ) - return cast(CustomValidatorUpdates, self.get("validator_updates")) - - @property - def validators(self) -> CustomValidatorUpdates: - """Get the 'validators' content from the message.""" - enforce(self.is_set("validators"), "'validators' content is not set.") - return cast(CustomValidatorUpdates, self.get("validators")) - - @property - def value(self) -> bytes: - """Get the 'value' content from the message.""" - enforce(self.is_set("value"), "'value' content is not set.") - return cast(bytes, self.get("value")) - - @property - def version(self) -> str: - """Get the 'version' content from the message.""" - enforce(self.is_set("version"), "'version' content is not set.") - return cast(str, self.get("version")) - - def _is_consistent(self) -> bool: - """Check that the message follows the abci protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, AbciMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == AbciMessage.Performative.REQUEST_ECHO: - expected_nb_of_contents = 1 - enforce( - isinstance(self.message, str), - "Invalid type for content 'message'. Expected 'str'. Found '{}'.".format( - type(self.message) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_FLUSH: - expected_nb_of_contents = 0 - elif self.performative == AbciMessage.Performative.REQUEST_INFO: - expected_nb_of_contents = 3 - enforce( - isinstance(self.version, str), - "Invalid type for content 'version'. Expected 'str'. Found '{}'.".format( - type(self.version) - ), - ) - enforce( - type(self.block_version) is int, - "Invalid type for content 'block_version'. Expected 'int'. Found '{}'.".format( - type(self.block_version) - ), - ) - enforce( - type(self.p2p_version) is int, - "Invalid type for content 'p2p_version'. Expected 'int'. Found '{}'.".format( - type(self.p2p_version) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_SET_OPTION: - expected_nb_of_contents = 2 - enforce( - isinstance(self.option_key, str), - "Invalid type for content 'option_key'. Expected 'str'. Found '{}'.".format( - type(self.option_key) - ), - ) - enforce( - isinstance(self.option_value, str), - "Invalid type for content 'option_value'. Expected 'str'. Found '{}'.".format( - type(self.option_value) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_INIT_CHAIN: - expected_nb_of_contents = 5 - enforce( - isinstance(self.time, CustomTimestamp), - "Invalid type for content 'time'. Expected 'Timestamp'. Found '{}'.".format( - type(self.time) - ), - ) - enforce( - isinstance(self.chain_id, str), - "Invalid type for content 'chain_id'. Expected 'str'. Found '{}'.".format( - type(self.chain_id) - ), - ) - if self.is_set("consensus_params"): - expected_nb_of_contents += 1 - consensus_params = cast( - CustomConsensusParams, self.consensus_params - ) - enforce( - isinstance(consensus_params, CustomConsensusParams), - "Invalid type for content 'consensus_params'. Expected 'ConsensusParams'. Found '{}'.".format( - type(consensus_params) - ), - ) - enforce( - isinstance(self.validators, CustomValidatorUpdates), - "Invalid type for content 'validators'. Expected 'ValidatorUpdates'. Found '{}'.".format( - type(self.validators) - ), - ) - enforce( - isinstance(self.app_state_bytes, bytes), - "Invalid type for content 'app_state_bytes'. Expected 'bytes'. Found '{}'.".format( - type(self.app_state_bytes) - ), - ) - enforce( - type(self.initial_height) is int, - "Invalid type for content 'initial_height'. Expected 'int'. Found '{}'.".format( - type(self.initial_height) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_QUERY: - expected_nb_of_contents = 4 - enforce( - isinstance(self.query_data, bytes), - "Invalid type for content 'query_data'. Expected 'bytes'. Found '{}'.".format( - type(self.query_data) - ), - ) - enforce( - isinstance(self.path, str), - "Invalid type for content 'path'. Expected 'str'. Found '{}'.".format( - type(self.path) - ), - ) - enforce( - type(self.height) is int, - "Invalid type for content 'height'. Expected 'int'. Found '{}'.".format( - type(self.height) - ), - ) - enforce( - isinstance(self.prove, bool), - "Invalid type for content 'prove'. Expected 'bool'. Found '{}'.".format( - type(self.prove) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_BEGIN_BLOCK: - expected_nb_of_contents = 4 - enforce( - isinstance(self.hash, bytes), - "Invalid type for content 'hash'. Expected 'bytes'. Found '{}'.".format( - type(self.hash) - ), - ) - enforce( - isinstance(self.header, CustomHeader), - "Invalid type for content 'header'. Expected 'Header'. Found '{}'.".format( - type(self.header) - ), - ) - enforce( - isinstance(self.last_commit_info, CustomLastCommitInfo), - "Invalid type for content 'last_commit_info'. Expected 'LastCommitInfo'. Found '{}'.".format( - type(self.last_commit_info) - ), - ) - enforce( - isinstance(self.byzantine_validators, CustomEvidences), - "Invalid type for content 'byzantine_validators'. Expected 'Evidences'. Found '{}'.".format( - type(self.byzantine_validators) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_CHECK_TX: - expected_nb_of_contents = 2 - enforce( - isinstance(self.tx, bytes), - "Invalid type for content 'tx'. Expected 'bytes'. Found '{}'.".format( - type(self.tx) - ), - ) - enforce( - isinstance(self.type, CustomCheckTxType), - "Invalid type for content 'type'. Expected 'CheckTxType'. Found '{}'.".format( - type(self.type) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_DELIVER_TX: - expected_nb_of_contents = 1 - enforce( - isinstance(self.tx, bytes), - "Invalid type for content 'tx'. Expected 'bytes'. Found '{}'.".format( - type(self.tx) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_END_BLOCK: - expected_nb_of_contents = 1 - enforce( - type(self.height) is int, - "Invalid type for content 'height'. Expected 'int'. Found '{}'.".format( - type(self.height) - ), - ) - elif self.performative == AbciMessage.Performative.REQUEST_COMMIT: - expected_nb_of_contents = 0 - elif self.performative == AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS: - expected_nb_of_contents = 0 - elif self.performative == AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT: - expected_nb_of_contents = 2 - enforce( - isinstance(self.snapshot, CustomSnapshot), - "Invalid type for content 'snapshot'. Expected 'Snapshot'. Found '{}'.".format( - type(self.snapshot) - ), - ) - enforce( - isinstance(self.app_hash, bytes), - "Invalid type for content 'app_hash'. Expected 'bytes'. Found '{}'.".format( - type(self.app_hash) - ), - ) - elif ( - self.performative - == AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK - ): - expected_nb_of_contents = 3 - enforce( - type(self.height) is int, - "Invalid type for content 'height'. Expected 'int'. Found '{}'.".format( - type(self.height) - ), - ) - enforce( - type(self.format) is int, - "Invalid type for content 'format'. Expected 'int'. Found '{}'.".format( - type(self.format) - ), - ) - enforce( - type(self.chunk_index) is int, - "Invalid type for content 'chunk_index'. Expected 'int'. Found '{}'.".format( - type(self.chunk_index) - ), - ) - elif ( - self.performative - == AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK - ): - expected_nb_of_contents = 3 - enforce( - type(self.index) is int, - "Invalid type for content 'index'. Expected 'int'. Found '{}'.".format( - type(self.index) - ), - ) - enforce( - isinstance(self.chunk, bytes), - "Invalid type for content 'chunk'. Expected 'bytes'. Found '{}'.".format( - type(self.chunk) - ), - ) - enforce( - isinstance(self.chunk_sender, str), - "Invalid type for content 'chunk_sender'. Expected 'str'. Found '{}'.".format( - type(self.chunk_sender) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_EXCEPTION: - expected_nb_of_contents = 1 - enforce( - isinstance(self.error, str), - "Invalid type for content 'error'. Expected 'str'. Found '{}'.".format( - type(self.error) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_ECHO: - expected_nb_of_contents = 1 - enforce( - isinstance(self.message, str), - "Invalid type for content 'message'. Expected 'str'. Found '{}'.".format( - type(self.message) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_FLUSH: - expected_nb_of_contents = 0 - elif self.performative == AbciMessage.Performative.RESPONSE_INFO: - expected_nb_of_contents = 5 - enforce( - isinstance(self.info_data, str), - "Invalid type for content 'info_data'. Expected 'str'. Found '{}'.".format( - type(self.info_data) - ), - ) - enforce( - isinstance(self.version, str), - "Invalid type for content 'version'. Expected 'str'. Found '{}'.".format( - type(self.version) - ), - ) - enforce( - type(self.app_version) is int, - "Invalid type for content 'app_version'. Expected 'int'. Found '{}'.".format( - type(self.app_version) - ), - ) - enforce( - type(self.last_block_height) is int, - "Invalid type for content 'last_block_height'. Expected 'int'. Found '{}'.".format( - type(self.last_block_height) - ), - ) - enforce( - isinstance(self.last_block_app_hash, bytes), - "Invalid type for content 'last_block_app_hash'. Expected 'bytes'. Found '{}'.".format( - type(self.last_block_app_hash) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_SET_OPTION: - expected_nb_of_contents = 3 - enforce( - type(self.code) is int, - "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( - type(self.code) - ), - ) - enforce( - isinstance(self.log, str), - "Invalid type for content 'log'. Expected 'str'. Found '{}'.".format( - type(self.log) - ), - ) - enforce( - isinstance(self.info, str), - "Invalid type for content 'info'. Expected 'str'. Found '{}'.".format( - type(self.info) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_INIT_CHAIN: - expected_nb_of_contents = 2 - if self.is_set("consensus_params"): - expected_nb_of_contents += 1 - consensus_params = cast( - CustomConsensusParams, self.consensus_params - ) - enforce( - isinstance(consensus_params, CustomConsensusParams), - "Invalid type for content 'consensus_params'. Expected 'ConsensusParams'. Found '{}'.".format( - type(consensus_params) - ), - ) - enforce( - isinstance(self.validators, CustomValidatorUpdates), - "Invalid type for content 'validators'. Expected 'ValidatorUpdates'. Found '{}'.".format( - type(self.validators) - ), - ) - enforce( - isinstance(self.app_hash, bytes), - "Invalid type for content 'app_hash'. Expected 'bytes'. Found '{}'.".format( - type(self.app_hash) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_QUERY: - expected_nb_of_contents = 9 - enforce( - type(self.code) is int, - "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( - type(self.code) - ), - ) - enforce( - isinstance(self.log, str), - "Invalid type for content 'log'. Expected 'str'. Found '{}'.".format( - type(self.log) - ), - ) - enforce( - isinstance(self.info, str), - "Invalid type for content 'info'. Expected 'str'. Found '{}'.".format( - type(self.info) - ), - ) - enforce( - type(self.index) is int, - "Invalid type for content 'index'. Expected 'int'. Found '{}'.".format( - type(self.index) - ), - ) - enforce( - isinstance(self.key, bytes), - "Invalid type for content 'key'. Expected 'bytes'. Found '{}'.".format( - type(self.key) - ), - ) - enforce( - isinstance(self.value, bytes), - "Invalid type for content 'value'. Expected 'bytes'. Found '{}'.".format( - type(self.value) - ), - ) - enforce( - isinstance(self.proof_ops, CustomProofOps), - "Invalid type for content 'proof_ops'. Expected 'ProofOps'. Found '{}'.".format( - type(self.proof_ops) - ), - ) - enforce( - type(self.height) is int, - "Invalid type for content 'height'. Expected 'int'. Found '{}'.".format( - type(self.height) - ), - ) - enforce( - isinstance(self.codespace, str), - "Invalid type for content 'codespace'. Expected 'str'. Found '{}'.".format( - type(self.codespace) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_BEGIN_BLOCK: - expected_nb_of_contents = 1 - enforce( - isinstance(self.events, CustomEvents), - "Invalid type for content 'events'. Expected 'Events'. Found '{}'.".format( - type(self.events) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_CHECK_TX: - expected_nb_of_contents = 8 - enforce( - type(self.code) is int, - "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( - type(self.code) - ), - ) - enforce( - isinstance(self.data, bytes), - "Invalid type for content 'data'. Expected 'bytes'. Found '{}'.".format( - type(self.data) - ), - ) - enforce( - isinstance(self.log, str), - "Invalid type for content 'log'. Expected 'str'. Found '{}'.".format( - type(self.log) - ), - ) - enforce( - isinstance(self.info, str), - "Invalid type for content 'info'. Expected 'str'. Found '{}'.".format( - type(self.info) - ), - ) - enforce( - type(self.gas_wanted) is int, - "Invalid type for content 'gas_wanted'. Expected 'int'. Found '{}'.".format( - type(self.gas_wanted) - ), - ) - enforce( - type(self.gas_used) is int, - "Invalid type for content 'gas_used'. Expected 'int'. Found '{}'.".format( - type(self.gas_used) - ), - ) - enforce( - isinstance(self.events, CustomEvents), - "Invalid type for content 'events'. Expected 'Events'. Found '{}'.".format( - type(self.events) - ), - ) - enforce( - isinstance(self.codespace, str), - "Invalid type for content 'codespace'. Expected 'str'. Found '{}'.".format( - type(self.codespace) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_DELIVER_TX: - expected_nb_of_contents = 8 - enforce( - type(self.code) is int, - "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( - type(self.code) - ), - ) - enforce( - isinstance(self.data, bytes), - "Invalid type for content 'data'. Expected 'bytes'. Found '{}'.".format( - type(self.data) - ), - ) - enforce( - isinstance(self.log, str), - "Invalid type for content 'log'. Expected 'str'. Found '{}'.".format( - type(self.log) - ), - ) - enforce( - isinstance(self.info, str), - "Invalid type for content 'info'. Expected 'str'. Found '{}'.".format( - type(self.info) - ), - ) - enforce( - type(self.gas_wanted) is int, - "Invalid type for content 'gas_wanted'. Expected 'int'. Found '{}'.".format( - type(self.gas_wanted) - ), - ) - enforce( - type(self.gas_used) is int, - "Invalid type for content 'gas_used'. Expected 'int'. Found '{}'.".format( - type(self.gas_used) - ), - ) - enforce( - isinstance(self.events, CustomEvents), - "Invalid type for content 'events'. Expected 'Events'. Found '{}'.".format( - type(self.events) - ), - ) - enforce( - isinstance(self.codespace, str), - "Invalid type for content 'codespace'. Expected 'str'. Found '{}'.".format( - type(self.codespace) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_END_BLOCK: - expected_nb_of_contents = 2 - enforce( - isinstance(self.validator_updates, CustomValidatorUpdates), - "Invalid type for content 'validator_updates'. Expected 'ValidatorUpdates'. Found '{}'.".format( - type(self.validator_updates) - ), - ) - if self.is_set("consensus_param_updates"): - expected_nb_of_contents += 1 - consensus_param_updates = cast( - CustomConsensusParams, self.consensus_param_updates - ) - enforce( - isinstance(consensus_param_updates, CustomConsensusParams), - "Invalid type for content 'consensus_param_updates'. Expected 'ConsensusParams'. Found '{}'.".format( - type(consensus_param_updates) - ), - ) - enforce( - isinstance(self.events, CustomEvents), - "Invalid type for content 'events'. Expected 'Events'. Found '{}'.".format( - type(self.events) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_COMMIT: - expected_nb_of_contents = 2 - enforce( - isinstance(self.data, bytes), - "Invalid type for content 'data'. Expected 'bytes'. Found '{}'.".format( - type(self.data) - ), - ) - enforce( - type(self.retain_height) is int, - "Invalid type for content 'retain_height'. Expected 'int'. Found '{}'.".format( - type(self.retain_height) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS: - expected_nb_of_contents = 1 - enforce( - isinstance(self.snapshots, CustomSnapShots), - "Invalid type for content 'snapshots'. Expected 'SnapShots'. Found '{}'.".format( - type(self.snapshots) - ), - ) - elif self.performative == AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT: - expected_nb_of_contents = 1 - enforce( - isinstance(self.result, CustomResult), - "Invalid type for content 'result'. Expected 'Result'. Found '{}'.".format( - type(self.result) - ), - ) - elif ( - self.performative - == AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK - ): - expected_nb_of_contents = 1 - enforce( - isinstance(self.chunk, bytes), - "Invalid type for content 'chunk'. Expected 'bytes'. Found '{}'.".format( - type(self.chunk) - ), - ) - elif ( - self.performative - == AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK - ): - expected_nb_of_contents = 3 - enforce( - isinstance(self.result, CustomResult), - "Invalid type for content 'result'. Expected 'Result'. Found '{}'.".format( - type(self.result) - ), - ) - enforce( - isinstance(self.refetch_chunks, tuple), - "Invalid type for content 'refetch_chunks'. Expected 'tuple'. Found '{}'.".format( - type(self.refetch_chunks) - ), - ) - enforce( - all(type(element) is int for element in self.refetch_chunks), - "Invalid type for tuple elements in content 'refetch_chunks'. Expected 'int'.", - ) - enforce( - isinstance(self.reject_senders, tuple), - "Invalid type for content 'reject_senders'. Expected 'tuple'. Found '{}'.".format( - type(self.reject_senders) - ), - ) - enforce( - all(isinstance(element, str) for element in self.reject_senders), - "Invalid type for tuple elements in content 'reject_senders'. Expected 'str'.", - ) - elif self.performative == AbciMessage.Performative.DUMMY: - expected_nb_of_contents = 1 - enforce( - isinstance(self.dummy_consensus_params, CustomConsensusParams), - "Invalid type for content 'dummy_consensus_params'. Expected 'ConsensusParams'. Found '{}'.".format( - type(self.dummy_consensus_params) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_old/vendor/valory/protocols/abci/protocol.yaml b/trader_old/vendor/valory/protocols/abci/protocol.yaml deleted file mode 100644 index 205cccc92..000000000 --- a/trader_old/vendor/valory/protocols/abci/protocol.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: abci -author: valory -version: 0.1.0 -protocol_specification_id: valory/abci:0.1.0 -type: protocol -description: A protocol for ABCI requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeia5y34dgznojhabsw7js2auxzmwxoubs2yacvscvoqkmt323d3npq - __init__.py: bafybeigdywrj2szik3yvkpnouvsdwna2c3w6txzfyxqgqvmq3brhy2guqy - abci.proto: bafybeid2kv4fy6xx453apqxashnqfjymhbrvtxj3uq2vdtqr45lvlfjzm4 - abci_pb2.py: bafybeiamdsjnddab32gu3xxa2tj4hkuaor2aboqem5dpt4ug25hhejp2li - custom_types.py: bafybeihpkluue4c7cunrcaxze3pqexhmwxkybrv4c3bzmkkakze7n6v44a - dialogues.py: bafybeihllufuvxtzb6vtz7qbsxqoyboaxik7lacwrbqfl4wfdzkfiv35de - message.py: bafybeifyexp6v5ajzqtuneknamnhhcobnaekbsbo3uq2xlu6a2lpfavfjm - serialization.py: bafybeifbqcuyp6kjsditiprvujhlr5zyj67icjtceu2wrkmtun6icwfnre - tests/__init__.py: bafybeie4cd5xo7o4teyfjclaju3zoguuahjvkpsbshda3x23jcph53fdpi - tests/conftest.py: bafybeidomydt6bdji22rndrdb5w773vvdja55o5m5n4pbfslx7ey5euot4 - tests/test_abci.py: bafybeig4gex7e62uxca7riaetmr2pu5xekxg3d7xjvck72zjd3uxny4v64 - tests/test_abci_dialogues.py: bafybeiby6ahpj6dnvjagnyyew3hgncstay37tt3xqu5x2c2yx3nldwvzzi - tests/test_abci_messages.py: bafybeidbec7g3gvyr4jon57m6pfcobslj3nvnnynzeib3mgvm46d3ywdgi -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_old/vendor/valory/protocols/abci/serialization.py b/trader_old/vendor/valory/protocols/abci/serialization.py deleted file mode 100644 index f5fad05e4..000000000 --- a/trader_old/vendor/valory/protocols/abci/serialization.py +++ /dev/null @@ -1,617 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for abci protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.abci import abci_pb2 # type: ignore -from packages.valory.protocols.abci.custom_types import ( # type: ignore - CheckTxType, - ConsensusParams, - Events, - Evidences, - Header, - LastCommitInfo, - ProofOps, - Result, - SnapShots, - Snapshot, - Timestamp, - ValidatorUpdates, -) -from packages.valory.protocols.abci.message import AbciMessage # type: ignore - - -class AbciSerializer(Serializer): - """Serialization for the 'abci' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'Abci' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(AbciMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - abci_msg = abci_pb2.AbciMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == AbciMessage.Performative.REQUEST_ECHO: - performative = abci_pb2.AbciMessage.Request_Echo_Performative() # type: ignore - message = msg.message - performative.message = message - abci_msg.request_echo.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_FLUSH: - performative = abci_pb2.AbciMessage.Request_Flush_Performative() # type: ignore - abci_msg.request_flush.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_INFO: - performative = abci_pb2.AbciMessage.Request_Info_Performative() # type: ignore - version = msg.version - performative.version = version - block_version = msg.block_version - performative.block_version = block_version - p2p_version = msg.p2p_version - performative.p2p_version = p2p_version - abci_msg.request_info.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_SET_OPTION: - performative = abci_pb2.AbciMessage.Request_Set_Option_Performative() # type: ignore - option_key = msg.option_key - performative.option_key = option_key - option_value = msg.option_value - performative.option_value = option_value - abci_msg.request_set_option.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_INIT_CHAIN: - performative = abci_pb2.AbciMessage.Request_Init_Chain_Performative() # type: ignore - time = msg.time - Timestamp.encode(performative.time, time) - chain_id = msg.chain_id - performative.chain_id = chain_id - if msg.is_set("consensus_params"): - performative.consensus_params_is_set = True - consensus_params = msg.consensus_params - ConsensusParams.encode(performative.consensus_params, consensus_params) - validators = msg.validators - ValidatorUpdates.encode(performative.validators, validators) - app_state_bytes = msg.app_state_bytes - performative.app_state_bytes = app_state_bytes - initial_height = msg.initial_height - performative.initial_height = initial_height - abci_msg.request_init_chain.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_QUERY: - performative = abci_pb2.AbciMessage.Request_Query_Performative() # type: ignore - query_data = msg.query_data - performative.query_data = query_data - path = msg.path - performative.path = path - height = msg.height - performative.height = height - prove = msg.prove - performative.prove = prove - abci_msg.request_query.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_BEGIN_BLOCK: - performative = abci_pb2.AbciMessage.Request_Begin_Block_Performative() # type: ignore - hash = msg.hash - performative.hash = hash - header = msg.header - Header.encode(performative.header, header) - last_commit_info = msg.last_commit_info - LastCommitInfo.encode(performative.last_commit_info, last_commit_info) - byzantine_validators = msg.byzantine_validators - Evidences.encode(performative.byzantine_validators, byzantine_validators) - abci_msg.request_begin_block.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_CHECK_TX: - performative = abci_pb2.AbciMessage.Request_Check_Tx_Performative() # type: ignore - tx = msg.tx - performative.tx = tx - type = msg.type - CheckTxType.encode(performative.type, type) - abci_msg.request_check_tx.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_DELIVER_TX: - performative = abci_pb2.AbciMessage.Request_Deliver_Tx_Performative() # type: ignore - tx = msg.tx - performative.tx = tx - abci_msg.request_deliver_tx.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_END_BLOCK: - performative = abci_pb2.AbciMessage.Request_End_Block_Performative() # type: ignore - height = msg.height - performative.height = height - abci_msg.request_end_block.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_COMMIT: - performative = abci_pb2.AbciMessage.Request_Commit_Performative() # type: ignore - abci_msg.request_commit.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS: - performative = abci_pb2.AbciMessage.Request_List_Snapshots_Performative() # type: ignore - abci_msg.request_list_snapshots.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT: - performative = abci_pb2.AbciMessage.Request_Offer_Snapshot_Performative() # type: ignore - snapshot = msg.snapshot - Snapshot.encode(performative.snapshot, snapshot) - app_hash = msg.app_hash - performative.app_hash = app_hash - abci_msg.request_offer_snapshot.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK: - performative = abci_pb2.AbciMessage.Request_Load_Snapshot_Chunk_Performative() # type: ignore - height = msg.height - performative.height = height - format = msg.format - performative.format = format - chunk_index = msg.chunk_index - performative.chunk_index = chunk_index - abci_msg.request_load_snapshot_chunk.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK: - performative = abci_pb2.AbciMessage.Request_Apply_Snapshot_Chunk_Performative() # type: ignore - index = msg.index - performative.index = index - chunk = msg.chunk - performative.chunk = chunk - chunk_sender = msg.chunk_sender - performative.chunk_sender = chunk_sender - abci_msg.request_apply_snapshot_chunk.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_EXCEPTION: - performative = abci_pb2.AbciMessage.Response_Exception_Performative() # type: ignore - error = msg.error - performative.error = error - abci_msg.response_exception.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_ECHO: - performative = abci_pb2.AbciMessage.Response_Echo_Performative() # type: ignore - message = msg.message - performative.message = message - abci_msg.response_echo.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_FLUSH: - performative = abci_pb2.AbciMessage.Response_Flush_Performative() # type: ignore - abci_msg.response_flush.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_INFO: - performative = abci_pb2.AbciMessage.Response_Info_Performative() # type: ignore - info_data = msg.info_data - performative.info_data = info_data - version = msg.version - performative.version = version - app_version = msg.app_version - performative.app_version = app_version - last_block_height = msg.last_block_height - performative.last_block_height = last_block_height - last_block_app_hash = msg.last_block_app_hash - performative.last_block_app_hash = last_block_app_hash - abci_msg.response_info.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_SET_OPTION: - performative = abci_pb2.AbciMessage.Response_Set_Option_Performative() # type: ignore - code = msg.code - performative.code = code - log = msg.log - performative.log = log - info = msg.info - performative.info = info - abci_msg.response_set_option.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_INIT_CHAIN: - performative = abci_pb2.AbciMessage.Response_Init_Chain_Performative() # type: ignore - if msg.is_set("consensus_params"): - performative.consensus_params_is_set = True - consensus_params = msg.consensus_params - ConsensusParams.encode(performative.consensus_params, consensus_params) - validators = msg.validators - ValidatorUpdates.encode(performative.validators, validators) - app_hash = msg.app_hash - performative.app_hash = app_hash - abci_msg.response_init_chain.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_QUERY: - performative = abci_pb2.AbciMessage.Response_Query_Performative() # type: ignore - code = msg.code - performative.code = code - log = msg.log - performative.log = log - info = msg.info - performative.info = info - index = msg.index - performative.index = index - key = msg.key - performative.key = key - value = msg.value - performative.value = value - proof_ops = msg.proof_ops - ProofOps.encode(performative.proof_ops, proof_ops) - height = msg.height - performative.height = height - codespace = msg.codespace - performative.codespace = codespace - abci_msg.response_query.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_BEGIN_BLOCK: - performative = abci_pb2.AbciMessage.Response_Begin_Block_Performative() # type: ignore - events = msg.events - Events.encode(performative.events, events) - abci_msg.response_begin_block.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_CHECK_TX: - performative = abci_pb2.AbciMessage.Response_Check_Tx_Performative() # type: ignore - code = msg.code - performative.code = code - data = msg.data - performative.data = data - log = msg.log - performative.log = log - info = msg.info - performative.info = info - gas_wanted = msg.gas_wanted - performative.gas_wanted = gas_wanted - gas_used = msg.gas_used - performative.gas_used = gas_used - events = msg.events - Events.encode(performative.events, events) - codespace = msg.codespace - performative.codespace = codespace - abci_msg.response_check_tx.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_DELIVER_TX: - performative = abci_pb2.AbciMessage.Response_Deliver_Tx_Performative() # type: ignore - code = msg.code - performative.code = code - data = msg.data - performative.data = data - log = msg.log - performative.log = log - info = msg.info - performative.info = info - gas_wanted = msg.gas_wanted - performative.gas_wanted = gas_wanted - gas_used = msg.gas_used - performative.gas_used = gas_used - events = msg.events - Events.encode(performative.events, events) - codespace = msg.codespace - performative.codespace = codespace - abci_msg.response_deliver_tx.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_END_BLOCK: - performative = abci_pb2.AbciMessage.Response_End_Block_Performative() # type: ignore - validator_updates = msg.validator_updates - ValidatorUpdates.encode(performative.validator_updates, validator_updates) - if msg.is_set("consensus_param_updates"): - performative.consensus_param_updates_is_set = True - consensus_param_updates = msg.consensus_param_updates - ConsensusParams.encode( - performative.consensus_param_updates, consensus_param_updates - ) - events = msg.events - Events.encode(performative.events, events) - abci_msg.response_end_block.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_COMMIT: - performative = abci_pb2.AbciMessage.Response_Commit_Performative() # type: ignore - data = msg.data - performative.data = data - retain_height = msg.retain_height - performative.retain_height = retain_height - abci_msg.response_commit.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS: - performative = abci_pb2.AbciMessage.Response_List_Snapshots_Performative() # type: ignore - snapshots = msg.snapshots - SnapShots.encode(performative.snapshots, snapshots) - abci_msg.response_list_snapshots.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT: - performative = abci_pb2.AbciMessage.Response_Offer_Snapshot_Performative() # type: ignore - result = msg.result - Result.encode(performative.result, result) - abci_msg.response_offer_snapshot.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK: - performative = abci_pb2.AbciMessage.Response_Load_Snapshot_Chunk_Performative() # type: ignore - chunk = msg.chunk - performative.chunk = chunk - abci_msg.response_load_snapshot_chunk.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK: - performative = abci_pb2.AbciMessage.Response_Apply_Snapshot_Chunk_Performative() # type: ignore - result = msg.result - Result.encode(performative.result, result) - refetch_chunks = msg.refetch_chunks - performative.refetch_chunks.extend(refetch_chunks) - reject_senders = msg.reject_senders - performative.reject_senders.extend(reject_senders) - abci_msg.response_apply_snapshot_chunk.CopyFrom(performative) - elif performative_id == AbciMessage.Performative.DUMMY: - performative = abci_pb2.AbciMessage.Dummy_Performative() # type: ignore - dummy_consensus_params = msg.dummy_consensus_params - ConsensusParams.encode( - performative.dummy_consensus_params, dummy_consensus_params - ) - abci_msg.dummy.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = abci_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'Abci' message. - - :param obj: the bytes object. - :return: the 'Abci' message. - """ - message_pb = ProtobufMessage() - abci_pb = abci_pb2.AbciMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - abci_pb.ParseFromString(message_pb.dialogue_message.content) - performative = abci_pb.WhichOneof("performative") - performative_id = AbciMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == AbciMessage.Performative.REQUEST_ECHO: - message = abci_pb.request_echo.message - performative_content["message"] = message - elif performative_id == AbciMessage.Performative.REQUEST_FLUSH: - pass - elif performative_id == AbciMessage.Performative.REQUEST_INFO: - version = abci_pb.request_info.version - performative_content["version"] = version - block_version = abci_pb.request_info.block_version - performative_content["block_version"] = block_version - p2p_version = abci_pb.request_info.p2p_version - performative_content["p2p_version"] = p2p_version - elif performative_id == AbciMessage.Performative.REQUEST_SET_OPTION: - option_key = abci_pb.request_set_option.option_key - performative_content["option_key"] = option_key - option_value = abci_pb.request_set_option.option_value - performative_content["option_value"] = option_value - elif performative_id == AbciMessage.Performative.REQUEST_INIT_CHAIN: - pb2_time = abci_pb.request_init_chain.time - time = Timestamp.decode(pb2_time) - performative_content["time"] = time - chain_id = abci_pb.request_init_chain.chain_id - performative_content["chain_id"] = chain_id - if abci_pb.request_init_chain.consensus_params_is_set: - pb2_consensus_params = abci_pb.request_init_chain.consensus_params - consensus_params = ConsensusParams.decode(pb2_consensus_params) - performative_content["consensus_params"] = consensus_params - pb2_validators = abci_pb.request_init_chain.validators - validators = ValidatorUpdates.decode(pb2_validators) - performative_content["validators"] = validators - app_state_bytes = abci_pb.request_init_chain.app_state_bytes - performative_content["app_state_bytes"] = app_state_bytes - initial_height = abci_pb.request_init_chain.initial_height - performative_content["initial_height"] = initial_height - elif performative_id == AbciMessage.Performative.REQUEST_QUERY: - query_data = abci_pb.request_query.query_data - performative_content["query_data"] = query_data - path = abci_pb.request_query.path - performative_content["path"] = path - height = abci_pb.request_query.height - performative_content["height"] = height - prove = abci_pb.request_query.prove - performative_content["prove"] = prove - elif performative_id == AbciMessage.Performative.REQUEST_BEGIN_BLOCK: - hash = abci_pb.request_begin_block.hash - performative_content["hash"] = hash - pb2_header = abci_pb.request_begin_block.header - header = Header.decode(pb2_header) - performative_content["header"] = header - pb2_last_commit_info = abci_pb.request_begin_block.last_commit_info - last_commit_info = LastCommitInfo.decode(pb2_last_commit_info) - performative_content["last_commit_info"] = last_commit_info - pb2_byzantine_validators = abci_pb.request_begin_block.byzantine_validators - byzantine_validators = Evidences.decode(pb2_byzantine_validators) - performative_content["byzantine_validators"] = byzantine_validators - elif performative_id == AbciMessage.Performative.REQUEST_CHECK_TX: - tx = abci_pb.request_check_tx.tx - performative_content["tx"] = tx - pb2_type = abci_pb.request_check_tx.type - type = CheckTxType.decode(pb2_type) - performative_content["type"] = type - elif performative_id == AbciMessage.Performative.REQUEST_DELIVER_TX: - tx = abci_pb.request_deliver_tx.tx - performative_content["tx"] = tx - elif performative_id == AbciMessage.Performative.REQUEST_END_BLOCK: - height = abci_pb.request_end_block.height - performative_content["height"] = height - elif performative_id == AbciMessage.Performative.REQUEST_COMMIT: - pass - elif performative_id == AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS: - pass - elif performative_id == AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT: - pb2_snapshot = abci_pb.request_offer_snapshot.snapshot - snapshot = Snapshot.decode(pb2_snapshot) - performative_content["snapshot"] = snapshot - app_hash = abci_pb.request_offer_snapshot.app_hash - performative_content["app_hash"] = app_hash - elif performative_id == AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK: - height = abci_pb.request_load_snapshot_chunk.height - performative_content["height"] = height - format = abci_pb.request_load_snapshot_chunk.format - performative_content["format"] = format - chunk_index = abci_pb.request_load_snapshot_chunk.chunk_index - performative_content["chunk_index"] = chunk_index - elif performative_id == AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK: - index = abci_pb.request_apply_snapshot_chunk.index - performative_content["index"] = index - chunk = abci_pb.request_apply_snapshot_chunk.chunk - performative_content["chunk"] = chunk - chunk_sender = abci_pb.request_apply_snapshot_chunk.chunk_sender - performative_content["chunk_sender"] = chunk_sender - elif performative_id == AbciMessage.Performative.RESPONSE_EXCEPTION: - error = abci_pb.response_exception.error - performative_content["error"] = error - elif performative_id == AbciMessage.Performative.RESPONSE_ECHO: - message = abci_pb.response_echo.message - performative_content["message"] = message - elif performative_id == AbciMessage.Performative.RESPONSE_FLUSH: - pass - elif performative_id == AbciMessage.Performative.RESPONSE_INFO: - info_data = abci_pb.response_info.info_data - performative_content["info_data"] = info_data - version = abci_pb.response_info.version - performative_content["version"] = version - app_version = abci_pb.response_info.app_version - performative_content["app_version"] = app_version - last_block_height = abci_pb.response_info.last_block_height - performative_content["last_block_height"] = last_block_height - last_block_app_hash = abci_pb.response_info.last_block_app_hash - performative_content["last_block_app_hash"] = last_block_app_hash - elif performative_id == AbciMessage.Performative.RESPONSE_SET_OPTION: - code = abci_pb.response_set_option.code - performative_content["code"] = code - log = abci_pb.response_set_option.log - performative_content["log"] = log - info = abci_pb.response_set_option.info - performative_content["info"] = info - elif performative_id == AbciMessage.Performative.RESPONSE_INIT_CHAIN: - if abci_pb.response_init_chain.consensus_params_is_set: - pb2_consensus_params = abci_pb.response_init_chain.consensus_params - consensus_params = ConsensusParams.decode(pb2_consensus_params) - performative_content["consensus_params"] = consensus_params - pb2_validators = abci_pb.response_init_chain.validators - validators = ValidatorUpdates.decode(pb2_validators) - performative_content["validators"] = validators - app_hash = abci_pb.response_init_chain.app_hash - performative_content["app_hash"] = app_hash - elif performative_id == AbciMessage.Performative.RESPONSE_QUERY: - code = abci_pb.response_query.code - performative_content["code"] = code - log = abci_pb.response_query.log - performative_content["log"] = log - info = abci_pb.response_query.info - performative_content["info"] = info - index = abci_pb.response_query.index - performative_content["index"] = index - key = abci_pb.response_query.key - performative_content["key"] = key - value = abci_pb.response_query.value - performative_content["value"] = value - pb2_proof_ops = abci_pb.response_query.proof_ops - proof_ops = ProofOps.decode(pb2_proof_ops) - performative_content["proof_ops"] = proof_ops - height = abci_pb.response_query.height - performative_content["height"] = height - codespace = abci_pb.response_query.codespace - performative_content["codespace"] = codespace - elif performative_id == AbciMessage.Performative.RESPONSE_BEGIN_BLOCK: - pb2_events = abci_pb.response_begin_block.events - events = Events.decode(pb2_events) - performative_content["events"] = events - elif performative_id == AbciMessage.Performative.RESPONSE_CHECK_TX: - code = abci_pb.response_check_tx.code - performative_content["code"] = code - data = abci_pb.response_check_tx.data - performative_content["data"] = data - log = abci_pb.response_check_tx.log - performative_content["log"] = log - info = abci_pb.response_check_tx.info - performative_content["info"] = info - gas_wanted = abci_pb.response_check_tx.gas_wanted - performative_content["gas_wanted"] = gas_wanted - gas_used = abci_pb.response_check_tx.gas_used - performative_content["gas_used"] = gas_used - pb2_events = abci_pb.response_check_tx.events - events = Events.decode(pb2_events) - performative_content["events"] = events - codespace = abci_pb.response_check_tx.codespace - performative_content["codespace"] = codespace - elif performative_id == AbciMessage.Performative.RESPONSE_DELIVER_TX: - code = abci_pb.response_deliver_tx.code - performative_content["code"] = code - data = abci_pb.response_deliver_tx.data - performative_content["data"] = data - log = abci_pb.response_deliver_tx.log - performative_content["log"] = log - info = abci_pb.response_deliver_tx.info - performative_content["info"] = info - gas_wanted = abci_pb.response_deliver_tx.gas_wanted - performative_content["gas_wanted"] = gas_wanted - gas_used = abci_pb.response_deliver_tx.gas_used - performative_content["gas_used"] = gas_used - pb2_events = abci_pb.response_deliver_tx.events - events = Events.decode(pb2_events) - performative_content["events"] = events - codespace = abci_pb.response_deliver_tx.codespace - performative_content["codespace"] = codespace - elif performative_id == AbciMessage.Performative.RESPONSE_END_BLOCK: - pb2_validator_updates = abci_pb.response_end_block.validator_updates - validator_updates = ValidatorUpdates.decode(pb2_validator_updates) - performative_content["validator_updates"] = validator_updates - if abci_pb.response_end_block.consensus_param_updates_is_set: - pb2_consensus_param_updates = ( - abci_pb.response_end_block.consensus_param_updates - ) - consensus_param_updates = ConsensusParams.decode( - pb2_consensus_param_updates - ) - performative_content[ - "consensus_param_updates" - ] = consensus_param_updates - pb2_events = abci_pb.response_end_block.events - events = Events.decode(pb2_events) - performative_content["events"] = events - elif performative_id == AbciMessage.Performative.RESPONSE_COMMIT: - data = abci_pb.response_commit.data - performative_content["data"] = data - retain_height = abci_pb.response_commit.retain_height - performative_content["retain_height"] = retain_height - elif performative_id == AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS: - pb2_snapshots = abci_pb.response_list_snapshots.snapshots - snapshots = SnapShots.decode(pb2_snapshots) - performative_content["snapshots"] = snapshots - elif performative_id == AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT: - pb2_result = abci_pb.response_offer_snapshot.result - result = Result.decode(pb2_result) - performative_content["result"] = result - elif performative_id == AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK: - chunk = abci_pb.response_load_snapshot_chunk.chunk - performative_content["chunk"] = chunk - elif performative_id == AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK: - pb2_result = abci_pb.response_apply_snapshot_chunk.result - result = Result.decode(pb2_result) - performative_content["result"] = result - refetch_chunks = abci_pb.response_apply_snapshot_chunk.refetch_chunks - refetch_chunks_tuple = tuple(refetch_chunks) - performative_content["refetch_chunks"] = refetch_chunks_tuple - reject_senders = abci_pb.response_apply_snapshot_chunk.reject_senders - reject_senders_tuple = tuple(reject_senders) - performative_content["reject_senders"] = reject_senders_tuple - elif performative_id == AbciMessage.Performative.DUMMY: - pb2_dummy_consensus_params = abci_pb.dummy.dummy_consensus_params - dummy_consensus_params = ConsensusParams.decode(pb2_dummy_consensus_params) - performative_content["dummy_consensus_params"] = dummy_consensus_params - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return AbciMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_old/vendor/valory/protocols/abci/tests/__init__.py b/trader_old/vendor/valory/protocols/abci/tests/__init__.py deleted file mode 100644 index 5fe6a268e..000000000 --- a/trader_old/vendor/valory/protocols/abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""ABCI protocol tests.""" diff --git a/trader_old/vendor/valory/protocols/abci/tests/conftest.py b/trader_old/vendor/valory/protocols/abci/tests/conftest.py deleted file mode 100644 index d3a5cfa36..000000000 --- a/trader_old/vendor/valory/protocols/abci/tests/conftest.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Conftest module.""" diff --git a/trader_old/vendor/valory/protocols/abci/tests/test_abci.py b/trader_old/vendor/valory/protocols/abci/tests/test_abci.py deleted file mode 100644 index 156930d60..000000000 --- a/trader_old/vendor/valory/protocols/abci/tests/test_abci.py +++ /dev/null @@ -1,910 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for the 'valory/abci' protocol.""" -import datetime -from abc import abstractmethod -from typing import Callable, Type -from unittest import mock - -import pytest -from aea.common import Address -from aea.exceptions import AEAEnforceError -from aea.mail.base import Envelope -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.abci import AbciMessage, message -from packages.valory.protocols.abci.custom_types import ( - BlockID, - BlockParams, - CheckTxType, - CheckTxTypeEnum, - ConsensusParams, - ConsensusVersion, - Duration, - Event, - EventAttribute, - Events, - Evidence, - EvidenceParams, - EvidenceType, - Evidences, - Header, - LastCommitInfo, - PartSetHeader, - ProofOp, - ProofOps, - PublicKey, - Result, - ResultType, - SnapShots, - Snapshot, - Timestamp, - Validator, - ValidatorParams, - ValidatorUpdate, - ValidatorUpdates, - VersionParams, - VoteInfo, -) -from packages.valory.protocols.abci.dialogues import AbciDialogue, AbciDialogues -from packages.valory.protocols.abci.message import ( - _default_logger as abci_message_logger, -) - - -class BaseTestMessageConstruction: - """Base class to test message construction for the ABCI protocol.""" - - @abstractmethod - def build_message(self) -> AbciMessage: - """Build the message to be used for testing.""" - - def test_run(self) -> None: - """Run the test.""" - msg = self.build_message() - msg.to = "receiver" - envelope = Envelope(to=msg.to, sender="sender", message=msg) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = AbciMessage.serializer.decode(actual_envelope.message_bytes) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - @classmethod - def _make_consensus_params(cls) -> ConsensusParams: - """Build a ConsensuParams object.""" - return ConsensusParams( - BlockParams(0, 0), - EvidenceParams(0, Duration(0, 0), 0), - ValidatorParams(["pub_key"]), - VersionParams(0), - ) - - @classmethod - def _make_snapshot(cls) -> Snapshot: - """Build a Snapshot object.""" - return Snapshot(0, 0, 0, b"hash", b"metadata") - - -class TestRequestEcho(BaseTestMessageConstruction): - """Test ABCI request abci.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_ECHO, # type: ignore - message="hello", - ) - - -class TestResponseEcho(BaseTestMessageConstruction): - """Test ABCI response abci.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_ECHO, # type: ignore - message="hello", - ) - - -class TestRequestFlush(BaseTestMessageConstruction): - """Test ABCI request flush.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_FLUSH, # type: ignore - ) - - -class TestResponseFlush(BaseTestMessageConstruction): - """Test ABCI response flush.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_FLUSH, # type: ignore - ) - - -class TestRequestInfo(BaseTestMessageConstruction): - """Test ABCI request info.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_INFO, # type: ignore - version="0.1.0", - block_version=1, - p2p_version=1, - ) - - -class TestResponseInfo(BaseTestMessageConstruction): - """Test ABCI response info.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_INFO, # type: ignore - info_data="info", - version="0.1.0", - app_version=1, - last_block_height=1, - last_block_app_hash=b"bytes", - ) - - -class TestRequestInitChain(BaseTestMessageConstruction): - """Test ABCI request init chain.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - consensus_params = super()._make_consensus_params() - - validators = ValidatorUpdates( - [ - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.ed25519), 1 - ), - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.secp256k1), 2 - ), - ] - ) - - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_INIT_CHAIN, # type: ignore - time=Timestamp(0, 0), - chain_id="1", - consensus_params=consensus_params, - validators=validators, - app_state_bytes=b"bytes", - initial_height=0, - ) - - -class TestResponseInitChain(BaseTestMessageConstruction): - """Test ABCI response init chain.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - consensus_params = super()._make_consensus_params() - - validators = ValidatorUpdates( - [ - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.ed25519), 1 - ), - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.secp256k1), 2 - ), - ] - ) - - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_INIT_CHAIN, # type: ignore - consensus_params=consensus_params, - validators=validators, - app_hash=b"app_hash", - ) - - -class TestRequestQuery(BaseTestMessageConstruction): - """Test ABCI response query.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_QUERY, # type: ignore - query_data=b"bytes", - path="", - height=0, - prove=False, - ) - - -class TestResponseQuery(BaseTestMessageConstruction): - """Test ABCI response query.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_QUERY, # type: ignore - code=0, - log="log", - info="info", - index=0, - key=b"key", - value=b"value", - proof_ops=ProofOps( - [ - ProofOp("type", b"key", b"data"), - ProofOp("type", b"key", b"data"), - ] - ), - height=0, - codespace="", - ) - - -class TestRequestBeginBlock(BaseTestMessageConstruction): - """Test ABCI request begin block.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - header = Header( - ConsensusVersion(0, 0), - "chain_id", - 0, - Timestamp(0, 0), - BlockID(b"hash", PartSetHeader(0, b"hash")), - b"last_commit_hash", - b"data_hash", - b"validators_hash", - b"next_validators_hash", - b"consensus_hash", - b"app_hash", - b"last_results_hash", - b"evidence_hash", - b"proposer_address", - ) - - assert header.timestamp == datetime.datetime.fromtimestamp(0) - - validator = Validator(b"address", 0) - last_commit_info = LastCommitInfo( - 0, - [ - VoteInfo(validator, True), - VoteInfo(validator, False), - ], - ) - - evidences = Evidences( - [ - Evidence(EvidenceType.UNKNOWN, validator, 0, Timestamp(0, 0), 0), - Evidence(EvidenceType.DUPLICATE_VOTE, validator, 0, Timestamp(0, 0), 0), - ] - ) - - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_BEGIN_BLOCK, # type: ignore - hash=b"hash", - header=header, - last_commit_info=last_commit_info, - byzantine_validators=evidences, - ) - - -class TestResponseBeginBlock(BaseTestMessageConstruction): - """Test ABCI response begin block.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - event = Event("type", [EventAttribute(b"key", b"value", True)]) - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, # type: ignore - events=Events([event, event]), - ) - - -class TestRequestCheckTx(BaseTestMessageConstruction): - """Test ABCI request check tx.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - tx = b"bytes" - type_ = CheckTxType(CheckTxTypeEnum.NEW) - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_CHECK_TX, # type: ignore - tx=tx, - type=type_, - ) - - -class TestResponseCheckTx(BaseTestMessageConstruction): - """Test ABCI response check tx.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - attribute = EventAttribute(b"key", b"value", True) - event = Event("type", attributes=[attribute, attribute]) - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, # type: ignore - code=0, - data=b"data", - log="log", - info="info", - gas_wanted=0, - gas_used=0, - events=Events([event, event]), - codespace="codespace", - ) - - -class TestRequestDeliverTx(BaseTestMessageConstruction): - """Test ABCI request deliver tx.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, # type: ignore - tx=b"tx", - ) - - -class TestResponseDeliverTx(BaseTestMessageConstruction): - """Test ABCI response deliver tx.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - attribute = EventAttribute(b"key", b"value", True) - event = Event("type", attributes=[attribute, attribute]) - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, # type: ignore - code=0, - data=b"data", - log="log", - info="info", - gas_wanted=0, - gas_used=0, - events=Events([event, event]), - codespace="codespace", - ) - - -class TestRequestEndBlock(BaseTestMessageConstruction): - """Test ABCI request end block.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_END_BLOCK, # type: ignore - height=0, - ) - - -class TestRequestSetOption(BaseTestMessageConstruction): - """Test ABCI request end block.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_SET_OPTION, # type: ignore - option_key="", - option_value="", - ) - - -class TestResponseEndBlock(BaseTestMessageConstruction): - """Test ABCI response end block.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - attribute = EventAttribute(b"key", b"value", True) - event = Event("type", attributes=[attribute, attribute]) - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_END_BLOCK, # type: ignore - validator_updates=ValidatorUpdates( - [ - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.ed25519), 1 - ), - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.secp256k1), - 2, - ), - ] - ), - consensus_param_updates=super()._make_consensus_params(), - events=Events([event, event]), - ) - - -class TestRequestCommit(BaseTestMessageConstruction): - """Test ABCI request commit.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_COMMIT, # type: ignore - ) - - -class TestResponseCommit(BaseTestMessageConstruction): - """Test ABCI response commit.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_COMMIT, # type: ignore - data=b"bytes", - retain_height=0, - ) - - -class TestRequestListSnapshots(BaseTestMessageConstruction): - """Test ABCI request list snapshots.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS, # type: ignore - ) - - -class TestResponseListSnapshots(BaseTestMessageConstruction): - """Test ABCI response list snapshots.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - snapshots = SnapShots( - [ - super()._make_snapshot(), - super()._make_snapshot(), - ] - ) - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, # type: ignore - snapshots=snapshots, - ) - - -class TestRequestOfferSnapshot(BaseTestMessageConstruction): - """Test ABCI request offer snapshot.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT, # type: ignore - snapshot=super()._make_snapshot(), - app_hash=b"app_hash", - ) - - -class TestResponseOfferSnapshot(BaseTestMessageConstruction): - """Test ABCI response offer snapshot.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, # type: ignore - result=Result(ResultType.UNKNOWN), - ) - - -class TestRequestLoadSnapshotChunk(BaseTestMessageConstruction): - """Test ABCI request load snapshot chunk.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK, # type: ignore - height=0, - format=0, - chunk_index=0, - ) - - -class TestResponseLoadSnapshotChunk(BaseTestMessageConstruction): - """Test ABCI response load snapshot chunk.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, # type: ignore - chunk=b"chunk", - ) - - -class TestRequestApplySnapshotChunk(BaseTestMessageConstruction): - """Test ABCI request load snapshot chunk.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK, # type: ignore - index=0, - chunk=b"chunk", - chunk_sender="sender", - ) - - -class TestResponseApplySnapshotChunk(BaseTestMessageConstruction): - """Test ABCI response apply snapshot chunk.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, # type: ignore - result=Result(ResultType.REJECT), - refetch_chunks=(0, 1, 2), - reject_senders=("sender_1", "sender_2"), - ) - - -class TestDummy(BaseTestMessageConstruction): - """Test ABCI request abci.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.DUMMY, # type: ignore - dummy_consensus_params=self._make_consensus_params(), - ) - - -class TestResponseException(BaseTestMessageConstruction): - """Test ABCI request abci.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_EXCEPTION, error="" # type: ignore - ) - - -class TestResponseSetOption(BaseTestMessageConstruction): - """Test ABCI request end block.""" - - def build_message(self) -> AbciMessage: - """Build the message.""" - return AbciMessage( - performative=AbciMessage.Performative.RESPONSE_SET_OPTION, # type: ignore - code=1, - log="", - info="", - ) - - -@mock.patch.object( - message, - "enforce", - side_effect=AEAEnforceError("some error"), -) -def test_incorrect_message( - mocked_enforce: Callable, # pylint: disable=unused-argument -) -> None: - """Test that we raise an exception when the message is incorrect.""" - with mock.patch.object(abci_message_logger, "error") as mock_logger: - AbciMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=AbciMessage.Performative.DUMMY, # type: ignore - ) - - mock_logger.assert_any_call("some error") - - -def test_performative_string_value() -> None: - """Test the string valoe of performatives.""" - - assert str(AbciMessage.Performative.DUMMY) == "dummy", "The str value must be dummy" - assert ( - str(AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK) - == "request_apply_snapshot_chunk" - ), "The str value must be request_apply_snapshot_chunk" - assert ( - str(AbciMessage.Performative.REQUEST_BEGIN_BLOCK) == "request_begin_block" - ), "The str value must be request_begin_block" - assert ( - str(AbciMessage.Performative.REQUEST_CHECK_TX) == "request_check_tx" - ), "The str value must be request_check_tx" - assert ( - str(AbciMessage.Performative.REQUEST_COMMIT) == "request_commit" - ), "The str value must be request_commit" - assert ( - str(AbciMessage.Performative.REQUEST_DELIVER_TX) == "request_deliver_tx" - ), "The str value must be request_deliver_tx" - assert ( - str(AbciMessage.Performative.REQUEST_ECHO) == "request_echo" - ), "The str value must be request_echo" - assert ( - str(AbciMessage.Performative.REQUEST_END_BLOCK) == "request_end_block" - ), "The str value must be request_end_block" - assert ( - str(AbciMessage.Performative.REQUEST_FLUSH) == "request_flush" - ), "The str value must be request_flush" - assert ( - str(AbciMessage.Performative.REQUEST_INFO) == "request_info" - ), "The str value must be request_info" - assert ( - str(AbciMessage.Performative.REQUEST_INIT_CHAIN) == "request_init_chain" - ), "The str value must be request_init_chain" - assert ( - str(AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS) == "request_list_snapshots" - ), "The str value must be request_list_snapshots" - assert ( - str(AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK) - == "request_load_snapshot_chunk" - ), "The str value must be request_load_snapshot_chunk" - assert ( - str(AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT) == "request_offer_snapshot" - ), "The str value must be request_offer_snapshot" - assert ( - str(AbciMessage.Performative.REQUEST_QUERY) == "request_query" - ), "The str value must be request_query" - assert ( - str(AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK) - == "response_apply_snapshot_chunk" - ), "The str value must be response_apply_snapshot_chunk" - assert ( - str(AbciMessage.Performative.RESPONSE_BEGIN_BLOCK) == "response_begin_block" - ), "The str value must be response_begin_block" - assert ( - str(AbciMessage.Performative.RESPONSE_CHECK_TX) == "response_check_tx" - ), "The str value must be response_check_tx" - assert ( - str(AbciMessage.Performative.RESPONSE_COMMIT) == "response_commit" - ), "The str value must be response_commit" - assert ( - str(AbciMessage.Performative.RESPONSE_DELIVER_TX) == "response_deliver_tx" - ), "The str value must be response_deliver_tx" - assert ( - str(AbciMessage.Performative.RESPONSE_ECHO) == "response_echo" - ), "The str value must be response_echo" - assert ( - str(AbciMessage.Performative.RESPONSE_END_BLOCK) == "response_end_block" - ), "The str value must be response_end_block" - assert ( - str(AbciMessage.Performative.RESPONSE_EXCEPTION) == "response_exception" - ), "The str value must be response_exception" - assert ( - str(AbciMessage.Performative.RESPONSE_FLUSH) == "response_flush" - ), "The str value must be response_flush" - assert ( - str(AbciMessage.Performative.RESPONSE_INFO) == "response_info" - ), "The str value must be response_info" - assert ( - str(AbciMessage.Performative.RESPONSE_INIT_CHAIN) == "response_init_chain" - ), "The str value must be response_init_chain" - assert ( - str(AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS) - == "response_list_snapshots" - ), "The str value must be response_list_snapshots" - assert ( - str(AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK) - == "response_load_snapshot_chunk" - ), "The str value must be response_load_snapshot_chunk" - assert ( - str(AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT) - == "response_offer_snapshot" - ), "The str value must be response_offer_snapshot" - assert ( - str(AbciMessage.Performative.RESPONSE_QUERY) == "response_query" - ), "The str value must be response_query" - assert ( - str(AbciMessage.Performative.RESPONSE_SET_OPTION) == "response_set_option" - ), "The str value must be response_set_option" - assert ( - str(AbciMessage.Performative.REQUEST_SET_OPTION) == "request_set_option" - ), "The str value must be request_set_option" - - -def test_encoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = AbciMessage( - performative=AbciMessage.Performative.REQUEST_ECHO, message="Hello" # type: ignore - ) - - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object(AbciMessage.Performative, "__eq__", return_value=False): - AbciMessage.serializer.encode(msg) - - -def test_decoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = AbciMessage( - performative=AbciMessage.Performative.REQUEST_ECHO, message="Hello" # type: ignore - ) - - encoded_msg = AbciMessage.serializer.encode(msg) - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object(AbciMessage.Performative, "__eq__", return_value=False): - AbciMessage.serializer.decode(encoded_msg) - - -class AgentDialogue(AbciDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[AbciMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - AbciDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class AgentDialogues(AbciDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.CLIENT - - AbciDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=AgentDialogue, - ) - - -class ServerDialogue(AbciDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[AbciMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - AbciDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class ServerDialogues(AbciDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.SERVER - - AbciDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=ServerDialogue, - ) - - -class TestDialogues: - """Tests abci dialogues.""" - - agent_addr: str - server_addr: str - agent_dialogues: AgentDialogues - server_dialogues: ServerDialogues - - @classmethod - def setup_class(cls) -> None: - """Set up the test.""" - cls.agent_addr = "agent address" - cls.server_addr = "server address" - cls.agent_dialogues = AgentDialogues(cls.agent_addr) - cls.server_dialogues = ServerDialogues(cls.server_addr) - - def test_create_self_initiated(self) -> None: - """Test the self initialisation of a dialogue.""" - result = self.agent_dialogues._create_self_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.server_addr, - dialogue_reference=(str(0), ""), - role=AbciDialogue.Role.CLIENT, - ) - assert isinstance(result, AbciDialogue) - assert result.role == AbciDialogue.Role.CLIENT, "The role must be client." - - def test_create_opponent_initiated(self) -> None: - """Test the opponent initialisation of a dialogue.""" - result = self.agent_dialogues._create_opponent_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.server_addr, - dialogue_reference=(str(0), ""), - role=AbciDialogue.Role.CLIENT, - ) - assert isinstance(result, AbciDialogue) - assert result.role == AbciDialogue.Role.CLIENT, "The role must be client." diff --git a/trader_old/vendor/valory/protocols/abci/tests/test_abci_dialogues.py b/trader_old/vendor/valory/protocols/abci/tests/test_abci_dialogues.py deleted file mode 100644 index e6055a9cf..000000000 --- a/trader_old/vendor/valory/protocols/abci/tests/test_abci_dialogues.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for abci protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.abci.dialogues import AbciDialogue, AbciDialogues -from packages.valory.protocols.abci.message import AbciMessage - - -class TestDialoguesAbci(BaseProtocolDialoguesTestCase): - """Test for the 'abci' protocol dialogues.""" - - MESSAGE_CLASS = AbciMessage - - DIALOGUE_CLASS = AbciDialogue - - DIALOGUES_CLASS = AbciDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = AbciDialogue.Role.CLIENT # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=AbciMessage.Performative.REQUEST_ECHO, - message="some str", - ) diff --git a/trader_old/vendor/valory/protocols/abci/tests/test_abci_messages.py b/trader_old/vendor/valory/protocols/abci/tests/test_abci_messages.py deleted file mode 100644 index 40f3a799c..000000000 --- a/trader_old/vendor/valory/protocols/abci/tests/test_abci_messages.py +++ /dev/null @@ -1,491 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for abci protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.abci.custom_types import ( - BlockID, - BlockParams, - CheckTxType, - CheckTxTypeEnum, - ConsensusParams, - ConsensusVersion, - Duration, - Event, - EventAttribute, - Events, - Evidence, - EvidenceParams, - EvidenceType, - Evidences, - Header, - LastCommitInfo, - PartSetHeader, - ProofOp, - ProofOps, - PublicKey, - Result, - ResultType, - SnapShots, - Snapshot, - Timestamp, - Validator, - ValidatorParams, - ValidatorUpdate, - ValidatorUpdates, - VersionParams, - VoteInfo, -) -from packages.valory.protocols.abci.message import AbciMessage - - -event = Event("type", [EventAttribute(b"key", b"value", True)]) -events = Events([event, event]) - -header = Header( - ConsensusVersion(0, 0), - "chain_id", - 0, - Timestamp(0, 0), - BlockID(b"hash", PartSetHeader(0, b"hash")), - b"last_commit_hash", - b"data_hash", - b"validators_hash", - b"next_validators_hash", - b"consensus_hash", - b"app_hash", - b"last_results_hash", - b"evidence_hash", - b"proposer_address", -) - -validator = Validator(b"address", 0) -last_commit_info = LastCommitInfo( - 0, - [ - VoteInfo(validator, True), - VoteInfo(validator, False), - ], -) - -consensus_params = ConsensusParams( - BlockParams(0, 0), - EvidenceParams(0, Duration(0, 0), 0), - ValidatorParams(["pub_key"]), - VersionParams(0), -) - -evidences = Evidences( - [ - Evidence(EvidenceType.UNKNOWN, validator, 0, Timestamp(0, 0), 0), - Evidence(EvidenceType.DUPLICATE_VOTE, validator, 0, Timestamp(0, 0), 0), - ] -) - - -validators = ValidatorUpdates( - [ - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.ed25519), 1 - ), - ValidatorUpdate( - PublicKey(b"pub_key_bytes", PublicKey.PublicKeyType.secp256k1), 2 - ), - ] -) -snapshot = Snapshot(0, 0, 0, b"hash", b"metadata") -snapshots = SnapShots([snapshot, snapshot]) -proof_ops = ( - ProofOps( - [ - ProofOp("type", b"key", b"data"), - ProofOp("type", b"key", b"data"), - ] - ), -) - - -class TestMessageAbci(BaseProtocolMessagesTestCase): - """Test for the 'abci' protocol message.""" - - MESSAGE_CLASS = AbciMessage - - def build_messages(self) -> List[AbciMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - AbciMessage( - performative=AbciMessage.Performative.REQUEST_ECHO, - message="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_FLUSH, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_INFO, - version="some str", - block_version=12, - p2p_version=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_SET_OPTION, - option_key="some str", - option_value="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_INIT_CHAIN, - time=Timestamp(seconds=1, nanos=1), - chain_id="some str", - consensus_params=consensus_params, - validators=validators, - app_state_bytes=b"some_bytes", - initial_height=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_QUERY, - query_data=b"some_bytes", - path="some str", - height=12, - prove=True, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_BEGIN_BLOCK, - hash=b"some_bytes", - header=header, - last_commit_info=last_commit_info, - byzantine_validators=evidences, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_CHECK_TX, - tx=b"some_bytes", - type=CheckTxType(CheckTxTypeEnum.NEW), - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - tx=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_END_BLOCK, - height=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_COMMIT, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT, - snapshot=Snapshot(0, 0, 0, b"hash", b"metadata"), - app_hash=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK, - height=12, - format=12, - chunk_index=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK, - index=12, - chunk=b"some_bytes", - chunk_sender="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_EXCEPTION, - error="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_ECHO, - message="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_FLUSH, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_INFO, - info_data="some str", - version="some str", - app_version=12, - last_block_height=12, - last_block_app_hash=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_SET_OPTION, - code=12, - log="some str", - info="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_INIT_CHAIN, - consensus_params=consensus_params, - validators=validators, - app_hash=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_QUERY, - code=12, - log="some str", - info="some str", - index=12, - key=b"some_bytes", - value=b"some_bytes", - proof_ops=ProofOps( - [ - ProofOp("type", b"key", b"data"), - ProofOp("type", b"key", b"data"), - ] - ), - height=12, - codespace="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, - events=events, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, - code=12, - data=b"some_bytes", - log="some str", - info="some str", - gas_wanted=12, - gas_used=12, - events=events, - codespace="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, - code=12, - data=b"some_bytes", - log="some str", - info="some str", - gas_wanted=12, - gas_used=12, - events=events, - codespace="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_END_BLOCK, - validator_updates=validators, - consensus_param_updates=consensus_params, - events=events, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_COMMIT, - data=b"some_bytes", - retain_height=12, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, - snapshots=snapshots, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, - result=Result(ResultType.UNKNOWN), - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, - chunk=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, - result=Result(ResultType.UNKNOWN), - refetch_chunks=(12,), - reject_senders=("some str",), - ), - AbciMessage( - performative=AbciMessage.Performative.DUMMY, - dummy_consensus_params=consensus_params, - ), - ] - - def build_inconsistent(self) -> List[AbciMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - AbciMessage( - performative=AbciMessage.Performative.REQUEST_ECHO, - # skip content: message - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_INFO, - # skip content: version - block_version=12, - p2p_version=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_SET_OPTION, - # skip content: option_key - option_value="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_INIT_CHAIN, - # skip content: time,app_state_bytes - chain_id="some str", - consensus_params=consensus_params, - validators=validators, - initial_height=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_QUERY, - # skip content: query_data - path="some str", - height=12, - prove=True, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_BEGIN_BLOCK, - # skip content: hash - header=header, - last_commit_info=last_commit_info, - byzantine_validators=evidences, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_CHECK_TX, - # skip content: tx - type=CheckTxType(CheckTxTypeEnum.NEW), - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - # skip content: tx - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_END_BLOCK, - # skip content: height - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT, - # skip content: snapshot - app_hash=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK, - # skip content: height - format=12, - chunk_index=12, - ), - AbciMessage( - performative=AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK, - # skip content: index - chunk=b"some_bytes", - chunk_sender="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_EXCEPTION, - # skip content: error - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_ECHO, - # skip content: message - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_INFO, - # skip content: info_data - version="some str", - app_version=12, - last_block_height=12, - last_block_app_hash=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_SET_OPTION, - # skip content: code - log="some str", - info="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_INIT_CHAIN, - # skip content: consensus_params, validators - app_hash=b"some_bytes", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_QUERY, - # skip content: code - log="some str", - info="some str", - index=12, - key=b"some_bytes", - value=b"some_bytes", - proof_ops=proof_ops, - height=12, - codespace="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, - # skip content: events - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, - # skip content: code - data=b"some_bytes", - log="some str", - info="some str", - gas_wanted=12, - gas_used=12, - events=events, - codespace="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, - # skip content: code - data=b"some_bytes", - log="some str", - info="some str", - gas_wanted=12, - gas_used=12, - events=events, - codespace="some str", - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_END_BLOCK, - # skip content: validator_updates - consensus_param_updates=consensus_params, - events=events, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_COMMIT, - # skip content: data - retain_height=12, - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, - # skip content: snapshots - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, - # skip content: result - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, - # skip content: chunk - ), - AbciMessage( - performative=AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, - # skip content: result - refetch_chunks=(12,), - reject_senders=("some str",), - ), - AbciMessage( - performative=AbciMessage.Performative.DUMMY, - # skip content: dummy_consensus_params - ), - ] diff --git a/trader_old/vendor/valory/protocols/acn/README.md b/trader_old/vendor/valory/protocols/acn/README.md deleted file mode 100644 index 7c44e6b2d..000000000 --- a/trader_old/vendor/valory/protocols/acn/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# ACN Protocol - -## Description - -This is a protocol for ACN (agent communication network) envelope delivery. - -## Specification - -```yaml ---- -name: acn -author: valory -version: 1.1.0 -description: The protocol used for envelope delivery on the ACN. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: aea/acn:1.0.0 -speech_acts: - register: - record: ct:AgentRecord - lookup_request: - agent_address: pt:str - lookup_response: - record: ct:AgentRecord - aea_envelope: - envelope: pt:bytes - record: ct:AgentRecord - status: - body: ct:StatusBody -... ---- -ct:AgentRecord: - string service_id = 1; - string ledger_id = 2; - string address = 3; - string public_key = 4; - string peer_public_key = 5; - string signature = 6; - string not_before = 7; - string not_after = 8; -ct:StatusBody: | - enum StatusCodeEnum { - // common (0x) - SUCCESS = 0; - ERROR_UNSUPPORTED_VERSION = 1; - ERROR_UNEXPECTED_PAYLOAD = 2; - ERROR_GENERIC = 3; - ERROR_DECODE = 4; - // register (1x) - ERROR_WRONG_AGENT_ADDRESS = 10; - ERROR_WRONG_PUBLIC_KEY = 11; - ERROR_INVALID_PROOF = 12; - ERROR_UNSUPPORTED_LEDGER = 13; - // lookup & delivery (2x) - ERROR_UNKNOWN_AGENT_ADDRESS = 20; - ERROR_AGENT_NOT_READY = 21; - } - StatusCodeEnum code = 1; - repeated string msgs = 2; -... ---- -initiation: [register, lookup_request, aea_envelope] -reply: - register: [status] - lookup_request: [lookup_response, status] - aea_envelope: [status] - status: [] - lookup_response: [] -termination: [status, lookup_response] -roles: {node} -end_states: [successful, failed] -keep_terminal_state_dialogues: false -... -``` - -## Links diff --git a/trader_old/vendor/valory/protocols/acn/__init__.py b/trader_old/vendor/valory/protocols/acn/__init__.py deleted file mode 100644 index 6d72792dc..000000000 --- a/trader_old/vendor/valory/protocols/acn/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the acn protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.acn.message import AcnMessage -from packages.valory.protocols.acn.serialization import AcnSerializer - - -AcnMessage.serializer = AcnSerializer diff --git a/trader_old/vendor/valory/protocols/acn/acn.proto b/trader_old/vendor/valory/protocols/acn/acn.proto deleted file mode 100644 index a2c2dc25d..000000000 --- a/trader_old/vendor/valory/protocols/acn/acn.proto +++ /dev/null @@ -1,71 +0,0 @@ -syntax = "proto3"; - -package aea.aea.acn.v1_0_0; - -message AcnMessage{ - - // Custom Types - message AgentRecord{ - string service_id = 1; - string ledger_id = 2; - string address = 3; - string public_key = 4; - string peer_public_key = 5; - string signature = 6; - string not_before = 7; - string not_after = 8; - } - - message StatusBody{ - enum StatusCodeEnum { - // common (0x) - SUCCESS = 0; - ERROR_UNSUPPORTED_VERSION = 1; - ERROR_UNEXPECTED_PAYLOAD = 2; - ERROR_GENERIC = 3; - ERROR_DECODE = 4; - // register (1x) - ERROR_WRONG_AGENT_ADDRESS = 10; - ERROR_WRONG_PUBLIC_KEY = 11; - ERROR_INVALID_PROOF = 12; - ERROR_UNSUPPORTED_LEDGER = 13; - // lookup & delivery (2x) - ERROR_UNKNOWN_AGENT_ADDRESS = 20; - ERROR_AGENT_NOT_READY = 21; - } - StatusCodeEnum code = 1; - repeated string msgs = 2; - } - - - // Performatives and contents - message Register_Performative{ - AgentRecord record = 1; - } - - message Lookup_Request_Performative{ - string agent_address = 1; - } - - message Lookup_Response_Performative{ - AgentRecord record = 1; - } - - message Aea_Envelope_Performative{ - bytes envelope = 1; - AgentRecord record = 2; - } - - message Status_Performative{ - StatusBody body = 1; - } - - - oneof performative{ - Aea_Envelope_Performative aea_envelope = 5; - Lookup_Request_Performative lookup_request = 6; - Lookup_Response_Performative lookup_response = 7; - Register_Performative register = 8; - Status_Performative status = 9; - } -} diff --git a/trader_old/vendor/valory/protocols/acn/acn_pb2.py b/trader_old/vendor/valory/protocols/acn/acn_pb2.py deleted file mode 100644 index 9047a16ea..000000000 --- a/trader_old/vendor/valory/protocols/acn/acn_pb2.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: acn.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\tacn.proto\x12\x12\x61\x65\x61.aea.acn.v1_0_0"\x92\x0b\n\nAcnMessage\x12P\n\x0c\x61\x65\x61_envelope\x18\x05 \x01(\x0b\x32\x38.aea.aea.acn.v1_0_0.AcnMessage.Aea_Envelope_PerformativeH\x00\x12T\n\x0elookup_request\x18\x06 \x01(\x0b\x32:.aea.aea.acn.v1_0_0.AcnMessage.Lookup_Request_PerformativeH\x00\x12V\n\x0flookup_response\x18\x07 \x01(\x0b\x32;.aea.aea.acn.v1_0_0.AcnMessage.Lookup_Response_PerformativeH\x00\x12H\n\x08register\x18\x08 \x01(\x0b\x32\x34.aea.aea.acn.v1_0_0.AcnMessage.Register_PerformativeH\x00\x12\x44\n\x06status\x18\t \x01(\x0b\x32\x32.aea.aea.acn.v1_0_0.AcnMessage.Status_PerformativeH\x00\x1a\xac\x01\n\x0b\x41gentRecord\x12\x12\n\nservice_id\x18\x01 \x01(\t\x12\x11\n\tledger_id\x18\x02 \x01(\t\x12\x0f\n\x07\x61\x64\x64ress\x18\x03 \x01(\t\x12\x12\n\npublic_key\x18\x04 \x01(\t\x12\x17\n\x0fpeer_public_key\x18\x05 \x01(\t\x12\x11\n\tsignature\x18\x06 \x01(\t\x12\x12\n\nnot_before\x18\x07 \x01(\t\x12\x11\n\tnot_after\x18\x08 \x01(\t\x1a\x92\x03\n\nStatusBody\x12\x46\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x38.aea.aea.acn.v1_0_0.AcnMessage.StatusBody.StatusCodeEnum\x12\x0c\n\x04msgs\x18\x02 \x03(\t"\xad\x02\n\x0eStatusCodeEnum\x12\x0b\n\x07SUCCESS\x10\x00\x12\x1d\n\x19\x45RROR_UNSUPPORTED_VERSION\x10\x01\x12\x1c\n\x18\x45RROR_UNEXPECTED_PAYLOAD\x10\x02\x12\x11\n\rERROR_GENERIC\x10\x03\x12\x10\n\x0c\x45RROR_DECODE\x10\x04\x12\x1d\n\x19\x45RROR_WRONG_AGENT_ADDRESS\x10\n\x12\x1a\n\x16\x45RROR_WRONG_PUBLIC_KEY\x10\x0b\x12\x17\n\x13\x45RROR_INVALID_PROOF\x10\x0c\x12\x1c\n\x18\x45RROR_UNSUPPORTED_LEDGER\x10\r\x12\x1f\n\x1b\x45RROR_UNKNOWN_AGENT_ADDRESS\x10\x14\x12\x19\n\x15\x45RROR_AGENT_NOT_READY\x10\x15\x1aS\n\x15Register_Performative\x12:\n\x06record\x18\x01 \x01(\x0b\x32*.aea.aea.acn.v1_0_0.AcnMessage.AgentRecord\x1a\x34\n\x1bLookup_Request_Performative\x12\x15\n\ragent_address\x18\x01 \x01(\t\x1aZ\n\x1cLookup_Response_Performative\x12:\n\x06record\x18\x01 \x01(\x0b\x32*.aea.aea.acn.v1_0_0.AcnMessage.AgentRecord\x1ai\n\x19\x41\x65\x61_Envelope_Performative\x12\x10\n\x08\x65nvelope\x18\x01 \x01(\x0c\x12:\n\x06record\x18\x02 \x01(\x0b\x32*.aea.aea.acn.v1_0_0.AcnMessage.AgentRecord\x1aN\n\x13Status_Performative\x12\x37\n\x04\x62ody\x18\x01 \x01(\x0b\x32).aea.aea.acn.v1_0_0.AcnMessage.StatusBodyB\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "acn_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals["_ACNMESSAGE"]._serialized_start = 34 - _globals["_ACNMESSAGE"]._serialized_end = 1460 - _globals["_ACNMESSAGE_AGENTRECORD"]._serialized_start = 449 - _globals["_ACNMESSAGE_AGENTRECORD"]._serialized_end = 621 - _globals["_ACNMESSAGE_STATUSBODY"]._serialized_start = 624 - _globals["_ACNMESSAGE_STATUSBODY"]._serialized_end = 1026 - _globals["_ACNMESSAGE_STATUSBODY_STATUSCODEENUM"]._serialized_start = 725 - _globals["_ACNMESSAGE_STATUSBODY_STATUSCODEENUM"]._serialized_end = 1026 - _globals["_ACNMESSAGE_REGISTER_PERFORMATIVE"]._serialized_start = 1028 - _globals["_ACNMESSAGE_REGISTER_PERFORMATIVE"]._serialized_end = 1111 - _globals["_ACNMESSAGE_LOOKUP_REQUEST_PERFORMATIVE"]._serialized_start = 1113 - _globals["_ACNMESSAGE_LOOKUP_REQUEST_PERFORMATIVE"]._serialized_end = 1165 - _globals["_ACNMESSAGE_LOOKUP_RESPONSE_PERFORMATIVE"]._serialized_start = 1167 - _globals["_ACNMESSAGE_LOOKUP_RESPONSE_PERFORMATIVE"]._serialized_end = 1257 - _globals["_ACNMESSAGE_AEA_ENVELOPE_PERFORMATIVE"]._serialized_start = 1259 - _globals["_ACNMESSAGE_AEA_ENVELOPE_PERFORMATIVE"]._serialized_end = 1364 - _globals["_ACNMESSAGE_STATUS_PERFORMATIVE"]._serialized_start = 1366 - _globals["_ACNMESSAGE_STATUS_PERFORMATIVE"]._serialized_end = 1444 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/protocols/acn/custom_types.py b/trader_old/vendor/valory/protocols/acn/custom_types.py deleted file mode 100644 index bb7069c1c..000000000 --- a/trader_old/vendor/valory/protocols/acn/custom_types.py +++ /dev/null @@ -1,224 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 class representations corresponding to every custom type in the protocol specification.""" -# pylint: disable-all -from enum import Enum -from typing import Any, List - -from aea.helpers.base import SimpleId, SimpleIdOrStr - - -class AgentRecord: - """ - This class represents an instance of AgentRecord. - - Eventually needs to be unified with `aea.helpers.acn.agent_record`. - """ - - __slots__ = ( - "_address", - "_public_key", - "_peer_public_key", - "_signature", - "_service_id", - "_ledger_id", - "_message_format", - "_message", - ) - - def __init__( - self, - address: str, - public_key: str, - peer_public_key: str, - signature: str, - service_id: SimpleIdOrStr, - ledger_id: SimpleIdOrStr, - ) -> None: - """Initialise an instance of AgentRecord.""" - self._address = address - self._public_key = public_key - self._peer_public_key = peer_public_key - self._signature = signature - self._service_id = str(SimpleId(service_id)) - self._ledger_id = str(SimpleId(ledger_id)) - - @property - def address(self) -> str: - """Get agent address""" - return self._address - - @property - def public_key(self) -> str: - """Get agent public key""" - return self._public_key - - @property - def peer_public_key(self) -> str: - """Get agent representative's public key""" - return self._peer_public_key - - @property - def signature(self) -> str: - """Get record signature""" - return self._signature - - @property - def service_id(self) -> SimpleIdOrStr: - """Get the identifier.""" - return self._service_id - - @property - def ledger_id(self) -> SimpleIdOrStr: - """Get ledger id.""" - return self._ledger_id - - @staticmethod - def encode( - agent_record_protobuf_object: Any, agent_record_object: "AgentRecord" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the agent_record_protobuf_object argument is matched with the instance of this class in the 'agent_record_object' argument. - - :param agent_record_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param agent_record_object: an instance of this class to be encoded in the protocol buffer object. - """ - agent_record_protobuf_object.address = agent_record_object.address - agent_record_protobuf_object.public_key = agent_record_object.public_key - agent_record_protobuf_object.peer_public_key = ( - agent_record_object.peer_public_key - ) - agent_record_protobuf_object.signature = agent_record_object.signature - agent_record_protobuf_object.service_id = agent_record_object.service_id - agent_record_protobuf_object.ledger_id = agent_record_object.ledger_id - - @classmethod - def decode(cls, agent_record_protobuf_object: Any) -> "AgentRecord": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'agent_record_protobuf_object' argument. - - :param agent_record_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'agent_record_protobuf_object' argument. - """ - record = cls( - address=agent_record_protobuf_object.address, - public_key=agent_record_protobuf_object.public_key, - peer_public_key=agent_record_protobuf_object.peer_public_key, - signature=agent_record_protobuf_object.signature, - service_id=agent_record_protobuf_object.service_id, - ledger_id=agent_record_protobuf_object.ledger_id, - ) - return record - - def __eq__(self, other: Any) -> bool: - """Compare to objects of this class.""" - return ( - isinstance(other, AgentRecord) - and self.address == other.address - and self.public_key == other.public_key - ) - - -class StatusBody: - """This class represents an instance of StatusBody.""" - - __slots__ = ( - "_status_code", - "_msgs", - ) - - class StatusCode(Enum): - """Status code enum.""" - - SUCCESS = 0 - ERROR_UNSUPPORTED_VERSION = 1 - ERROR_UNEXPECTED_PAYLOAD = 2 - ERROR_GENERIC = 3 - ERROR_DECODE = 4 - - ERROR_WRONG_AGENT_ADDRESS = 10 - ERROR_WRONG_PUBLIC_KEY = 11 - ERROR_INVALID_PROOF = 12 - ERROR_UNSUPPORTED_LEDGER = 13 - - ERROR_UNKNOWN_AGENT_ADDRESS = 20 - ERROR_AGENT_NOT_READY = 21 - - def __int__(self) -> int: - """Get string representation.""" - return self.value - - def __init__(self, status_code: StatusCode, msgs: List[str]) -> None: - """Initialise an instance of StatusBody.""" - self._status_code = status_code - self._msgs = msgs - - @property - def status_code(self) -> "StatusCode": - """Get the status code.""" - return self._status_code - - @property - def msgs(self) -> List[str]: - """Get the list of messages.""" - return self._msgs - - @staticmethod - def encode( - status_body_protobuf_object: Any, status_body_object: "StatusBody" - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the status_body_protobuf_object argument is matched with the instance of this class in the 'status_body_object' argument. - - :param status_body_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param status_body_object: an instance of this class to be encoded in the protocol buffer object. - """ - status_body_protobuf_object.code = int(status_body_object.status_code) - status_body_protobuf_object.msgs.extend(status_body_object.msgs) - - @classmethod - def decode(cls, status_body_protobuf_object: Any) -> "StatusBody": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'status_body_protobuf_object' argument. - - :param status_body_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'status_body_protobuf_object' argument. - """ - status_body = cls( - status_code=cls.StatusCode(status_body_protobuf_object.code), - msgs=status_body_protobuf_object.msgs, - ) - return status_body - - def __eq__(self, other: Any) -> bool: - """Compare to objects of this class.""" - return ( - isinstance(other, StatusBody) - and self.status_code == other.status_code - and self.msgs == other.msgs - ) diff --git a/trader_old/vendor/valory/protocols/acn/dialogues.py b/trader_old/vendor/valory/protocols/acn/dialogues.py deleted file mode 100644 index 90b88ea30..000000000 --- a/trader_old/vendor/valory/protocols/acn/dialogues.py +++ /dev/null @@ -1,126 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for acn dialogue management. - -- AcnDialogue: The dialogue class maintains state of a dialogue and manages it. -- AcnDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.acn.message import AcnMessage - - -class AcnDialogue(Dialogue): - """The acn dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - AcnMessage.Performative.REGISTER, - AcnMessage.Performative.LOOKUP_REQUEST, - AcnMessage.Performative.AEA_ENVELOPE, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - {AcnMessage.Performative.STATUS, AcnMessage.Performative.LOOKUP_RESPONSE} - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - AcnMessage.Performative.AEA_ENVELOPE: frozenset( - {AcnMessage.Performative.STATUS} - ), - AcnMessage.Performative.LOOKUP_REQUEST: frozenset( - {AcnMessage.Performative.LOOKUP_RESPONSE, AcnMessage.Performative.STATUS} - ), - AcnMessage.Performative.LOOKUP_RESPONSE: frozenset(), - AcnMessage.Performative.REGISTER: frozenset({AcnMessage.Performative.STATUS}), - AcnMessage.Performative.STATUS: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a acn dialogue.""" - - NODE = "node" - - class EndState(Dialogue.EndState): - """This class defines the end states of a acn dialogue.""" - - SUCCESSFUL = 0 - FAILED = 1 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[AcnMessage] = AcnMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class AcnDialogues(Dialogues, ABC): - """This class keeps track of all acn dialogues.""" - - END_STATES = frozenset( - {AcnDialogue.EndState.SUCCESSFUL, AcnDialogue.EndState.FAILED} - ) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[AcnDialogue] = AcnDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=AcnMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_old/vendor/valory/protocols/acn/message.py b/trader_old/vendor/valory/protocols/acn/message.py deleted file mode 100644 index 5ef50253e..000000000 --- a/trader_old/vendor/valory/protocols/acn/message.py +++ /dev/null @@ -1,274 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 acn's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - -from packages.valory.protocols.acn.custom_types import AgentRecord as CustomAgentRecord -from packages.valory.protocols.acn.custom_types import StatusBody as CustomStatusBody - - -_default_logger = logging.getLogger("aea.packages.valory.protocols.acn.message") - -DEFAULT_BODY_SIZE = 4 - - -class AcnMessage(Message): - """The protocol used for envelope delivery on the ACN.""" - - protocol_id = PublicId.from_str("valory/acn:1.1.0") - protocol_specification_id = PublicId.from_str("aea/acn:1.0.0") - - AgentRecord = CustomAgentRecord - - StatusBody = CustomStatusBody - - class Performative(Message.Performative): - """Performatives for the acn protocol.""" - - AEA_ENVELOPE = "aea_envelope" - LOOKUP_REQUEST = "lookup_request" - LOOKUP_RESPONSE = "lookup_response" - REGISTER = "register" - STATUS = "status" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = { - "aea_envelope", - "lookup_request", - "lookup_response", - "register", - "status", - } - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "agent_address", - "body", - "dialogue_reference", - "envelope", - "message_id", - "performative", - "record", - "target", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of AcnMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=AcnMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(AcnMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def agent_address(self) -> str: - """Get the 'agent_address' content from the message.""" - enforce(self.is_set("agent_address"), "'agent_address' content is not set.") - return cast(str, self.get("agent_address")) - - @property - def body(self) -> CustomStatusBody: - """Get the 'body' content from the message.""" - enforce(self.is_set("body"), "'body' content is not set.") - return cast(CustomStatusBody, self.get("body")) - - @property - def envelope(self) -> bytes: - """Get the 'envelope' content from the message.""" - enforce(self.is_set("envelope"), "'envelope' content is not set.") - return cast(bytes, self.get("envelope")) - - @property - def record(self) -> CustomAgentRecord: - """Get the 'record' content from the message.""" - enforce(self.is_set("record"), "'record' content is not set.") - return cast(CustomAgentRecord, self.get("record")) - - def _is_consistent(self) -> bool: - """Check that the message follows the acn protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, AcnMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == AcnMessage.Performative.REGISTER: - expected_nb_of_contents = 1 - enforce( - isinstance(self.record, CustomAgentRecord), - "Invalid type for content 'record'. Expected 'AgentRecord'. Found '{}'.".format( - type(self.record) - ), - ) - elif self.performative == AcnMessage.Performative.LOOKUP_REQUEST: - expected_nb_of_contents = 1 - enforce( - isinstance(self.agent_address, str), - "Invalid type for content 'agent_address'. Expected 'str'. Found '{}'.".format( - type(self.agent_address) - ), - ) - elif self.performative == AcnMessage.Performative.LOOKUP_RESPONSE: - expected_nb_of_contents = 1 - enforce( - isinstance(self.record, CustomAgentRecord), - "Invalid type for content 'record'. Expected 'AgentRecord'. Found '{}'.".format( - type(self.record) - ), - ) - elif self.performative == AcnMessage.Performative.AEA_ENVELOPE: - expected_nb_of_contents = 2 - enforce( - isinstance(self.envelope, bytes), - "Invalid type for content 'envelope'. Expected 'bytes'. Found '{}'.".format( - type(self.envelope) - ), - ) - enforce( - isinstance(self.record, CustomAgentRecord), - "Invalid type for content 'record'. Expected 'AgentRecord'. Found '{}'.".format( - type(self.record) - ), - ) - elif self.performative == AcnMessage.Performative.STATUS: - expected_nb_of_contents = 1 - enforce( - isinstance(self.body, CustomStatusBody), - "Invalid type for content 'body'. Expected 'StatusBody'. Found '{}'.".format( - type(self.body) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_old/vendor/valory/protocols/acn/protocol.yaml b/trader_old/vendor/valory/protocols/acn/protocol.yaml deleted file mode 100644 index 2062cfb93..000000000 --- a/trader_old/vendor/valory/protocols/acn/protocol.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: acn -author: valory -version: 1.1.0 -protocol_specification_id: aea/acn:1.0.0 -type: protocol -description: The protocol used for envelope delivery on the ACN. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeie7paijucvzemlfhwfmmhorypwuhzbeimgoitlkokdio5c3ne4pjq - __init__.py: bafybeicqlp4gkeeef5osp6zopjztlgat24nxrzq43cy7wbwxk5omf2sc2m - acn.proto: bafybeidkun7o75sxpyk2sixt7dsykgty62f6dnixnes2irbunyamilqsh4 - acn_pb2.py: bafybeialafz3yomunwa3g5xgrdqwodzl7zg5dncvzuetv7xoew4zhw76ni - custom_types.py: bafybeigpueuq6mdeyjyayzv3menkmemutfgfiwlozlpl64t67cfnnom24q - dialogues.py: bafybeidjpyk7s3getyfegjdrgrt5blf2yutzqclohaktjehwcj3sqx2ole - message.py: bafybeiai7kond3rcbtwnr5xgpwzuauf5tusuep6ikopi4cqvp2wa5qfz3e - serialization.py: bafybeidu7fzixk6sm3iprhph4shbiq5qgvg56lg4yiryfaf3unuqk34bwi - tests/__init__.py: bafybeidteufp2npjd77ekcftk5e4gbaquq3gike5nxtk5xfmnusls56keu - tests/test_acn.py: bafybeignjgdtlfdnj25hc5necmg7zl3kvngsmzkjgcwfm5qg36liqa63ki - tests/test_acn_dialogues.py: bafybeia2kndutaokjpogo4wlb5pf4gkqacvcbngqromf4g4mzu6wyetz7q - tests/test_acn_messages.py: bafybeigriniqu3tfzeok7rjx3widzclyjqgjhkunkgt657lpng23mo7oxa -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_old/vendor/valory/protocols/acn/serialization.py b/trader_old/vendor/valory/protocols/acn/serialization.py deleted file mode 100644 index 4bf68c321..000000000 --- a/trader_old/vendor/valory/protocols/acn/serialization.py +++ /dev/null @@ -1,149 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for acn protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.acn import acn_pb2 # type: ignore -from packages.valory.protocols.acn.custom_types import ( # type: ignore - AgentRecord, - StatusBody, -) -from packages.valory.protocols.acn.message import AcnMessage # type: ignore - - -class AcnSerializer(Serializer): - """Serialization for the 'acn' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'Acn' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(AcnMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - acn_msg = acn_pb2.AcnMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == AcnMessage.Performative.REGISTER: - performative = acn_pb2.AcnMessage.Register_Performative() # type: ignore - record = msg.record - AgentRecord.encode(performative.record, record) - acn_msg.register.CopyFrom(performative) - elif performative_id == AcnMessage.Performative.LOOKUP_REQUEST: - performative = acn_pb2.AcnMessage.Lookup_Request_Performative() # type: ignore - agent_address = msg.agent_address - performative.agent_address = agent_address - acn_msg.lookup_request.CopyFrom(performative) - elif performative_id == AcnMessage.Performative.LOOKUP_RESPONSE: - performative = acn_pb2.AcnMessage.Lookup_Response_Performative() # type: ignore - record = msg.record - AgentRecord.encode(performative.record, record) - acn_msg.lookup_response.CopyFrom(performative) - elif performative_id == AcnMessage.Performative.AEA_ENVELOPE: - performative = acn_pb2.AcnMessage.Aea_Envelope_Performative() # type: ignore - envelope = msg.envelope - performative.envelope = envelope - record = msg.record - AgentRecord.encode(performative.record, record) - acn_msg.aea_envelope.CopyFrom(performative) - elif performative_id == AcnMessage.Performative.STATUS: - performative = acn_pb2.AcnMessage.Status_Performative() # type: ignore - body = msg.body - StatusBody.encode(performative.body, body) - acn_msg.status.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = acn_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'Acn' message. - - :param obj: the bytes object. - :return: the 'Acn' message. - """ - message_pb = ProtobufMessage() - acn_pb = acn_pb2.AcnMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - acn_pb.ParseFromString(message_pb.dialogue_message.content) - performative = acn_pb.WhichOneof("performative") - performative_id = AcnMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == AcnMessage.Performative.REGISTER: - pb2_record = acn_pb.register.record - record = AgentRecord.decode(pb2_record) - performative_content["record"] = record - elif performative_id == AcnMessage.Performative.LOOKUP_REQUEST: - agent_address = acn_pb.lookup_request.agent_address - performative_content["agent_address"] = agent_address - elif performative_id == AcnMessage.Performative.LOOKUP_RESPONSE: - pb2_record = acn_pb.lookup_response.record - record = AgentRecord.decode(pb2_record) - performative_content["record"] = record - elif performative_id == AcnMessage.Performative.AEA_ENVELOPE: - envelope = acn_pb.aea_envelope.envelope - performative_content["envelope"] = envelope - pb2_record = acn_pb.aea_envelope.record - record = AgentRecord.decode(pb2_record) - performative_content["record"] = record - elif performative_id == AcnMessage.Performative.STATUS: - pb2_body = acn_pb.status.body - body = StatusBody.decode(pb2_body) - performative_content["body"] = body - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return AcnMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_old/vendor/valory/protocols/acn/tests/__init__.py b/trader_old/vendor/valory/protocols/acn/tests/__init__.py deleted file mode 100644 index 0ca8df4d2..000000000 --- a/trader_old/vendor/valory/protocols/acn/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""The tests module contains the tests of the acn protocol.""" diff --git a/trader_old/vendor/valory/protocols/acn/tests/test_acn.py b/trader_old/vendor/valory/protocols/acn/tests/test_acn.py deleted file mode 100644 index efd8dfa95..000000000 --- a/trader_old/vendor/valory/protocols/acn/tests/test_acn.py +++ /dev/null @@ -1,256 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 the tests of the messages module.""" - -from typing import Type -from unittest import mock -from unittest.mock import patch - -import pytest - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.acn.dialogues import AcnDialogue as BaseAcnDialogue -from packages.valory.protocols.acn.dialogues import AcnDialogues as BaseAcnDialogues -from packages.valory.protocols.acn.message import AcnMessage - - -def test_acn_aea_envelope_serialization(): - """Test that the serialization for the 'simple' protocol works for the AEA_ENVELOPE message.""" - expected_msg = AcnMessage( - dialogue_reference=("", ""), - message_id=1, - target=0, - performative=AcnMessage.Performative.AEA_ENVELOPE, - envelope=b"envelope", - record=AcnMessage.AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ) - msg_bytes = AcnMessage.serializer.encode(expected_msg) - actual_msg = AcnMessage.serializer.decode(msg_bytes) - assert expected_msg == actual_msg - - -def test_acn_lookup_request_serialization(): - """Test that the serialization for the 'simple' protocol works for the LOOKUP_REQUEST message.""" - msg = AcnMessage( - dialogue_reference=("", ""), - message_id=1, - target=0, - performative=AcnMessage.Performative.LOOKUP_REQUEST, - agent_address="some_address", - ) - msg_bytes = AcnMessage.serializer.encode(msg) - actual_msg = AcnMessage.serializer.decode(msg_bytes) - expected_msg = msg - assert expected_msg == actual_msg - - -def test_acn_lookup_response_serialization(): - """Test that the serialization for the 'simple' protocol works for the LOOKUP_RESPONSE message.""" - msg = AcnMessage( - dialogue_reference=("", ""), - message_id=1, - target=0, - performative=AcnMessage.Performative.LOOKUP_RESPONSE, - record=AcnMessage.AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ) - msg_bytes = AcnMessage.serializer.encode(msg) - actual_msg = AcnMessage.serializer.decode(msg_bytes) - expected_msg = msg - assert expected_msg == actual_msg - - -def test_acn_record_serialization(): - """Test that the serialization for the 'simple' protocol works for the REGISTER message.""" - msg = AcnMessage( - dialogue_reference=("", ""), - message_id=1, - target=0, - performative=AcnMessage.Performative.REGISTER, - record=AcnMessage.AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ) - msg_bytes = AcnMessage.serializer.encode(msg) - actual_msg = AcnMessage.serializer.decode(msg_bytes) - expected_msg = msg - assert expected_msg == actual_msg - - -def test_acn_status_serialization(): - """Test that the serialization for the 'simple' protocol works for the STATUS message.""" - msg = AcnMessage( - dialogue_reference=("", ""), - message_id=1, - target=0, - performative=AcnMessage.Performative.STATUS, - body=AcnMessage.StatusBody( - status_code=AcnMessage.StatusBody.StatusCode.ERROR_UNSUPPORTED_VERSION, - msgs=["pbk"], - ), - ) - msg_bytes = AcnMessage.serializer.encode(msg) - actual_msg = AcnMessage.serializer.decode(msg_bytes) - expected_msg = msg - assert expected_msg == actual_msg - - -def test_acn_message_str_values(): - """Tests the returned string values of acn Message.""" - assert ( - str(AcnMessage.Performative.LOOKUP_REQUEST) == "lookup_request" - ), "AcnMessage.Performative.LOOKUP_REQUEST must be lookup_request" - - -def test_encoding_unknown_performative(): - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = AcnMessage( - performative=AcnMessage.Performative.LOOKUP_REQUEST, - agent_address="address", - ) - - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object(AcnMessage.Performative, "__eq__", return_value=False): - AcnMessage.serializer.encode(msg) - - -def test_check_consistency_raises_exception_when_type_not_recognized(): - """Test that we raise exception when the type of the message is not recognized.""" - message = AcnMessage( - dialogue_reference=("", ""), - message_id=1, - target=0, - performative=AcnMessage.Performative.LOOKUP_REQUEST, - agent_address="address", - ) - # mock the __eq__ method such that any kind of matching is going to fail. - with mock.patch.object(AcnMessage.Performative, "__eq__", return_value=False): - assert not message._is_consistent() # pylint: disable=protected-access - - -def test_acn_valid_performatives(): - """Test 'valid_performatives' getter.""" - msg = AcnMessage(AcnMessage.Performative.LOOKUP_REQUEST, agent_address="address") - assert msg.valid_performatives == set( - map(lambda x: x.value, iter(AcnMessage.Performative)) - ) - - -def test_serializer_performative_not_found(): - """Test the serializer when the performative is not found.""" - message = AcnMessage( - message_id=1, - target=0, - performative=AcnMessage.Performative.LOOKUP_REQUEST, - agent_address="address", - ) - message_bytes = message.serializer.encode(message) - with patch.object(AcnMessage.Performative, "__eq__", return_value=False): - with pytest.raises(ValueError, match="Performative not valid: .*"): - message.serializer.decode(message_bytes) - - -def test_dialogues(): - """Test intiaontiation of dialogues.""" - acn_dialogues = AcnDialogues("agent_addr") - _, dialogue = acn_dialogues.create( - counterparty="abc", - performative=AcnMessage.Performative.LOOKUP_REQUEST, - agent_address="address", - ) - assert dialogue is not None - - -class AcnDialogue(BaseAcnDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[AcnMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - BaseAcnDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class AcnDialogues(BaseAcnDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity that this dialogues is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AcnDialogue.Role.NODE - - BaseAcnDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=AcnDialogue, - ) diff --git a/trader_old/vendor/valory/protocols/acn/tests/test_acn_dialogues.py b/trader_old/vendor/valory/protocols/acn/tests/test_acn_dialogues.py deleted file mode 100644 index 825bc14c0..000000000 --- a/trader_old/vendor/valory/protocols/acn/tests/test_acn_dialogues.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for acn protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.acn.custom_types import AgentRecord -from packages.valory.protocols.acn.dialogues import AcnDialogue, AcnDialogues -from packages.valory.protocols.acn.message import AcnMessage - - -class TestDialoguesAcn(BaseProtocolDialoguesTestCase): - """Test for the 'acn' protocol dialogues.""" - - MESSAGE_CLASS = AcnMessage - - DIALOGUE_CLASS = AcnDialogue - - DIALOGUES_CLASS = AcnDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = AcnDialogue.Role.NODE # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=AcnMessage.Performative.REGISTER, - record=AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ) diff --git a/trader_old/vendor/valory/protocols/acn/tests/test_acn_messages.py b/trader_old/vendor/valory/protocols/acn/tests/test_acn_messages.py deleted file mode 100644 index 35dedd070..000000000 --- a/trader_old/vendor/valory/protocols/acn/tests/test_acn_messages.py +++ /dev/null @@ -1,117 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for acn protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.acn.custom_types import AgentRecord, StatusBody -from packages.valory.protocols.acn.message import AcnMessage - - -class TestMessageAcn(BaseProtocolMessagesTestCase): - """Test for the 'acn' protocol message.""" - - MESSAGE_CLASS = AcnMessage - - def build_messages(self) -> List[AcnMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - AcnMessage( - performative=AcnMessage.Performative.REGISTER, - record=AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ), - AcnMessage( - performative=AcnMessage.Performative.LOOKUP_REQUEST, - agent_address="some str", - ), - AcnMessage( - performative=AcnMessage.Performative.LOOKUP_RESPONSE, - record=AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ), - AcnMessage( - performative=AcnMessage.Performative.AEA_ENVELOPE, - envelope=b"some_bytes", - record=AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ), - AcnMessage( - performative=AcnMessage.Performative.STATUS, - body=StatusBody( - status_code=AcnMessage.StatusBody.StatusCode.ERROR_UNSUPPORTED_VERSION, - msgs=["pbk"], - ), - ), - ] - - def build_inconsistent(self) -> List[AcnMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - AcnMessage( - performative=AcnMessage.Performative.REGISTER, - # skip content: record - ), - AcnMessage( - performative=AcnMessage.Performative.LOOKUP_REQUEST, - # skip content: agent_address - ), - AcnMessage( - performative=AcnMessage.Performative.LOOKUP_RESPONSE, - # skip content: record - ), - AcnMessage( - performative=AcnMessage.Performative.AEA_ENVELOPE, - # skip content: envelope - record=AgentRecord( - address="address", - public_key="pbk", - peer_public_key="peerpbk", - signature="sign", - service_id="acn", - ledger_id="fetchai", - ), - ), - AcnMessage( - performative=AcnMessage.Performative.STATUS, - # skip content: body - ), - ] diff --git a/trader_old/vendor/valory/protocols/contract_api/README.md b/trader_old/vendor/valory/protocols/contract_api/README.md deleted file mode 100644 index 5aff863d1..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# Contract API Protocol - -## Description - -This is a protocol for contract APIs' requests and responses. - -## Specification - -```yaml ---- -name: contract_api -author: valory -version: 1.0.0 -description: A protocol for contract APIs requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: valory/contract_api:1.0.0 -speech_acts: - get_deploy_transaction: - ledger_id: pt:str - contract_id: pt:str - callable: pt:str - kwargs: ct:Kwargs - get_raw_transaction: - ledger_id: pt:str - contract_id: pt:str - contract_address: pt:str - callable: pt:str - kwargs: ct:Kwargs - get_raw_message: - ledger_id: pt:str - contract_id: pt:str - contract_address: pt:str - callable: pt:str - kwargs: ct:Kwargs - get_state: - ledger_id: pt:str - contract_id: pt:str - contract_address: pt:str - callable: pt:str - kwargs: ct:Kwargs - state: - state: ct:State - raw_transaction: - raw_transaction: ct:RawTransaction - raw_message: - raw_message: ct:RawMessage - error: - code: pt:optional[pt:int] - message: pt:optional[pt:str] - data: pt:bytes -... ---- -ct:Kwargs: - bytes kwargs = 1; -ct:State: - bytes state = 1; -ct:RawTransaction: - bytes raw_transaction = 1; -ct:RawMessage: - bytes raw_message = 1; -... ---- -initiation: [get_deploy_transaction, get_raw_transaction, get_raw_message, get_state] -reply: - get_deploy_transaction: [raw_transaction, error] - get_raw_transaction: [raw_transaction, error] - get_raw_message: [raw_message, error] - get_state: [state, error] - raw_transaction: [] - raw_message: [] - state: [] - error: [] -termination: [state, raw_transaction, raw_message, error] -roles: {agent, ledger} -end_states: [successful, failed] -keep_terminal_state_dialogues: false -... -``` - -## Links diff --git a/trader_old/vendor/valory/protocols/contract_api/__init__.py b/trader_old/vendor/valory/protocols/contract_api/__init__.py deleted file mode 100644 index 700b8ef27..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the contract_api protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.contract_api.message import ContractApiMessage -from packages.valory.protocols.contract_api.serialization import ContractApiSerializer - - -ContractApiMessage.serializer = ContractApiSerializer diff --git a/trader_old/vendor/valory/protocols/contract_api/contract_api.proto b/trader_old/vendor/valory/protocols/contract_api/contract_api.proto deleted file mode 100644 index f330d75bb..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/contract_api.proto +++ /dev/null @@ -1,88 +0,0 @@ -syntax = "proto3"; - -package aea.valory.contract_api.v1_0_0; - -message ContractApiMessage{ - - // Custom Types - message Kwargs{ - bytes kwargs = 1; - } - - message RawMessage{ - bytes raw_message = 1; - } - - message RawTransaction{ - bytes raw_transaction = 1; - } - - message State{ - bytes state = 1; - } - - - // Performatives and contents - message Get_Deploy_Transaction_Performative{ - string ledger_id = 1; - string contract_id = 2; - string callable = 3; - Kwargs kwargs = 4; - } - - message Get_Raw_Transaction_Performative{ - string ledger_id = 1; - string contract_id = 2; - string contract_address = 3; - string callable = 4; - Kwargs kwargs = 5; - } - - message Get_Raw_Message_Performative{ - string ledger_id = 1; - string contract_id = 2; - string contract_address = 3; - string callable = 4; - Kwargs kwargs = 5; - } - - message Get_State_Performative{ - string ledger_id = 1; - string contract_id = 2; - string contract_address = 3; - string callable = 4; - Kwargs kwargs = 5; - } - - message State_Performative{ - State state = 1; - } - - message Raw_Transaction_Performative{ - RawTransaction raw_transaction = 1; - } - - message Raw_Message_Performative{ - RawMessage raw_message = 1; - } - - message Error_Performative{ - int32 code = 1; - bool code_is_set = 2; - string message = 3; - bool message_is_set = 4; - bytes data = 5; - } - - - oneof performative{ - Error_Performative error = 5; - Get_Deploy_Transaction_Performative get_deploy_transaction = 6; - Get_Raw_Message_Performative get_raw_message = 7; - Get_Raw_Transaction_Performative get_raw_transaction = 8; - Get_State_Performative get_state = 9; - Raw_Message_Performative raw_message = 10; - Raw_Transaction_Performative raw_transaction = 11; - State_Performative state = 12; - } -} diff --git a/trader_old/vendor/valory/protocols/contract_api/contract_api_pb2.py b/trader_old/vendor/valory/protocols/contract_api/contract_api_pb2.py deleted file mode 100644 index f09367621..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/contract_api_pb2.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: contract_api.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x12\x63ontract_api.proto\x12\x1e\x61\x65\x61.valory.contract_api.v1_0_0"\x84\x11\n\x12\x43ontractApiMessage\x12V\n\x05\x65rror\x18\x05 \x01(\x0b\x32\x45.aea.valory.contract_api.v1_0_0.ContractApiMessage.Error_PerformativeH\x00\x12x\n\x16get_deploy_transaction\x18\x06 \x01(\x0b\x32V.aea.valory.contract_api.v1_0_0.ContractApiMessage.Get_Deploy_Transaction_PerformativeH\x00\x12j\n\x0fget_raw_message\x18\x07 \x01(\x0b\x32O.aea.valory.contract_api.v1_0_0.ContractApiMessage.Get_Raw_Message_PerformativeH\x00\x12r\n\x13get_raw_transaction\x18\x08 \x01(\x0b\x32S.aea.valory.contract_api.v1_0_0.ContractApiMessage.Get_Raw_Transaction_PerformativeH\x00\x12^\n\tget_state\x18\t \x01(\x0b\x32I.aea.valory.contract_api.v1_0_0.ContractApiMessage.Get_State_PerformativeH\x00\x12\x62\n\x0braw_message\x18\n \x01(\x0b\x32K.aea.valory.contract_api.v1_0_0.ContractApiMessage.Raw_Message_PerformativeH\x00\x12j\n\x0fraw_transaction\x18\x0b \x01(\x0b\x32O.aea.valory.contract_api.v1_0_0.ContractApiMessage.Raw_Transaction_PerformativeH\x00\x12V\n\x05state\x18\x0c \x01(\x0b\x32\x45.aea.valory.contract_api.v1_0_0.ContractApiMessage.State_PerformativeH\x00\x1a\x18\n\x06Kwargs\x12\x0e\n\x06kwargs\x18\x01 \x01(\x0c\x1a!\n\nRawMessage\x12\x13\n\x0braw_message\x18\x01 \x01(\x0c\x1a)\n\x0eRawTransaction\x12\x17\n\x0fraw_transaction\x18\x01 \x01(\x0c\x1a\x16\n\x05State\x12\r\n\x05state\x18\x01 \x01(\x0c\x1a\xaa\x01\n#Get_Deploy_Transaction_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x13\n\x0b\x63ontract_id\x18\x02 \x01(\t\x12\x10\n\x08\x63\x61llable\x18\x03 \x01(\t\x12I\n\x06kwargs\x18\x04 \x01(\x0b\x32\x39.aea.valory.contract_api.v1_0_0.ContractApiMessage.Kwargs\x1a\xc1\x01\n Get_Raw_Transaction_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x13\n\x0b\x63ontract_id\x18\x02 \x01(\t\x12\x18\n\x10\x63ontract_address\x18\x03 \x01(\t\x12\x10\n\x08\x63\x61llable\x18\x04 \x01(\t\x12I\n\x06kwargs\x18\x05 \x01(\x0b\x32\x39.aea.valory.contract_api.v1_0_0.ContractApiMessage.Kwargs\x1a\xbd\x01\n\x1cGet_Raw_Message_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x13\n\x0b\x63ontract_id\x18\x02 \x01(\t\x12\x18\n\x10\x63ontract_address\x18\x03 \x01(\t\x12\x10\n\x08\x63\x61llable\x18\x04 \x01(\t\x12I\n\x06kwargs\x18\x05 \x01(\x0b\x32\x39.aea.valory.contract_api.v1_0_0.ContractApiMessage.Kwargs\x1a\xb7\x01\n\x16Get_State_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x13\n\x0b\x63ontract_id\x18\x02 \x01(\t\x12\x18\n\x10\x63ontract_address\x18\x03 \x01(\t\x12\x10\n\x08\x63\x61llable\x18\x04 \x01(\t\x12I\n\x06kwargs\x18\x05 \x01(\x0b\x32\x39.aea.valory.contract_api.v1_0_0.ContractApiMessage.Kwargs\x1a]\n\x12State_Performative\x12G\n\x05state\x18\x01 \x01(\x0b\x32\x38.aea.valory.contract_api.v1_0_0.ContractApiMessage.State\x1az\n\x1cRaw_Transaction_Performative\x12Z\n\x0fraw_transaction\x18\x01 \x01(\x0b\x32\x41.aea.valory.contract_api.v1_0_0.ContractApiMessage.RawTransaction\x1an\n\x18Raw_Message_Performative\x12R\n\x0braw_message\x18\x01 \x01(\x0b\x32=.aea.valory.contract_api.v1_0_0.ContractApiMessage.RawMessage\x1an\n\x12\x45rror_Performative\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x13\n\x0b\x63ode_is_set\x18\x02 \x01(\x08\x12\x0f\n\x07message\x18\x03 \x01(\t\x12\x16\n\x0emessage_is_set\x18\x04 \x01(\x08\x12\x0c\n\x04\x64\x61ta\x18\x05 \x01(\x0c\x42\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "contract_api_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals["_CONTRACTAPIMESSAGE"]._serialized_start = 55 - _globals["_CONTRACTAPIMESSAGE"]._serialized_end = 2235 - _globals["_CONTRACTAPIMESSAGE_KWARGS"]._serialized_start = 903 - _globals["_CONTRACTAPIMESSAGE_KWARGS"]._serialized_end = 927 - _globals["_CONTRACTAPIMESSAGE_RAWMESSAGE"]._serialized_start = 929 - _globals["_CONTRACTAPIMESSAGE_RAWMESSAGE"]._serialized_end = 962 - _globals["_CONTRACTAPIMESSAGE_RAWTRANSACTION"]._serialized_start = 964 - _globals["_CONTRACTAPIMESSAGE_RAWTRANSACTION"]._serialized_end = 1005 - _globals["_CONTRACTAPIMESSAGE_STATE"]._serialized_start = 1007 - _globals["_CONTRACTAPIMESSAGE_STATE"]._serialized_end = 1029 - _globals[ - "_CONTRACTAPIMESSAGE_GET_DEPLOY_TRANSACTION_PERFORMATIVE" - ]._serialized_start = 1032 - _globals[ - "_CONTRACTAPIMESSAGE_GET_DEPLOY_TRANSACTION_PERFORMATIVE" - ]._serialized_end = 1202 - _globals[ - "_CONTRACTAPIMESSAGE_GET_RAW_TRANSACTION_PERFORMATIVE" - ]._serialized_start = 1205 - _globals[ - "_CONTRACTAPIMESSAGE_GET_RAW_TRANSACTION_PERFORMATIVE" - ]._serialized_end = 1398 - _globals[ - "_CONTRACTAPIMESSAGE_GET_RAW_MESSAGE_PERFORMATIVE" - ]._serialized_start = 1401 - _globals["_CONTRACTAPIMESSAGE_GET_RAW_MESSAGE_PERFORMATIVE"]._serialized_end = 1590 - _globals["_CONTRACTAPIMESSAGE_GET_STATE_PERFORMATIVE"]._serialized_start = 1593 - _globals["_CONTRACTAPIMESSAGE_GET_STATE_PERFORMATIVE"]._serialized_end = 1776 - _globals["_CONTRACTAPIMESSAGE_STATE_PERFORMATIVE"]._serialized_start = 1778 - _globals["_CONTRACTAPIMESSAGE_STATE_PERFORMATIVE"]._serialized_end = 1871 - _globals[ - "_CONTRACTAPIMESSAGE_RAW_TRANSACTION_PERFORMATIVE" - ]._serialized_start = 1873 - _globals["_CONTRACTAPIMESSAGE_RAW_TRANSACTION_PERFORMATIVE"]._serialized_end = 1995 - _globals["_CONTRACTAPIMESSAGE_RAW_MESSAGE_PERFORMATIVE"]._serialized_start = 1997 - _globals["_CONTRACTAPIMESSAGE_RAW_MESSAGE_PERFORMATIVE"]._serialized_end = 2107 - _globals["_CONTRACTAPIMESSAGE_ERROR_PERFORMATIVE"]._serialized_start = 2109 - _globals["_CONTRACTAPIMESSAGE_ERROR_PERFORMATIVE"]._serialized_end = 2219 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/protocols/contract_api/custom_types.py b/trader_old/vendor/valory/protocols/contract_api/custom_types.py deleted file mode 100644 index fb1ffa8b5..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/custom_types.py +++ /dev/null @@ -1,96 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2020 valory -# -# 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 class representations corresponding to every custom type in the protocol specification.""" - -from typing import Any - -from aea.common import JSONLike -from aea.exceptions import enforce -from aea.helpers.serializers import DictProtobufStructSerializer -from aea.helpers.transaction.base import RawMessage as BaseRawMessage -from aea.helpers.transaction.base import RawTransaction as BaseRawTransaction -from aea.helpers.transaction.base import State as BaseState - - -RawMessage = BaseRawMessage -RawTransaction = BaseRawTransaction -State = BaseState - - -class Kwargs: - """This class represents an instance of Kwargs.""" - - __slots__ = ("_body",) - - def __init__( - self, - body: JSONLike, - ): - """Initialise an instance of RawTransaction.""" - self._body = body - self._check_consistency() - - def _check_consistency(self) -> None: - """Check consistency of the object.""" - enforce( - isinstance(self._body, dict) - and all([isinstance(key, str) for key in self._body.keys()]), - "Body must be dict and keys must be str.", - ) - - @property - def body(self) -> JSONLike: - """Get the body.""" - return self._body - - @staticmethod - def encode(kwargs_protobuf_object: Any, kwargs_object: "Kwargs") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the kwargs_protobuf_object argument is matched with the instance of this class in the 'kwargs_object' argument. - - :param kwargs_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param kwargs_object: an instance of this class to be encoded in the protocol buffer object. - """ - kwargs_protobuf_object.kwargs = DictProtobufStructSerializer.encode( - kwargs_object.body - ) - - @classmethod - def decode(cls, kwargs_protobuf_object: Any) -> "Kwargs": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'kwargs_protobuf_object' argument. - - :param kwargs_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'kwargs_protobuf_object' argument. - """ - kwargs = DictProtobufStructSerializer.decode(kwargs_protobuf_object.kwargs) - return cls(kwargs) - - def __eq__(self, other: Any) -> bool: - """Check equality.""" - return isinstance(other, Kwargs) and self.body == other.body - - def __str__(self) -> str: - """Get string representation.""" - return "Kwargs: body={}".format(self.body) diff --git a/trader_old/vendor/valory/protocols/contract_api/dialogues.py b/trader_old/vendor/valory/protocols/contract_api/dialogues.py deleted file mode 100644 index 5b9f534f6..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/dialogues.py +++ /dev/null @@ -1,152 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for contract_api dialogue management. - -- ContractApiDialogue: The dialogue class maintains state of a dialogue and manages it. -- ContractApiDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.contract_api.message import ContractApiMessage - - -class ContractApiDialogue(Dialogue): - """The contract_api dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ContractApiMessage.Performative.GET_RAW_MESSAGE, - ContractApiMessage.Performative.GET_STATE, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - ContractApiMessage.Performative.STATE, - ContractApiMessage.Performative.RAW_TRANSACTION, - ContractApiMessage.Performative.RAW_MESSAGE, - ContractApiMessage.Performative.ERROR, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - ContractApiMessage.Performative.ERROR: frozenset(), - ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION: frozenset( - { - ContractApiMessage.Performative.RAW_TRANSACTION, - ContractApiMessage.Performative.ERROR, - } - ), - ContractApiMessage.Performative.GET_RAW_MESSAGE: frozenset( - { - ContractApiMessage.Performative.RAW_MESSAGE, - ContractApiMessage.Performative.ERROR, - } - ), - ContractApiMessage.Performative.GET_RAW_TRANSACTION: frozenset( - { - ContractApiMessage.Performative.RAW_TRANSACTION, - ContractApiMessage.Performative.ERROR, - } - ), - ContractApiMessage.Performative.GET_STATE: frozenset( - { - ContractApiMessage.Performative.STATE, - ContractApiMessage.Performative.ERROR, - } - ), - ContractApiMessage.Performative.RAW_MESSAGE: frozenset(), - ContractApiMessage.Performative.RAW_TRANSACTION: frozenset(), - ContractApiMessage.Performative.STATE: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a contract_api dialogue.""" - - AGENT = "agent" - LEDGER = "ledger" - - class EndState(Dialogue.EndState): - """This class defines the end states of a contract_api dialogue.""" - - SUCCESSFUL = 0 - FAILED = 1 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[ContractApiMessage] = ContractApiMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class ContractApiDialogues(Dialogues, ABC): - """This class keeps track of all contract_api dialogues.""" - - END_STATES = frozenset( - {ContractApiDialogue.EndState.SUCCESSFUL, ContractApiDialogue.EndState.FAILED} - ) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[ContractApiDialogue] = ContractApiDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=ContractApiMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_old/vendor/valory/protocols/contract_api/message.py b/trader_old/vendor/valory/protocols/contract_api/message.py deleted file mode 100644 index 1b68bc22e..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/message.py +++ /dev/null @@ -1,472 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 contract_api's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Optional, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - -from packages.valory.protocols.contract_api.custom_types import Kwargs as CustomKwargs -from packages.valory.protocols.contract_api.custom_types import ( - RawMessage as CustomRawMessage, -) -from packages.valory.protocols.contract_api.custom_types import ( - RawTransaction as CustomRawTransaction, -) -from packages.valory.protocols.contract_api.custom_types import State as CustomState - - -_default_logger = logging.getLogger( - "aea.packages.valory.protocols.contract_api.message" -) - -DEFAULT_BODY_SIZE = 4 - - -class ContractApiMessage(Message): - """A protocol for contract APIs requests and responses.""" - - protocol_id = PublicId.from_str("valory/contract_api:1.0.0") - protocol_specification_id = PublicId.from_str("valory/contract_api:1.0.0") - - Kwargs = CustomKwargs - - RawMessage = CustomRawMessage - - RawTransaction = CustomRawTransaction - - State = CustomState - - class Performative(Message.Performative): - """Performatives for the contract_api protocol.""" - - ERROR = "error" - GET_DEPLOY_TRANSACTION = "get_deploy_transaction" - GET_RAW_MESSAGE = "get_raw_message" - GET_RAW_TRANSACTION = "get_raw_transaction" - GET_STATE = "get_state" - RAW_MESSAGE = "raw_message" - RAW_TRANSACTION = "raw_transaction" - STATE = "state" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = { - "error", - "get_deploy_transaction", - "get_raw_message", - "get_raw_transaction", - "get_state", - "raw_message", - "raw_transaction", - "state", - } - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "callable", - "code", - "contract_address", - "contract_id", - "data", - "dialogue_reference", - "kwargs", - "ledger_id", - "message", - "message_id", - "performative", - "raw_message", - "raw_transaction", - "state", - "target", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of ContractApiMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=ContractApiMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(ContractApiMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def callable(self) -> str: - """Get the 'callable' content from the message.""" - enforce(self.is_set("callable"), "'callable' content is not set.") - return cast(str, self.get("callable")) - - @property - def code(self) -> Optional[int]: - """Get the 'code' content from the message.""" - return cast(Optional[int], self.get("code")) - - @property - def contract_address(self) -> str: - """Get the 'contract_address' content from the message.""" - enforce( - self.is_set("contract_address"), "'contract_address' content is not set." - ) - return cast(str, self.get("contract_address")) - - @property - def contract_id(self) -> str: - """Get the 'contract_id' content from the message.""" - enforce(self.is_set("contract_id"), "'contract_id' content is not set.") - return cast(str, self.get("contract_id")) - - @property - def data(self) -> bytes: - """Get the 'data' content from the message.""" - enforce(self.is_set("data"), "'data' content is not set.") - return cast(bytes, self.get("data")) - - @property - def kwargs(self) -> CustomKwargs: - """Get the 'kwargs' content from the message.""" - enforce(self.is_set("kwargs"), "'kwargs' content is not set.") - return cast(CustomKwargs, self.get("kwargs")) - - @property - def ledger_id(self) -> str: - """Get the 'ledger_id' content from the message.""" - enforce(self.is_set("ledger_id"), "'ledger_id' content is not set.") - return cast(str, self.get("ledger_id")) - - @property - def message(self) -> Optional[str]: - """Get the 'message' content from the message.""" - return cast(Optional[str], self.get("message")) - - @property - def raw_message(self) -> CustomRawMessage: - """Get the 'raw_message' content from the message.""" - enforce(self.is_set("raw_message"), "'raw_message' content is not set.") - return cast(CustomRawMessage, self.get("raw_message")) - - @property - def raw_transaction(self) -> CustomRawTransaction: - """Get the 'raw_transaction' content from the message.""" - enforce(self.is_set("raw_transaction"), "'raw_transaction' content is not set.") - return cast(CustomRawTransaction, self.get("raw_transaction")) - - @property - def state(self) -> CustomState: - """Get the 'state' content from the message.""" - enforce(self.is_set("state"), "'state' content is not set.") - return cast(CustomState, self.get("state")) - - def _is_consistent(self) -> bool: - """Check that the message follows the contract_api protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, ContractApiMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if ( - self.performative - == ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION - ): - expected_nb_of_contents = 4 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.contract_id, str), - "Invalid type for content 'contract_id'. Expected 'str'. Found '{}'.".format( - type(self.contract_id) - ), - ) - enforce( - isinstance(self.callable, str), - "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( - type(self.callable) - ), - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif ( - self.performative == ContractApiMessage.Performative.GET_RAW_TRANSACTION - ): - expected_nb_of_contents = 5 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.contract_id, str), - "Invalid type for content 'contract_id'. Expected 'str'. Found '{}'.".format( - type(self.contract_id) - ), - ) - enforce( - isinstance(self.contract_address, str), - "Invalid type for content 'contract_address'. Expected 'str'. Found '{}'.".format( - type(self.contract_address) - ), - ) - enforce( - isinstance(self.callable, str), - "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( - type(self.callable) - ), - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif self.performative == ContractApiMessage.Performative.GET_RAW_MESSAGE: - expected_nb_of_contents = 5 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.contract_id, str), - "Invalid type for content 'contract_id'. Expected 'str'. Found '{}'.".format( - type(self.contract_id) - ), - ) - enforce( - isinstance(self.contract_address, str), - "Invalid type for content 'contract_address'. Expected 'str'. Found '{}'.".format( - type(self.contract_address) - ), - ) - enforce( - isinstance(self.callable, str), - "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( - type(self.callable) - ), - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif self.performative == ContractApiMessage.Performative.GET_STATE: - expected_nb_of_contents = 5 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.contract_id, str), - "Invalid type for content 'contract_id'. Expected 'str'. Found '{}'.".format( - type(self.contract_id) - ), - ) - enforce( - isinstance(self.contract_address, str), - "Invalid type for content 'contract_address'. Expected 'str'. Found '{}'.".format( - type(self.contract_address) - ), - ) - enforce( - isinstance(self.callable, str), - "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( - type(self.callable) - ), - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif self.performative == ContractApiMessage.Performative.STATE: - expected_nb_of_contents = 1 - enforce( - isinstance(self.state, CustomState), - "Invalid type for content 'state'. Expected 'State'. Found '{}'.".format( - type(self.state) - ), - ) - elif self.performative == ContractApiMessage.Performative.RAW_TRANSACTION: - expected_nb_of_contents = 1 - enforce( - isinstance(self.raw_transaction, CustomRawTransaction), - "Invalid type for content 'raw_transaction'. Expected 'RawTransaction'. Found '{}'.".format( - type(self.raw_transaction) - ), - ) - elif self.performative == ContractApiMessage.Performative.RAW_MESSAGE: - expected_nb_of_contents = 1 - enforce( - isinstance(self.raw_message, CustomRawMessage), - "Invalid type for content 'raw_message'. Expected 'RawMessage'. Found '{}'.".format( - type(self.raw_message) - ), - ) - elif self.performative == ContractApiMessage.Performative.ERROR: - expected_nb_of_contents = 1 - if self.is_set("code"): - expected_nb_of_contents += 1 - code = cast(int, self.code) - enforce( - type(code) is int, - "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( - type(code) - ), - ) - if self.is_set("message"): - expected_nb_of_contents += 1 - message = cast(str, self.message) - enforce( - isinstance(message, str), - "Invalid type for content 'message'. Expected 'str'. Found '{}'.".format( - type(message) - ), - ) - enforce( - isinstance(self.data, bytes), - "Invalid type for content 'data'. Expected 'bytes'. Found '{}'.".format( - type(self.data) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_old/vendor/valory/protocols/contract_api/protocol.yaml b/trader_old/vendor/valory/protocols/contract_api/protocol.yaml deleted file mode 100644 index 8938192bd..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/protocol.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: contract_api -author: valory -version: 1.0.0 -protocol_specification_id: valory/contract_api:1.0.0 -type: protocol -description: A protocol for contract APIs requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeigaihpzixjv56vbuch6yqk5shzevt3rlpvchgqudmztid5mgchlqy - __init__.py: bafybeifxn7w75gxufl4ekvk27qo3tkxetdvxxnqmhq5gtnhjyvlhn3i6yu - contract_api.proto: bafybeiafpnyivdogs7omw2bxxxkmnbqcl3n32oqbzug65p7jimbeubgljy - contract_api_pb2.py: bafybeibjspkls7zjf7x4on2sm2274r355xzodgv3e54ueopz4vgpvg5owa - custom_types.py: bafybeiawof5bblaefwui5wgsou2ohvrxi2zrkdthehiet57qguplzsgrhu - dialogues.py: bafybeictadz75pczogizyglzklbk4mf76zoh6we66ras4stntz5dwzi7du - message.py: bafybeid75ybjywwslz7jwsng4aosfejutesj6jffkmrpdy5jg4oluwn5hm - serialization.py: bafybeie56ahly26zco47a7dg6umysqy6ygle65lebmwekstbiwmym62p7i - tests/__init__.py: bafybeicc5zmsziu4r5dwjnhckfbgnwbgydn7ekeyqsestutq2tusajqzmu - tests/test_contract_api.py: bafybeigszksq7bxi3skvw3zvpatkltgbnvnfatofjn63xnd5xds33iyni4 - tests/test_contract_api_dialogues.py: bafybeifalicqk4g44sl5dpeuvls5dqtyfdgc6nwyuf5cl4fofis7fr3mnq - tests/test_contract_api_messages.py: bafybeigjdnyyxpzfje4ok7sxi6a3gstbgaryzjm2izoxmn4x5twsec35fa -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_old/vendor/valory/protocols/contract_api/serialization.py b/trader_old/vendor/valory/protocols/contract_api/serialization.py deleted file mode 100644 index c8aeaad9d..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/serialization.py +++ /dev/null @@ -1,250 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for contract_api protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.contract_api import contract_api_pb2 # type: ignore -from packages.valory.protocols.contract_api.custom_types import ( # type: ignore - Kwargs, - RawMessage, - RawTransaction, - State, -) -from packages.valory.protocols.contract_api.message import ( # type: ignore - ContractApiMessage, -) - - -class ContractApiSerializer(Serializer): - """Serialization for the 'contract_api' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'ContractApi' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(ContractApiMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - contract_api_msg = contract_api_pb2.ContractApiMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION: - performative = contract_api_pb2.ContractApiMessage.Get_Deploy_Transaction_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - contract_id = msg.contract_id - performative.contract_id = contract_id - callable = msg.callable - performative.callable = callable - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - contract_api_msg.get_deploy_transaction.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.GET_RAW_TRANSACTION: - performative = contract_api_pb2.ContractApiMessage.Get_Raw_Transaction_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - contract_id = msg.contract_id - performative.contract_id = contract_id - contract_address = msg.contract_address - performative.contract_address = contract_address - callable = msg.callable - performative.callable = callable - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - contract_api_msg.get_raw_transaction.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.GET_RAW_MESSAGE: - performative = contract_api_pb2.ContractApiMessage.Get_Raw_Message_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - contract_id = msg.contract_id - performative.contract_id = contract_id - contract_address = msg.contract_address - performative.contract_address = contract_address - callable = msg.callable - performative.callable = callable - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - contract_api_msg.get_raw_message.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.GET_STATE: - performative = contract_api_pb2.ContractApiMessage.Get_State_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - contract_id = msg.contract_id - performative.contract_id = contract_id - contract_address = msg.contract_address - performative.contract_address = contract_address - callable = msg.callable - performative.callable = callable - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - contract_api_msg.get_state.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.STATE: - performative = contract_api_pb2.ContractApiMessage.State_Performative() # type: ignore - state = msg.state - State.encode(performative.state, state) - contract_api_msg.state.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.RAW_TRANSACTION: - performative = contract_api_pb2.ContractApiMessage.Raw_Transaction_Performative() # type: ignore - raw_transaction = msg.raw_transaction - RawTransaction.encode(performative.raw_transaction, raw_transaction) - contract_api_msg.raw_transaction.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.RAW_MESSAGE: - performative = contract_api_pb2.ContractApiMessage.Raw_Message_Performative() # type: ignore - raw_message = msg.raw_message - RawMessage.encode(performative.raw_message, raw_message) - contract_api_msg.raw_message.CopyFrom(performative) - elif performative_id == ContractApiMessage.Performative.ERROR: - performative = contract_api_pb2.ContractApiMessage.Error_Performative() # type: ignore - if msg.is_set("code"): - performative.code_is_set = True - code = msg.code - performative.code = code - if msg.is_set("message"): - performative.message_is_set = True - message = msg.message - performative.message = message - data = msg.data - performative.data = data - contract_api_msg.error.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = contract_api_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'ContractApi' message. - - :param obj: the bytes object. - :return: the 'ContractApi' message. - """ - message_pb = ProtobufMessage() - contract_api_pb = contract_api_pb2.ContractApiMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - contract_api_pb.ParseFromString(message_pb.dialogue_message.content) - performative = contract_api_pb.WhichOneof("performative") - performative_id = ContractApiMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION: - ledger_id = contract_api_pb.get_deploy_transaction.ledger_id - performative_content["ledger_id"] = ledger_id - contract_id = contract_api_pb.get_deploy_transaction.contract_id - performative_content["contract_id"] = contract_id - callable = contract_api_pb.get_deploy_transaction.callable - performative_content["callable"] = callable - pb2_kwargs = contract_api_pb.get_deploy_transaction.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == ContractApiMessage.Performative.GET_RAW_TRANSACTION: - ledger_id = contract_api_pb.get_raw_transaction.ledger_id - performative_content["ledger_id"] = ledger_id - contract_id = contract_api_pb.get_raw_transaction.contract_id - performative_content["contract_id"] = contract_id - contract_address = contract_api_pb.get_raw_transaction.contract_address - performative_content["contract_address"] = contract_address - callable = contract_api_pb.get_raw_transaction.callable - performative_content["callable"] = callable - pb2_kwargs = contract_api_pb.get_raw_transaction.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == ContractApiMessage.Performative.GET_RAW_MESSAGE: - ledger_id = contract_api_pb.get_raw_message.ledger_id - performative_content["ledger_id"] = ledger_id - contract_id = contract_api_pb.get_raw_message.contract_id - performative_content["contract_id"] = contract_id - contract_address = contract_api_pb.get_raw_message.contract_address - performative_content["contract_address"] = contract_address - callable = contract_api_pb.get_raw_message.callable - performative_content["callable"] = callable - pb2_kwargs = contract_api_pb.get_raw_message.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == ContractApiMessage.Performative.GET_STATE: - ledger_id = contract_api_pb.get_state.ledger_id - performative_content["ledger_id"] = ledger_id - contract_id = contract_api_pb.get_state.contract_id - performative_content["contract_id"] = contract_id - contract_address = contract_api_pb.get_state.contract_address - performative_content["contract_address"] = contract_address - callable = contract_api_pb.get_state.callable - performative_content["callable"] = callable - pb2_kwargs = contract_api_pb.get_state.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == ContractApiMessage.Performative.STATE: - pb2_state = contract_api_pb.state.state - state = State.decode(pb2_state) - performative_content["state"] = state - elif performative_id == ContractApiMessage.Performative.RAW_TRANSACTION: - pb2_raw_transaction = contract_api_pb.raw_transaction.raw_transaction - raw_transaction = RawTransaction.decode(pb2_raw_transaction) - performative_content["raw_transaction"] = raw_transaction - elif performative_id == ContractApiMessage.Performative.RAW_MESSAGE: - pb2_raw_message = contract_api_pb.raw_message.raw_message - raw_message = RawMessage.decode(pb2_raw_message) - performative_content["raw_message"] = raw_message - elif performative_id == ContractApiMessage.Performative.ERROR: - if contract_api_pb.error.code_is_set: - code = contract_api_pb.error.code - performative_content["code"] = code - if contract_api_pb.error.message_is_set: - message = contract_api_pb.error.message - performative_content["message"] = message - data = contract_api_pb.error.data - performative_content["data"] = data - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return ContractApiMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_old/vendor/valory/protocols/contract_api/tests/__init__.py b/trader_old/vendor/valory/protocols/contract_api/tests/__init__.py deleted file mode 100644 index f0a0d0f83..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/contract_api protocol.""" diff --git a/trader_old/vendor/valory/protocols/contract_api/tests/test_contract_api.py b/trader_old/vendor/valory/protocols/contract_api/tests/test_contract_api.py deleted file mode 100644 index 919358c2d..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/tests/test_contract_api.py +++ /dev/null @@ -1,734 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for the 'valory/contract_api' protocol.""" -from abc import abstractmethod -from typing import Callable, Type -from unittest import mock - -import pytest - -from aea.common import Address -from aea.exceptions import AEAEnforceError -from aea.mail.base import Envelope -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.contract_api import ContractApiMessage, message -from packages.valory.protocols.contract_api.custom_types import Kwargs -from packages.valory.protocols.contract_api.dialogues import ( - ContractApiDialogue, - ContractApiDialogues, -) -from packages.valory.protocols.contract_api.message import ( - _default_logger as contract_api_message_logger, -) - - -LEDGER_ID = "ethereum" -CONTRACT_ID = "contract_id_stub" -CALLABLE = "callable_stub" -CONTRACT_ADDRESS = "contract_address_stub" - - -def test_get_deploy_transaction_serialization(): - """Test the serialization for 'get_deploy_transaction' speech-act works.""" - kwargs_arg = ContractApiMessage.Kwargs({"key_1": 1, "key_2": 2}) - msg = ContractApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - ledger_id="some_ledger_id", - contract_id="some_contract_id", - callable="some_callable", - kwargs=kwargs_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_get_raw_transaction_serialization(): - """Test the serialization for 'get_raw_transaction' speech-act works.""" - kwargs_arg = ContractApiMessage.Kwargs({"key_1": 1, "key_2": 2}) - msg = ContractApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ledger_id="some_ledger_id", - contract_id="some_contract_id", - contract_address="some_contract_address", - callable="some_callable", - kwargs=kwargs_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_get_raw_message_serialization(): - """Test the serialization for 'get_raw_message' speech-act works.""" - kwargs_arg = ContractApiMessage.Kwargs({"key_1": 1, "key_2": 2}) - msg = ContractApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=ContractApiMessage.Performative.GET_RAW_MESSAGE, - ledger_id="some_ledger_id", - contract_id="some_contract_id", - contract_address="some_contract_address", - callable="some_callable", - kwargs=kwargs_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_get_state_serialization(): - """Test the serialization for 'get_state' speech-act works.""" - kwargs_arg = ContractApiMessage.Kwargs({"key_1": 1, "key_2": 2}) - msg = ContractApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=ContractApiMessage.Performative.GET_STATE, - ledger_id="some_ledger_id", - contract_id="some_contract_id", - contract_address="some_contract_address", - callable="some_callable", - kwargs=kwargs_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_state_serialization(): - """Test the serialization for 'state' speech-act works.""" - state_arg = ContractApiMessage.State("some_ledger_id", {"key": "some_body"}) - msg = ContractApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=ContractApiMessage.Performative.STATE, - state=state_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_raw_transaction_serialization(): - """Test the serialization for 'raw_transaction' speech-act works.""" - raw_transaction_arg = ContractApiMessage.RawTransaction( - "some_ledger_id", {"body": "some_body"} - ) - msg = ContractApiMessage( - message_id=2, - target=1, - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=raw_transaction_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_raw_message_serialization(): - """Test the serialization for 'raw_message' speech-act works.""" - raw_message_arg = ContractApiMessage.RawMessage("some_ledger_id", b"some_body") - msg = ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_MESSAGE, - raw_message=raw_message_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_error_serialization(): - """Test the serialization for 'error' speech-act works.""" - msg = ContractApiMessage( - performative=ContractApiMessage.Performative.ERROR, - code=7, - message="some_error_message", - data=b"some_error_data", - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = ContractApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_performative_string_value() -> None: - """Test the string value of the performatives.""" - assert ( - str(ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION) - == "get_deploy_transaction" - ), "The str value must be get_deploy_transaction" - assert ( - str(ContractApiMessage.Performative.GET_RAW_TRANSACTION) - == "get_raw_transaction" - ), "The str value must be get_raw_transaction" - assert ( - str(ContractApiMessage.Performative.GET_RAW_MESSAGE) == "get_raw_message" - ), "The str value must be get_raw_message" - assert ( - str(ContractApiMessage.Performative.GET_STATE) == "get_state" - ), "The str value must be get_state" - assert ( - str(ContractApiMessage.Performative.STATE) == "state" - ), "The str value must be state" - assert ( - str(ContractApiMessage.Performative.RAW_TRANSACTION) == "raw_transaction" - ), "The str value must be raw_transaction" - assert ( - str(ContractApiMessage.Performative.RAW_MESSAGE) == "raw_message" - ), "The str value must be raw_message" - assert ( - str(ContractApiMessage.Performative.ERROR) == "error" - ), "The str value must be error" - - -def test_encoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = ContractApiMessage( - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, # type: ignore - ledger_id=LEDGER_ID, - contract_id=CONTRACT_ID, - callable=CALLABLE, - kwargs=Kwargs({}), - ) - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object( - ContractApiMessage.Performative, "__eq__", return_value=False - ): - ContractApiMessage.serializer.encode(msg) - - -def test_decoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = ContractApiMessage( - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, # type: ignore - ledger_id=LEDGER_ID, - contract_id=CONTRACT_ID, - callable=CALLABLE, - kwargs=Kwargs({}), - ) - - encoded_msg = ContractApiMessage.serializer.encode(msg) - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object( - ContractApiMessage.Performative, "__eq__", return_value=False - ): - ContractApiMessage.serializer.decode(encoded_msg) - - -@mock.patch.object( - message, - "enforce", - side_effect=AEAEnforceError("some error"), -) -def test_incorrect_message( - mocked_enforce: Callable, # pylint: disable=unused-argument -) -> None: - """Test that we raise an exception when the message is incorrect.""" - with mock.patch.object(contract_api_message_logger, "error") as mock_logger: - ContractApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=ContractApiMessage.Performative.RAW_MESSAGE, # type: ignore - raw_message=ContractApiMessage.RawMessage("some_ledger_id", b"some_body"), - ) - - mock_logger.assert_any_call("some error") - - -def test_kwargs(): - """Test the kwargs custom type.""" - body = {"key_1": 1, "key_2": 2} - kwargs = ContractApiMessage.Kwargs(body) - assert str(kwargs) == "Kwargs: body={}".format(body) - - -class BaseTestMessageConstruction: - """Base class to test message construction for the ABCI protocol.""" - - ledger_id = LEDGER_ID - contract_id = CONTRACT_ID - callable_ = CALLABLE - msg_class = ContractApiMessage - contract_address = CONTRACT_ADDRESS - - @abstractmethod - def build_message(self) -> ContractApiMessage: - """Build the message to be used for testing.""" - - def test_run(self) -> None: - """Run the test.""" - msg = self.build_message() - msg.to = "receiver" - envelope = Envelope(to=msg.to, sender="sender", message=msg) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = self.msg_class.serializer.decode(actual_envelope.message_bytes) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - @classmethod - def _make_kwargs(cls) -> Kwargs: - """Build a ConsensuParams object.""" - return Kwargs(body={}) - - -class TestGetDeployTransaction(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - assert str(self._make_kwargs()) == "Kwargs: body={}" - return ContractApiMessage( - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, # type: ignore - ledger_id=self.ledger_id, - contract_id=self.contract_id, - callable=self.callable_, - kwargs=self._make_kwargs(), - ) - - -class TestError(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.ERROR, # type: ignore - code=1, - message="", - data=b"", - ) - - -class TestGetRawTransaction(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - ledger_id=self.ledger_id, - contract_id=self.contract_id, - contract_address=self.contract_address, - callable=self.callable_, - kwargs=self._make_kwargs(), - ) - - -class TestRawTransaction(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, # type: ignore - raw_transaction=ContractApiMessage.RawTransaction( - ledger_id=LEDGER_ID, body={} - ), - ) - - -class TestGetRawMessage(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.GET_RAW_MESSAGE, # type: ignore - ledger_id=self.ledger_id, - contract_id=self.contract_id, - contract_address=self.contract_address, - callable=self.callable_, - kwargs=self._make_kwargs(), - ) - - -class TestRawMessage(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_MESSAGE, # type: ignore - raw_message=ContractApiMessage.RawMessage(ledger_id=LEDGER_ID, body=b""), - ) - - -class TestGetState(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - ledger_id=self.ledger_id, - contract_id=self.contract_id, - contract_address=self.contract_address, - callable=self.callable_, - kwargs=self._make_kwargs(), - ) - - -class TestState(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> ContractApiMessage: - """Build the message.""" - return ContractApiMessage( - performative=ContractApiMessage.Performative.STATE, # type: ignore - state=ContractApiMessage.State(ledger_id=LEDGER_ID, body={}), - ) - - -class AgentDialogue(ContractApiDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[ContractApiMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - ContractApiDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class AgentDialogues(ContractApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return ContractApiDialogue.Role.AGENT - - ContractApiDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=AgentDialogue, - ) - - -class LedgerDialogue(ContractApiDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[ContractApiMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - ContractApiDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class LedgerDialogues(ContractApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return ContractApiDialogue.Role.LEDGER - - ContractApiDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=LedgerDialogue, - ) - - -class TestDialogues: - """Tests abci dialogues.""" - - agent_addr: str - ledger_addr: str - agent_dialogues: AgentDialogues - ledger_dialogues: LedgerDialogues - - @classmethod - def setup_class(cls) -> None: - """Set up the test.""" - cls.agent_addr = "agent address" - cls.ledger_addr = "ledger address" - cls.agent_dialogues = AgentDialogues(cls.agent_addr) - cls.ledger_dialogues = LedgerDialogues(cls.ledger_addr) - - def test_create_self_initiated(self) -> None: - """Test the self initialisation of a dialogue.""" - result = self.agent_dialogues._create_self_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.ledger_addr, - dialogue_reference=(str(0), ""), - role=ContractApiDialogue.Role.AGENT, - ) - assert isinstance(result, ContractApiDialogue) - assert result.role == ContractApiDialogue.Role.AGENT, "The role must be agent." - - def test_create_opponent_initiated(self) -> None: - """Test the opponent initialisation of a dialogue.""" - result = self.agent_dialogues._create_opponent_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.ledger_addr, - dialogue_reference=(str(0), ""), - role=ContractApiDialogue.Role.AGENT, - ) - assert isinstance(result, ContractApiDialogue) - assert result.role == ContractApiDialogue.Role.AGENT, "The role must be agent." diff --git a/trader_old/vendor/valory/protocols/contract_api/tests/test_contract_api_dialogues.py b/trader_old/vendor/valory/protocols/contract_api/tests/test_contract_api_dialogues.py deleted file mode 100644 index dd07d1c34..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/tests/test_contract_api_dialogues.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for contract_api protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.contract_api.custom_types import Kwargs -from packages.valory.protocols.contract_api.dialogues import ( - ContractApiDialogue, - ContractApiDialogues, -) -from packages.valory.protocols.contract_api.message import ContractApiMessage - - -class TestDialoguesContractApi(BaseProtocolDialoguesTestCase): - """Test for the 'contract_api' protocol dialogues.""" - - MESSAGE_CLASS = ContractApiMessage - - DIALOGUE_CLASS = ContractApiDialogue - - DIALOGUES_CLASS = ContractApiDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = ContractApiDialogue.Role.AGENT # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - ledger_id="some str", - contract_id="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ) diff --git a/trader_old/vendor/valory/protocols/contract_api/tests/test_contract_api_messages.py b/trader_old/vendor/valory/protocols/contract_api/tests/test_contract_api_messages.py deleted file mode 100644 index 09600e3c1..000000000 --- a/trader_old/vendor/valory/protocols/contract_api/tests/test_contract_api_messages.py +++ /dev/null @@ -1,147 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for contract_api protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.contract_api.custom_types import ( - Kwargs, - RawMessage, - RawTransaction, - State, -) -from packages.valory.protocols.contract_api.message import ContractApiMessage - - -class TestMessageContractApi(BaseProtocolMessagesTestCase): - """Test for the 'contract_api' protocol message.""" - - MESSAGE_CLASS = ContractApiMessage - - def build_messages(self) -> List[ContractApiMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - ledger_id="some str", - contract_id="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ledger_id="some str", - contract_id="some str", - contract_address="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_RAW_MESSAGE, - ledger_id="some str", - contract_id="some str", - contract_address="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_STATE, - ledger_id="some str", - contract_id="some str", - contract_address="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.STATE, - state=State("some_ledger_id", {"key": "some_body"}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=RawTransaction("some_ledger_id", {"body": "some_body"}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_MESSAGE, - raw_message=RawMessage("some_ledger_id", b"some_body"), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.ERROR, - code=12, - message="some str", - data=b"some_bytes", - ), - ] - - def build_inconsistent(self) -> List[ContractApiMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_DEPLOY_TRANSACTION, - # skip content: ledger_id - contract_id="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, - # skip content: ledger_id - contract_id="some str", - contract_address="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_RAW_MESSAGE, - # skip content: ledger_id - contract_id="some str", - contract_address="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.GET_STATE, - # skip content: ledger_id - contract_id="some str", - contract_address="some str", - callable="some str", - kwargs=Kwargs({"key_1": 1, "key_2": 2}), - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.STATE, - # skip content: state - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - # skip content: raw_transaction - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_MESSAGE, - # skip content: raw_message - ), - ContractApiMessage( - performative=ContractApiMessage.Performative.ERROR, - # skip content: code - message=["some str"], - data=b"some_bytes", - ), - ] diff --git a/trader_old/vendor/valory/protocols/http/README.md b/trader_old/vendor/valory/protocols/http/README.md deleted file mode 100644 index 446909ef6..000000000 --- a/trader_old/vendor/valory/protocols/http/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# HTTP Protocol - -## Description - -This is a protocol for interacting with a client/server via HTTP requests and responses. - -## Specification - -```yaml ---- -name: http -author: valory -version: 1.0.0 -description: A protocol for HTTP requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: valory/http:1.0.0 -speech_acts: - request: - method: pt:str - url: pt:str - version: pt:str - headers: pt:str - body: pt:bytes - response: - version: pt:str - status_code: pt:int - status_text: pt:str - headers: pt:str - body: pt:bytes -... ---- -initiation: [request] -reply: - request: [response] - response: [] -termination: [response] -roles: {client, server} -end_states: [successful] -keep_terminal_state_dialogues: false -... -``` - -## Links - -* HTTP Specification diff --git a/trader_old/vendor/valory/protocols/http/__init__.py b/trader_old/vendor/valory/protocols/http/__init__.py deleted file mode 100644 index 73442b676..000000000 --- a/trader_old/vendor/valory/protocols/http/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the http protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.http.message import HttpMessage -from packages.valory.protocols.http.serialization import HttpSerializer - - -HttpMessage.serializer = HttpSerializer diff --git a/trader_old/vendor/valory/protocols/http/dialogues.py b/trader_old/vendor/valory/protocols/http/dialogues.py deleted file mode 100644 index c8b68e416..000000000 --- a/trader_old/vendor/valory/protocols/http/dialogues.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for http dialogue management. - -- HttpDialogue: The dialogue class maintains state of a dialogue and manages it. -- HttpDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.http.message import HttpMessage - - -class HttpDialogue(Dialogue): - """The http dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - {HttpMessage.Performative.REQUEST} - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - {HttpMessage.Performative.RESPONSE} - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - HttpMessage.Performative.REQUEST: frozenset( - {HttpMessage.Performative.RESPONSE} - ), - HttpMessage.Performative.RESPONSE: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a http dialogue.""" - - CLIENT = "client" - SERVER = "server" - - class EndState(Dialogue.EndState): - """This class defines the end states of a http dialogue.""" - - SUCCESSFUL = 0 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[HttpMessage] = HttpMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class HttpDialogues(Dialogues, ABC): - """This class keeps track of all http dialogues.""" - - END_STATES = frozenset({HttpDialogue.EndState.SUCCESSFUL}) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[HttpDialogue] = HttpDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=HttpMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_old/vendor/valory/protocols/http/http.proto b/trader_old/vendor/valory/protocols/http/http.proto deleted file mode 100644 index 02f606944..000000000 --- a/trader_old/vendor/valory/protocols/http/http.proto +++ /dev/null @@ -1,29 +0,0 @@ -syntax = "proto3"; - -package aea.valory.http.v1_0_0; - -message HttpMessage{ - - // Performatives and contents - message Request_Performative{ - string method = 1; - string url = 2; - string version = 3; - string headers = 4; - bytes body = 5; - } - - message Response_Performative{ - string version = 1; - int32 status_code = 2; - string status_text = 3; - string headers = 4; - bytes body = 5; - } - - - oneof performative{ - Request_Performative request = 5; - Response_Performative response = 6; - } -} diff --git a/trader_old/vendor/valory/protocols/http/http_pb2.py b/trader_old/vendor/valory/protocols/http/http_pb2.py deleted file mode 100644 index 6c202f914..000000000 --- a/trader_old/vendor/valory/protocols/http/http_pb2.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: http.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\nhttp.proto\x12\x16\x61\x65\x61.valory.http.v1_0_0"\x91\x03\n\x0bHttpMessage\x12K\n\x07request\x18\x05 \x01(\x0b\x32\x38.aea.valory.http.v1_0_0.HttpMessage.Request_PerformativeH\x00\x12M\n\x08response\x18\x06 \x01(\x0b\x32\x39.aea.valory.http.v1_0_0.HttpMessage.Response_PerformativeH\x00\x1a\x63\n\x14Request_Performative\x12\x0e\n\x06method\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\t\x12\x0f\n\x07headers\x18\x04 \x01(\t\x12\x0c\n\x04\x62ody\x18\x05 \x01(\x0c\x1aq\n\x15Response_Performative\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x13\n\x0bstatus_code\x18\x02 \x01(\x05\x12\x13\n\x0bstatus_text\x18\x03 \x01(\t\x12\x0f\n\x07headers\x18\x04 \x01(\t\x12\x0c\n\x04\x62ody\x18\x05 \x01(\x0c\x42\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "http_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals["_HTTPMESSAGE"]._serialized_start = 39 - _globals["_HTTPMESSAGE"]._serialized_end = 440 - _globals["_HTTPMESSAGE_REQUEST_PERFORMATIVE"]._serialized_start = 210 - _globals["_HTTPMESSAGE_REQUEST_PERFORMATIVE"]._serialized_end = 309 - _globals["_HTTPMESSAGE_RESPONSE_PERFORMATIVE"]._serialized_start = 311 - _globals["_HTTPMESSAGE_RESPONSE_PERFORMATIVE"]._serialized_end = 424 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/protocols/http/message.py b/trader_old/vendor/valory/protocols/http/message.py deleted file mode 100644 index 44dcec3b1..000000000 --- a/trader_old/vendor/valory/protocols/http/message.py +++ /dev/null @@ -1,297 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 http's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - - -_default_logger = logging.getLogger("aea.packages.valory.protocols.http.message") - -DEFAULT_BODY_SIZE = 4 - - -class HttpMessage(Message): - """A protocol for HTTP requests and responses.""" - - protocol_id = PublicId.from_str("valory/http:1.0.0") - protocol_specification_id = PublicId.from_str("valory/http:1.0.0") - - class Performative(Message.Performative): - """Performatives for the http protocol.""" - - REQUEST = "request" - RESPONSE = "response" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = {"request", "response"} - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "body", - "dialogue_reference", - "headers", - "message_id", - "method", - "performative", - "status_code", - "status_text", - "target", - "url", - "version", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of HttpMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=HttpMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(HttpMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def body(self) -> bytes: - """Get the 'body' content from the message.""" - enforce(self.is_set("body"), "'body' content is not set.") - return cast(bytes, self.get("body")) - - @property - def headers(self) -> str: - """Get the 'headers' content from the message.""" - enforce(self.is_set("headers"), "'headers' content is not set.") - return cast(str, self.get("headers")) - - @property - def method(self) -> str: - """Get the 'method' content from the message.""" - enforce(self.is_set("method"), "'method' content is not set.") - return cast(str, self.get("method")) - - @property - def status_code(self) -> int: - """Get the 'status_code' content from the message.""" - enforce(self.is_set("status_code"), "'status_code' content is not set.") - return cast(int, self.get("status_code")) - - @property - def status_text(self) -> str: - """Get the 'status_text' content from the message.""" - enforce(self.is_set("status_text"), "'status_text' content is not set.") - return cast(str, self.get("status_text")) - - @property - def url(self) -> str: - """Get the 'url' content from the message.""" - enforce(self.is_set("url"), "'url' content is not set.") - return cast(str, self.get("url")) - - @property - def version(self) -> str: - """Get the 'version' content from the message.""" - enforce(self.is_set("version"), "'version' content is not set.") - return cast(str, self.get("version")) - - def _is_consistent(self) -> bool: - """Check that the message follows the http protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, HttpMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == HttpMessage.Performative.REQUEST: - expected_nb_of_contents = 5 - enforce( - isinstance(self.method, str), - "Invalid type for content 'method'. Expected 'str'. Found '{}'.".format( - type(self.method) - ), - ) - enforce( - isinstance(self.url, str), - "Invalid type for content 'url'. Expected 'str'. Found '{}'.".format( - type(self.url) - ), - ) - enforce( - isinstance(self.version, str), - "Invalid type for content 'version'. Expected 'str'. Found '{}'.".format( - type(self.version) - ), - ) - enforce( - isinstance(self.headers, str), - "Invalid type for content 'headers'. Expected 'str'. Found '{}'.".format( - type(self.headers) - ), - ) - enforce( - isinstance(self.body, bytes), - "Invalid type for content 'body'. Expected 'bytes'. Found '{}'.".format( - type(self.body) - ), - ) - elif self.performative == HttpMessage.Performative.RESPONSE: - expected_nb_of_contents = 5 - enforce( - isinstance(self.version, str), - "Invalid type for content 'version'. Expected 'str'. Found '{}'.".format( - type(self.version) - ), - ) - enforce( - type(self.status_code) is int, - "Invalid type for content 'status_code'. Expected 'int'. Found '{}'.".format( - type(self.status_code) - ), - ) - enforce( - isinstance(self.status_text, str), - "Invalid type for content 'status_text'. Expected 'str'. Found '{}'.".format( - type(self.status_text) - ), - ) - enforce( - isinstance(self.headers, str), - "Invalid type for content 'headers'. Expected 'str'. Found '{}'.".format( - type(self.headers) - ), - ) - enforce( - isinstance(self.body, bytes), - "Invalid type for content 'body'. Expected 'bytes'. Found '{}'.".format( - type(self.body) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_old/vendor/valory/protocols/http/protocol.yaml b/trader_old/vendor/valory/protocols/http/protocol.yaml deleted file mode 100644 index 0246138d0..000000000 --- a/trader_old/vendor/valory/protocols/http/protocol.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: http -author: valory -version: 1.0.0 -protocol_specification_id: valory/http:1.0.0 -type: protocol -description: A protocol for HTTP requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeihkatpicz56ofrvu5fgks7ecrsfzw5toz23o23yvoymhk6l6hl7dy - __init__.py: bafybeidjcefjfitptbesnqxuq2yyl3v6eh3ng7qx3xk5wlpjbg6pzoca7q - dialogues.py: bafybeiepab5wdmdfevelxcpaky6znmc3wjb6kezwe7c55dp6d4lpiw7zuy - http.proto: bafybeigq6ykgxdqi4m65x3rcj4ehdm3usaisejzl2oisn6kzkjits3fzkq - http_pb2.py: bafybeibvqp664j4iaozk2hyotmd7gzsyknk4dt3mcddniuzdvdxhtkjcoq - message.py: bafybeifnffq6yjisyew6oodtbpaiqsmiruiljr4ihydhlqvlhgwl2hx7qe - serialization.py: bafybeidujjt46tdrooo6fjppax7b2qstmb62gfafd6r6uydb7mpnw6ukyi - tests/__init__.py: bafybeifitr3wqclw3kammd2fw5zww6gvzbvu6s72di2p7544qfisuslhpq - tests/test_http.py: bafybeibbz5zcqmqsvtwp2rucj2ubbbazmqt3shpjnkt5bdhnlclqy4fseq - tests/test_http_dialogues.py: bafybeic22z3aatytdx3cxrtzt3hqwwhxlnaal6sn7grm3cn5k7ycq5v46y - tests/test_http_messages.py: bafybeihp6qmanjxpcfwuq6fngxcjvcogyzrxguax4lcollkbujq542mlv4 -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_old/vendor/valory/protocols/http/serialization.py b/trader_old/vendor/valory/protocols/http/serialization.py deleted file mode 100644 index 7dd42a23d..000000000 --- a/trader_old/vendor/valory/protocols/http/serialization.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for http protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.http import http_pb2 # type: ignore -from packages.valory.protocols.http.message import HttpMessage # type: ignore - - -class HttpSerializer(Serializer): - """Serialization for the 'http' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'Http' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(HttpMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - http_msg = http_pb2.HttpMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == HttpMessage.Performative.REQUEST: - performative = http_pb2.HttpMessage.Request_Performative() # type: ignore - method = msg.method - performative.method = method - url = msg.url - performative.url = url - version = msg.version - performative.version = version - headers = msg.headers - performative.headers = headers - body = msg.body - performative.body = body - http_msg.request.CopyFrom(performative) - elif performative_id == HttpMessage.Performative.RESPONSE: - performative = http_pb2.HttpMessage.Response_Performative() # type: ignore - version = msg.version - performative.version = version - status_code = msg.status_code - performative.status_code = status_code - status_text = msg.status_text - performative.status_text = status_text - headers = msg.headers - performative.headers = headers - body = msg.body - performative.body = body - http_msg.response.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = http_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'Http' message. - - :param obj: the bytes object. - :return: the 'Http' message. - """ - message_pb = ProtobufMessage() - http_pb = http_pb2.HttpMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - http_pb.ParseFromString(message_pb.dialogue_message.content) - performative = http_pb.WhichOneof("performative") - performative_id = HttpMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == HttpMessage.Performative.REQUEST: - method = http_pb.request.method - performative_content["method"] = method - url = http_pb.request.url - performative_content["url"] = url - version = http_pb.request.version - performative_content["version"] = version - headers = http_pb.request.headers - performative_content["headers"] = headers - body = http_pb.request.body - performative_content["body"] = body - elif performative_id == HttpMessage.Performative.RESPONSE: - version = http_pb.response.version - performative_content["version"] = version - status_code = http_pb.response.status_code - performative_content["status_code"] = status_code - status_text = http_pb.response.status_text - performative_content["status_text"] = status_text - headers = http_pb.response.headers - performative_content["headers"] = headers - body = http_pb.response.body - performative_content["body"] = body - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return HttpMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_old/vendor/valory/protocols/http/tests/__init__.py b/trader_old/vendor/valory/protocols/http/tests/__init__.py deleted file mode 100644 index 4864c2102..000000000 --- a/trader_old/vendor/valory/protocols/http/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/http protocol.""" diff --git a/trader_old/vendor/valory/protocols/http/tests/test_http.py b/trader_old/vendor/valory/protocols/http/tests/test_http.py deleted file mode 100644 index caaf7da6c..000000000 --- a/trader_old/vendor/valory/protocols/http/tests/test_http.py +++ /dev/null @@ -1,394 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for the 'valory/http' protocol.""" -from abc import abstractmethod -from typing import Callable, Type -from unittest import mock - -import pytest - -from aea.common import Address -from aea.exceptions import AEAEnforceError -from aea.mail.base import Envelope -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.http import HttpMessage, message -from packages.valory.protocols.http.dialogues import HttpDialogue, HttpDialogues -from packages.valory.protocols.http.message import ( - _default_logger as http_message_logger, -) - - -LEDGER_ID = "ethereum" - - -def test_request_serialization(): - """Test the serialization for 'request' speech-act works.""" - msg = HttpMessage( - performative=HttpMessage.Performative.REQUEST, - method="some_method", - url="url", - version="some_version", - headers="some_headers", - body=b"some_body", - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = HttpMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_response_serialization(): - """Test the serialization for 'response' speech-act works.""" - msg = HttpMessage( - message_id=2, - target=1, - performative=HttpMessage.Performative.RESPONSE, - version="some_version", - status_code=1, - status_text="some_status_text", - headers="some_headers", - body=b"some_body", - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = HttpMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_performative_string_value() -> None: - """Test the string valoe of performatives.""" - - assert ( - str(HttpMessage.Performative.REQUEST) == "request" - ), "The str value must be request" - assert ( - str(HttpMessage.Performative.RESPONSE) == "response" - ), "The str value must be response" - - -def test_encoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = HttpMessage( - performative=HttpMessage.Performative.REQUEST, # type: ignore - method="GET", - url="http://example.com", - version="", - headers="", - body=b"", - ) - - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object(HttpMessage.Performative, "__eq__", return_value=False): - HttpMessage.serializer.encode(msg) - - -def test_decoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = HttpMessage( - performative=HttpMessage.Performative.REQUEST, # type: ignore - method="GET", - url="http://example.com", - version="", - headers="", - body=b"", - ) - - encoded_msg = HttpMessage.serializer.encode(msg) - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object(HttpMessage.Performative, "__eq__", return_value=False): - HttpMessage.serializer.decode(encoded_msg) - - -class BaseTestMessageConstruction: - """Base class to test message construction for the ABCI protocol.""" - - msg_class = HttpMessage - - @abstractmethod - def build_message(self) -> HttpMessage: - """Build the message to be used for testing.""" - - def test_run(self) -> None: - """Run the test.""" - msg = self.build_message() - msg.to = "receiver" - envelope = Envelope(to=msg.to, sender="sender", message=msg) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = self.msg_class.serializer.decode(actual_envelope.message_bytes) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -class TestRequest(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> HttpMessage: - """Build the message.""" - return HttpMessage( - performative=HttpMessage.Performative.REQUEST, # type: ignore - method="GET", - url="http://example.com", - version="", - headers="", - body=b"", - ) - - -class TestResponse(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> HttpMessage: - """Build the message.""" - return HttpMessage( - performative=HttpMessage.Performative.RESPONSE, # type: ignore - version="", - status_code=200, - status_text="OK", - headers="", - body=b"", - ) - - -@mock.patch.object( - message, - "enforce", - side_effect=AEAEnforceError("some error"), -) -def test_incorrect_message( - mocked_enforce: Callable, # pylint: disable=unused-argument -) -> None: - """Test that we raise an exception when the message is incorrect.""" - with mock.patch.object(http_message_logger, "error") as mock_logger: - HttpMessage( - performative=HttpMessage.Performative.REQUEST, # type: ignore - method="GET", - url="http://example.com", - version="", - headers="", - body=b"", - ) - mock_logger.assert_any_call("some error") - - -class AgentDialogue(HttpDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[HttpMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - HttpDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class AgentDialogues(HttpDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return HttpDialogue.Role.CLIENT - - HttpDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=AgentDialogue, - ) - - -class LedgerDialogue(HttpDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[HttpMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - HttpDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class LedgerDialogues(HttpDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return HttpDialogue.Role.SERVER - - HttpDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=LedgerDialogue, - ) - - -class TestDialogues: - """Tests abci dialogues.""" - - agent_addr: str - ledger_addr: str - agent_dialogues: AgentDialogues - ledger_dialogues: LedgerDialogues - - @classmethod - def setup_class(cls) -> None: - """Set up the test.""" - cls.agent_addr = "agent address" - cls.ledger_addr = "ledger address" - cls.agent_dialogues = AgentDialogues(cls.agent_addr) - cls.ledger_dialogues = LedgerDialogues(cls.ledger_addr) - - def test_create_self_initiated(self) -> None: - """Test the self initialisation of a dialogue.""" - result = self.agent_dialogues._create_self_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.ledger_addr, - dialogue_reference=(str(0), ""), - role=HttpDialogue.Role.CLIENT, - ) - assert isinstance(result, HttpDialogue) - assert result.role == HttpDialogue.Role.CLIENT, "The role must be agent." - - def test_create_opponent_initiated(self) -> None: - """Test the opponent initialisation of a dialogue.""" - result = self.agent_dialogues._create_opponent_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.ledger_addr, - dialogue_reference=(str(0), ""), - role=HttpDialogue.Role.CLIENT, - ) - assert isinstance(result, HttpDialogue) - assert result.role == HttpDialogue.Role.CLIENT, "The role must be agent." diff --git a/trader_old/vendor/valory/protocols/http/tests/test_http_dialogues.py b/trader_old/vendor/valory/protocols/http/tests/test_http_dialogues.py deleted file mode 100644 index 6a2224e79..000000000 --- a/trader_old/vendor/valory/protocols/http/tests/test_http_dialogues.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for http protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.http.dialogues import HttpDialogue, HttpDialogues -from packages.valory.protocols.http.message import HttpMessage - - -class TestDialoguesHttp(BaseProtocolDialoguesTestCase): - """Test for the 'http' protocol dialogues.""" - - MESSAGE_CLASS = HttpMessage - - DIALOGUE_CLASS = HttpDialogue - - DIALOGUES_CLASS = HttpDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = HttpDialogue.Role.CLIENT # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=HttpMessage.Performative.REQUEST, - method="some str", - url="some str", - version="some str", - headers="some str", - body=b"some_bytes", - ) diff --git a/trader_old/vendor/valory/protocols/http/tests/test_http_messages.py b/trader_old/vendor/valory/protocols/http/tests/test_http_messages.py deleted file mode 100644 index 817f9928e..000000000 --- a/trader_old/vendor/valory/protocols/http/tests/test_http_messages.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for http protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.http.message import HttpMessage - - -class TestMessageHttp(BaseProtocolMessagesTestCase): - """Test for the 'http' protocol message.""" - - MESSAGE_CLASS = HttpMessage - - def build_messages(self) -> List[HttpMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - HttpMessage( - performative=HttpMessage.Performative.REQUEST, - method="some str", - url="some str", - version="some str", - headers="some str", - body=b"some_bytes", - ), - HttpMessage( - performative=HttpMessage.Performative.RESPONSE, - version="some str", - status_code=12, - status_text="some str", - headers="some str", - body=b"some_bytes", - ), - ] - - def build_inconsistent(self) -> List[HttpMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - HttpMessage( - performative=HttpMessage.Performative.REQUEST, - # skip content: method - url="some str", - version="some str", - headers="some str", - body=b"some_bytes", - ), - HttpMessage( - performative=HttpMessage.Performative.RESPONSE, - # skip content: version - status_code=12, - status_text="some str", - headers="some str", - body=b"some_bytes", - ), - ] diff --git a/trader_old/vendor/valory/protocols/ipfs/README.md b/trader_old/vendor/valory/protocols/ipfs/README.md deleted file mode 100644 index 72ddf37a3..000000000 --- a/trader_old/vendor/valory/protocols/ipfs/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# IPFS Protocol - -## Description - -This is a protocol for interacting with IPFS. - -## Specification - -```yaml ---- -name: ipfs -author: valory -version: 0.1.0 -description: A protocol specification for IPFS requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: valory/ipfs:0.1.0 -speech_acts: - store_files: - files: pt:dict[pt:str, pt:str] - timeout: pt:optional[pt:float] - ipfs_hash: - ipfs_hash: pt:str - get_files: - ipfs_hash: pt:str - timeout: pt:optional[pt:float] - files: - files: pt:dict[pt:str, pt:str] - error: - reason: pt:str ---- -initiation: [get_files, store_files] -reply: - store_files: [ipfs_hash, error] - ipfs_hash: [] - get_files: [files, error] - files: [] - error: [] -termination: [ipfs_hash, files, error] -roles: {skill, connection} -end_states: [ok, error] -keep_terminal_state_dialogues: false -... -``` - -## Links - diff --git a/trader_old/vendor/valory/protocols/ipfs/__init__.py b/trader_old/vendor/valory/protocols/ipfs/__init__.py deleted file mode 100644 index 5e2342280..000000000 --- a/trader_old/vendor/valory/protocols/ipfs/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the ipfs protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.ipfs.message import IpfsMessage -from packages.valory.protocols.ipfs.serialization import IpfsSerializer - - -IpfsMessage.serializer = IpfsSerializer diff --git a/trader_old/vendor/valory/protocols/ipfs/dialogues.py b/trader_old/vendor/valory/protocols/ipfs/dialogues.py deleted file mode 100644 index 46bb54e81..000000000 --- a/trader_old/vendor/valory/protocols/ipfs/dialogues.py +++ /dev/null @@ -1,125 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for ipfs dialogue management. - -- IpfsDialogue: The dialogue class maintains state of a dialogue and manages it. -- IpfsDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.ipfs.message import IpfsMessage - - -class IpfsDialogue(Dialogue): - """The ipfs dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - {IpfsMessage.Performative.GET_FILES, IpfsMessage.Performative.STORE_FILES} - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - IpfsMessage.Performative.IPFS_HASH, - IpfsMessage.Performative.FILES, - IpfsMessage.Performative.ERROR, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - IpfsMessage.Performative.ERROR: frozenset(), - IpfsMessage.Performative.FILES: frozenset(), - IpfsMessage.Performative.GET_FILES: frozenset( - {IpfsMessage.Performative.FILES, IpfsMessage.Performative.ERROR} - ), - IpfsMessage.Performative.IPFS_HASH: frozenset(), - IpfsMessage.Performative.STORE_FILES: frozenset( - {IpfsMessage.Performative.IPFS_HASH, IpfsMessage.Performative.ERROR} - ), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a ipfs dialogue.""" - - CONNECTION = "connection" - SKILL = "skill" - - class EndState(Dialogue.EndState): - """This class defines the end states of a ipfs dialogue.""" - - OK = 0 - ERROR = 1 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[IpfsMessage] = IpfsMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class IpfsDialogues(Dialogues, ABC): - """This class keeps track of all ipfs dialogues.""" - - END_STATES = frozenset({IpfsDialogue.EndState.OK, IpfsDialogue.EndState.ERROR}) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[IpfsDialogue] = IpfsDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=IpfsMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_old/vendor/valory/protocols/ipfs/ipfs.proto b/trader_old/vendor/valory/protocols/ipfs/ipfs.proto deleted file mode 100644 index ae5311eb2..000000000 --- a/trader_old/vendor/valory/protocols/ipfs/ipfs.proto +++ /dev/null @@ -1,40 +0,0 @@ -syntax = "proto3"; - -package aea.valory.ipfs.v0_1_0; - -message IpfsMessage{ - - // Performatives and contents - message Store_Files_Performative{ - map files = 1; - double timeout = 2; - bool timeout_is_set = 3; - } - - message Ipfs_Hash_Performative{ - string ipfs_hash = 1; - } - - message Get_Files_Performative{ - string ipfs_hash = 1; - double timeout = 2; - bool timeout_is_set = 3; - } - - message Files_Performative{ - map files = 1; - } - - message Error_Performative{ - string reason = 1; - } - - - oneof performative{ - Error_Performative error = 5; - Files_Performative files = 6; - Get_Files_Performative get_files = 7; - Ipfs_Hash_Performative ipfs_hash = 8; - Store_Files_Performative store_files = 9; - } -} diff --git a/trader_old/vendor/valory/protocols/ipfs/ipfs_pb2.py b/trader_old/vendor/valory/protocols/ipfs/ipfs_pb2.py deleted file mode 100644 index c69233ef6..000000000 --- a/trader_old/vendor/valory/protocols/ipfs/ipfs_pb2.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: ipfs.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\nipfs.proto\x12\x16\x61\x65\x61.valory.ipfs.v0_1_0"\xb2\x07\n\x0bIpfsMessage\x12G\n\x05\x65rror\x18\x05 \x01(\x0b\x32\x36.aea.valory.ipfs.v0_1_0.IpfsMessage.Error_PerformativeH\x00\x12G\n\x05\x66iles\x18\x06 \x01(\x0b\x32\x36.aea.valory.ipfs.v0_1_0.IpfsMessage.Files_PerformativeH\x00\x12O\n\tget_files\x18\x07 \x01(\x0b\x32:.aea.valory.ipfs.v0_1_0.IpfsMessage.Get_Files_PerformativeH\x00\x12O\n\tipfs_hash\x18\x08 \x01(\x0b\x32:.aea.valory.ipfs.v0_1_0.IpfsMessage.Ipfs_Hash_PerformativeH\x00\x12S\n\x0bstore_files\x18\t \x01(\x0b\x32<.aea.valory.ipfs.v0_1_0.IpfsMessage.Store_Files_PerformativeH\x00\x1a\xc9\x01\n\x18Store_Files_Performative\x12V\n\x05\x66iles\x18\x01 \x03(\x0b\x32G.aea.valory.ipfs.v0_1_0.IpfsMessage.Store_Files_Performative.FilesEntry\x12\x0f\n\x07timeout\x18\x02 \x01(\x01\x12\x16\n\x0etimeout_is_set\x18\x03 \x01(\x08\x1a,\n\nFilesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a+\n\x16Ipfs_Hash_Performative\x12\x11\n\tipfs_hash\x18\x01 \x01(\t\x1aT\n\x16Get_Files_Performative\x12\x11\n\tipfs_hash\x18\x01 \x01(\t\x12\x0f\n\x07timeout\x18\x02 \x01(\x01\x12\x16\n\x0etimeout_is_set\x18\x03 \x01(\x08\x1a\x94\x01\n\x12\x46iles_Performative\x12P\n\x05\x66iles\x18\x01 \x03(\x0b\x32\x41.aea.valory.ipfs.v0_1_0.IpfsMessage.Files_Performative.FilesEntry\x1a,\n\nFilesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a$\n\x12\x45rror_Performative\x12\x0e\n\x06reason\x18\x01 \x01(\tB\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "ipfs_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _IPFSMESSAGE_STORE_FILES_PERFORMATIVE_FILESENTRY._options = None - _IPFSMESSAGE_STORE_FILES_PERFORMATIVE_FILESENTRY._serialized_options = b"8\001" - _IPFSMESSAGE_FILES_PERFORMATIVE_FILESENTRY._options = None - _IPFSMESSAGE_FILES_PERFORMATIVE_FILESENTRY._serialized_options = b"8\001" - _globals["_IPFSMESSAGE"]._serialized_start = 39 - _globals["_IPFSMESSAGE"]._serialized_end = 985 - _globals["_IPFSMESSAGE_STORE_FILES_PERFORMATIVE"]._serialized_start = 448 - _globals["_IPFSMESSAGE_STORE_FILES_PERFORMATIVE"]._serialized_end = 649 - _globals["_IPFSMESSAGE_STORE_FILES_PERFORMATIVE_FILESENTRY"]._serialized_start = 605 - _globals["_IPFSMESSAGE_STORE_FILES_PERFORMATIVE_FILESENTRY"]._serialized_end = 649 - _globals["_IPFSMESSAGE_IPFS_HASH_PERFORMATIVE"]._serialized_start = 651 - _globals["_IPFSMESSAGE_IPFS_HASH_PERFORMATIVE"]._serialized_end = 694 - _globals["_IPFSMESSAGE_GET_FILES_PERFORMATIVE"]._serialized_start = 696 - _globals["_IPFSMESSAGE_GET_FILES_PERFORMATIVE"]._serialized_end = 780 - _globals["_IPFSMESSAGE_FILES_PERFORMATIVE"]._serialized_start = 783 - _globals["_IPFSMESSAGE_FILES_PERFORMATIVE"]._serialized_end = 931 - _globals["_IPFSMESSAGE_FILES_PERFORMATIVE_FILESENTRY"]._serialized_start = 605 - _globals["_IPFSMESSAGE_FILES_PERFORMATIVE_FILESENTRY"]._serialized_end = 649 - _globals["_IPFSMESSAGE_ERROR_PERFORMATIVE"]._serialized_start = 933 - _globals["_IPFSMESSAGE_ERROR_PERFORMATIVE"]._serialized_end = 969 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/protocols/ipfs/message.py b/trader_old/vendor/valory/protocols/ipfs/message.py deleted file mode 100644 index 93aa55baa..000000000 --- a/trader_old/vendor/valory/protocols/ipfs/message.py +++ /dev/null @@ -1,298 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 ipfs's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Dict, Optional, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - - -_default_logger = logging.getLogger("aea.packages.valory.protocols.ipfs.message") - -DEFAULT_BODY_SIZE = 4 - - -class IpfsMessage(Message): - """A protocol specification for IPFS requests and responses.""" - - protocol_id = PublicId.from_str("valory/ipfs:0.1.0") - protocol_specification_id = PublicId.from_str("valory/ipfs:0.1.0") - - class Performative(Message.Performative): - """Performatives for the ipfs protocol.""" - - ERROR = "error" - FILES = "files" - GET_FILES = "get_files" - IPFS_HASH = "ipfs_hash" - STORE_FILES = "store_files" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = {"error", "files", "get_files", "ipfs_hash", "store_files"} - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "dialogue_reference", - "files", - "ipfs_hash", - "message_id", - "performative", - "reason", - "target", - "timeout", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of IpfsMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=IpfsMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(IpfsMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def files(self) -> Dict[str, str]: - """Get the 'files' content from the message.""" - enforce(self.is_set("files"), "'files' content is not set.") - return cast(Dict[str, str], self.get("files")) - - @property - def ipfs_hash(self) -> str: - """Get the 'ipfs_hash' content from the message.""" - enforce(self.is_set("ipfs_hash"), "'ipfs_hash' content is not set.") - return cast(str, self.get("ipfs_hash")) - - @property - def reason(self) -> str: - """Get the 'reason' content from the message.""" - enforce(self.is_set("reason"), "'reason' content is not set.") - return cast(str, self.get("reason")) - - @property - def timeout(self) -> Optional[float]: - """Get the 'timeout' content from the message.""" - return cast(Optional[float], self.get("timeout")) - - def _is_consistent(self) -> bool: - """Check that the message follows the ipfs protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, IpfsMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == IpfsMessage.Performative.STORE_FILES: - expected_nb_of_contents = 1 - enforce( - isinstance(self.files, dict), - "Invalid type for content 'files'. Expected 'dict'. Found '{}'.".format( - type(self.files) - ), - ) - for key_of_files, value_of_files in self.files.items(): - enforce( - isinstance(key_of_files, str), - "Invalid type for dictionary keys in content 'files'. Expected 'str'. Found '{}'.".format( - type(key_of_files) - ), - ) - enforce( - isinstance(value_of_files, str), - "Invalid type for dictionary values in content 'files'. Expected 'str'. Found '{}'.".format( - type(value_of_files) - ), - ) - if self.is_set("timeout"): - expected_nb_of_contents += 1 - timeout = cast(float, self.timeout) - enforce( - isinstance(timeout, float), - "Invalid type for content 'timeout'. Expected 'float'. Found '{}'.".format( - type(timeout) - ), - ) - elif self.performative == IpfsMessage.Performative.IPFS_HASH: - expected_nb_of_contents = 1 - enforce( - isinstance(self.ipfs_hash, str), - "Invalid type for content 'ipfs_hash'. Expected 'str'. Found '{}'.".format( - type(self.ipfs_hash) - ), - ) - elif self.performative == IpfsMessage.Performative.GET_FILES: - expected_nb_of_contents = 1 - enforce( - isinstance(self.ipfs_hash, str), - "Invalid type for content 'ipfs_hash'. Expected 'str'. Found '{}'.".format( - type(self.ipfs_hash) - ), - ) - if self.is_set("timeout"): - expected_nb_of_contents += 1 - timeout = cast(float, self.timeout) - enforce( - isinstance(timeout, float), - "Invalid type for content 'timeout'. Expected 'float'. Found '{}'.".format( - type(timeout) - ), - ) - elif self.performative == IpfsMessage.Performative.FILES: - expected_nb_of_contents = 1 - enforce( - isinstance(self.files, dict), - "Invalid type for content 'files'. Expected 'dict'. Found '{}'.".format( - type(self.files) - ), - ) - for key_of_files, value_of_files in self.files.items(): - enforce( - isinstance(key_of_files, str), - "Invalid type for dictionary keys in content 'files'. Expected 'str'. Found '{}'.".format( - type(key_of_files) - ), - ) - enforce( - isinstance(value_of_files, str), - "Invalid type for dictionary values in content 'files'. Expected 'str'. Found '{}'.".format( - type(value_of_files) - ), - ) - elif self.performative == IpfsMessage.Performative.ERROR: - expected_nb_of_contents = 1 - enforce( - isinstance(self.reason, str), - "Invalid type for content 'reason'. Expected 'str'. Found '{}'.".format( - type(self.reason) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_old/vendor/valory/protocols/ipfs/protocol.yaml b/trader_old/vendor/valory/protocols/ipfs/protocol.yaml deleted file mode 100644 index 6e5a91883..000000000 --- a/trader_old/vendor/valory/protocols/ipfs/protocol.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: ipfs -author: valory -version: 0.1.0 -protocol_specification_id: valory/ipfs:0.1.0 -type: protocol -description: A protocol specification for IPFS requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeidv64ed7ljvsggruwj3onb7dj7b5nyx4ngohacztdreujjztsuns4 - __init__.py: bafybeigvsifgesa6mc7dikvjdhyr3nsfksn5f73eryfk5imj47xvdbtqam - dialogues.py: bafybeidjf3k6pg6qgtgrzu2iothckvx2wuprx4ft4bqocz6mni63feptl4 - ipfs.proto: bafybeifpe6szd3m2zjlvn5zwiy7mbimur7pu46lobxvyyarozabxpmhcs4 - ipfs_pb2.py: bafybeihzspjtj2zoy3owb5itbz2lrintf7odanhvsi4qooxuqxu3ar6qpu - message.py: bafybeicxtql2e72atkcdsxc4ni4blffywconumyvh3mlsvb7o2dljqk7oy - serialization.py: bafybeicvvind4q6gqfwcmrjttlsm74pz7lc7z2uciyc2vghxckmmuh3dze - tests/test_ipfs_dialogues.py: bafybeigqi2cal5m252qf3ry75mldfd5kyqj3bgstvyzpjgpjgxhi2otpoa - tests/test_ipfs_messages.py: bafybeiasgajluoijzuln3s4gcbv5xenzazejt5kgbs54momozsntzrudw4 -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_old/vendor/valory/protocols/ipfs/serialization.py b/trader_old/vendor/valory/protocols/ipfs/serialization.py deleted file mode 100644 index faa999a7c..000000000 --- a/trader_old/vendor/valory/protocols/ipfs/serialization.py +++ /dev/null @@ -1,153 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for ipfs protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.ipfs import ipfs_pb2 # type: ignore -from packages.valory.protocols.ipfs.message import IpfsMessage # type: ignore - - -class IpfsSerializer(Serializer): - """Serialization for the 'ipfs' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'Ipfs' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(IpfsMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - ipfs_msg = ipfs_pb2.IpfsMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == IpfsMessage.Performative.STORE_FILES: - performative = ipfs_pb2.IpfsMessage.Store_Files_Performative() # type: ignore - files = msg.files - performative.files.update(files) - if msg.is_set("timeout"): - performative.timeout_is_set = True - timeout = msg.timeout - performative.timeout = timeout - ipfs_msg.store_files.CopyFrom(performative) - elif performative_id == IpfsMessage.Performative.IPFS_HASH: - performative = ipfs_pb2.IpfsMessage.Ipfs_Hash_Performative() # type: ignore - ipfs_hash = msg.ipfs_hash - performative.ipfs_hash = ipfs_hash - ipfs_msg.ipfs_hash.CopyFrom(performative) - elif performative_id == IpfsMessage.Performative.GET_FILES: - performative = ipfs_pb2.IpfsMessage.Get_Files_Performative() # type: ignore - ipfs_hash = msg.ipfs_hash - performative.ipfs_hash = ipfs_hash - if msg.is_set("timeout"): - performative.timeout_is_set = True - timeout = msg.timeout - performative.timeout = timeout - ipfs_msg.get_files.CopyFrom(performative) - elif performative_id == IpfsMessage.Performative.FILES: - performative = ipfs_pb2.IpfsMessage.Files_Performative() # type: ignore - files = msg.files - performative.files.update(files) - ipfs_msg.files.CopyFrom(performative) - elif performative_id == IpfsMessage.Performative.ERROR: - performative = ipfs_pb2.IpfsMessage.Error_Performative() # type: ignore - reason = msg.reason - performative.reason = reason - ipfs_msg.error.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = ipfs_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'Ipfs' message. - - :param obj: the bytes object. - :return: the 'Ipfs' message. - """ - message_pb = ProtobufMessage() - ipfs_pb = ipfs_pb2.IpfsMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - ipfs_pb.ParseFromString(message_pb.dialogue_message.content) - performative = ipfs_pb.WhichOneof("performative") - performative_id = IpfsMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == IpfsMessage.Performative.STORE_FILES: - files = ipfs_pb.store_files.files - files_dict = dict(files) - performative_content["files"] = files_dict - if ipfs_pb.store_files.timeout_is_set: - timeout = ipfs_pb.store_files.timeout - performative_content["timeout"] = timeout - elif performative_id == IpfsMessage.Performative.IPFS_HASH: - ipfs_hash = ipfs_pb.ipfs_hash.ipfs_hash - performative_content["ipfs_hash"] = ipfs_hash - elif performative_id == IpfsMessage.Performative.GET_FILES: - ipfs_hash = ipfs_pb.get_files.ipfs_hash - performative_content["ipfs_hash"] = ipfs_hash - if ipfs_pb.get_files.timeout_is_set: - timeout = ipfs_pb.get_files.timeout - performative_content["timeout"] = timeout - elif performative_id == IpfsMessage.Performative.FILES: - files = ipfs_pb.files.files - files_dict = dict(files) - performative_content["files"] = files_dict - elif performative_id == IpfsMessage.Performative.ERROR: - reason = ipfs_pb.error.reason - performative_content["reason"] = reason - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return IpfsMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_old/vendor/valory/protocols/ipfs/tests/test_ipfs_dialogues.py b/trader_old/vendor/valory/protocols/ipfs/tests/test_ipfs_dialogues.py deleted file mode 100644 index 8a515a22b..000000000 --- a/trader_old/vendor/valory/protocols/ipfs/tests/test_ipfs_dialogues.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for ipfs protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.ipfs.dialogues import IpfsDialogue, IpfsDialogues -from packages.valory.protocols.ipfs.message import IpfsMessage - - -class TestDialoguesIpfs(BaseProtocolDialoguesTestCase): - """Test for the 'ipfs' protocol dialogues.""" - - MESSAGE_CLASS = IpfsMessage - - DIALOGUE_CLASS = IpfsDialogue - - DIALOGUES_CLASS = IpfsDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = IpfsDialogue.Role.CONNECTION # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=IpfsMessage.Performative.GET_FILES, - ipfs_hash="some str", - timeout=1.0, - ) diff --git a/trader_old/vendor/valory/protocols/ipfs/tests/test_ipfs_messages.py b/trader_old/vendor/valory/protocols/ipfs/tests/test_ipfs_messages.py deleted file mode 100644 index 075918486..000000000 --- a/trader_old/vendor/valory/protocols/ipfs/tests/test_ipfs_messages.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for ipfs protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.ipfs.message import IpfsMessage - - -class TestMessageIpfs(BaseProtocolMessagesTestCase): - """Test for the 'ipfs' protocol message.""" - - MESSAGE_CLASS = IpfsMessage - - def build_messages(self) -> List[IpfsMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - IpfsMessage( - performative=IpfsMessage.Performative.STORE_FILES, - files={"some str": "some str"}, - timeout=1.0, - ), - IpfsMessage( - performative=IpfsMessage.Performative.IPFS_HASH, - ipfs_hash="some str", - ), - IpfsMessage( - performative=IpfsMessage.Performative.GET_FILES, - ipfs_hash="some str", - timeout=1.0, - ), - IpfsMessage( - performative=IpfsMessage.Performative.FILES, - files={"some str": "some str"}, - ), - IpfsMessage( - performative=IpfsMessage.Performative.ERROR, - reason="some str", - ), - ] - - def build_inconsistent(self) -> List[IpfsMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - IpfsMessage( - performative=IpfsMessage.Performative.STORE_FILES, - # skip content: files - timeout=1.0, - ), - IpfsMessage( - performative=IpfsMessage.Performative.IPFS_HASH, - # skip content: ipfs_hash - ), - IpfsMessage( - performative=IpfsMessage.Performative.GET_FILES, - # skip content: ipfs_hash - timeout=1.0, - ), - IpfsMessage( - performative=IpfsMessage.Performative.FILES, - # skip content: files - ), - IpfsMessage( - performative=IpfsMessage.Performative.ERROR, - # skip content: reason - ), - ] diff --git a/trader_old/vendor/valory/protocols/ledger_api/README.md b/trader_old/vendor/valory/protocols/ledger_api/README.md deleted file mode 100644 index 09303f9aa..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/README.md +++ /dev/null @@ -1,103 +0,0 @@ -# Ledger API Protocol - -## Description - -This is a protocol for interacting with ledger APIs. - -## Specification - -```yaml ---- -name: ledger_api -author: valory -version: 1.0.0 -description: A protocol for ledger APIs requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -protocol_specification_id: valory/ledger_api:1.0.0 -speech_acts: - get_balance: - ledger_id: pt:str - address: pt:str - get_raw_transaction: - terms: ct:Terms - send_signed_transaction: - signed_transaction: ct:SignedTransaction - kwargs: ct:Kwargs - send_signed_transactions: - signed_transactions: ct:SignedTransactions - kwargs: ct:Kwargs - get_transaction_receipt: - transaction_digest: ct:TransactionDigest - retry_timeout: pt:optional[pt:int] - retry_attempts: pt:optional[pt:int] - balance: - ledger_id: pt:str - balance: pt:int - raw_transaction: - raw_transaction: ct:RawTransaction - transaction_digest: - transaction_digest: ct:TransactionDigest - transaction_digests: - transaction_digests: ct:TransactionDigests - transaction_receipt: - transaction_receipt: ct:TransactionReceipt - get_state: - ledger_id: pt:str - callable: pt:str - args: pt:list[pt:str] - kwargs: ct:Kwargs - state: - ledger_id: pt:str - state: ct:State - error: - code: pt:int - message: pt:optional[pt:str] - data: pt:optional[pt:bytes] -... ---- -ct:Terms: | - bytes terms = 1; -ct:Kwargs: | - bytes kwargs = 1; -ct:State: | - bytes state = 1; -ct:SignedTransaction: | - bytes signed_transaction = 1; -ct:SignedTransactions: | - string ledger_id = 1; - repeated bytes signed_transactions = 2; -ct:RawTransaction: | - bytes raw_transaction = 1; -ct:TransactionDigest: | - bytes transaction_digest = 1; -ct:TransactionDigests: | - string ledger_id = 1; - repeated string transaction_digests = 2; -ct:TransactionReceipt: | - bytes transaction_receipt = 1; -... ---- -initiation: [get_balance, get_state, get_raw_transaction, send_signed_transaction, send_signed_transactions, get_transaction_receipt] -reply: - get_balance: [balance, error] - balance: [] - get_state: [state, error] - state: [] - get_raw_transaction: [raw_transaction, error] - raw_transaction: [] - send_signed_transaction: [transaction_digest, error] - send_signed_transactions: [transaction_digests, error] - transaction_digest: [] - transaction_digests: [] - get_transaction_receipt: [transaction_receipt, error] - transaction_receipt: [] - error: [] -termination: [balance, state, raw_transaction, transaction_digest, transaction_digests, transaction_receipt, error] -roles: {agent, ledger} -end_states: [successful] -keep_terminal_state_dialogues: false -... -``` - -## Links diff --git a/trader_old/vendor/valory/protocols/ledger_api/__init__.py b/trader_old/vendor/valory/protocols/ledger_api/__init__.py deleted file mode 100644 index 21b4d2592..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the ledger_api protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.protocols.ledger_api.serialization import LedgerApiSerializer - - -LedgerApiMessage.serializer = LedgerApiSerializer diff --git a/trader_old/vendor/valory/protocols/ledger_api/custom_types.py b/trader_old/vendor/valory/protocols/ledger_api/custom_types.py deleted file mode 100644 index ba2e11140..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/custom_types.py +++ /dev/null @@ -1,284 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2020-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 class representations corresponding to every custom type in the protocol specification.""" - -from typing import Any, List - -from aea.common import JSONLike -from aea.exceptions import enforce -from aea.helpers.serializers import DictProtobufStructSerializer -from aea.helpers.transaction.base import RawTransaction as BaseRawTransaction -from aea.helpers.transaction.base import SignedTransaction as BaseSignedTransaction -from aea.helpers.transaction.base import State as BaseState -from aea.helpers.transaction.base import Terms as BaseTerms -from aea.helpers.transaction.base import TransactionDigest as BaseTransactionDigest -from aea.helpers.transaction.base import TransactionReceipt as BaseTransactionReceipt - - -RawTransaction = BaseRawTransaction -SignedTransaction = BaseSignedTransaction -State = BaseState -Terms = BaseTerms -TransactionDigest = BaseTransactionDigest -TransactionReceipt = BaseTransactionReceipt - - -class Kwargs: - """This class represents an instance of Kwargs.""" - - __slots__ = ("_body",) - - def __init__( - self, - body: JSONLike, - ): - """Initialise an instance of RawTransaction.""" - self._body = body - self._check_consistency() - - def _check_consistency(self) -> None: - """Check consistency of the object.""" - enforce( - isinstance(self._body, dict) - and all([isinstance(key, str) for key in self._body.keys()]), - "Body must be dict and keys must be str.", - ) - - @property - def body(self) -> JSONLike: - """Get the body.""" - return self._body - - @staticmethod - def encode(kwargs_protobuf_object: Any, kwargs_object: "Kwargs") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the kwargs_protobuf_object argument is matched with the instance of this class in the 'kwargs_object' argument. - - :param kwargs_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param kwargs_object: an instance of this class to be encoded in the protocol buffer object. - """ - kwargs_protobuf_object.kwargs = DictProtobufStructSerializer.encode( - kwargs_object.body - ) - - @classmethod - def decode(cls, kwargs_protobuf_object: Any) -> "Kwargs": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'kwargs_protobuf_object' argument. - - :param kwargs_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'kwargs_protobuf_object' argument. - """ - kwargs = DictProtobufStructSerializer.decode(kwargs_protobuf_object.kwargs) - return cls(kwargs) - - def __eq__(self, other: Any) -> bool: - """Check equality.""" - return isinstance(other, Kwargs) and self.body == other.body - - def __str__(self) -> str: - """Get string representation.""" - return "Kwargs: body={}".format(self.body) - - -class SignedTransactions: - """This class represents an instance of SignedTransactions.""" - - __slots__ = ( - "_ledger_id", - "_signed_transactions", - ) - - def __init__( - self, - ledger_id: str, - signed_transactions: List[JSONLike], - ): - """Initialise an instance of SignedTransactions.""" - self._ledger_id = ledger_id - self._signed_transactions = signed_transactions - self._check_consistency() - - def _check_consistency(self) -> None: - """Check consistency of the object.""" - enforce(isinstance(self._ledger_id, str), "ledger_id must be str.") - enforce( - isinstance(self._signed_transactions, list), - "signed_transactions must be list.", - ) - - @property - def ledger_id(self) -> str: - """Get the body.""" - return self._ledger_id - - @property - def signed_transactions(self) -> List[JSONLike]: - """Get the body.""" - return self._signed_transactions - - @staticmethod - def encode( - signed_transactions_protobuf_object: Any, - signed_transactions_object: "SignedTransactions", - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the signed_transactions_protobuf_object argument is matched with the instance of this class in the 'signed_transactions_object' argument. - - :param signed_transactions_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param signed_transactions_object: an instance of this class to be encoded in the protocol buffer object. - """ - encoded_transactions = [ - DictProtobufStructSerializer.encode(tx) - for tx in signed_transactions_object.signed_transactions - ] - signed_transactions_protobuf_object.signed_transactions.extend( - encoded_transactions - ) - signed_transactions_protobuf_object.ledger_id = ( - signed_transactions_object.ledger_id - ) - - @classmethod - def decode(cls, signed_transactions_protobuf_object: Any) -> "SignedTransactions": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'signed_transactions_protobuf_object' argument. - - :param signed_transactions_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'signed_transactions_protobuf_object' argument. - """ - decoded_transactions = [ - DictProtobufStructSerializer.decode(tx) - for tx in signed_transactions_protobuf_object.signed_transactions - ] - return cls( - ledger_id=signed_transactions_protobuf_object.ledger_id, - signed_transactions=decoded_transactions, - ) - - def __eq__(self, other: Any) -> bool: - """Check equality.""" - return ( - isinstance(other, SignedTransactions) - and self.ledger_id == other.ledger_id - and self.signed_transactions == other.signed_transactions - ) - - def __str__(self) -> str: - """Get string representation.""" - return "SignedTransactions: ledger_id={} signed_transactions={}".format( - self.ledger_id, self.signed_transactions - ) - - -class TransactionDigests: - """This class represents an instance of TransactionDigests.""" - - __slots__ = ( - "_ledger_id", - "_transaction_digests", - ) - - def __init__( - self, - ledger_id: str, - transaction_digests: List[str], - ): - """Initialise an instance of TransactionDigests.""" - self._ledger_id = ledger_id - self._transaction_digests = transaction_digests - self._check_consistency() - - def _check_consistency(self) -> None: - """Check consistency of the object.""" - enforce(isinstance(self._ledger_id, str), "ledger_id must be str.") - enforce( - isinstance(self._transaction_digests, list), - "transaction_digests must be list.", - ) - - @property - def ledger_id(self) -> str: - """Get the body.""" - return self._ledger_id - - @property - def transaction_digests(self) -> List[str]: - """Get the body.""" - return self._transaction_digests - - @staticmethod - def encode( - transaction_digests_protobuf_object: Any, - transaction_digests_object: "TransactionDigests", - ) -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the transaction_digests_protobuf_object argument is matched with the instance of this class in the 'transaction_digests_object' argument. - - :param transaction_digests_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param transaction_digests_object: an instance of this class to be encoded in the protocol buffer object. - """ - transaction_digests_protobuf_object.transaction_digests.extend( - transaction_digests_object.transaction_digests - ) - transaction_digests_protobuf_object.ledger_id = ( - transaction_digests_object.ledger_id - ) - - @classmethod - def decode(cls, transaction_digests_protobuf_object: Any) -> "TransactionDigests": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'transaction_digests_protobuf_object' argument. - - :param transaction_digests_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'transaction_digests_protobuf_object' argument. - """ - return cls( - ledger_id=transaction_digests_protobuf_object.ledger_id, - transaction_digests=list( - transaction_digests_protobuf_object.transaction_digests - ), - ) - - def __eq__(self, other: Any) -> bool: - """Check equality.""" - return ( - isinstance(other, TransactionDigests) - and self.ledger_id == other.ledger_id - and self.transaction_digests == other.transaction_digests - ) - - def __str__(self) -> str: - """Get string representation.""" - return "TransactionDigests: ledger_id={} transaction_digests={}".format( - self.ledger_id, self.transaction_digests - ) diff --git a/trader_old/vendor/valory/protocols/ledger_api/dialogues.py b/trader_old/vendor/valory/protocols/ledger_api/dialogues.py deleted file mode 100644 index d08650274..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/dialogues.py +++ /dev/null @@ -1,163 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for ledger_api dialogue management. - -- LedgerApiDialogue: The dialogue class maintains state of a dialogue and manages it. -- LedgerApiDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.ledger_api.message import LedgerApiMessage - - -class LedgerApiDialogue(Dialogue): - """The ledger_api dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - LedgerApiMessage.Performative.GET_BALANCE, - LedgerApiMessage.Performative.GET_STATE, - LedgerApiMessage.Performative.GET_RAW_TRANSACTION, - LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, - LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS, - LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - LedgerApiMessage.Performative.BALANCE, - LedgerApiMessage.Performative.STATE, - LedgerApiMessage.Performative.RAW_TRANSACTION, - LedgerApiMessage.Performative.TRANSACTION_DIGEST, - LedgerApiMessage.Performative.TRANSACTION_DIGESTS, - LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - LedgerApiMessage.Performative.ERROR, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - LedgerApiMessage.Performative.BALANCE: frozenset(), - LedgerApiMessage.Performative.ERROR: frozenset(), - LedgerApiMessage.Performative.GET_BALANCE: frozenset( - {LedgerApiMessage.Performative.BALANCE, LedgerApiMessage.Performative.ERROR} - ), - LedgerApiMessage.Performative.GET_RAW_TRANSACTION: frozenset( - { - LedgerApiMessage.Performative.RAW_TRANSACTION, - LedgerApiMessage.Performative.ERROR, - } - ), - LedgerApiMessage.Performative.GET_STATE: frozenset( - {LedgerApiMessage.Performative.STATE, LedgerApiMessage.Performative.ERROR} - ), - LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT: frozenset( - { - LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - LedgerApiMessage.Performative.ERROR, - } - ), - LedgerApiMessage.Performative.RAW_TRANSACTION: frozenset(), - LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION: frozenset( - { - LedgerApiMessage.Performative.TRANSACTION_DIGEST, - LedgerApiMessage.Performative.ERROR, - } - ), - LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS: frozenset( - { - LedgerApiMessage.Performative.TRANSACTION_DIGESTS, - LedgerApiMessage.Performative.ERROR, - } - ), - LedgerApiMessage.Performative.STATE: frozenset(), - LedgerApiMessage.Performative.TRANSACTION_DIGEST: frozenset(), - LedgerApiMessage.Performative.TRANSACTION_DIGESTS: frozenset(), - LedgerApiMessage.Performative.TRANSACTION_RECEIPT: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a ledger_api dialogue.""" - - AGENT = "agent" - LEDGER = "ledger" - - class EndState(Dialogue.EndState): - """This class defines the end states of a ledger_api dialogue.""" - - SUCCESSFUL = 0 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[LedgerApiMessage] = LedgerApiMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class LedgerApiDialogues(Dialogues, ABC): - """This class keeps track of all ledger_api dialogues.""" - - END_STATES = frozenset({LedgerApiDialogue.EndState.SUCCESSFUL}) - - _keep_terminal_state_dialogues = False - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[LedgerApiDialogue] = LedgerApiDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=LedgerApiMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_old/vendor/valory/protocols/ledger_api/ledger_api.proto b/trader_old/vendor/valory/protocols/ledger_api/ledger_api.proto deleted file mode 100644 index e0441b4f0..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/ledger_api.proto +++ /dev/null @@ -1,132 +0,0 @@ -syntax = "proto3"; - -package aea.valory.ledger_api.v1_0_0; - -message LedgerApiMessage{ - - // Custom Types - message Kwargs{ - bytes kwargs = 1; - } - - message RawTransaction{ - bytes raw_transaction = 1; - } - - message SignedTransaction{ - bytes signed_transaction = 1; - } - - message SignedTransactions{ - string ledger_id = 1; - repeated bytes signed_transactions = 2; - } - - message State{ - bytes state = 1; - } - - message Terms{ - bytes terms = 1; - } - - message TransactionDigest{ - bytes transaction_digest = 1; - } - - message TransactionDigests{ - string ledger_id = 1; - repeated string transaction_digests = 2; - } - - message TransactionReceipt{ - bytes transaction_receipt = 1; - } - - - // Performatives and contents - message Get_Balance_Performative{ - string ledger_id = 1; - string address = 2; - } - - message Get_Raw_Transaction_Performative{ - Terms terms = 1; - } - - message Send_Signed_Transaction_Performative{ - SignedTransaction signed_transaction = 1; - Kwargs kwargs = 2; - } - - message Send_Signed_Transactions_Performative{ - SignedTransactions signed_transactions = 1; - Kwargs kwargs = 2; - } - - message Get_Transaction_Receipt_Performative{ - TransactionDigest transaction_digest = 1; - int32 retry_timeout = 2; - bool retry_timeout_is_set = 3; - int32 retry_attempts = 4; - bool retry_attempts_is_set = 5; - } - - message Balance_Performative{ - string ledger_id = 1; - int32 balance = 2; - } - - message Raw_Transaction_Performative{ - RawTransaction raw_transaction = 1; - } - - message Transaction_Digest_Performative{ - TransactionDigest transaction_digest = 1; - } - - message Transaction_Digests_Performative{ - TransactionDigests transaction_digests = 1; - } - - message Transaction_Receipt_Performative{ - TransactionReceipt transaction_receipt = 1; - } - - message Get_State_Performative{ - string ledger_id = 1; - string callable = 2; - repeated string args = 3; - Kwargs kwargs = 4; - } - - message State_Performative{ - string ledger_id = 1; - State state = 2; - } - - message Error_Performative{ - int32 code = 1; - string message = 2; - bool message_is_set = 3; - bytes data = 4; - bool data_is_set = 5; - } - - - oneof performative{ - Balance_Performative balance = 5; - Error_Performative error = 6; - Get_Balance_Performative get_balance = 7; - Get_Raw_Transaction_Performative get_raw_transaction = 8; - Get_State_Performative get_state = 9; - Get_Transaction_Receipt_Performative get_transaction_receipt = 10; - Raw_Transaction_Performative raw_transaction = 11; - Send_Signed_Transaction_Performative send_signed_transaction = 12; - Send_Signed_Transactions_Performative send_signed_transactions = 13; - State_Performative state = 14; - Transaction_Digest_Performative transaction_digest = 15; - Transaction_Digests_Performative transaction_digests = 16; - Transaction_Receipt_Performative transaction_receipt = 17; - } -} diff --git a/trader_old/vendor/valory/protocols/ledger_api/ledger_api_pb2.py b/trader_old/vendor/valory/protocols/ledger_api/ledger_api_pb2.py deleted file mode 100644 index 38cc5978e..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/ledger_api_pb2.py +++ /dev/null @@ -1,96 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: ledger_api.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x10ledger_api.proto\x12\x1c\x61\x65\x61.valory.ledger_api.v1_0_0"\xf1\x1b\n\x10LedgerApiMessage\x12V\n\x07\x62\x61lance\x18\x05 \x01(\x0b\x32\x43.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Balance_PerformativeH\x00\x12R\n\x05\x65rror\x18\x06 \x01(\x0b\x32\x41.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Error_PerformativeH\x00\x12^\n\x0bget_balance\x18\x07 \x01(\x0b\x32G.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Get_Balance_PerformativeH\x00\x12n\n\x13get_raw_transaction\x18\x08 \x01(\x0b\x32O.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Get_Raw_Transaction_PerformativeH\x00\x12Z\n\tget_state\x18\t \x01(\x0b\x32\x45.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Get_State_PerformativeH\x00\x12v\n\x17get_transaction_receipt\x18\n \x01(\x0b\x32S.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Get_Transaction_Receipt_PerformativeH\x00\x12\x66\n\x0fraw_transaction\x18\x0b \x01(\x0b\x32K.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Raw_Transaction_PerformativeH\x00\x12v\n\x17send_signed_transaction\x18\x0c \x01(\x0b\x32S.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Send_Signed_Transaction_PerformativeH\x00\x12x\n\x18send_signed_transactions\x18\r \x01(\x0b\x32T.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Send_Signed_Transactions_PerformativeH\x00\x12R\n\x05state\x18\x0e \x01(\x0b\x32\x41.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.State_PerformativeH\x00\x12l\n\x12transaction_digest\x18\x0f \x01(\x0b\x32N.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Transaction_Digest_PerformativeH\x00\x12n\n\x13transaction_digests\x18\x10 \x01(\x0b\x32O.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Transaction_Digests_PerformativeH\x00\x12n\n\x13transaction_receipt\x18\x11 \x01(\x0b\x32O.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Transaction_Receipt_PerformativeH\x00\x1a\x18\n\x06Kwargs\x12\x0e\n\x06kwargs\x18\x01 \x01(\x0c\x1a)\n\x0eRawTransaction\x12\x17\n\x0fraw_transaction\x18\x01 \x01(\x0c\x1a/\n\x11SignedTransaction\x12\x1a\n\x12signed_transaction\x18\x01 \x01(\x0c\x1a\x44\n\x12SignedTransactions\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x1b\n\x13signed_transactions\x18\x02 \x03(\x0c\x1a\x16\n\x05State\x12\r\n\x05state\x18\x01 \x01(\x0c\x1a\x16\n\x05Terms\x12\r\n\x05terms\x18\x01 \x01(\x0c\x1a/\n\x11TransactionDigest\x12\x1a\n\x12transaction_digest\x18\x01 \x01(\x0c\x1a\x44\n\x12TransactionDigests\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x1b\n\x13transaction_digests\x18\x02 \x03(\t\x1a\x31\n\x12TransactionReceipt\x12\x1b\n\x13transaction_receipt\x18\x01 \x01(\x0c\x1a>\n\x18Get_Balance_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x1ag\n Get_Raw_Transaction_Performative\x12\x43\n\x05terms\x18\x01 \x01(\x0b\x32\x34.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Terms\x1a\xcb\x01\n$Send_Signed_Transaction_Performative\x12\\\n\x12signed_transaction\x18\x01 \x01(\x0b\x32@.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.SignedTransaction\x12\x45\n\x06kwargs\x18\x02 \x01(\x0b\x32\x35.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Kwargs\x1a\xce\x01\n%Send_Signed_Transactions_Performative\x12^\n\x13signed_transactions\x18\x01 \x01(\x0b\x32\x41.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.SignedTransactions\x12\x45\n\x06kwargs\x18\x02 \x01(\x0b\x32\x35.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Kwargs\x1a\xf0\x01\n$Get_Transaction_Receipt_Performative\x12\\\n\x12transaction_digest\x18\x01 \x01(\x0b\x32@.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.TransactionDigest\x12\x15\n\rretry_timeout\x18\x02 \x01(\x05\x12\x1c\n\x14retry_timeout_is_set\x18\x03 \x01(\x08\x12\x16\n\x0eretry_attempts\x18\x04 \x01(\x05\x12\x1d\n\x15retry_attempts_is_set\x18\x05 \x01(\x08\x1a:\n\x14\x42\x61lance_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x0f\n\x07\x62\x61lance\x18\x02 \x01(\x05\x1av\n\x1cRaw_Transaction_Performative\x12V\n\x0fraw_transaction\x18\x01 \x01(\x0b\x32=.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.RawTransaction\x1a\x7f\n\x1fTransaction_Digest_Performative\x12\\\n\x12transaction_digest\x18\x01 \x01(\x0b\x32@.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.TransactionDigest\x1a\x82\x01\n Transaction_Digests_Performative\x12^\n\x13transaction_digests\x18\x01 \x01(\x0b\x32\x41.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.TransactionDigests\x1a\x82\x01\n Transaction_Receipt_Performative\x12^\n\x13transaction_receipt\x18\x01 \x01(\x0b\x32\x41.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.TransactionReceipt\x1a\x92\x01\n\x16Get_State_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x10\n\x08\x63\x61llable\x18\x02 \x01(\t\x12\x0c\n\x04\x61rgs\x18\x03 \x03(\t\x12\x45\n\x06kwargs\x18\x04 \x01(\x0b\x32\x35.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.Kwargs\x1al\n\x12State_Performative\x12\x11\n\tledger_id\x18\x01 \x01(\t\x12\x43\n\x05state\x18\x02 \x01(\x0b\x32\x34.aea.valory.ledger_api.v1_0_0.LedgerApiMessage.State\x1an\n\x12\x45rror_Performative\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x16\n\x0emessage_is_set\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\x0c\x12\x13\n\x0b\x64\x61ta_is_set\x18\x05 \x01(\x08\x42\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "ledger_api_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _globals["_LEDGERAPIMESSAGE"]._serialized_start = 51 - _globals["_LEDGERAPIMESSAGE"]._serialized_end = 3620 - _globals["_LEDGERAPIMESSAGE_KWARGS"]._serialized_start = 1427 - _globals["_LEDGERAPIMESSAGE_KWARGS"]._serialized_end = 1451 - _globals["_LEDGERAPIMESSAGE_RAWTRANSACTION"]._serialized_start = 1453 - _globals["_LEDGERAPIMESSAGE_RAWTRANSACTION"]._serialized_end = 1494 - _globals["_LEDGERAPIMESSAGE_SIGNEDTRANSACTION"]._serialized_start = 1496 - _globals["_LEDGERAPIMESSAGE_SIGNEDTRANSACTION"]._serialized_end = 1543 - _globals["_LEDGERAPIMESSAGE_SIGNEDTRANSACTIONS"]._serialized_start = 1545 - _globals["_LEDGERAPIMESSAGE_SIGNEDTRANSACTIONS"]._serialized_end = 1613 - _globals["_LEDGERAPIMESSAGE_STATE"]._serialized_start = 1615 - _globals["_LEDGERAPIMESSAGE_STATE"]._serialized_end = 1637 - _globals["_LEDGERAPIMESSAGE_TERMS"]._serialized_start = 1639 - _globals["_LEDGERAPIMESSAGE_TERMS"]._serialized_end = 1661 - _globals["_LEDGERAPIMESSAGE_TRANSACTIONDIGEST"]._serialized_start = 1663 - _globals["_LEDGERAPIMESSAGE_TRANSACTIONDIGEST"]._serialized_end = 1710 - _globals["_LEDGERAPIMESSAGE_TRANSACTIONDIGESTS"]._serialized_start = 1712 - _globals["_LEDGERAPIMESSAGE_TRANSACTIONDIGESTS"]._serialized_end = 1780 - _globals["_LEDGERAPIMESSAGE_TRANSACTIONRECEIPT"]._serialized_start = 1782 - _globals["_LEDGERAPIMESSAGE_TRANSACTIONRECEIPT"]._serialized_end = 1831 - _globals["_LEDGERAPIMESSAGE_GET_BALANCE_PERFORMATIVE"]._serialized_start = 1833 - _globals["_LEDGERAPIMESSAGE_GET_BALANCE_PERFORMATIVE"]._serialized_end = 1895 - _globals[ - "_LEDGERAPIMESSAGE_GET_RAW_TRANSACTION_PERFORMATIVE" - ]._serialized_start = 1897 - _globals[ - "_LEDGERAPIMESSAGE_GET_RAW_TRANSACTION_PERFORMATIVE" - ]._serialized_end = 2000 - _globals[ - "_LEDGERAPIMESSAGE_SEND_SIGNED_TRANSACTION_PERFORMATIVE" - ]._serialized_start = 2003 - _globals[ - "_LEDGERAPIMESSAGE_SEND_SIGNED_TRANSACTION_PERFORMATIVE" - ]._serialized_end = 2206 - _globals[ - "_LEDGERAPIMESSAGE_SEND_SIGNED_TRANSACTIONS_PERFORMATIVE" - ]._serialized_start = 2209 - _globals[ - "_LEDGERAPIMESSAGE_SEND_SIGNED_TRANSACTIONS_PERFORMATIVE" - ]._serialized_end = 2415 - _globals[ - "_LEDGERAPIMESSAGE_GET_TRANSACTION_RECEIPT_PERFORMATIVE" - ]._serialized_start = 2418 - _globals[ - "_LEDGERAPIMESSAGE_GET_TRANSACTION_RECEIPT_PERFORMATIVE" - ]._serialized_end = 2658 - _globals["_LEDGERAPIMESSAGE_BALANCE_PERFORMATIVE"]._serialized_start = 2660 - _globals["_LEDGERAPIMESSAGE_BALANCE_PERFORMATIVE"]._serialized_end = 2718 - _globals["_LEDGERAPIMESSAGE_RAW_TRANSACTION_PERFORMATIVE"]._serialized_start = 2720 - _globals["_LEDGERAPIMESSAGE_RAW_TRANSACTION_PERFORMATIVE"]._serialized_end = 2838 - _globals[ - "_LEDGERAPIMESSAGE_TRANSACTION_DIGEST_PERFORMATIVE" - ]._serialized_start = 2840 - _globals["_LEDGERAPIMESSAGE_TRANSACTION_DIGEST_PERFORMATIVE"]._serialized_end = 2967 - _globals[ - "_LEDGERAPIMESSAGE_TRANSACTION_DIGESTS_PERFORMATIVE" - ]._serialized_start = 2970 - _globals[ - "_LEDGERAPIMESSAGE_TRANSACTION_DIGESTS_PERFORMATIVE" - ]._serialized_end = 3100 - _globals[ - "_LEDGERAPIMESSAGE_TRANSACTION_RECEIPT_PERFORMATIVE" - ]._serialized_start = 3103 - _globals[ - "_LEDGERAPIMESSAGE_TRANSACTION_RECEIPT_PERFORMATIVE" - ]._serialized_end = 3233 - _globals["_LEDGERAPIMESSAGE_GET_STATE_PERFORMATIVE"]._serialized_start = 3236 - _globals["_LEDGERAPIMESSAGE_GET_STATE_PERFORMATIVE"]._serialized_end = 3382 - _globals["_LEDGERAPIMESSAGE_STATE_PERFORMATIVE"]._serialized_start = 3384 - _globals["_LEDGERAPIMESSAGE_STATE_PERFORMATIVE"]._serialized_end = 3492 - _globals["_LEDGERAPIMESSAGE_ERROR_PERFORMATIVE"]._serialized_start = 3494 - _globals["_LEDGERAPIMESSAGE_ERROR_PERFORMATIVE"]._serialized_end = 3604 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/protocols/ledger_api/message.py b/trader_old/vendor/valory/protocols/ledger_api/message.py deleted file mode 100644 index 37e5606a7..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/message.py +++ /dev/null @@ -1,594 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 ledger_api's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Optional, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - -from packages.valory.protocols.ledger_api.custom_types import Kwargs as CustomKwargs -from packages.valory.protocols.ledger_api.custom_types import ( - RawTransaction as CustomRawTransaction, -) -from packages.valory.protocols.ledger_api.custom_types import ( - SignedTransaction as CustomSignedTransaction, -) -from packages.valory.protocols.ledger_api.custom_types import ( - SignedTransactions as CustomSignedTransactions, -) -from packages.valory.protocols.ledger_api.custom_types import State as CustomState -from packages.valory.protocols.ledger_api.custom_types import Terms as CustomTerms -from packages.valory.protocols.ledger_api.custom_types import ( - TransactionDigest as CustomTransactionDigest, -) -from packages.valory.protocols.ledger_api.custom_types import ( - TransactionDigests as CustomTransactionDigests, -) -from packages.valory.protocols.ledger_api.custom_types import ( - TransactionReceipt as CustomTransactionReceipt, -) - - -_default_logger = logging.getLogger("aea.packages.valory.protocols.ledger_api.message") - -DEFAULT_BODY_SIZE = 4 - - -class LedgerApiMessage(Message): - """A protocol for ledger APIs requests and responses.""" - - protocol_id = PublicId.from_str("valory/ledger_api:1.0.0") - protocol_specification_id = PublicId.from_str("valory/ledger_api:1.0.0") - - Kwargs = CustomKwargs - - RawTransaction = CustomRawTransaction - - SignedTransaction = CustomSignedTransaction - - SignedTransactions = CustomSignedTransactions - - State = CustomState - - Terms = CustomTerms - - TransactionDigest = CustomTransactionDigest - - TransactionDigests = CustomTransactionDigests - - TransactionReceipt = CustomTransactionReceipt - - class Performative(Message.Performative): - """Performatives for the ledger_api protocol.""" - - BALANCE = "balance" - ERROR = "error" - GET_BALANCE = "get_balance" - GET_RAW_TRANSACTION = "get_raw_transaction" - GET_STATE = "get_state" - GET_TRANSACTION_RECEIPT = "get_transaction_receipt" - RAW_TRANSACTION = "raw_transaction" - SEND_SIGNED_TRANSACTION = "send_signed_transaction" - SEND_SIGNED_TRANSACTIONS = "send_signed_transactions" - STATE = "state" - TRANSACTION_DIGEST = "transaction_digest" - TRANSACTION_DIGESTS = "transaction_digests" - TRANSACTION_RECEIPT = "transaction_receipt" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = { - "balance", - "error", - "get_balance", - "get_raw_transaction", - "get_state", - "get_transaction_receipt", - "raw_transaction", - "send_signed_transaction", - "send_signed_transactions", - "state", - "transaction_digest", - "transaction_digests", - "transaction_receipt", - } - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "address", - "args", - "balance", - "callable", - "code", - "data", - "dialogue_reference", - "kwargs", - "ledger_id", - "message", - "message_id", - "performative", - "raw_transaction", - "retry_attempts", - "retry_timeout", - "signed_transaction", - "signed_transactions", - "state", - "target", - "terms", - "transaction_digest", - "transaction_digests", - "transaction_receipt", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of LedgerApiMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=LedgerApiMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(LedgerApiMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def address(self) -> str: - """Get the 'address' content from the message.""" - enforce(self.is_set("address"), "'address' content is not set.") - return cast(str, self.get("address")) - - @property - def args(self) -> Tuple[str, ...]: - """Get the 'args' content from the message.""" - enforce(self.is_set("args"), "'args' content is not set.") - return cast(Tuple[str, ...], self.get("args")) - - @property - def balance(self) -> int: - """Get the 'balance' content from the message.""" - enforce(self.is_set("balance"), "'balance' content is not set.") - return cast(int, self.get("balance")) - - @property - def callable(self) -> str: - """Get the 'callable' content from the message.""" - enforce(self.is_set("callable"), "'callable' content is not set.") - return cast(str, self.get("callable")) - - @property - def code(self) -> int: - """Get the 'code' content from the message.""" - enforce(self.is_set("code"), "'code' content is not set.") - return cast(int, self.get("code")) - - @property - def data(self) -> Optional[bytes]: - """Get the 'data' content from the message.""" - return cast(Optional[bytes], self.get("data")) - - @property - def kwargs(self) -> CustomKwargs: - """Get the 'kwargs' content from the message.""" - enforce(self.is_set("kwargs"), "'kwargs' content is not set.") - return cast(CustomKwargs, self.get("kwargs")) - - @property - def ledger_id(self) -> str: - """Get the 'ledger_id' content from the message.""" - enforce(self.is_set("ledger_id"), "'ledger_id' content is not set.") - return cast(str, self.get("ledger_id")) - - @property - def message(self) -> Optional[str]: - """Get the 'message' content from the message.""" - return cast(Optional[str], self.get("message")) - - @property - def raw_transaction(self) -> CustomRawTransaction: - """Get the 'raw_transaction' content from the message.""" - enforce(self.is_set("raw_transaction"), "'raw_transaction' content is not set.") - return cast(CustomRawTransaction, self.get("raw_transaction")) - - @property - def retry_attempts(self) -> Optional[int]: - """Get the 'retry_attempts' content from the message.""" - return cast(Optional[int], self.get("retry_attempts")) - - @property - def retry_timeout(self) -> Optional[int]: - """Get the 'retry_timeout' content from the message.""" - return cast(Optional[int], self.get("retry_timeout")) - - @property - def signed_transaction(self) -> CustomSignedTransaction: - """Get the 'signed_transaction' content from the message.""" - enforce( - self.is_set("signed_transaction"), - "'signed_transaction' content is not set.", - ) - return cast(CustomSignedTransaction, self.get("signed_transaction")) - - @property - def signed_transactions(self) -> CustomSignedTransactions: - """Get the 'signed_transactions' content from the message.""" - enforce( - self.is_set("signed_transactions"), - "'signed_transactions' content is not set.", - ) - return cast(CustomSignedTransactions, self.get("signed_transactions")) - - @property - def state(self) -> CustomState: - """Get the 'state' content from the message.""" - enforce(self.is_set("state"), "'state' content is not set.") - return cast(CustomState, self.get("state")) - - @property - def terms(self) -> CustomTerms: - """Get the 'terms' content from the message.""" - enforce(self.is_set("terms"), "'terms' content is not set.") - return cast(CustomTerms, self.get("terms")) - - @property - def transaction_digest(self) -> CustomTransactionDigest: - """Get the 'transaction_digest' content from the message.""" - enforce( - self.is_set("transaction_digest"), - "'transaction_digest' content is not set.", - ) - return cast(CustomTransactionDigest, self.get("transaction_digest")) - - @property - def transaction_digests(self) -> CustomTransactionDigests: - """Get the 'transaction_digests' content from the message.""" - enforce( - self.is_set("transaction_digests"), - "'transaction_digests' content is not set.", - ) - return cast(CustomTransactionDigests, self.get("transaction_digests")) - - @property - def transaction_receipt(self) -> CustomTransactionReceipt: - """Get the 'transaction_receipt' content from the message.""" - enforce( - self.is_set("transaction_receipt"), - "'transaction_receipt' content is not set.", - ) - return cast(CustomTransactionReceipt, self.get("transaction_receipt")) - - def _is_consistent(self) -> bool: - """Check that the message follows the ledger_api protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, LedgerApiMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == LedgerApiMessage.Performative.GET_BALANCE: - expected_nb_of_contents = 2 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.address, str), - "Invalid type for content 'address'. Expected 'str'. Found '{}'.".format( - type(self.address) - ), - ) - elif self.performative == LedgerApiMessage.Performative.GET_RAW_TRANSACTION: - expected_nb_of_contents = 1 - enforce( - isinstance(self.terms, CustomTerms), - "Invalid type for content 'terms'. Expected 'Terms'. Found '{}'.".format( - type(self.terms) - ), - ) - elif ( - self.performative - == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION - ): - expected_nb_of_contents = 2 - enforce( - isinstance(self.signed_transaction, CustomSignedTransaction), - "Invalid type for content 'signed_transaction'. Expected 'SignedTransaction'. Found '{}'.".format( - type(self.signed_transaction) - ), - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif ( - self.performative - == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS - ): - expected_nb_of_contents = 2 - enforce( - isinstance(self.signed_transactions, CustomSignedTransactions), - "Invalid type for content 'signed_transactions'. Expected 'SignedTransactions'. Found '{}'.".format( - type(self.signed_transactions) - ), - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif ( - self.performative - == LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT - ): - expected_nb_of_contents = 1 - enforce( - isinstance(self.transaction_digest, CustomTransactionDigest), - "Invalid type for content 'transaction_digest'. Expected 'TransactionDigest'. Found '{}'.".format( - type(self.transaction_digest) - ), - ) - if self.is_set("retry_timeout"): - expected_nb_of_contents += 1 - retry_timeout = cast(int, self.retry_timeout) - enforce( - type(retry_timeout) is int, - "Invalid type for content 'retry_timeout'. Expected 'int'. Found '{}'.".format( - type(retry_timeout) - ), - ) - if self.is_set("retry_attempts"): - expected_nb_of_contents += 1 - retry_attempts = cast(int, self.retry_attempts) - enforce( - type(retry_attempts) is int, - "Invalid type for content 'retry_attempts'. Expected 'int'. Found '{}'.".format( - type(retry_attempts) - ), - ) - elif self.performative == LedgerApiMessage.Performative.BALANCE: - expected_nb_of_contents = 2 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - type(self.balance) is int, - "Invalid type for content 'balance'. Expected 'int'. Found '{}'.".format( - type(self.balance) - ), - ) - elif self.performative == LedgerApiMessage.Performative.RAW_TRANSACTION: - expected_nb_of_contents = 1 - enforce( - isinstance(self.raw_transaction, CustomRawTransaction), - "Invalid type for content 'raw_transaction'. Expected 'RawTransaction'. Found '{}'.".format( - type(self.raw_transaction) - ), - ) - elif self.performative == LedgerApiMessage.Performative.TRANSACTION_DIGEST: - expected_nb_of_contents = 1 - enforce( - isinstance(self.transaction_digest, CustomTransactionDigest), - "Invalid type for content 'transaction_digest'. Expected 'TransactionDigest'. Found '{}'.".format( - type(self.transaction_digest) - ), - ) - elif self.performative == LedgerApiMessage.Performative.TRANSACTION_DIGESTS: - expected_nb_of_contents = 1 - enforce( - isinstance(self.transaction_digests, CustomTransactionDigests), - "Invalid type for content 'transaction_digests'. Expected 'TransactionDigests'. Found '{}'.".format( - type(self.transaction_digests) - ), - ) - elif self.performative == LedgerApiMessage.Performative.TRANSACTION_RECEIPT: - expected_nb_of_contents = 1 - enforce( - isinstance(self.transaction_receipt, CustomTransactionReceipt), - "Invalid type for content 'transaction_receipt'. Expected 'TransactionReceipt'. Found '{}'.".format( - type(self.transaction_receipt) - ), - ) - elif self.performative == LedgerApiMessage.Performative.GET_STATE: - expected_nb_of_contents = 4 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.callable, str), - "Invalid type for content 'callable'. Expected 'str'. Found '{}'.".format( - type(self.callable) - ), - ) - enforce( - isinstance(self.args, tuple), - "Invalid type for content 'args'. Expected 'tuple'. Found '{}'.".format( - type(self.args) - ), - ) - enforce( - all(isinstance(element, str) for element in self.args), - "Invalid type for tuple elements in content 'args'. Expected 'str'.", - ) - enforce( - isinstance(self.kwargs, CustomKwargs), - "Invalid type for content 'kwargs'. Expected 'Kwargs'. Found '{}'.".format( - type(self.kwargs) - ), - ) - elif self.performative == LedgerApiMessage.Performative.STATE: - expected_nb_of_contents = 2 - enforce( - isinstance(self.ledger_id, str), - "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( - type(self.ledger_id) - ), - ) - enforce( - isinstance(self.state, CustomState), - "Invalid type for content 'state'. Expected 'State'. Found '{}'.".format( - type(self.state) - ), - ) - elif self.performative == LedgerApiMessage.Performative.ERROR: - expected_nb_of_contents = 1 - enforce( - type(self.code) is int, - "Invalid type for content 'code'. Expected 'int'. Found '{}'.".format( - type(self.code) - ), - ) - if self.is_set("message"): - expected_nb_of_contents += 1 - message = cast(str, self.message) - enforce( - isinstance(message, str), - "Invalid type for content 'message'. Expected 'str'. Found '{}'.".format( - type(message) - ), - ) - if self.is_set("data"): - expected_nb_of_contents += 1 - data = cast(bytes, self.data) - enforce( - isinstance(data, bytes), - "Invalid type for content 'data'. Expected 'bytes'. Found '{}'.".format( - type(data) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_old/vendor/valory/protocols/ledger_api/protocol.yaml b/trader_old/vendor/valory/protocols/ledger_api/protocol.yaml deleted file mode 100644 index 5d767dca8..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/protocol.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: ledger_api -author: valory -version: 1.0.0 -protocol_specification_id: valory/ledger_api:1.0.0 -type: protocol -description: A protocol for ledger APIs requests and responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeieviyxw7rq2fxq74c2fq2vv4qsyvxvioyke6wlz3m7ubfgxvebica - __init__.py: bafybeigxgphnez54c6elal3mfgdxwv3el36srmvblkec6sfpt6hcrcexsq - custom_types.py: bafybeiefoqbszkmctw6fep4pot6rdlm4irfy2dydoihlcb7g6i3v47gu4m - dialogues.py: bafybeiaeulvhvizadautscwbf2mi4uw6gdyh3fe36mixgoyy4wnofexebu - ledger_api.proto: bafybeidsmls6jcbeqv4kokizh3kvwzrlae2penr7ntungtosk6m4lxzd4u - ledger_api_pb2.py: bafybeib6kxlzndw5766nxmwfaqurybwjkw3u3uvowe7vn5h4ljsik2l3xu - message.py: bafybeietvabblvsj4nd3zkf2wtnyt2a7bijjygtjxbzndf3h7ng4sfvb44 - serialization.py: bafybeicbpsrxxk5zohsm642gtryhyebdn7lvrfrgika74lg3w6vxns7afq - tests/__init__.py: bafybeih2pvd62uql4qcvrrzqx6evsuu3apqok6wu63qq4r5qm3rikbfsmy - tests/test_ledger_api.py: bafybeiayvznmhqqy66rfqffyurysjc5jfp3bywhcv4zfvwr7kdwj25qjpa - tests/test_ledger_api_dialogues.py: bafybeiaq4ia6kvbwblyyuq7l64vwlluf57lpdkfddohbkbf2osiolrjeku - tests/test_ledger_api_messages.py: bafybeif4abvermxrxcqqfp65blbajadzl5ymnfjmwx62obj6n45emnlzuu -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_old/vendor/valory/protocols/ledger_api/serialization.py b/trader_old/vendor/valory/protocols/ledger_api/serialization.py deleted file mode 100644 index ebc2e6132..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/serialization.py +++ /dev/null @@ -1,309 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for ledger_api protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.ledger_api import ledger_api_pb2 # type: ignore -from packages.valory.protocols.ledger_api.custom_types import ( # type: ignore - Kwargs, - RawTransaction, - SignedTransaction, - SignedTransactions, - State, - Terms, - TransactionDigest, - TransactionDigests, - TransactionReceipt, -) -from packages.valory.protocols.ledger_api.message import ( # type: ignore - LedgerApiMessage, -) - - -class LedgerApiSerializer(Serializer): - """Serialization for the 'ledger_api' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'LedgerApi' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(LedgerApiMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - ledger_api_msg = ledger_api_pb2.LedgerApiMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == LedgerApiMessage.Performative.GET_BALANCE: - performative = ledger_api_pb2.LedgerApiMessage.Get_Balance_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - address = msg.address - performative.address = address - ledger_api_msg.get_balance.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.GET_RAW_TRANSACTION: - performative = ledger_api_pb2.LedgerApiMessage.Get_Raw_Transaction_Performative() # type: ignore - terms = msg.terms - Terms.encode(performative.terms, terms) - ledger_api_msg.get_raw_transaction.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION: - performative = ledger_api_pb2.LedgerApiMessage.Send_Signed_Transaction_Performative() # type: ignore - signed_transaction = msg.signed_transaction - SignedTransaction.encode( - performative.signed_transaction, signed_transaction - ) - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - ledger_api_msg.send_signed_transaction.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS: - performative = ledger_api_pb2.LedgerApiMessage.Send_Signed_Transactions_Performative() # type: ignore - signed_transactions = msg.signed_transactions - SignedTransactions.encode( - performative.signed_transactions, signed_transactions - ) - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - ledger_api_msg.send_signed_transactions.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT: - performative = ledger_api_pb2.LedgerApiMessage.Get_Transaction_Receipt_Performative() # type: ignore - transaction_digest = msg.transaction_digest - TransactionDigest.encode( - performative.transaction_digest, transaction_digest - ) - if msg.is_set("retry_timeout"): - performative.retry_timeout_is_set = True - retry_timeout = msg.retry_timeout - performative.retry_timeout = retry_timeout - if msg.is_set("retry_attempts"): - performative.retry_attempts_is_set = True - retry_attempts = msg.retry_attempts - performative.retry_attempts = retry_attempts - ledger_api_msg.get_transaction_receipt.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.BALANCE: - performative = ledger_api_pb2.LedgerApiMessage.Balance_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - balance = msg.balance - performative.balance = balance - ledger_api_msg.balance.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.RAW_TRANSACTION: - performative = ledger_api_pb2.LedgerApiMessage.Raw_Transaction_Performative() # type: ignore - raw_transaction = msg.raw_transaction - RawTransaction.encode(performative.raw_transaction, raw_transaction) - ledger_api_msg.raw_transaction.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.TRANSACTION_DIGEST: - performative = ledger_api_pb2.LedgerApiMessage.Transaction_Digest_Performative() # type: ignore - transaction_digest = msg.transaction_digest - TransactionDigest.encode( - performative.transaction_digest, transaction_digest - ) - ledger_api_msg.transaction_digest.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.TRANSACTION_DIGESTS: - performative = ledger_api_pb2.LedgerApiMessage.Transaction_Digests_Performative() # type: ignore - transaction_digests = msg.transaction_digests - TransactionDigests.encode( - performative.transaction_digests, transaction_digests - ) - ledger_api_msg.transaction_digests.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.TRANSACTION_RECEIPT: - performative = ledger_api_pb2.LedgerApiMessage.Transaction_Receipt_Performative() # type: ignore - transaction_receipt = msg.transaction_receipt - TransactionReceipt.encode( - performative.transaction_receipt, transaction_receipt - ) - ledger_api_msg.transaction_receipt.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.GET_STATE: - performative = ledger_api_pb2.LedgerApiMessage.Get_State_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - callable = msg.callable - performative.callable = callable - args = msg.args - performative.args.extend(args) - kwargs = msg.kwargs - Kwargs.encode(performative.kwargs, kwargs) - ledger_api_msg.get_state.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.STATE: - performative = ledger_api_pb2.LedgerApiMessage.State_Performative() # type: ignore - ledger_id = msg.ledger_id - performative.ledger_id = ledger_id - state = msg.state - State.encode(performative.state, state) - ledger_api_msg.state.CopyFrom(performative) - elif performative_id == LedgerApiMessage.Performative.ERROR: - performative = ledger_api_pb2.LedgerApiMessage.Error_Performative() # type: ignore - code = msg.code - performative.code = code - if msg.is_set("message"): - performative.message_is_set = True - message = msg.message - performative.message = message - if msg.is_set("data"): - performative.data_is_set = True - data = msg.data - performative.data = data - ledger_api_msg.error.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = ledger_api_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'LedgerApi' message. - - :param obj: the bytes object. - :return: the 'LedgerApi' message. - """ - message_pb = ProtobufMessage() - ledger_api_pb = ledger_api_pb2.LedgerApiMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - ledger_api_pb.ParseFromString(message_pb.dialogue_message.content) - performative = ledger_api_pb.WhichOneof("performative") - performative_id = LedgerApiMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == LedgerApiMessage.Performative.GET_BALANCE: - ledger_id = ledger_api_pb.get_balance.ledger_id - performative_content["ledger_id"] = ledger_id - address = ledger_api_pb.get_balance.address - performative_content["address"] = address - elif performative_id == LedgerApiMessage.Performative.GET_RAW_TRANSACTION: - pb2_terms = ledger_api_pb.get_raw_transaction.terms - terms = Terms.decode(pb2_terms) - performative_content["terms"] = terms - elif performative_id == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION: - pb2_signed_transaction = ( - ledger_api_pb.send_signed_transaction.signed_transaction - ) - signed_transaction = SignedTransaction.decode(pb2_signed_transaction) - performative_content["signed_transaction"] = signed_transaction - pb2_kwargs = ledger_api_pb.send_signed_transaction.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS: - pb2_signed_transactions = ( - ledger_api_pb.send_signed_transactions.signed_transactions - ) - signed_transactions = SignedTransactions.decode(pb2_signed_transactions) - performative_content["signed_transactions"] = signed_transactions - pb2_kwargs = ledger_api_pb.send_signed_transactions.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT: - pb2_transaction_digest = ( - ledger_api_pb.get_transaction_receipt.transaction_digest - ) - transaction_digest = TransactionDigest.decode(pb2_transaction_digest) - performative_content["transaction_digest"] = transaction_digest - if ledger_api_pb.get_transaction_receipt.retry_timeout_is_set: - retry_timeout = ledger_api_pb.get_transaction_receipt.retry_timeout - performative_content["retry_timeout"] = retry_timeout - if ledger_api_pb.get_transaction_receipt.retry_attempts_is_set: - retry_attempts = ledger_api_pb.get_transaction_receipt.retry_attempts - performative_content["retry_attempts"] = retry_attempts - elif performative_id == LedgerApiMessage.Performative.BALANCE: - ledger_id = ledger_api_pb.balance.ledger_id - performative_content["ledger_id"] = ledger_id - balance = ledger_api_pb.balance.balance - performative_content["balance"] = balance - elif performative_id == LedgerApiMessage.Performative.RAW_TRANSACTION: - pb2_raw_transaction = ledger_api_pb.raw_transaction.raw_transaction - raw_transaction = RawTransaction.decode(pb2_raw_transaction) - performative_content["raw_transaction"] = raw_transaction - elif performative_id == LedgerApiMessage.Performative.TRANSACTION_DIGEST: - pb2_transaction_digest = ledger_api_pb.transaction_digest.transaction_digest - transaction_digest = TransactionDigest.decode(pb2_transaction_digest) - performative_content["transaction_digest"] = transaction_digest - elif performative_id == LedgerApiMessage.Performative.TRANSACTION_DIGESTS: - pb2_transaction_digests = ( - ledger_api_pb.transaction_digests.transaction_digests - ) - transaction_digests = TransactionDigests.decode(pb2_transaction_digests) - performative_content["transaction_digests"] = transaction_digests - elif performative_id == LedgerApiMessage.Performative.TRANSACTION_RECEIPT: - pb2_transaction_receipt = ( - ledger_api_pb.transaction_receipt.transaction_receipt - ) - transaction_receipt = TransactionReceipt.decode(pb2_transaction_receipt) - performative_content["transaction_receipt"] = transaction_receipt - elif performative_id == LedgerApiMessage.Performative.GET_STATE: - ledger_id = ledger_api_pb.get_state.ledger_id - performative_content["ledger_id"] = ledger_id - callable = ledger_api_pb.get_state.callable - performative_content["callable"] = callable - args = ledger_api_pb.get_state.args - args_tuple = tuple(args) - performative_content["args"] = args_tuple - pb2_kwargs = ledger_api_pb.get_state.kwargs - kwargs = Kwargs.decode(pb2_kwargs) - performative_content["kwargs"] = kwargs - elif performative_id == LedgerApiMessage.Performative.STATE: - ledger_id = ledger_api_pb.state.ledger_id - performative_content["ledger_id"] = ledger_id - pb2_state = ledger_api_pb.state.state - state = State.decode(pb2_state) - performative_content["state"] = state - elif performative_id == LedgerApiMessage.Performative.ERROR: - code = ledger_api_pb.error.code - performative_content["code"] = code - if ledger_api_pb.error.message_is_set: - message = ledger_api_pb.error.message - performative_content["message"] = message - if ledger_api_pb.error.data_is_set: - data = ledger_api_pb.error.data - performative_content["data"] = data - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return LedgerApiMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_old/vendor/valory/protocols/ledger_api/tests/__init__.py b/trader_old/vendor/valory/protocols/ledger_api/tests/__init__.py deleted file mode 100644 index 42ad6b368..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for valory/ledger_api protocol.""" diff --git a/trader_old/vendor/valory/protocols/ledger_api/tests/test_ledger_api.py b/trader_old/vendor/valory/protocols/ledger_api/tests/test_ledger_api.py deleted file mode 100644 index 8ef6ef00a..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/tests/test_ledger_api.py +++ /dev/null @@ -1,963 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 Valory AG -# Copyright 2018-2021 Fetch.AI Limited -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for the 'valory/ledger_api' protocol.""" -from abc import abstractmethod -from typing import Callable, Type -from unittest import mock - -import pytest - -from aea.common import Address -from aea.exceptions import AEAEnforceError -from aea.mail.base import Envelope -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.ledger_api import LedgerApiMessage, message -from packages.valory.protocols.ledger_api.custom_types import ( - Kwargs, - SignedTransactions, - State, - Terms, - TransactionDigests, -) -from packages.valory.protocols.ledger_api.dialogues import ( - LedgerApiDialogue, - LedgerApiDialogues, -) -from packages.valory.protocols.ledger_api.message import ( - _default_logger as ledger_api_message_logger, -) - - -LEDGER_ID = "ethereum" -CONTRACT_ID = "contract_id_stub" -CALLABLE = "callable_stub" -CONTRACT_ADDRESS = "contract_address_stub" - - -def test_get_balance_serialization(): - """Test the serialization for 'get_balance' speech-act works.""" - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, - ledger_id="some_ledger_id", - address="some_address", - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_get_state_serialization(): - """Test the serialization for 'get_state' speech-act works.""" - - args = ("arg1", "arg2") - kwargs = Kwargs({"key": "value"}) - - assert str(kwargs) == "Kwargs: body={'key': 'value'}" - - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_STATE, - ledger_id="some_ledger_id", - callable="some_function", - args=args, - kwargs=kwargs, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_get_raw_transaction_serialization(): - """Test the serialization for 'get_raw_transaction' speech-act works.""" - terms_arg = LedgerApiMessage.Terms( - ledger_id="some_ledger_id", - sender_address="some_sender_address", - counterparty_address="some_counterparty_address", - amount_by_currency_id={"currency_id_1": 1}, - quantities_by_good_id={"good_id_1": -1, "good_id_2": -2}, - nonce="some_nonce", - is_sender_payable_tx_fee=False, - fee_by_currency_id={"currency_id_1": 1}, - is_strict=True, - ) - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, - terms=terms_arg, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_send_signed_transaction_serialization(): - """Test the serialization for 'send_signed_transaction' speech-act works.""" - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, - signed_transaction=LedgerApiMessage.SignedTransaction( - "some_ledger_id", {"body": "some_body"} - ), - kwargs=Kwargs({}), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_get_transaction_receipt_serialization(): - """Test the serialization for 'get_transaction_receipt' speech-act works.""" - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, - transaction_digest=LedgerApiMessage.TransactionDigest( - "some_ledger_id", "some_body" - ), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_balance_serialization(): - """Test the serialization for 'balance' speech-act works.""" - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.BALANCE, - ledger_id="some_ledger_id", - balance=125, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_state_serialization(): - """Test the serialization for 'state' speech-act works.""" - - ledger_id = "some_ledger_id" - state = State(ledger_id, {"key": "some_state"}) - - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.STATE, - ledger_id=ledger_id, - state=state, - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_raw_transaction_serialization(): - """Test the serialization for 'raw_transaction' speech-act works.""" - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=LedgerApiMessage.RawTransaction( - "some_ledger_id", {"body": "some_body"} - ), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_transaction_digest_serialization(): - """Test the serialization for 'transaction_digest' speech-act works.""" - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, - transaction_digest=LedgerApiMessage.TransactionDigest( - "some_ledger_id", "some_body" - ), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_transaction_receipt_serialization(): - """Test the serialization for 'transaction_receipt' speech-act works.""" - msg = LedgerApiMessage( - message_id=2, - target=1, - performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - transaction_receipt=LedgerApiMessage.TransactionReceipt( - "some_ledger_id", {"key": "some_receipt"}, {"key": "some_transaction"} - ), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_error_serialization(): - """Test the serialization for 'error' speech-act works.""" - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.ERROR, - code=7, - message="some_error_message", - data=b"some_error_data", - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_performative_string_value() -> None: - """Test the string value of the performatives.""" - assert ( - str(LedgerApiMessage.Performative.GET_BALANCE) == "get_balance" - ), "The str value must be get_balance" - assert ( - str(LedgerApiMessage.Performative.GET_RAW_TRANSACTION) == "get_raw_transaction" - ), "The str value must be get_raw_transaction" - assert ( - str(LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION) - == "send_signed_transaction" - ), "The str value must be send_signed_transaction" - assert ( - str(LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT) - == "get_transaction_receipt" - ), "The str value must be get_transaction_receipt" - assert ( - str(LedgerApiMessage.Performative.BALANCE) == "balance" - ), "The str value must be balance" - assert ( - str(LedgerApiMessage.Performative.RAW_TRANSACTION) == "raw_transaction" - ), "The str value must be raw_transaction" - assert ( - str(LedgerApiMessage.Performative.TRANSACTION_DIGEST) == "transaction_digest" - ), "The str value must be transaction_digest" - assert ( - str(LedgerApiMessage.Performative.TRANSACTION_RECEIPT) == "transaction_receipt" - ), "The str value must be transaction_receipt" - assert ( - str(LedgerApiMessage.Performative.ERROR) == "error" - ), "The str value must be error" - - -def test_encoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, # type: ignore - ledger_id=LEDGER_ID, - address="address", - ) - - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object( - LedgerApiMessage.Performative, "__eq__", return_value=False - ): - LedgerApiMessage.serializer.encode(msg) - - -def test_decoding_unknown_performative() -> None: - """Test that we raise an exception when the performative is unknown during encoding.""" - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, # type: ignore - ledger_id=LEDGER_ID, - address="address", - ) - - encoded_msg = LedgerApiMessage.serializer.encode(msg) - with pytest.raises(ValueError, match="Performative not valid:"): - with mock.patch.object( - LedgerApiMessage.Performative, "__eq__", return_value=False - ): - LedgerApiMessage.serializer.decode(encoded_msg) - - -@mock.patch.object( - message, - "enforce", - side_effect=AEAEnforceError("some error"), -) -def test_incorrect_message( - mocked_enforce: Callable, # pylint: disable=unused-argument -) -> None: - """Test that we raise an exception when the message is incorrect.""" - with mock.patch.object(ledger_api_message_logger, "error") as mock_logger: - LedgerApiMessage( - message_id=1, - dialogue_reference=(str(0), ""), - target=0, - performative=LedgerApiMessage.Performative.STATE, # type: ignore - ledger_id=LEDGER_ID, - state=LedgerApiMessage.State("some_ledger_id", {}), - ) - - mock_logger.assert_any_call("some error") - - -def test_send_signed_transactions_serialization() -> None: - """Test that the serialization for 'send_signed_transactions' works.""" - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS, - signed_transactions=SignedTransactions( - ledger_id=LEDGER_ID, signed_transactions=[dict(), dict(), dict(), dict()] - ), - kwargs=Kwargs(body={}), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_transaction_digests_serialization() -> None: - """Test that the serialization for 'transaction_digests' works.""" - msg = LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGESTS, - transaction_digests=TransactionDigests( - ledger_id=LEDGER_ID, transaction_digests=["", "", "", ""] - ), - ) - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = LedgerApiMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -class BaseTestMessageConstruction: - """Base class to test message construction for the ABCI protocol.""" - - ledger_id = LEDGER_ID - address = "address_stub" - contract_id = CONTRACT_ID - callable_ = CALLABLE - msg_class = LedgerApiMessage - contract_address = CONTRACT_ADDRESS - - @abstractmethod - def build_message(self) -> LedgerApiMessage: - """Build the message to be used for testing.""" - - def test_run(self) -> None: - """Run the test.""" - msg = self.build_message() - msg.to = "receiver" - envelope = Envelope(to=msg.to, sender="sender", message=msg) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = self.msg_class.serializer.decode(actual_envelope.message_bytes) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - @classmethod - def _make_terms(cls) -> Terms: - """Build a Terms object.""" - return LedgerApiMessage.Terms( - ledger_id=cls.ledger_id, - sender_address="sender_address", - counterparty_address="counterparty_address", - amount_by_currency_id={}, - quantities_by_good_id={}, - nonce="nonce_stub", - ) - - -class TestGetBalance(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, # type: ignore - ledger_id=self.ledger_id, - address=self.address, - ) - - -class TestBalance(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - assert str(LedgerApiMessage.Kwargs({})) == "Kwargs: body={}" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.BALANCE, # type: ignore - ledger_id=self.ledger_id, - balance=0, - ) - - -class TestGetRawTransaction(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - terms=self._make_terms(), - ) - - -class TestRawTransaction(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.RAW_TRANSACTION, # type: ignore - raw_transaction=LedgerApiMessage.RawTransaction( - ledger_id=LEDGER_ID, body={} - ), - ) - - -class TestSendSignedTransaction(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, # type: ignore - signed_transaction=LedgerApiMessage.SignedTransaction( - ledger_id=self.ledger_id, body={} - ), - kwargs=Kwargs({}), - ) - - -class TestTransactionDigest(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, # type: ignore - transaction_digest=LedgerApiMessage.TransactionDigest( - ledger_id=LEDGER_ID, body="" - ), - ) - - -class TestGetTransactionReceipt(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, # type: ignore - transaction_digest=LedgerApiMessage.TransactionDigest( - ledger_id=LEDGER_ID, body="" - ), - ) - - -class TestGetTransactionReceiptWithParams(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, # type: ignore - transaction_digest=LedgerApiMessage.TransactionDigest( - ledger_id=LEDGER_ID, body="" - ), - retry_timeout=3, - retry_attempts=1, - ) - - -class TestTransactionReceipt(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT, # type: ignore - transaction_receipt=LedgerApiMessage.TransactionReceipt( - ledger_id=LEDGER_ID, receipt={}, transaction={} - ), - ) - - -class TestGetState(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_STATE, # type: ignore - ledger_id=self.ledger_id, - callable="cabllable", - args=("",), - kwargs=LedgerApiMessage.Kwargs({}), - ) - - -class TestState(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.STATE, # type: ignore - ledger_id=self.ledger_id, - state=LedgerApiMessage.State(ledger_id=LEDGER_ID, body={}), - ) - - -class TestError(BaseTestMessageConstruction): - """Test message.""" - - def build_message(self) -> LedgerApiMessage: - """Build the message.""" - return LedgerApiMessage( - performative=LedgerApiMessage.Performative.ERROR, # type: ignore - code=1, - message="", - data=b"", - ) - - -class AgentDialogue(LedgerApiDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[LedgerApiMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - LedgerApiDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class AgentDialogues(LedgerApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return LedgerApiDialogue.Role.AGENT - - LedgerApiDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=AgentDialogue, - ) - - -class LedgerDialogue(LedgerApiDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[LedgerApiMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - LedgerApiDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class LedgerDialogues(LedgerApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return LedgerApiDialogue.Role.LEDGER - - LedgerApiDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=LedgerDialogue, - ) - - -class TestDialogues: - """Tests abci dialogues.""" - - agent_addr: str - ledger_addr: str - agent_dialogues: AgentDialogues - ledger_dialogues: LedgerDialogues - - @classmethod - def setup_class(cls) -> None: - """Set up the test.""" - cls.agent_addr = "agent address" - cls.ledger_addr = "ledger address" - cls.agent_dialogues = AgentDialogues(cls.agent_addr) - cls.ledger_dialogues = LedgerDialogues(cls.ledger_addr) - - def test_create_self_initiated(self) -> None: - """Test the self initialisation of a dialogue.""" - result = self.agent_dialogues._create_self_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.ledger_addr, - dialogue_reference=(str(0), ""), - role=LedgerApiDialogue.Role.AGENT, - ) - assert isinstance(result, LedgerApiDialogue) - assert result.role == LedgerApiDialogue.Role.AGENT, "The role must be agent." - - def test_create_opponent_initiated(self) -> None: - """Test the opponent initialisation of a dialogue.""" - result = self.agent_dialogues._create_opponent_initiated( # pylint: disable=protected-access - dialogue_opponent_addr=self.ledger_addr, - dialogue_reference=(str(0), ""), - role=LedgerApiDialogue.Role.AGENT, - ) - assert isinstance(result, LedgerApiDialogue) - assert result.role == LedgerApiDialogue.Role.AGENT, "The role must be agent." diff --git a/trader_old/vendor/valory/protocols/ledger_api/tests/test_ledger_api_dialogues.py b/trader_old/vendor/valory/protocols/ledger_api/tests/test_ledger_api_dialogues.py deleted file mode 100644 index 55cdea143..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/tests/test_ledger_api_dialogues.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for ledger_api protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.ledger_api.dialogues import ( - LedgerApiDialogue, - LedgerApiDialogues, -) -from packages.valory.protocols.ledger_api.message import LedgerApiMessage - - -class TestDialoguesLedgerApi(BaseProtocolDialoguesTestCase): - """Test for the 'ledger_api' protocol dialogues.""" - - MESSAGE_CLASS = LedgerApiMessage - - DIALOGUE_CLASS = LedgerApiDialogue - - DIALOGUES_CLASS = LedgerApiDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = LedgerApiDialogue.Role.AGENT # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=LedgerApiMessage.Performative.GET_BALANCE, - ledger_id="some str", - address="some str", - ) diff --git a/trader_old/vendor/valory/protocols/ledger_api/tests/test_ledger_api_messages.py b/trader_old/vendor/valory/protocols/ledger_api/tests/test_ledger_api_messages.py deleted file mode 100644 index 3bdbf1c4a..000000000 --- a/trader_old/vendor/valory/protocols/ledger_api/tests/test_ledger_api_messages.py +++ /dev/null @@ -1,180 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for ledger_api protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.ledger_api.custom_types import ( - Kwargs, - RawTransaction, - SignedTransaction, - State, - Terms, - TransactionDigest, - TransactionReceipt, -) -from packages.valory.protocols.ledger_api.message import LedgerApiMessage - - -LEDGER_ID = "ethereum" - - -class TestMessageLedgerApi(BaseProtocolMessagesTestCase): - """Test for the 'ledger_api' protocol message.""" - - MESSAGE_CLASS = LedgerApiMessage - - ledger_id = LEDGER_ID - terms = Terms( - ledger_id=ledger_id, - sender_address="sender_address", - counterparty_address="counterparty_address", - amount_by_currency_id={}, - quantities_by_good_id={}, - nonce="nonce_stub", - ) - - def build_messages(self) -> List[LedgerApiMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, - ledger_id="some str", - address="some str", - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, - terms=self.terms, - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, - signed_transaction=SignedTransaction( - "some_ledger_id", {"body": "some_body"} - ), - kwargs=Kwargs({}), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, - transaction_digest=TransactionDigest("some_ledger_id", "some_body"), - retry_timeout=12, - retry_attempts=12, - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.BALANCE, - ledger_id="some str", - balance=12, - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=RawTransaction("some_ledger_id", {"body": "some_body"}), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, - transaction_digest=TransactionDigest("some_ledger_id", "some_body"), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - transaction_receipt=TransactionReceipt( - "some_ledger_id", - {"key": "some_receipt"}, - {"key": "some_transaction"}, - ), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_STATE, - ledger_id="some str", - callable="some str", - args=("some str",), - kwargs=Kwargs({}), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.STATE, - ledger_id="some str", - state=State(ledger_id=LEDGER_ID, body={}), # check it please! - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.ERROR, - code=12, - message="some str", - data=b"some_bytes", - ), - ] - - def build_inconsistent(self) -> List[LedgerApiMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_BALANCE, - # skip content: ledger_id - address="some str", - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_RAW_TRANSACTION, - # skip content: terms - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, - # skip content: signed_transaction - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, - # skip content: transaction_digest - retry_timeout=12, - retry_attempts=12, - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.BALANCE, - # skip content: ledger_id - balance=12, - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.RAW_TRANSACTION, - # skip content: raw_transaction - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, - # skip content: transaction_digest - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - # skip content: transaction_receipt - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.GET_STATE, - # skip content: ledger_id - callable="some str", - args=("some str",), - kwargs=Kwargs({}), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.STATE, - # skip content: ledger_id - state=State(ledger_id=LEDGER_ID, body={}), - ), - LedgerApiMessage( - performative=LedgerApiMessage.Performative.ERROR, - # skip content: code - message="some str", - data=b"some_bytes", - ), - ] diff --git a/trader_old/vendor/valory/protocols/tendermint/README.md b/trader_old/vendor/valory/protocols/tendermint/README.md deleted file mode 100644 index c10d0ad13..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Tendermint Protocol - -## Description - -This is a protocol for communication between AEAs for sharing their tendermint configuration details. - -## Specification - -```yaml ---- -name: tendermint -author: valory -version: 0.1.0 -protocol_specification_id: valory/tendermint:0.1.0 -description: A protocol for communication between two AEAs to share tendermint configuration details. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -speech_acts: - get_genesis_info: - query: pt:optional[pt:str] - get_recovery_params: - query: pt:optional[pt:str] - genesis_info: - info: pt:str - recovery_params: - params: pt:str - error: - error_code: ct:ErrorCode - error_msg: pt:str - error_data: pt:dict[pt:str, pt:str] -... ---- -ct:ErrorCode: | - enum ErrorCodeEnum { - INVALID_REQUEST = 0; - } - ErrorCodeEnum error_code = 1; -... ---- -initiation: [get_genesis_info, get_recovery_params] -reply: - get_genesis_info: [genesis_info, error] - get_recovery_params: [recovery_params, error] - genesis_info: [] - recovery_params: [] - error: [] -roles: {agent} -termination: [genesis_info, recovery_params, error] -end_states: [communicated, not_communicated] -keep_terminal_state_dialogues: true -... -``` - -## Links - diff --git a/trader_old/vendor/valory/protocols/tendermint/__init__.py b/trader_old/vendor/valory/protocols/tendermint/__init__.py deleted file mode 100644 index 90ee9b950..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the support resources for the tendermint protocol. - -It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. -""" - -from packages.valory.protocols.tendermint.message import TendermintMessage -from packages.valory.protocols.tendermint.serialization import TendermintSerializer - - -TendermintMessage.serializer = TendermintSerializer diff --git a/trader_old/vendor/valory/protocols/tendermint/custom_types.py b/trader_old/vendor/valory/protocols/tendermint/custom_types.py deleted file mode 100644 index e3dc43c8b..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/custom_types.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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 class representations corresponding to every custom type in the protocol specification.""" - -from enum import Enum -from typing import Any - - -class ErrorCode(Enum): - """This class represents an instance of ErrorCode.""" - - INVALID_REQUEST = 0 - - @staticmethod - def encode(error_code_protobuf_object: Any, error_code_object: "ErrorCode") -> None: - """ - Encode an instance of this class into the protocol buffer object. - - The protocol buffer object in the error_code_protobuf_object argument is matched with the instance of this class in the 'error_code_object' argument. - - :param error_code_protobuf_object: the protocol buffer object whose type corresponds with this class. - :param error_code_object: an instance of this class to be encoded in the protocol buffer object. - """ - error_code_protobuf_object.error_code = error_code_object.value - - @classmethod - def decode(cls, error_code_protobuf_object: Any) -> "ErrorCode": - """ - Decode a protocol buffer object that corresponds with this class into an instance of this class. - - A new instance of this class is created that matches the protocol buffer object in the 'error_code_protobuf_object' argument. - - :param error_code_protobuf_object: the protocol buffer object whose type corresponds with this class. - :return: A new instance of this class that matches the protocol buffer object in the 'error_code_protobuf_object' argument. - """ - enum_value_from_pb2 = error_code_protobuf_object.error_code - return ErrorCode(enum_value_from_pb2) diff --git a/trader_old/vendor/valory/protocols/tendermint/dialogues.py b/trader_old/vendor/valory/protocols/tendermint/dialogues.py deleted file mode 100644 index c2bcb42a8..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/dialogues.py +++ /dev/null @@ -1,138 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 the classes required for tendermint dialogue management. - -- TendermintDialogue: The dialogue class maintains state of a dialogue and manages it. -- TendermintDialogues: The dialogues class keeps track of all dialogues. -""" - -from abc import ABC -from typing import Callable, Dict, FrozenSet, Type, cast - -from aea.common import Address -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues - -from packages.valory.protocols.tendermint.message import TendermintMessage - - -class TendermintDialogue(Dialogue): - """The tendermint dialogue class maintains state of a dialogue and manages it.""" - - INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - TendermintMessage.Performative.GET_GENESIS_INFO, - TendermintMessage.Performative.GET_RECOVERY_PARAMS, - } - ) - TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( - { - TendermintMessage.Performative.GENESIS_INFO, - TendermintMessage.Performative.RECOVERY_PARAMS, - TendermintMessage.Performative.ERROR, - } - ) - VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { - TendermintMessage.Performative.ERROR: frozenset(), - TendermintMessage.Performative.GENESIS_INFO: frozenset(), - TendermintMessage.Performative.GET_GENESIS_INFO: frozenset( - { - TendermintMessage.Performative.GENESIS_INFO, - TendermintMessage.Performative.ERROR, - } - ), - TendermintMessage.Performative.GET_RECOVERY_PARAMS: frozenset( - { - TendermintMessage.Performative.RECOVERY_PARAMS, - TendermintMessage.Performative.ERROR, - } - ), - TendermintMessage.Performative.RECOVERY_PARAMS: frozenset(), - } - - class Role(Dialogue.Role): - """This class defines the agent's role in a tendermint dialogue.""" - - AGENT = "agent" - - class EndState(Dialogue.EndState): - """This class defines the end states of a tendermint dialogue.""" - - COMMUNICATED = 0 - NOT_COMMUNICATED = 1 - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: Dialogue.Role, - message_class: Type[TendermintMessage] = TendermintMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class used - """ - Dialogue.__init__( - self, - dialogue_label=dialogue_label, - message_class=message_class, - self_address=self_address, - role=role, - ) - - -class TendermintDialogues(Dialogues, ABC): - """This class keeps track of all tendermint dialogues.""" - - END_STATES = frozenset( - { - TendermintDialogue.EndState.COMMUNICATED, - TendermintDialogue.EndState.NOT_COMMUNICATED, - } - ) - - _keep_terminal_state_dialogues = True - - def __init__( - self, - self_address: Address, - role_from_first_message: Callable[[Message, Address], Dialogue.Role], - dialogue_class: Type[TendermintDialogue] = TendermintDialogue, - ) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom dialogues are maintained - :param dialogue_class: the dialogue class used - :param role_from_first_message: the callable determining role from first message - """ - Dialogues.__init__( - self, - self_address=self_address, - end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), - message_class=TendermintMessage, - dialogue_class=dialogue_class, - role_from_first_message=role_from_first_message, - ) diff --git a/trader_old/vendor/valory/protocols/tendermint/message.py b/trader_old/vendor/valory/protocols/tendermint/message.py deleted file mode 100644 index a6e633d98..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/message.py +++ /dev/null @@ -1,313 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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 tendermint's message definition.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,too-many-branches,not-an-iterable,unidiomatic-typecheck,unsubscriptable-object -import logging -from typing import Any, Dict, Optional, Set, Tuple, cast - -from aea.configurations.base import PublicId -from aea.exceptions import AEAEnforceError, enforce -from aea.protocols.base import Message # type: ignore - -from packages.valory.protocols.tendermint.custom_types import ( - ErrorCode as CustomErrorCode, -) - - -_default_logger = logging.getLogger("aea.packages.valory.protocols.tendermint.message") - -DEFAULT_BODY_SIZE = 4 - - -class TendermintMessage(Message): - """A protocol for communication between two AEAs to share tendermint configuration details.""" - - protocol_id = PublicId.from_str("valory/tendermint:0.1.0") - protocol_specification_id = PublicId.from_str("valory/tendermint:0.1.0") - - ErrorCode = CustomErrorCode - - class Performative(Message.Performative): - """Performatives for the tendermint protocol.""" - - ERROR = "error" - GENESIS_INFO = "genesis_info" - GET_GENESIS_INFO = "get_genesis_info" - GET_RECOVERY_PARAMS = "get_recovery_params" - RECOVERY_PARAMS = "recovery_params" - - def __str__(self) -> str: - """Get the string representation.""" - return str(self.value) - - _performatives = { - "error", - "genesis_info", - "get_genesis_info", - "get_recovery_params", - "recovery_params", - } - __slots__: Tuple[str, ...] = tuple() - - class _SlotsCls: - __slots__ = ( - "dialogue_reference", - "error_code", - "error_data", - "error_msg", - "info", - "message_id", - "params", - "performative", - "query", - "target", - ) - - def __init__( - self, - performative: Performative, - dialogue_reference: Tuple[str, str] = ("", ""), - message_id: int = 1, - target: int = 0, - **kwargs: Any, - ): - """ - Initialise an instance of TendermintMessage. - - :param message_id: the message id. - :param dialogue_reference: the dialogue reference. - :param target: the message target. - :param performative: the message performative. - :param **kwargs: extra options. - """ - super().__init__( - dialogue_reference=dialogue_reference, - message_id=message_id, - target=target, - performative=TendermintMessage.Performative(performative), - **kwargs, - ) - - @property - def valid_performatives(self) -> Set[str]: - """Get valid performatives.""" - return self._performatives - - @property - def dialogue_reference(self) -> Tuple[str, str]: - """Get the dialogue_reference of the message.""" - enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") - return cast(Tuple[str, str], self.get("dialogue_reference")) - - @property - def message_id(self) -> int: - """Get the message_id of the message.""" - enforce(self.is_set("message_id"), "message_id is not set.") - return cast(int, self.get("message_id")) - - @property - def performative(self) -> Performative: # type: ignore # noqa: F821 - """Get the performative of the message.""" - enforce(self.is_set("performative"), "performative is not set.") - return cast(TendermintMessage.Performative, self.get("performative")) - - @property - def target(self) -> int: - """Get the target of the message.""" - enforce(self.is_set("target"), "target is not set.") - return cast(int, self.get("target")) - - @property - def error_code(self) -> CustomErrorCode: - """Get the 'error_code' content from the message.""" - enforce(self.is_set("error_code"), "'error_code' content is not set.") - return cast(CustomErrorCode, self.get("error_code")) - - @property - def error_data(self) -> Dict[str, str]: - """Get the 'error_data' content from the message.""" - enforce(self.is_set("error_data"), "'error_data' content is not set.") - return cast(Dict[str, str], self.get("error_data")) - - @property - def error_msg(self) -> str: - """Get the 'error_msg' content from the message.""" - enforce(self.is_set("error_msg"), "'error_msg' content is not set.") - return cast(str, self.get("error_msg")) - - @property - def info(self) -> str: - """Get the 'info' content from the message.""" - enforce(self.is_set("info"), "'info' content is not set.") - return cast(str, self.get("info")) - - @property - def params(self) -> str: - """Get the 'params' content from the message.""" - enforce(self.is_set("params"), "'params' content is not set.") - return cast(str, self.get("params")) - - @property - def query(self) -> Optional[str]: - """Get the 'query' content from the message.""" - return cast(Optional[str], self.get("query")) - - def _is_consistent(self) -> bool: - """Check that the message follows the tendermint protocol.""" - try: - enforce( - isinstance(self.dialogue_reference, tuple), - "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( - type(self.dialogue_reference) - ), - ) - enforce( - isinstance(self.dialogue_reference[0], str), - "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[0]) - ), - ) - enforce( - isinstance(self.dialogue_reference[1], str), - "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( - type(self.dialogue_reference[1]) - ), - ) - enforce( - type(self.message_id) is int, - "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( - type(self.message_id) - ), - ) - enforce( - type(self.target) is int, - "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( - type(self.target) - ), - ) - - # Light Protocol Rule 2 - # Check correct performative - enforce( - isinstance(self.performative, TendermintMessage.Performative), - "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( - self.valid_performatives, self.performative - ), - ) - - # Check correct contents - actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE - expected_nb_of_contents = 0 - if self.performative == TendermintMessage.Performative.GET_GENESIS_INFO: - expected_nb_of_contents = 0 - if self.is_set("query"): - expected_nb_of_contents += 1 - query = cast(str, self.query) - enforce( - isinstance(query, str), - "Invalid type for content 'query'. Expected 'str'. Found '{}'.".format( - type(query) - ), - ) - elif ( - self.performative == TendermintMessage.Performative.GET_RECOVERY_PARAMS - ): - expected_nb_of_contents = 0 - if self.is_set("query"): - expected_nb_of_contents += 1 - query = cast(str, self.query) - enforce( - isinstance(query, str), - "Invalid type for content 'query'. Expected 'str'. Found '{}'.".format( - type(query) - ), - ) - elif self.performative == TendermintMessage.Performative.GENESIS_INFO: - expected_nb_of_contents = 1 - enforce( - isinstance(self.info, str), - "Invalid type for content 'info'. Expected 'str'. Found '{}'.".format( - type(self.info) - ), - ) - elif self.performative == TendermintMessage.Performative.RECOVERY_PARAMS: - expected_nb_of_contents = 1 - enforce( - isinstance(self.params, str), - "Invalid type for content 'params'. Expected 'str'. Found '{}'.".format( - type(self.params) - ), - ) - elif self.performative == TendermintMessage.Performative.ERROR: - expected_nb_of_contents = 3 - enforce( - isinstance(self.error_code, CustomErrorCode), - "Invalid type for content 'error_code'. Expected 'ErrorCode'. Found '{}'.".format( - type(self.error_code) - ), - ) - enforce( - isinstance(self.error_msg, str), - "Invalid type for content 'error_msg'. Expected 'str'. Found '{}'.".format( - type(self.error_msg) - ), - ) - enforce( - isinstance(self.error_data, dict), - "Invalid type for content 'error_data'. Expected 'dict'. Found '{}'.".format( - type(self.error_data) - ), - ) - for key_of_error_data, value_of_error_data in self.error_data.items(): - enforce( - isinstance(key_of_error_data, str), - "Invalid type for dictionary keys in content 'error_data'. Expected 'str'. Found '{}'.".format( - type(key_of_error_data) - ), - ) - enforce( - isinstance(value_of_error_data, str), - "Invalid type for dictionary values in content 'error_data'. Expected 'str'. Found '{}'.".format( - type(value_of_error_data) - ), - ) - - # Check correct content count - enforce( - expected_nb_of_contents == actual_nb_of_contents, - "Incorrect number of contents. Expected {}. Found {}".format( - expected_nb_of_contents, actual_nb_of_contents - ), - ) - - # Light Protocol Rule 3 - if self.message_id == 1: - enforce( - self.target == 0, - "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( - self.target - ), - ) - except (AEAEnforceError, ValueError, KeyError) as e: - _default_logger.error(str(e)) - return False - - return True diff --git a/trader_old/vendor/valory/protocols/tendermint/protocol.yaml b/trader_old/vendor/valory/protocols/tendermint/protocol.yaml deleted file mode 100644 index c9adaab40..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/protocol.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: tendermint -author: valory -version: 0.1.0 -protocol_specification_id: valory/tendermint:0.1.0 -type: protocol -description: A protocol for communication between two AEAs to share tendermint configuration - details. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeib23wtp5el2lu4vpq3uap7jiyhm5fmoofvv4sz54cvvqq6vsksra4 - __init__.py: bafybeibaei6te5zbqkbcknl2rjh3nryamz6boe4gvvzbaxwi6ynq5uxqfa - custom_types.py: bafybeidbqm4h4fv24o3w6ueu4o3lyn5yaleyukahq7suvk6m2b6ydw4w3a - dialogues.py: bafybeih3kwv3hqnc7qe7gwvsxj755e3pridoesfashknt3i4z7sra7mm6m - message.py: bafybeiguo2x2vx5m3u6li4dl4fxomdjrtz63qkvpor22e2oq4hcj7r5pve - serialization.py: bafybeigs3sxcgyv5qrvltwzjvqq3suxcj2dmvrptvvnfopfpcar3v3evj4 - tendermint.proto: bafybeiaqoltnijwje7iog7s3r4nbtly6rbfp6zwb2btnrw7xuenoxtobui - tendermint_pb2.py: bafybeiay3q3pcvlitnhifh63vqkzvdyu4ywbbwj6vnoe5omqxmxg6gu25a - tests/__init__.py: bafybeiguds53xs5tmygjd26a7xxilzdrgi2x262relfagdlvdzymacumie - tests/test_tendermint.py: bafybeihnjxpkvgsclevn4bwi4qepw56vz554wox7gmhnjwobelbee7xpce - tests/test_tendermint_dialogues.py: bafybeieoviq62cv62h4nglyr7qflzb32bjcvjbepmytgfpycuypnz3mriy - tests/test_tendermint_messages.py: bafybeifqebxh5x5i5luiiypi6mqtcroejmb7ov6foj37ipfgqm7h5f5yve -fingerprint_ignore_patterns: [] -dependencies: - protobuf: {} diff --git a/trader_old/vendor/valory/protocols/tendermint/serialization.py b/trader_old/vendor/valory/protocols/tendermint/serialization.py deleted file mode 100644 index 86d1f1218..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/serialization.py +++ /dev/null @@ -1,156 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Serialization module for tendermint protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import Any, Dict, cast - -from aea.mail.base_pb2 import DialogueMessage # type: ignore -from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore -from aea.protocols.base import Message # type: ignore -from aea.protocols.base import Serializer # type: ignore - -from packages.valory.protocols.tendermint import tendermint_pb2 # type: ignore -from packages.valory.protocols.tendermint.custom_types import ErrorCode # type: ignore -from packages.valory.protocols.tendermint.message import ( # type: ignore - TendermintMessage, -) - - -class TendermintSerializer(Serializer): - """Serialization for the 'tendermint' protocol.""" - - @staticmethod - def encode(msg: Message) -> bytes: - """ - Encode a 'Tendermint' message into bytes. - - :param msg: the message object. - :return: the bytes. - """ - msg = cast(TendermintMessage, msg) - message_pb = ProtobufMessage() - dialogue_message_pb = DialogueMessage() - tendermint_msg = tendermint_pb2.TendermintMessage() # type: ignore - - dialogue_message_pb.message_id = msg.message_id - dialogue_reference = msg.dialogue_reference - dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] - dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] - dialogue_message_pb.target = msg.target - - performative_id = msg.performative - if performative_id == TendermintMessage.Performative.GET_GENESIS_INFO: - performative = tendermint_pb2.TendermintMessage.Get_Genesis_Info_Performative() # type: ignore - if msg.is_set("query"): - performative.query_is_set = True - query = msg.query - performative.query = query - tendermint_msg.get_genesis_info.CopyFrom(performative) - elif performative_id == TendermintMessage.Performative.GET_RECOVERY_PARAMS: - performative = tendermint_pb2.TendermintMessage.Get_Recovery_Params_Performative() # type: ignore - if msg.is_set("query"): - performative.query_is_set = True - query = msg.query - performative.query = query - tendermint_msg.get_recovery_params.CopyFrom(performative) - elif performative_id == TendermintMessage.Performative.GENESIS_INFO: - performative = tendermint_pb2.TendermintMessage.Genesis_Info_Performative() # type: ignore - info = msg.info - performative.info = info - tendermint_msg.genesis_info.CopyFrom(performative) - elif performative_id == TendermintMessage.Performative.RECOVERY_PARAMS: - performative = tendermint_pb2.TendermintMessage.Recovery_Params_Performative() # type: ignore - params = msg.params - performative.params = params - tendermint_msg.recovery_params.CopyFrom(performative) - elif performative_id == TendermintMessage.Performative.ERROR: - performative = tendermint_pb2.TendermintMessage.Error_Performative() # type: ignore - error_code = msg.error_code - ErrorCode.encode(performative.error_code, error_code) - error_msg = msg.error_msg - performative.error_msg = error_msg - error_data = msg.error_data - performative.error_data.update(error_data) - tendermint_msg.error.CopyFrom(performative) - else: - raise ValueError("Performative not valid: {}".format(performative_id)) - - dialogue_message_pb.content = tendermint_msg.SerializeToString() - - message_pb.dialogue_message.CopyFrom(dialogue_message_pb) - message_bytes = message_pb.SerializeToString() - return message_bytes - - @staticmethod - def decode(obj: bytes) -> Message: - """ - Decode bytes into a 'Tendermint' message. - - :param obj: the bytes object. - :return: the 'Tendermint' message. - """ - message_pb = ProtobufMessage() - tendermint_pb = tendermint_pb2.TendermintMessage() # type: ignore - message_pb.ParseFromString(obj) - message_id = message_pb.dialogue_message.message_id - dialogue_reference = ( - message_pb.dialogue_message.dialogue_starter_reference, - message_pb.dialogue_message.dialogue_responder_reference, - ) - target = message_pb.dialogue_message.target - - tendermint_pb.ParseFromString(message_pb.dialogue_message.content) - performative = tendermint_pb.WhichOneof("performative") - performative_id = TendermintMessage.Performative(str(performative)) - performative_content = dict() # type: Dict[str, Any] - if performative_id == TendermintMessage.Performative.GET_GENESIS_INFO: - if tendermint_pb.get_genesis_info.query_is_set: - query = tendermint_pb.get_genesis_info.query - performative_content["query"] = query - elif performative_id == TendermintMessage.Performative.GET_RECOVERY_PARAMS: - if tendermint_pb.get_recovery_params.query_is_set: - query = tendermint_pb.get_recovery_params.query - performative_content["query"] = query - elif performative_id == TendermintMessage.Performative.GENESIS_INFO: - info = tendermint_pb.genesis_info.info - performative_content["info"] = info - elif performative_id == TendermintMessage.Performative.RECOVERY_PARAMS: - params = tendermint_pb.recovery_params.params - performative_content["params"] = params - elif performative_id == TendermintMessage.Performative.ERROR: - pb2_error_code = tendermint_pb.error.error_code - error_code = ErrorCode.decode(pb2_error_code) - performative_content["error_code"] = error_code - error_msg = tendermint_pb.error.error_msg - performative_content["error_msg"] = error_msg - error_data = tendermint_pb.error.error_data - error_data_dict = dict(error_data) - performative_content["error_data"] = error_data_dict - else: - raise ValueError("Performative not valid: {}.".format(performative_id)) - - return TendermintMessage( - message_id=message_id, - dialogue_reference=dialogue_reference, - target=target, - performative=performative, - **performative_content - ) diff --git a/trader_old/vendor/valory/protocols/tendermint/tendermint.proto b/trader_old/vendor/valory/protocols/tendermint/tendermint.proto deleted file mode 100644 index bfd922020..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/tendermint.proto +++ /dev/null @@ -1,49 +0,0 @@ -syntax = "proto3"; - -package aea.valory.tendermint.v0_1_0; - -message TendermintMessage{ - - // Custom Types - message ErrorCode{ - enum ErrorCodeEnum { - INVALID_REQUEST = 0; - } - ErrorCodeEnum error_code = 1; - } - - - // Performatives and contents - message Get_Genesis_Info_Performative{ - string query = 1; - bool query_is_set = 2; - } - - message Get_Recovery_Params_Performative{ - string query = 1; - bool query_is_set = 2; - } - - message Genesis_Info_Performative{ - string info = 1; - } - - message Recovery_Params_Performative{ - string params = 1; - } - - message Error_Performative{ - ErrorCode error_code = 1; - string error_msg = 2; - map error_data = 3; - } - - - oneof performative{ - Error_Performative error = 5; - Genesis_Info_Performative genesis_info = 6; - Get_Genesis_Info_Performative get_genesis_info = 7; - Get_Recovery_Params_Performative get_recovery_params = 8; - Recovery_Params_Performative recovery_params = 9; - } -} diff --git a/trader_old/vendor/valory/protocols/tendermint/tendermint_pb2.py b/trader_old/vendor/valory/protocols/tendermint/tendermint_pb2.py deleted file mode 100644 index aa4355b03..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/tendermint_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: tendermint.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder - - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x10tendermint.proto\x12\x1c\x61\x65\x61.valory.tendermint.v0_1_0"\xad\t\n\x11TendermintMessage\x12S\n\x05\x65rror\x18\x05 \x01(\x0b\x32\x42.aea.valory.tendermint.v0_1_0.TendermintMessage.Error_PerformativeH\x00\x12\x61\n\x0cgenesis_info\x18\x06 \x01(\x0b\x32I.aea.valory.tendermint.v0_1_0.TendermintMessage.Genesis_Info_PerformativeH\x00\x12i\n\x10get_genesis_info\x18\x07 \x01(\x0b\x32M.aea.valory.tendermint.v0_1_0.TendermintMessage.Get_Genesis_Info_PerformativeH\x00\x12o\n\x13get_recovery_params\x18\x08 \x01(\x0b\x32P.aea.valory.tendermint.v0_1_0.TendermintMessage.Get_Recovery_Params_PerformativeH\x00\x12g\n\x0frecovery_params\x18\t \x01(\x0b\x32L.aea.valory.tendermint.v0_1_0.TendermintMessage.Recovery_Params_PerformativeH\x00\x1a\x8e\x01\n\tErrorCode\x12[\n\nerror_code\x18\x01 \x01(\x0e\x32G.aea.valory.tendermint.v0_1_0.TendermintMessage.ErrorCode.ErrorCodeEnum"$\n\rErrorCodeEnum\x12\x13\n\x0fINVALID_REQUEST\x10\x00\x1a\x44\n\x1dGet_Genesis_Info_Performative\x12\r\n\x05query\x18\x01 \x01(\t\x12\x14\n\x0cquery_is_set\x18\x02 \x01(\x08\x1aG\n Get_Recovery_Params_Performative\x12\r\n\x05query\x18\x01 \x01(\t\x12\x14\n\x0cquery_is_set\x18\x02 \x01(\x08\x1a)\n\x19Genesis_Info_Performative\x12\x0c\n\x04info\x18\x01 \x01(\t\x1a.\n\x1cRecovery_Params_Performative\x12\x0e\n\x06params\x18\x01 \x01(\t\x1a\x8f\x02\n\x12\x45rror_Performative\x12M\n\nerror_code\x18\x01 \x01(\x0b\x32\x39.aea.valory.tendermint.v0_1_0.TendermintMessage.ErrorCode\x12\x11\n\terror_msg\x18\x02 \x01(\t\x12\x65\n\nerror_data\x18\x03 \x03(\x0b\x32Q.aea.valory.tendermint.v0_1_0.TendermintMessage.Error_Performative.ErrorDataEntry\x1a\x30\n\x0e\x45rrorDataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x0e\n\x0cperformativeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "tendermint_pb2", _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _TENDERMINTMESSAGE_ERROR_PERFORMATIVE_ERRORDATAENTRY._options = None - _TENDERMINTMESSAGE_ERROR_PERFORMATIVE_ERRORDATAENTRY._serialized_options = b"8\001" - _globals["_TENDERMINTMESSAGE"]._serialized_start = 51 - _globals["_TENDERMINTMESSAGE"]._serialized_end = 1248 - _globals["_TENDERMINTMESSAGE_ERRORCODE"]._serialized_start = 582 - _globals["_TENDERMINTMESSAGE_ERRORCODE"]._serialized_end = 724 - _globals["_TENDERMINTMESSAGE_ERRORCODE_ERRORCODEENUM"]._serialized_start = 688 - _globals["_TENDERMINTMESSAGE_ERRORCODE_ERRORCODEENUM"]._serialized_end = 724 - _globals["_TENDERMINTMESSAGE_GET_GENESIS_INFO_PERFORMATIVE"]._serialized_start = 726 - _globals["_TENDERMINTMESSAGE_GET_GENESIS_INFO_PERFORMATIVE"]._serialized_end = 794 - _globals[ - "_TENDERMINTMESSAGE_GET_RECOVERY_PARAMS_PERFORMATIVE" - ]._serialized_start = 796 - _globals[ - "_TENDERMINTMESSAGE_GET_RECOVERY_PARAMS_PERFORMATIVE" - ]._serialized_end = 867 - _globals["_TENDERMINTMESSAGE_GENESIS_INFO_PERFORMATIVE"]._serialized_start = 869 - _globals["_TENDERMINTMESSAGE_GENESIS_INFO_PERFORMATIVE"]._serialized_end = 910 - _globals["_TENDERMINTMESSAGE_RECOVERY_PARAMS_PERFORMATIVE"]._serialized_start = 912 - _globals["_TENDERMINTMESSAGE_RECOVERY_PARAMS_PERFORMATIVE"]._serialized_end = 958 - _globals["_TENDERMINTMESSAGE_ERROR_PERFORMATIVE"]._serialized_start = 961 - _globals["_TENDERMINTMESSAGE_ERROR_PERFORMATIVE"]._serialized_end = 1232 - _globals[ - "_TENDERMINTMESSAGE_ERROR_PERFORMATIVE_ERRORDATAENTRY" - ]._serialized_start = 1184 - _globals[ - "_TENDERMINTMESSAGE_ERROR_PERFORMATIVE_ERRORDATAENTRY" - ]._serialized_end = 1232 -# @@protoc_insertion_point(module_scope) diff --git a/trader_old/vendor/valory/protocols/tendermint/tests/__init__.py b/trader_old/vendor/valory/protocols/tendermint/tests/__init__.py deleted file mode 100644 index 283e0f64c..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for tendermint protocol.""" diff --git a/trader_old/vendor/valory/protocols/tendermint/tests/test_tendermint.py b/trader_old/vendor/valory/protocols/tendermint/tests/test_tendermint.py deleted file mode 100644 index c133f7019..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/tests/test_tendermint.py +++ /dev/null @@ -1,217 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for the 'valory/tendermint' protocol.""" -import logging -from typing import Type -from unittest import mock - -import pytest -from _pytest.logging import LogCaptureFixture # type: ignore -from aea.common import Address -from aea.mail.base import Envelope -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel - -from packages.valory.protocols.tendermint.custom_types import ErrorCode -from packages.valory.protocols.tendermint.dialogues import ( - TendermintDialogue, - TendermintDialogues, -) -from packages.valory.protocols.tendermint.message import ( - TendermintMessage, - _default_logger, -) - - -@pytest.mark.parametrize( - "msg", - [ - TendermintMessage( - performative=TendermintMessage.Performative.GET_GENESIS_INFO, # type: ignore - query="", - ), - TendermintMessage( - performative=TendermintMessage.Performative.GET_RECOVERY_PARAMS, # type: ignore - query="", - ), - TendermintMessage( - performative=TendermintMessage.Performative.GENESIS_INFO, # type: ignore - info="", - ), - TendermintMessage( - performative=TendermintMessage.Performative.RECOVERY_PARAMS, # type: ignore - params="", - ), - TendermintMessage( - performative=TendermintMessage.Performative.ERROR, # type: ignore - error_code=ErrorCode.INVALID_REQUEST, - error_msg="", - error_data=dict(message="dummy"), - ), - ], -) -def test_serialization(msg: TendermintMessage) -> None: - """Test the serialization of Tendermint speech-act messages.""" - - msg.to = "receiver" - envelope = Envelope( - to=msg.to, - sender="sender", - message=msg, - ) - envelope_bytes = envelope.encode() - - actual_envelope = Envelope.decode(envelope_bytes) - expected_envelope = envelope - assert expected_envelope.to == actual_envelope.to - assert expected_envelope.sender == actual_envelope.sender - assert ( - expected_envelope.protocol_specification_id - == actual_envelope.protocol_specification_id - ) - assert expected_envelope.message != actual_envelope.message - - actual_msg = TendermintMessage.serializer.decode(actual_envelope.message) - actual_msg.to = actual_envelope.to - actual_msg.sender = actual_envelope.sender - expected_msg = msg - assert expected_msg == actual_msg - - -def test_incorrect_error_data_logged(caplog: LogCaptureFixture) -> None: - """Test incorrect error_data is logged""" - - expected = "Invalid type for dictionary values in content 'error_data'. Expected 'str'. Found ''." - with caplog.at_level(logging.ERROR, logger=_default_logger.name): - TendermintMessage( - performative=TendermintMessage.Performative.ERROR, # type: ignore - error_code=ErrorCode.INVALID_REQUEST, - error_msg="", - error_data=dict(message=1), # incorrect type - ) - assert expected in caplog.text - - -def test_serialization_performative_not_valid() -> None: - """Test serialization performative not valid""" - - msg = TendermintMessage( - performative=TendermintMessage.Performative.GET_GENESIS_INFO, # type: ignore - query="", - ) - encoded_msg = msg.encode() - - with mock.patch.object(TendermintMessage, "Performative"): - with pytest.raises(ValueError, match="Performative not valid: "): - msg.encode() - with pytest.raises(ValueError, match="Performative not valid: "): - msg.decode(encoded_msg) - - -class AgentDialogue(TendermintDialogue): - """The dialogue class maintains state of a dialogue and manages it.""" - - def __init__( - self, - dialogue_label: DialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[TendermintMessage], - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - TendermintDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - - -class AgentDialogues(TendermintDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, self_address: Address) -> None: - """ - Initialize dialogues. - - :param self_address: the address of the entity for whom this dialogue is maintained - """ - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, # pylint: disable=redefined-outer-name - receiver_address: Address, - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return TendermintDialogue.Role.AGENT - - TendermintDialogues.__init__( - self, - self_address=self_address, - role_from_first_message=role_from_first_message, - dialogue_class=AgentDialogue, - ) - - -class TestDialogues: - """Tests abci dialogues.""" - - agent_dialogues: AgentDialogues - - @classmethod - def setup_class(cls) -> None: - """Setup test class""" - - cls.agent_dialogues = AgentDialogues("agent_address") - - def test_create_self_initiated(self) -> None: - """Test the self initialisation of a dialogue.""" - - result = self.agent_dialogues._create_self_initiated( # pylint: disable=protected-access - dialogue_opponent_addr="dummy_address", - dialogue_reference=(str(0), ""), - role=TendermintDialogue.Role.AGENT, - ) - assert isinstance(result, TendermintDialogue) - assert result.role == TendermintDialogue.Role.AGENT, "The role must be agent." - - def test_create_opponent_initiated(self) -> None: - """Test the opponent initialisation of a dialogue.""" - - result = self.agent_dialogues._create_opponent_initiated( # pylint: disable=protected-access - dialogue_opponent_addr="dummy_address", - dialogue_reference=(str(0), ""), - role=TendermintDialogue.Role.AGENT, - ) - assert isinstance(result, TendermintDialogue) - assert result.role == TendermintDialogue.Role.AGENT, "The role must be agent." diff --git a/trader_old/vendor/valory/protocols/tendermint/tests/test_tendermint_dialogues.py b/trader_old/vendor/valory/protocols/tendermint/tests/test_tendermint_dialogues.py deleted file mode 100644 index 4a55efd92..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/tests/test_tendermint_dialogues.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test dialogues module for tendermint protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase - -from packages.valory.protocols.tendermint.dialogues import ( - TendermintDialogue, - TendermintDialogues, -) -from packages.valory.protocols.tendermint.message import TendermintMessage - - -class TestDialoguesTendermint(BaseProtocolDialoguesTestCase): - """Test for the 'tendermint' protocol dialogues.""" - - MESSAGE_CLASS = TendermintMessage - - DIALOGUE_CLASS = TendermintDialogue - - DIALOGUES_CLASS = TendermintDialogues - - ROLE_FOR_THE_FIRST_MESSAGE = TendermintDialogue.Role.AGENT # CHECK - - def make_message_content(self) -> dict: - """Make a dict with message contruction content for dialogues.create.""" - return dict( - performative=TendermintMessage.Performative.GET_GENESIS_INFO, - query="some str", - ) diff --git a/trader_old/vendor/valory/protocols/tendermint/tests/test_tendermint_messages.py b/trader_old/vendor/valory/protocols/tendermint/tests/test_tendermint_messages.py deleted file mode 100644 index a279cef0c..000000000 --- a/trader_old/vendor/valory/protocols/tendermint/tests/test_tendermint_messages.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023 valory -# -# 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. -# -# ------------------------------------------------------------------------------ - -"""Test messages module for tendermint protocol.""" - -# pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin -from typing import List - -from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase - -from packages.valory.protocols.tendermint.custom_types import ErrorCode -from packages.valory.protocols.tendermint.message import TendermintMessage - - -class TestMessageTendermint(BaseProtocolMessagesTestCase): - """Test for the 'tendermint' protocol message.""" - - MESSAGE_CLASS = TendermintMessage - - def build_messages(self) -> List[TendermintMessage]: # type: ignore[override] - """Build the messages to be used for testing.""" - return [ - TendermintMessage( - performative=TendermintMessage.Performative.GET_GENESIS_INFO, - query="some str", - ), - TendermintMessage( - performative=TendermintMessage.Performative.GET_RECOVERY_PARAMS, - query="some str", - ), - TendermintMessage( - performative=TendermintMessage.Performative.GENESIS_INFO, - info="some str", - ), - TendermintMessage( - performative=TendermintMessage.Performative.RECOVERY_PARAMS, - params="some str", - ), - TendermintMessage( - performative=TendermintMessage.Performative.ERROR, - error_code=ErrorCode.INVALID_REQUEST, - error_msg="some str", - error_data={"some str": "some str"}, - ), - ] - - def build_inconsistent(self) -> List[TendermintMessage]: # type: ignore[override] - """Build inconsistent messages to be used for testing.""" - return [ - TendermintMessage( - performative=TendermintMessage.Performative.GENESIS_INFO, - # skip content: info - ), - TendermintMessage( - performative=TendermintMessage.Performative.RECOVERY_PARAMS, - # skip content: params - ), - TendermintMessage( - performative=TendermintMessage.Performative.ERROR, - # skip content: error_code - error_msg="some str", - error_data={"some str": "some str"}, - ), - ] diff --git a/trader_old/vendor/valory/skills/__init__.py b/trader_old/vendor/valory/skills/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_old/vendor/valory/skills/abstract_abci/README.md b/trader_old/vendor/valory/skills/abstract_abci/README.md deleted file mode 100644 index 4a99a118c..000000000 --- a/trader_old/vendor/valory/skills/abstract_abci/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Abstract abci - -## Description - -This module contains an abstract ABCI skill template for an AEA. - -## Behaviours - -No behaviours (the skill is purely reactive). - -## Handlers - -* `ABCIHandler` - - This abstract skill provides a template of an ABCI application managed by an - AEA. This abstract Handler replies to ABCI requests with default responses. - In another skill, extend the class and override the request handlers - to implement a custom behaviour. - - diff --git a/trader_old/vendor/valory/skills/abstract_abci/__init__.py b/trader_old/vendor/valory/skills/abstract_abci/__init__.py deleted file mode 100644 index 8c9d1355f..000000000 --- a/trader_old/vendor/valory/skills/abstract_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 an abstract ABCI skill template for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/abstract_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/abstract_abci/dialogues.py b/trader_old/vendor/valory/skills/abstract_abci/dialogues.py deleted file mode 100644 index e38665b5f..000000000 --- a/trader_old/vendor/valory/skills/abstract_abci/dialogues.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the classes required for dialogue management.""" - -from typing import Any - -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.skills.base import Model - -from packages.valory.protocols.abci.dialogues import AbciDialogue as BaseAbciDialogue -from packages.valory.protocols.abci.dialogues import AbciDialogues as BaseAbciDialogues - - -AbciDialogue = BaseAbciDialogue - - -class AbciDialogues(Model, BaseAbciDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.CLIENT - - BaseAbciDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - ) diff --git a/trader_old/vendor/valory/skills/abstract_abci/handlers.py b/trader_old/vendor/valory/skills/abstract_abci/handlers.py deleted file mode 100644 index 93e95e35d..000000000 --- a/trader_old/vendor/valory/skills/abstract_abci/handlers.py +++ /dev/null @@ -1,408 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the handler for the 'abci' skill.""" -from typing import List, cast - -from aea.protocols.base import Message -from aea.skills.base import Handler - -from packages.valory.connections.abci.connection import PUBLIC_ID -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import ( - Events, - ProofOps, - Result, - ResultType, - SnapShots, - ValidatorUpdates, -) -from packages.valory.protocols.abci.dialogues import AbciDialogue, AbciDialogues - - -ERROR_CODE = 1 - - -class ABCIHandler(Handler): - """ - Default ABCI handler. - - This abstract skill provides a template of an ABCI application managed by an - AEA. This abstract Handler replies to ABCI requests with default responses. - In another skill, extend the class and override the request handlers - to implement a custom behaviour. - """ - - SUPPORTED_PROTOCOL = AbciMessage.protocol_id - - def setup(self) -> None: - """Set up the handler.""" - self.context.logger.debug( - f"ABCI Handler: setup method called. Using {PUBLIC_ID}." - ) - - def handle(self, message: Message) -> None: - """ - Handle the message. - - :param message: the message. - """ - abci_message = cast(AbciMessage, message) - - # recover dialogue - abci_dialogues = cast(AbciDialogues, self.context.abci_dialogues) - abci_dialogue = cast(AbciDialogue, abci_dialogues.update(message)) - - if abci_dialogue is None: - self.log_exception(abci_message, "Invalid dialogue.") - return - - performative = message.performative.value - - # handle message - request_type = performative.replace("request_", "") - self.context.logger.debug(f"Received ABCI request of type {request_type}") - handler = getattr(self, request_type, None) - if handler is None: # pragma: nocover - self.context.logger.warning( - f"Cannot handle request '{request_type}', ignoring..." - ) - return - - self.context.logger.debug( - "ABCI Handler: message={}, sender={}".format(message, message.sender) - ) - response = handler(message, abci_dialogue) - self.context.outbox.put_message(message=response) - - def teardown(self) -> None: - """Teardown the handler.""" - self.context.logger.debug("ABCI Handler: teardown method called.") - - def log_exception(self, message: AbciMessage, error_message: str) -> None: - """Log a response exception.""" - self.context.logger.error( - f"An exception occurred: {error_message} for message: {message}" - ) - - def echo( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_ECHO performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_ECHO, - target_message=message, - message=message.message, - ) - return cast(AbciMessage, reply) - - def info( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_INFO performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - info_data = "" - version = "" - app_version = 0 - last_block_height = 0 - last_block_app_hash = b"" - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_INFO, - target_message=message, - info_data=info_data, - version=version, - app_version=app_version, - last_block_height=last_block_height, - last_block_app_hash=last_block_app_hash, - ) - return cast(AbciMessage, reply) - - def flush( # pylint: disable=no-self-use - self, - message: AbciMessage, - dialogue: AbciDialogue, - ) -> AbciMessage: - """ - Handle a message of REQUEST_FLUSH performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_FLUSH, - target_message=message, - ) - return cast(AbciMessage, reply) - - def set_option( # pylint: disable=no-self-use - self, - message: AbciMessage, - dialogue: AbciDialogue, - ) -> AbciMessage: - """ - Handle a message of REQUEST_SET_OPTION performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_SET_OPTION, - target_message=message, - code=ERROR_CODE, - log="operation not supported", - info="operation not supported", - ) - return cast(AbciMessage, reply) - - def init_chain( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_INIT_CHAIN performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - validators: List = [] - app_hash = b"" - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_INIT_CHAIN, - target_message=message, - validators=ValidatorUpdates(validators), - app_hash=app_hash, - ) - return cast(AbciMessage, reply) - - def query( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_QUERY performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_QUERY, - target_message=message, - code=ERROR_CODE, - log="operation not supported", - info="operation not supported", - index=0, - key=b"", - value=b"", - proof_ops=ProofOps([]), - height=0, - codespace="", - ) - return cast(AbciMessage, reply) - - def check_tx( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_CHECK_TX performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, - target_message=message, - code=ERROR_CODE, - data=b"", - log="operation not supported", - info="operation not supported", - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, reply) - - def deliver_tx( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_DELIVER_TX performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, - target_message=message, - code=ERROR_CODE, - data=b"", - log="operation not supported", - info="operation not supported", - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, reply) - - def begin_block( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_BEGIN_BLOCK performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_BEGIN_BLOCK, - target_message=message, - events=Events([]), - ) - return cast(AbciMessage, reply) - - def end_block( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_END_BLOCK performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_END_BLOCK, - target_message=message, - validator_updates=ValidatorUpdates([]), - events=Events([]), - ) - return cast(AbciMessage, reply) - - def commit( # pylint: disable=no-self-use - self, message: AbciMessage, dialogue: AbciDialogue - ) -> AbciMessage: - """ - Handle a message of REQUEST_COMMIT performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_COMMIT, - target_message=message, - data=b"", - retain_height=0, - ) - return cast(AbciMessage, reply) - - def list_snapshots( # pylint: disable=no-self-use - self, - message: AbciMessage, - dialogue: AbciDialogue, - ) -> AbciMessage: - """ - Handle a message of REQUEST_LIST_SNAPSHOT performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS, - target_message=message, - snapshots=SnapShots([]), - ) - return cast(AbciMessage, reply) - - def offer_snapshot( # pylint: disable=no-self-use - self, - message: AbciMessage, - dialogue: AbciDialogue, - ) -> AbciMessage: - """ - Handle a message of REQUEST_OFFER_SNAPSHOT performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT, - target_message=message, - result=Result(ResultType.REJECT), # by default, we reject - ) - return cast(AbciMessage, reply) - - def load_snapshot_chunk( # pylint: disable=no-self-use - self, - message: AbciMessage, - dialogue: AbciDialogue, - ) -> AbciMessage: - """ - Handle a message of REQUEST_LOAD_SNAPSHOT_CHUNK performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK, - target_message=message, - chunk=b"", - ) - return cast(AbciMessage, reply) - - def apply_snapshot_chunk( # pylint: disable=no-self-use - self, - message: AbciMessage, - dialogue: AbciDialogue, - ) -> AbciMessage: - """ - Handle a message of REQUEST_APPLY_SNAPSHOT_CHUNK performative. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK, - target_message=message, - result=Result(ResultType.REJECT), - refetch_chunks=tuple(), - reject_senders=tuple(), - ) - return cast(AbciMessage, reply) diff --git a/trader_old/vendor/valory/skills/abstract_abci/skill.yaml b/trader_old/vendor/valory/skills/abstract_abci/skill.yaml deleted file mode 100644 index 0ffadfd19..000000000 --- a/trader_old/vendor/valory/skills/abstract_abci/skill.yaml +++ /dev/null @@ -1,34 +0,0 @@ -name: abstract_abci -author: valory -version: 0.1.0 -type: skill -description: The abci skill provides a template of an ABCI application. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeiezmhsokdhxat2gzxgau2zotd5nqjepg5lb2y7ypijuuq75xnxxrq - __init__.py: bafybeigdpqcsxpxp3akxdy5wcccfahom7pmbrnmututws2fmpcr7q6ryoe - dialogues.py: bafybeib6cex55nl57xe6boa4c3z4ynlxstnospqjehdb5owpgtvzsu5ucm - handlers.py: bafybeihb25swvt26vtqpnvldf6viizt34ophj6hijfpu5pevrlmvpvzkdq - tests/__init__.py: bafybeicnx4gezk2zrgz23mco2kv7ws3yd5yspku5e3ng4cb5tw7s2zexsu - tests/test_dialogues.py: bafybeig3kubiyq7bqmetrka67fjk7vymgtjwguyui3yubbvgtzzhfizsdu - tests/test_handlers.py: bafybeieeuwtu35ddaevr2wgnk33l7kdhrx7ruoeb5jiltiyn65ufdcnopu -fingerprint_ignore_patterns: [] -connections: -- valory/abci:0.1.0:bafybeia6etkacvqend7xj6viejkqgo7ozu3yn4yg3qezfthf2xhrjjwse4 -contracts: [] -protocols: -- valory/abci:0.1.0:bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u -skills: [] -behaviours: {} -handlers: - abci: - args: {} - class_name: ABCIHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues -dependencies: {} -is_abstract: true -customs: [] diff --git a/trader_old/vendor/valory/skills/abstract_abci/tests/__init__.py b/trader_old/vendor/valory/skills/abstract_abci/tests/__init__.py deleted file mode 100644 index 499994e54..000000000 --- a/trader_old/vendor/valory/skills/abstract_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/abstract_abci skill.""" diff --git a/trader_old/vendor/valory/skills/abstract_abci/tests/test_dialogues.py b/trader_old/vendor/valory/skills/abstract_abci/tests/test_dialogues.py deleted file mode 100644 index 4de0596ce..000000000 --- a/trader_old/vendor/valory/skills/abstract_abci/tests/test_dialogues.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" -from enum import Enum -from typing import Type, cast -from unittest.mock import MagicMock - -import pytest -from aea.protocols.dialogue.base import Dialogues - -from packages.valory.skills.abstract_abci.dialogues import AbciDialogue, AbciDialogues - - -@pytest.mark.parametrize( - "dialogues_cls,expected_role_from_first_message", - [ - (AbciDialogues, AbciDialogue.Role.CLIENT), - ], -) -def test_dialogues_creation( - dialogues_cls: Type[AbciDialogues], expected_role_from_first_message: Enum -) -> None: - """Test XDialogues creations.""" - dialogues = cast(Dialogues, dialogues_cls(name="", skill_context=MagicMock())) - assert ( - expected_role_from_first_message - == dialogues._role_from_first_message( # pylint: disable=protected-access - MagicMock(), MagicMock() - ) - ) diff --git a/trader_old/vendor/valory/skills/abstract_abci/tests/test_handlers.py b/trader_old/vendor/valory/skills/abstract_abci/tests/test_handlers.py deleted file mode 100644 index c653c34d5..000000000 --- a/trader_old/vendor/valory/skills/abstract_abci/tests/test_handlers.py +++ /dev/null @@ -1,398 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the handlers.py module of the skill.""" -import logging -from pathlib import Path -from typing import Any, cast -from unittest.mock import MagicMock, patch - -from aea.configurations.data_types import PublicId -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.test_tools.test_skill import BaseSkillTestCase - -from packages.valory.connections.abci.connection import PUBLIC_ID -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import ( - CheckTxType, - CheckTxTypeEnum, - Evidences, - Header, - LastCommitInfo, - PublicKey, - Result, - ResultType, - SnapShots, - Snapshot, - Timestamp, - ValidatorUpdate, - ValidatorUpdates, -) -from packages.valory.protocols.abci.dialogues import AbciDialogues as BaseAbciDialogues -from packages.valory.skills.abstract_abci.dialogues import AbciDialogue, AbciDialogues -from packages.valory.skills.abstract_abci.handlers import ABCIHandler, ERROR_CODE - - -PACKAGE_DIR = Path(__file__).parent.parent - - -class AbciDialoguesServer(BaseAbciDialogues): - """The dialogues class keeps track of all ABCI dialogues.""" - - def __init__(self, address: str) -> None: - """Initialize dialogues.""" - self.address = address - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.SERVER - - BaseAbciDialogues.__init__( - self, - self_address=self.address, - role_from_first_message=role_from_first_message, - dialogue_class=AbciDialogue, - ) - - -class TestABCIHandlerOld(BaseSkillTestCase): - """Test ABCIHandler methods.""" - - path_to_skill = PACKAGE_DIR - abci_handler: ABCIHandler - logger: logging.Logger - abci_dialogues: AbciDialogues - - @classmethod - def setup_class(cls, **kwargs: Any) -> None: - """Setup the test class.""" - super().setup_class() - cls.abci_handler = cast(ABCIHandler, cls._skill.skill_context.handlers.abci) - cls.logger = cls._skill.skill_context.logger - - cls.abci_dialogues = cast( - AbciDialogues, cls._skill.skill_context.abci_dialogues - ) - - def test_setup(self) -> None: - """Test the setup method of the echo handler.""" - with patch.object(self.logger, "log") as mock_logger: - self.abci_handler.setup() - - # after - self.assert_quantity_in_outbox(0) - - mock_logger.assert_any_call( - logging.DEBUG, f"ABCI Handler: setup method called. Using {PUBLIC_ID}." - ) - - def test_teardown(self) -> None: - """Test the teardown method of the echo handler.""" - with patch.object(self.logger, "log") as mock_logger: - self.abci_handler.teardown() - - # after - self.assert_quantity_in_outbox(0) - - mock_logger.assert_any_call( - logging.DEBUG, "ABCI Handler: teardown method called." - ) - - -class TestABCIHandler: - """Test 'ABCIHandler'.""" - - def setup(self) -> None: - """Set up the tests.""" - self.skill_id = ( # pylint: disable=attribute-defined-outside-init - PublicId.from_str("dummy/skill:0.1.0") - ) - self.context = MagicMock( # pylint: disable=attribute-defined-outside-init - skill_id=self.skill_id - ) - self.context.abci_dialogues = AbciDialogues(name="", skill_context=self.context) - self.dialogues = ( # pylint: disable=attribute-defined-outside-init - AbciDialoguesServer(address="server") - ) - self.handler = ABCIHandler( # pylint: disable=attribute-defined-outside-init - name="", skill_context=self.context - ) - - def test_setup(self) -> None: - """Test the setup method.""" - self.handler.setup() - - def test_teardown(self) -> None: - """Test the teardown method.""" - self.handler.teardown() - - def test_handle(self) -> None: - """Test the message gets handled.""" - message, _ = self.dialogues.create( - counterparty=str(self.skill_id), - performative=AbciMessage.Performative.REQUEST_INFO, - version="", - block_version=0, - p2p_version=0, - ) - self.handler.handle(cast(AbciMessage, message)) - - def test_handle_log_exception(self) -> None: - """Test the message gets handled.""" - message = AbciMessage( - dialogue_reference=("", ""), - performative=AbciMessage.Performative.REQUEST_INFO, # type: ignore - version="", - block_version=0, - p2p_version=0, - target=0, - message_id=1, - ) - message._sender = "server" # pylint: disable=protected-access - message._to = str(self.skill_id) # pylint: disable=protected-access - self.handler.handle(message) - - def test_info(self) -> None: - """Test the 'info' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_INFO, - version="", - block_version=0, - p2p_version=0, - ) - response = self.handler.info( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_INFO - - def test_echo(self) -> None: - """Test the 'echo' handler method.""" - expected_message = "message" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_ECHO, - message=expected_message, - ) - response = self.handler.echo( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_ECHO - assert response.message == expected_message - - def test_set_option(self) -> None: - """Test the 'set_option' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_SET_OPTION, - ) - response = self.handler.set_option( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_SET_OPTION - assert response.code == ERROR_CODE - - def test_begin_block(self) -> None: - """Test the 'begin_block' handler method.""" - header = Header(*(MagicMock() for _ in range(14))) - last_commit_info = LastCommitInfo(*(MagicMock() for _ in range(2))) - byzantine_validators = Evidences(MagicMock()) - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_BEGIN_BLOCK, - hash=b"", - header=header, - last_commit_info=last_commit_info, - byzantine_validators=byzantine_validators, - ) - response = self.handler.begin_block( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_BEGIN_BLOCK - - def test_check_tx(self, *_: Any) -> None: - """Test the 'check_tx' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_CHECK_TX, - tx=b"", - type=CheckTxType(CheckTxTypeEnum.NEW), - ) - response = self.handler.check_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_CHECK_TX - assert response.code == ERROR_CODE - - def test_deliver_tx(self, *_: Any) -> None: - """Test the 'deliver_tx' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - tx=b"", - ) - response = self.handler.deliver_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_DELIVER_TX - assert response.code == ERROR_CODE - - def test_end_block(self) -> None: - """Test the 'end_block' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_END_BLOCK, - height=1, - ) - response = self.handler.end_block( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_END_BLOCK - - def test_commit(self) -> None: - """Test the 'commit' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_COMMIT, - ) - response = self.handler.commit( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_COMMIT - - def test_flush(self) -> None: - """Test the 'flush' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_FLUSH, - ) - response = self.handler.flush( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_FLUSH - - def test_init_chain(self) -> None: - """Test the 'init_chain' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_INIT_CHAIN, - time=Timestamp(1, 1), - chain_id="", - validators=ValidatorUpdates( - [ - ValidatorUpdate( - PublicKey(data=b"", key_type=PublicKey.PublicKeyType.ed25519), 1 - ) - ] - ), - app_state_bytes=b"", - initial_height=0, - ) - response = self.handler.init_chain( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_INIT_CHAIN - - def test_query(self) -> None: - """Test the 'init_chain' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_QUERY, - query_data=b"", - path="", - height=0, - prove=True, - ) - response = self.handler.query( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_QUERY - assert response.code == ERROR_CODE - - def test_list_snapshots(self) -> None: - """Test the 'list_snapshots' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_LIST_SNAPSHOTS, - ) - response = self.handler.list_snapshots( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_LIST_SNAPSHOTS - assert response.snapshots == SnapShots([]) - - def test_offer_snapshot(self) -> None: - """Test the 'offer_snapshot' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_OFFER_SNAPSHOT, - snapshot=Snapshot(0, 0, 0, b"", b""), - app_hash=b"", - ) - response = self.handler.offer_snapshot( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_OFFER_SNAPSHOT - assert response.result == Result(ResultType.REJECT) - - def test_load_snapshot_chunk(self) -> None: - """Test the 'load_snapshot_chunk' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_LOAD_SNAPSHOT_CHUNK, - height=0, - format=0, - chunk_index=0, - ) - response = self.handler.load_snapshot_chunk( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert ( - response.performative - == AbciMessage.Performative.RESPONSE_LOAD_SNAPSHOT_CHUNK - ) - assert response.chunk == b"" - - def test_apply_snapshot_chunk(self) -> None: - """Test the 'apply_snapshot_chunk' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_APPLY_SNAPSHOT_CHUNK, - index=0, - chunk=b"", - chunk_sender="", - ) - response = self.handler.apply_snapshot_chunk( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert ( - response.performative - == AbciMessage.Performative.RESPONSE_APPLY_SNAPSHOT_CHUNK - ) - assert response.result == Result(ResultType.REJECT) - assert response.refetch_chunks == tuple() - assert response.reject_senders == tuple() diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/README.md b/trader_old/vendor/valory/skills/abstract_round_abci/README.md deleted file mode 100644 index 4ee033ebd..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Abstract round abci - -## Description - -This module contains an abstract round ABCI skill template for an AEA. - -## Behaviours - -* `AbstractRoundBehaviour` - - This behaviour implements an abstract round behaviour. - -* `_MetaRoundBehaviour` - - A metaclass that validates AbstractRoundBehaviour's attributes. - - -## Handlers - -* `ABCIRoundHandler` - - ABCI handler. - -* `AbstractResponseHandler` - - The concrete classes must set the `allowed_response_performatives` - class attribute to the (frozen)set of performative the developer - wants the handler to handle. - -* `ContractApiHandler` - - Implement the contract api handler. - -* `HttpHandler` - - The HTTP response handler. - -* `LedgerApiHandler` - - Implement the ledger handler. - -* `SigningHandler` - - Implement the transaction handler. - - diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/__init__.py b/trader_old/vendor/valory/skills/abstract_round_abci/__init__.py deleted file mode 100644 index 2bc8fd5fb..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 an abstract round ABCI skill template for an AEA.""" # pragma: nocover - -from aea.configurations.base import PublicId # pragma: nocover - - -PUBLIC_ID = PublicId.from_str("valory/abstract_round_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/abci_app_chain.py b/trader_old/vendor/valory/skills/abstract_round_abci/abci_app_chain.py deleted file mode 100644 index 577fb8c33..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/abci_app_chain.py +++ /dev/null @@ -1,291 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 utilities for AbciApps.""" -import logging -from copy import deepcopy -from typing import Any, Dict, FrozenSet, List, Optional, Set, Tuple, Type - -from aea.exceptions import enforce - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AppState, - EventToTimeout, - EventType, -) - - -_default_logger = logging.getLogger( - "aea.packages.valory.skills.abstract_round_abci.abci_app_chain" -) - -AbciAppTransitionMapping = Dict[AppState, AppState] - - -def check_set_uniqueness(sets: Tuple) -> Optional[Any]: - """Checks that all elements in the set list are unique and not repeated among different sets""" - all_elements = set.union(*sets) - for element in all_elements: - # Count the number of sets that include this element - sets_in = [set_ for set_ in sets if element in set_] - if len(sets_in) > 1: - return element - return None - - -def chain( # pylint: disable=too-many-locals,too-many-statements - abci_apps: Tuple[Type[AbciApp], ...], - abci_app_transition_mapping: AbciAppTransitionMapping, -) -> Type[AbciApp]: - """ - Concatenate multiple AbciApp types. - - The consistency checks assume that the first element in - abci_apps is the entry-point abci_app (i.e. the associated round of - the initial_behaviour_cls of the AbstractRoundBehaviour in which - the chained AbciApp is used is one of the initial_states of the first element.) - """ - enforce( - len(abci_apps) > 1, - f"there must be a minimum of two AbciApps to chain, found ({len(abci_apps)})", - ) - enforce( - len(set(abci_apps)) == len(abci_apps), - "Found multiple occurrences of same Abci App", - ) - non_abstract_abci_apps = [ - abci_app.__name__ for abci_app in abci_apps if not abci_app.is_abstract() - ] - enforce( - len(non_abstract_abci_apps) == 0, - f"found non-abstract AbciApp during chaining: {non_abstract_abci_apps}", - ) - - # Get the apps rounds - rounds = tuple(app.get_all_rounds() for app in abci_apps) - round_ids = tuple( - {round_.auto_round_id() for round_ in app.get_all_rounds()} for app in abci_apps - ) - - # Ensure there are no common rounds - common_round_classes = check_set_uniqueness(rounds) - enforce( - not common_round_classes, - f"rounds in common between abci apps are not allowed ({common_round_classes})", - ) - - # Ensure there are no common round_ids - common_round_ids = check_set_uniqueness(round_ids) - enforce( - not common_round_ids, - f"round ids in common between abci apps are not allowed ({common_round_ids})", - ) - - # Ensure all states in app transition mapping (keys and values) are final states or initial states, respectively. - all_final_states = { - final_state for app in abci_apps for final_state in app.final_states - } - all_initial_states = { - initial_state for app in abci_apps for initial_state in app.initial_states - }.union({app.initial_round_cls for app in abci_apps}) - for key, value in abci_app_transition_mapping.items(): - if key not in all_final_states: - raise ValueError( - f"Found non-final state {key} specified in abci_app_transition_mapping." - ) - if value not in all_initial_states: - raise ValueError( - f"Found non-initial state {value} specified in abci_app_transition_mapping." - ) - - # Ensure all DB pre- and post-conditions are consistent - # Since we know which app is the "entry-point" we can - # simply work forward from there through all branches. When - # we loop back on an earlier node we stop. - initial_state_to_app: Dict[AppState, Type[AbciApp]] = {} - for value in abci_app_transition_mapping.values(): - for app in abci_apps: - if value in app.initial_states or value == app.initial_round_cls: - initial_state_to_app[value] = app - break - - def get_paths( - initial_state: AppState, - app: Type[AbciApp], - previous_apps: Optional[List[Type[AbciApp]]] = None, - ) -> List[List[Tuple[AppState, Type[AbciApp], Optional[AppState]]]]: - """Get paths.""" - previous_apps_: List[Type[AbciApp]] = ( - deepcopy(previous_apps) if previous_apps is not None else [] - ) - default: List[List[Tuple[AppState, Type[AbciApp], Optional[AppState]]]] = [ - [(initial_state, app, None)] - ] - if app.final_states == {}: - return default # pragma: no cover - paths: List[List[Tuple[AppState, Type[AbciApp], Optional[AppState]]]] = [] - for final_state in app.final_states: - element: Tuple[AppState, Type[AbciApp], Optional[AppState]] = ( - initial_state, - app, - final_state, - ) - if final_state not in abci_app_transition_mapping: - # no linkage defined - paths.append([element]) - continue - next_initial_state = abci_app_transition_mapping[final_state] - next_app = initial_state_to_app[next_initial_state] - if next_app in previous_apps_: - # self-loops do not require attention - # we don't append to path - continue - new_previous_apps = previous_apps_ + [app] - for path in get_paths(next_initial_state, next_app, new_previous_apps): - # if element not in path: - paths.append([element] + path) - return paths if paths else default - - all_paths: List[ - List[Tuple[AppState, Type[AbciApp], Optional[AppState]]] - ] = get_paths(abci_apps[0].initial_round_cls, abci_apps[0]) - new_db_post_conditions: Dict[AppState, Set[str]] = {} - for path in all_paths: - current_initial_state, current_app, current_final_state = path[0] - accumulated_post_conditions: Set[str] = current_app.db_pre_conditions.get( - current_initial_state, set() - ) - for next_initial_state, next_app, next_final_state in path[1:]: - if current_final_state is None: - # No outwards transition, nothing to check. - # we are at the end of a path where the last - # app has no final state and therefore no post conditions - break # pragma: no cover - accumulated_post_conditions = accumulated_post_conditions.union( - set(current_app.db_post_conditions[current_final_state]) - ) - # we now check that the pre conditions of the next app - # are compatible with the post conditions of the current apps. - if next_initial_state in next_app.db_pre_conditions: - diff = set.difference( - next_app.db_pre_conditions[next_initial_state], - accumulated_post_conditions, - ) - if len(diff) != 0: - raise ValueError( - f"Pre conditions '{diff}' of app '{next_app}' not a post condition of app '{current_app}' or any preceding app in path {path}." - ) - else: - raise ValueError( - f"No pre-conditions have been set for {next_initial_state}! " - f"You need to explicitly specify them as empty if there are no pre-conditions for this FSM." - ) - current_app = next_app - current_final_state = next_final_state - - if current_final_state is not None: - new_db_post_conditions[current_final_state] = accumulated_post_conditions - - # Warn about events duplicated in multiple apps - app_to_events = {app: app.get_all_events() for app in abci_apps} - all_events = set.union(*app_to_events.values()) - for event in all_events: - apps = [str(app) for app, events in app_to_events.items() if event in events] - if len(apps) > 1: - apps_str = "\n".join(apps) - _default_logger.warning( - f"The same event '{event}' has been found in several apps:\n{apps_str}\n" - "It will be interpreted as the same event. " - "If this is not the intended behaviour, please rename it to enforce its uniqueness." - ) - - new_initial_round_cls = abci_apps[0].initial_round_cls - new_initial_states = abci_apps[0].initial_states - new_db_pre_conditions = abci_apps[0].db_pre_conditions - - # Merge the transition functions, final states and events - potential_final_states = set.union(*(app.final_states for app in abci_apps)) - potential_events_to_timeout: EventToTimeout = {} - for app in abci_apps: - for e, t in app.event_to_timeout.items(): - if e in potential_events_to_timeout and potential_events_to_timeout[e] != t: - raise ValueError( - f"Event {e} defined in app {app} is defined with timeout {t} but it is already defined in a prior app with timeout {potential_events_to_timeout[e]}." - ) - potential_events_to_timeout[e] = t - - potential_transition_function: AbciAppTransitionFunction = {} - for app in abci_apps: - for state, events_to_rounds in app.transition_function.items(): - if state in abci_app_transition_mapping: - # we remove these final states - continue - # Update transition function according to the transition mapping - new_events_to_rounds = {} - for event, round_ in events_to_rounds.items(): - destination_round = abci_app_transition_mapping.get(round_, round_) - new_events_to_rounds[event] = destination_round - potential_transition_function[state] = new_events_to_rounds - - # Remove no longer used states from transition function and final states - destination_states: Set[AppState] = set() - for event_to_states in potential_transition_function.values(): - destination_states.update(event_to_states.values()) - new_transition_function: AbciAppTransitionFunction = { - state: events_to_rounds - for state, events_to_rounds in potential_transition_function.items() - if state in destination_states or state is new_initial_round_cls - } - new_final_states = { - state for state in potential_final_states if state in destination_states - } - - # Remove no longer used events - used_events: Set[str] = set() - for event_to_states in new_transition_function.values(): - used_events.update(event_to_states.keys()) - new_events_to_timeout = { - event: timeout - for event, timeout in potential_events_to_timeout.items() - if event in used_events - } - - # Collect keys to persist across periods from all abcis - new_cross_period_persisted_keys: Set[str] = set() - for app in abci_apps: - new_cross_period_persisted_keys.update(app.cross_period_persisted_keys) - - # Return the composed result - class ComposedAbciApp(AbciApp[EventType]): - """Composed abci app class.""" - - initial_round_cls: AppState = new_initial_round_cls - initial_states: Set[AppState] = new_initial_states - transition_function: AbciAppTransitionFunction = new_transition_function - final_states: Set[AppState] = new_final_states - event_to_timeout: EventToTimeout = new_events_to_timeout - cross_period_persisted_keys: FrozenSet[str] = frozenset( - new_cross_period_persisted_keys - ) - db_pre_conditions: Dict[AppState, Set[str]] = new_db_pre_conditions - db_post_conditions: Dict[AppState, Set[str]] = new_db_post_conditions - - return ComposedAbciApp diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/base.py b/trader_old/vendor/valory/skills/abstract_round_abci/base.py deleted file mode 100644 index 9718c8e98..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/base.py +++ /dev/null @@ -1,3850 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the base classes for the models classes of the skill.""" - -import datetime -import hashlib -import heapq -import itertools -import json -import logging -import re -import sys -import textwrap -import uuid -from abc import ABC, ABCMeta, abstractmethod -from collections import Counter, deque -from copy import copy, deepcopy -from dataclasses import asdict, astuple, dataclass, field, is_dataclass -from enum import Enum -from inspect import isclass -from math import ceil -from typing import ( - Any, - Callable, - Deque, - Dict, - FrozenSet, - Generic, - Iterator, - List, - Mapping, - Optional, - Sequence, - Set, - Tuple, - Type, - TypeVar, - Union, - cast, -) - -from aea.crypto.ledger_apis import LedgerApis -from aea.exceptions import enforce -from aea.skills.base import SkillContext - -from packages.valory.connections.abci.connection import MAX_READ_IN_BYTES -from packages.valory.connections.ledger.connection import ( - PUBLIC_ID as LEDGER_CONNECTION_PUBLIC_ID, -) -from packages.valory.protocols.abci.custom_types import ( - EvidenceType, - Evidences, - Header, - LastCommitInfo, - Validator, -) -from packages.valory.skills.abstract_round_abci.utils import ( - consensus_threshold, - is_json_serializable, -) - - -_logger = logging.getLogger("aea.packages.valory.skills.abstract_round_abci.base") - -OK_CODE = 0 -ERROR_CODE = 1 -LEDGER_API_ADDRESS = str(LEDGER_CONNECTION_PUBLIC_ID) -ROUND_COUNT_DEFAULT = -1 -MIN_HISTORY_DEPTH = 1 -ADDRESS_LENGTH = 42 -MAX_INT_256 = 2**256 - 1 -RESET_COUNT_START = 0 -VALUE_NOT_PROVIDED = object() -# tolerance in seconds for new blocks not having arrived yet -BLOCKS_STALL_TOLERANCE = 60 -SERIOUS_OFFENCE_ENUM_MIN = 1000 -NUMBER_OF_BLOCKS_TRACKED = 10_000 -NUMBER_OF_ROUNDS_TRACKED = 50 - -EventType = TypeVar("EventType") - - -def get_name(prop: Any) -> str: - """Get the name of a property.""" - if not (isinstance(prop, property) and hasattr(prop, "fget")): - raise ValueError(f"{prop} is not a property") - if prop.fget is None: - raise ValueError(f"fget of {prop} is None") # pragma: nocover - return prop.fget.__name__ - - -class ABCIAppException(Exception): - """A parent class for all exceptions related to the ABCIApp.""" - - -class SignatureNotValidError(ABCIAppException): - """Error raised when a signature is invalid.""" - - -class AddBlockError(ABCIAppException): - """Exception raised when a block addition is not valid.""" - - -class ABCIAppInternalError(ABCIAppException): - """Internal error due to a bad implementation of the ABCIApp.""" - - def __init__(self, message: str, *args: Any) -> None: - """Initialize the error object.""" - super().__init__("internal error: " + message, *args) - - -class TransactionTypeNotRecognizedError(ABCIAppException): - """Error raised when a transaction type is not recognized.""" - - -class TransactionNotValidError(ABCIAppException): - """Error raised when a transaction is not valid.""" - - -class LateArrivingTransaction(ABCIAppException): - """Error raised when the transaction belongs to previous round.""" - - -class AbstractRoundInternalError(ABCIAppException): - """Internal error due to a bad implementation of the AbstractRound.""" - - def __init__(self, message: str, *args: Any) -> None: - """Initialize the error object.""" - super().__init__("internal error: " + message, *args) - - -class _MetaPayload(ABCMeta): - """ - Payload metaclass. - - The purpose of this metaclass is to remember the association - between the type of payload and the payload class to build it. - This is necessary to recover the right payload class to instantiate - at decoding time. - """ - - registry: Dict[str, Type["BaseTxPayload"]] = {} - - def __new__(mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any) -> Type: # type: ignore - """Create a new class object.""" - new_cls = super().__new__(mcs, name, bases, namespace, **kwargs) - - if new_cls.__module__ == mcs.__module__ and new_cls.__name__ == "BaseTxPayload": - return new_cls - if not issubclass(new_cls, BaseTxPayload): - raise ValueError( # pragma: no cover - f"class {name} must inherit from {BaseTxPayload.__name__}" - ) - new_cls = cast(Type[BaseTxPayload], new_cls) - # remember association from transaction type to payload class - _metaclass_registry_key = f"{new_cls.__module__}.{new_cls.__name__}" # type: ignore - mcs.registry[_metaclass_registry_key] = new_cls - - return new_cls - - -@dataclass(frozen=True) -class BaseTxPayload(metaclass=_MetaPayload): - """This class represents a base class for transaction payload classes.""" - - sender: str - round_count: int = field(default=ROUND_COUNT_DEFAULT, init=False) - id_: str = field(default_factory=lambda: uuid.uuid4().hex, init=False) - - @property - def data(self) -> Dict[str, Any]: - """Data""" - excluded = ["sender", "round_count", "id_"] - return {k: v for k, v in asdict(self).items() if k not in excluded} - - @property - def values(self) -> Tuple[Any, ...]: - """Data""" - excluded = 3 # refers to ["sender", "round_count", "id_"] - return astuple(self)[excluded:] - - @property - def json(self) -> Dict[str, Any]: - """Json""" - data, cls = asdict(self), self.__class__ - data["_metaclass_registry_key"] = f"{cls.__module__}.{cls.__name__}" - return data - - @classmethod - def from_json(cls, obj: Dict) -> "BaseTxPayload": - """Decode the payload.""" - data = copy(obj) - round_count, id_ = data.pop("round_count"), data.pop("id_") - payload_cls = _MetaPayload.registry[data.pop("_metaclass_registry_key")] - payload = payload_cls(**data) # type: ignore - object.__setattr__(payload, "round_count", round_count) - object.__setattr__(payload, "id_", id_) - return payload - - def with_new_id(self) -> "BaseTxPayload": - """Create a new payload with the same content but new id.""" - new = type(self)(sender=self.sender, **self.data) # type: ignore - object.__setattr__(new, "round_count", self.round_count) - return new - - def encode(self) -> bytes: - """Encode""" - encoded_data = json.dumps(self.json, sort_keys=True).encode() - if sys.getsizeof(encoded_data) > MAX_READ_IN_BYTES: - msg = f"{type(self)} must be smaller than {MAX_READ_IN_BYTES} bytes" - raise ValueError(msg) - return encoded_data - - @classmethod - def decode(cls, obj: bytes) -> "BaseTxPayload": - """Decode""" - return cls.from_json(json.loads(obj.decode())) - - -@dataclass(frozen=True) -class Transaction(ABC): - """Class to represent a transaction for the ephemeral chain of a period.""" - - payload: BaseTxPayload - signature: str - - def encode(self) -> bytes: - """Encode the transaction.""" - - data = dict(payload=self.payload.json, signature=self.signature) - encoded_data = json.dumps(data, sort_keys=True).encode() - if sys.getsizeof(encoded_data) > MAX_READ_IN_BYTES: - raise ValueError( - f"Transaction must be smaller than {MAX_READ_IN_BYTES} bytes" - ) - return encoded_data - - @classmethod - def decode(cls, obj: bytes) -> "Transaction": - """Decode the transaction.""" - - data = json.loads(obj.decode()) - signature = data["signature"] - payload = BaseTxPayload.from_json(data["payload"]) - return Transaction(payload, signature) - - def verify(self, ledger_id: str) -> None: - """ - Verify the signature is correct. - - :param ledger_id: the ledger id of the address - :raises: SignatureNotValidError: if the signature is not valid. - """ - payload_bytes = self.payload.encode() - addresses = LedgerApis.recover_message( - identifier=ledger_id, message=payload_bytes, signature=self.signature - ) - if self.payload.sender not in addresses: - raise SignatureNotValidError(f"Signature not valid on transaction: {self}") - - -class Block: # pylint: disable=too-few-public-methods - """Class to represent (a subset of) data of a Tendermint block.""" - - def __init__( - self, - header: Header, - transactions: Sequence[Transaction], - ) -> None: - """Initialize the block.""" - self.header = header - self._transactions: Tuple[Transaction, ...] = tuple(transactions) - - @property - def transactions(self) -> Tuple[Transaction, ...]: - """Get the transactions.""" - return self._transactions - - @property - def timestamp(self) -> datetime.datetime: - """Get the block timestamp.""" - return self.header.timestamp - - -class Blockchain: - """ - Class to represent a (naive) Tendermint blockchain. - - The consistency of the data in the blocks is guaranteed by Tendermint. - """ - - def __init__(self, height_offset: int = 0, is_init: bool = True) -> None: - """Initialize the blockchain.""" - self._blocks: List[Block] = [] - self._height_offset = height_offset - self._is_init = is_init - - @property - def is_init(self) -> bool: - """Returns true if the blockchain is initialized.""" - return self._is_init - - def add_block(self, block: Block) -> None: - """Add a block to the list.""" - expected_height = self.height + 1 - actual_height = block.header.height - if actual_height < self._height_offset: - # if the current block has a lower height than the - # initial height, ignore it - return - - if expected_height != actual_height: - raise AddBlockError( - f"expected height {expected_height}, got {actual_height}" - ) - self._blocks.append(block) - - @property - def height(self) -> int: - """ - Get the height. - - Tendermint's height starts from 1. A return value - equal to 0 means empty blockchain. - - :return: the height. - """ - return self.length + self._height_offset - - @property - def length(self) -> int: - """Get the blockchain length.""" - return len(self._blocks) - - @property - def blocks(self) -> Tuple[Block, ...]: - """Get the blocks.""" - return tuple(self._blocks) - - @property - def last_block( - self, - ) -> Block: - """Returns the last stored block.""" - return self._blocks[-1] - - -class BlockBuilder: - """Helper class to build a block.""" - - _current_header: Optional[Header] = None - _current_transactions: List[Transaction] = [] - - def __init__(self) -> None: - """Initialize the block builder.""" - self.reset() - - def reset(self) -> None: - """Reset the temporary data structures.""" - self._current_header = None - self._current_transactions = [] - - @property - def header(self) -> Header: - """ - Get the block header. - - :return: the block header - """ - if self._current_header is None: - raise ValueError("header not set") - return self._current_header - - @header.setter - def header(self, header: Header) -> None: - """Set the header.""" - if self._current_header is not None: - raise ValueError("header already set") - self._current_header = header - - @property - def transactions(self) -> Tuple[Transaction, ...]: - """Get the sequence of transactions.""" - return tuple(self._current_transactions) - - def add_transaction(self, transaction: Transaction) -> None: - """Add a transaction.""" - self._current_transactions.append(transaction) - - def get_block(self) -> Block: - """Get the block.""" - return Block( - self.header, - self._current_transactions, - ) - - -class AbciAppDB: - """Class to represent all data replicated across agents. - - This class stores all the data in self._data. Every entry on this dict represents an optional "period" within your app execution. - The concept of period is user-defined, so it might be something like a sequence of rounds that together conform a logical cycle of - its execution, or it might have no sense at all (thus its optionality) and therefore only period 0 will be used. - - Every "period" entry stores a dict where every key is a saved parameter and its corresponding value a list containing the history - of the parameter values. For instance, for period 0: - - 0: {"parameter_name": [parameter_history]} - - A complete database could look like this: - - data = { - 0: { - "participants": - [ - {"participant_a", "participant_b", "participant_c", "participant_d"}, - {"participant_a", "participant_b", "participant_c"}, - {"participant_a", "participant_b", "participant_c", "participant_d"}, - ] - }, - "other_parameter": [0, 2, 8] - }, - 1: { - "participants": - [ - {"participant_a", "participant_c", "participant_d"}, - {"participant_a", "participant_b", "participant_c", "participant_d"}, - {"participant_a", "participant_b", "participant_c"}, - {"participant_a", "participant_b", "participant_d"}, - {"participant_a", "participant_b", "participant_c", "participant_d"}, - ], - "other_parameter": [3, 19, 10, 32, 6] - }, - 2: ... - } - - # Adding and removing data from the current period - -------------------------------------------------- - To update the current period entry, just call update() on the class. The new values will be appended to the current list for each updated parameter. - - To clean up old data from the current period entry, call cleanup_current_histories(cleanup_history_depth_current), where cleanup_history_depth_current - is the amount of data that you want to keep after the cleanup. The newest cleanup_history_depth_current values will be kept for each parameter in the DB. - - # Creating and removing old periods - ----------------------------------- - To create a new period entry, call create() on the class. The new values will be stored in a new list for each updated parameter. - - To remove old periods, call cleanup(cleanup_history_depth, [cleanup_history_depth_current]), where cleanup_history_depth is the amount of periods - that you want to keep after the cleanup. The newest cleanup_history_depth periods will be kept. If you also specify cleanup_history_depth_current, - cleanup_current_histories will be also called (see previous point). - - The parameters cleanup_history_depth and cleanup_history_depth_current can also be configured in skill.yaml so they are used automatically - when the cleanup method is called from AbciApp.cleanup(). - - # Memory warning - ----------------------------------- - The database is implemented in such a way to avoid indirect modification of its contents. - It copies all the mutable data structures*, which means that it consumes more memory than expected. - This is necessary because otherwise it would risk chance of modification from the behaviour side, - which is a safety concern. - - The effect of this on the memory usage should not be a big concern, because: - - 1. The synchronized data of the agents are not intended to store large amount of data. - IPFS should be used in such cases, and only the hash should be synchronized in the db. - 2. The data are automatically wiped after a predefined `cleanup_history` depth as described above. - 3. The retrieved data are only meant to be used for a short amount of time, - e.g., to perform a decision on a behaviour, which means that the gc will collect them before they are noticed. - - * the in-built `copy` module is used, which automatically detects if an item is immutable and skips copying it. - For more information take a look at the `_deepcopy_atomic` method and its usage: - https://github.com/python/cpython/blob/3.10/Lib/copy.py#L182-L183 - """ - - DB_DATA_KEY = "db_data" - SLASHING_CONFIG_KEY = "slashing_config" - - # database keys which values are always set for the next period by default - default_cross_period_keys: FrozenSet[str] = frozenset( - { - "all_participants", - "participants", - "consensus_threshold", - "safe_contract_address", - } - ) - - def __init__( - self, - setup_data: Dict[str, List[Any]], - cross_period_persisted_keys: Optional[FrozenSet[str]] = None, - logger: Optional[logging.Logger] = None, - ) -> None: - """Initialize the AbciApp database. - - setup_data must be passed as a Dict[str, List[Any]] (the database internal format). - The staticmethod 'data_to_lists' can be used to convert from Dict[str, Any] to Dict[str, List[Any]] - before instantiating this class. - - :param setup_data: the setup data - :param cross_period_persisted_keys: data keys that will be kept after a new period starts - :param logger: the logger of the abci app - """ - self.logger = logger or _logger - AbciAppDB._check_data(setup_data) - self._setup_data = deepcopy(setup_data) - self._data: Dict[int, Dict[str, List[Any]]] = { - RESET_COUNT_START: self.setup_data # the key represents the reset index - } - self._round_count = ROUND_COUNT_DEFAULT # ensures first round is indexed at 0! - - self._cross_period_persisted_keys = self.default_cross_period_keys.union( - cross_period_persisted_keys or frozenset() - ) - self._cross_period_check() - self.slashing_config: str = "" - - def _cross_period_check(self) -> None: - """Check the cross period keys against the setup data.""" - not_in_cross_period = set(self._setup_data).difference( - self.cross_period_persisted_keys - ) - if not_in_cross_period: - self.logger.warning( - f"The setup data ({self._setup_data.keys()}) contain keys that are not in the " - f"cross period persisted keys ({self.cross_period_persisted_keys}): {not_in_cross_period}" - ) - - @staticmethod - def normalize(value: Any) -> str: - """Attempt to normalize a non-primitive type to insert it into the db.""" - if is_json_serializable(value): - return value - - if isinstance(value, Enum): - return value.value - - if isinstance(value, bytes): - return value.hex() - - if isinstance(value, set): - try: - return json.dumps(list(value)) - except TypeError: - pass - - raise ValueError(f"Cannot normalize {value} to insert it in the db!") - - @property - def setup_data(self) -> Dict[str, Any]: - """ - Get the setup_data without entries which have empty values. - - :return: the setup_data - """ - # do not return data if no value has been set - return {k: v for k, v in deepcopy(self._setup_data).items() if len(v)} - - @staticmethod - def _check_data(data: Any) -> None: - """Check that all fields in setup data were passed as a list, and that the data can be accepted into the db.""" - if ( - not isinstance(data, dict) - or not all((isinstance(k, str) for k in data.keys())) - or not all((isinstance(v, list) for v in data.values())) - ): - raise ValueError( - f"AbciAppDB data must be `Dict[str, List[Any]]`, found `{type(data)}` instead." - ) - - AbciAppDB.validate(data) - - @property - def reset_index(self) -> int: - """Get the current reset index.""" - # should return the last key or 0 if we have no data - return list(self._data)[-1] if self._data else 0 - - @property - def round_count(self) -> int: - """Get the round count.""" - return self._round_count - - @round_count.setter - def round_count(self, round_count: int) -> None: - """Set the round count.""" - self._round_count = round_count - - @property - def cross_period_persisted_keys(self) -> FrozenSet[str]: - """Keys in the database which are persistent across periods.""" - return self._cross_period_persisted_keys - - def get(self, key: str, default: Any = VALUE_NOT_PROVIDED) -> Optional[Any]: - """Given a key, get its last for the current reset index.""" - if key in self._data[self.reset_index]: - return deepcopy(self._data[self.reset_index][key][-1]) - if default != VALUE_NOT_PROVIDED: - return default - raise ValueError( - f"'{key}' field is not set for this period [{self.reset_index}] and no default value was provided." - ) - - def get_strict(self, key: str) -> Any: - """Get a value from the data dictionary and raise if it is None.""" - return self.get(key) - - @staticmethod - def validate(data: Any) -> None: - """Validate if the given data are json serializable and therefore can be accepted into the database. - - :param data: the data to check. - :raises ABCIAppInternalError: If the data are not serializable. - """ - if not is_json_serializable(data): - raise ABCIAppInternalError( - f"`AbciAppDB` data must be json-serializable. Please convert non-serializable data in `{data}`. " - "You may use `AbciAppDB.validate(your_data)` to validate your data for the `AbciAppDB`." - ) - - def update(self, **kwargs: Any) -> None: - """Update the current data.""" - self.validate(kwargs) - - # Append new data to the key history - data = self._data[self.reset_index] - for key, value in deepcopy(kwargs).items(): - data.setdefault(key, []).append(value) - - def create(self, **kwargs: Any) -> None: - """Add a new entry to the data. - - Passes automatically the values of the `cross_period_persisted_keys` to the next period. - - :param kwargs: keyword arguments - """ - for key in self.cross_period_persisted_keys.union(kwargs.keys()): - value = kwargs.get(key, VALUE_NOT_PROVIDED) - if value is VALUE_NOT_PROVIDED: - value = self.get_latest().get(key, VALUE_NOT_PROVIDED) - if value is VALUE_NOT_PROVIDED: - raise ABCIAppInternalError( - f"Cross period persisted key `{key}` was not found in the db but was required for the next period." - ) - if isinstance(value, (set, frozenset)): - value = tuple(sorted(value)) - kwargs[key] = value - - data = self.data_to_lists(kwargs) - self._create_from_keys(**data) - - def _create_from_keys(self, **kwargs: Any) -> None: - """Add a new entry to the data using the provided key-value pairs.""" - AbciAppDB._check_data(kwargs) - self._data[self.reset_index + 1] = deepcopy(kwargs) - - def get_latest_from_reset_index(self, reset_index: int) -> Dict[str, Any]: - """Get the latest key-value pairs from the data dictionary for the specified period.""" - return { - key: values[-1] - for key, values in deepcopy(self._data.get(reset_index, {})).items() - } - - def get_latest(self) -> Dict[str, Any]: - """Get the latest key-value pairs from the data dictionary for the current period.""" - return self.get_latest_from_reset_index(self.reset_index) - - def increment_round_count(self) -> None: - """Increment the round count.""" - self._round_count += 1 - - def __repr__(self) -> str: - """Return a string representation of the data.""" - return f"AbciAppDB({self._data})" - - def cleanup( - self, - cleanup_history_depth: int, - cleanup_history_depth_current: Optional[int] = None, - ) -> None: - """Reset the db, keeping only the latest entries (periods). - - If cleanup_history_depth_current has been also set, also clear oldest historic values in the current entry. - - :param cleanup_history_depth: depth to clean up history - :param cleanup_history_depth_current: whether or not to clean up current entry too. - """ - cleanup_history_depth = max(cleanup_history_depth, MIN_HISTORY_DEPTH) - self._data = { - key: self._data[key] - for key in sorted(self._data.keys())[-cleanup_history_depth:] - } - if cleanup_history_depth_current: - self.cleanup_current_histories(cleanup_history_depth_current) - - def cleanup_current_histories(self, cleanup_history_depth_current: int) -> None: - """Reset the parameter histories for the current entry (period), keeping only the latest values for each parameter.""" - cleanup_history_depth_current = max( - cleanup_history_depth_current, MIN_HISTORY_DEPTH - ) - self._data[self.reset_index] = { - key: history[-cleanup_history_depth_current:] - for key, history in self._data[self.reset_index].items() - } - - def serialize(self) -> str: - """Serialize the data of the database to a string.""" - db = { - self.DB_DATA_KEY: self._data, - self.SLASHING_CONFIG_KEY: self.slashing_config, - } - return json.dumps(db, sort_keys=True) - - @staticmethod - def _as_abci_data(data: Dict) -> Dict[int, Any]: - """Hook to load serialized data as `AbciAppDB` data.""" - return {int(index): content for index, content in data.items()} - - def sync(self, serialized_data: str) -> None: - """Synchronize the data using a serialized object. - - :param serialized_data: the serialized data to use in order to sync the db. - :raises ABCIAppInternalError: if the given data cannot be deserialized. - """ - try: - loaded_data = json.loads(serialized_data) - except json.JSONDecodeError as exc: - raise ABCIAppInternalError( - f"Could not decode data using {serialized_data}: {exc}" - ) from exc - - input_report = f"\nThe following serialized data were given: {serialized_data}" - try: - db_data = loaded_data[self.DB_DATA_KEY] - slashing_config = loaded_data[self.SLASHING_CONFIG_KEY] - except KeyError as exc: - raise ABCIAppInternalError( - "Mandatory keys `db_data`, `slashing_config` are missing from the deserialized data: " - f"{loaded_data}{input_report}" - ) from exc - - try: - db_data = self._as_abci_data(db_data) - except AttributeError as exc: - raise ABCIAppInternalError( - f"Could not decode db data with an invalid format: {db_data}{input_report}" - ) from exc - except ValueError as exc: - raise ABCIAppInternalError( - f"An invalid index was found while trying to sync the db using data: {db_data}{input_report}" - ) from exc - - self._check_data(dict(tuple(db_data.values())[0])) - self._data = db_data - self.slashing_config = slashing_config - - def hash(self) -> bytes: - """Create a hash of the data.""" - # Compute the sha256 hash of the serialized data - sha256 = hashlib.sha256() - data = self.serialize() - sha256.update(data.encode("utf-8")) - hash_ = sha256.digest() - self.logger.debug(f"root hash: {hash_.hex()}; data: {data}") - return hash_ - - @staticmethod - def data_to_lists(data: Dict[str, Any]) -> Dict[str, List[Any]]: - """Convert Dict[str, Any] to Dict[str, List[Any]].""" - return {k: [v] for k, v in data.items()} - - -SerializedCollection = Dict[str, Dict[str, Any]] -DeserializedCollection = Mapping[str, BaseTxPayload] - - -class BaseSynchronizedData: - """ - Class to represent the synchronized data. - - This is the relevant data constructed and replicated by the agents. - """ - - # Keys always set by default - # `round_count` and `period_count` need to be guaranteed to be synchronized too: - # - # * `round_count` is only incremented when scheduling a new round, - # which is by definition always a synchronized action. - # * `period_count` comes from the `reset_index` which is the last key of the `self._data`. - # The `self._data` keys are only updated on create, and cleanup operations, - # which are also meant to be synchronized since they are used at the rounds. - default_db_keys: Set[str] = { - "round_count", - "period_count", - "all_participants", - "nb_participants", - "max_participants", - "consensus_threshold", - "safe_contract_address", - } - - def __init__( - self, - db: AbciAppDB, - ) -> None: - """Initialize the synchronized data.""" - self._db = db - - @property - def db(self) -> AbciAppDB: - """Get DB.""" - return self._db - - @property - def round_count(self) -> int: - """Get the round count.""" - return self.db.round_count - - @property - def period_count(self) -> int: - """Get the period count. - - Periods are executions between calls to AbciAppDB.create(), so as soon as it is called, - a new period begins. It is useful to have a logical subdivision of the FSM execution. - For example, if AbciAppDB.create() is called during reset, then a period will be the - execution between resets. - - :return: the period count - """ - return self.db.reset_index - - @property - def participants(self) -> FrozenSet[str]: - """Get the currently active participants.""" - participants = frozenset(self.db.get_strict("participants")) - if len(participants) == 0: - raise ValueError("List participants cannot be empty.") - return cast(FrozenSet[str], participants) - - @property - def all_participants(self) -> FrozenSet[str]: - """Get all registered participants.""" - all_participants = frozenset(self.db.get_strict("all_participants")) - if len(all_participants) == 0: - raise ValueError("List participants cannot be empty.") - return cast(FrozenSet[str], all_participants) - - @property - def max_participants(self) -> int: - """Get the number of all the participants.""" - return len(self.all_participants) - - @property - def consensus_threshold(self) -> int: - """Get the consensus threshold.""" - threshold = self.db.get_strict("consensus_threshold") - min_threshold = consensus_threshold(self.max_participants) - - if threshold is None: - return min_threshold - - threshold = int(threshold) - max_threshold = len(self.all_participants) - - if min_threshold <= threshold <= max_threshold: - return threshold - - expected_range = ( - f"can only be {min_threshold}" - if min_threshold == max_threshold - else f"not in [{min_threshold}, {max_threshold}]" - ) - raise ValueError(f"Consensus threshold {threshold} {expected_range}.") - - @property - def sorted_participants(self) -> Sequence[str]: - """ - Get the sorted participants' addresses. - - The addresses are sorted according to their hexadecimal value; - this is the reason we use key=str.lower as comparator. - - This property is useful when interacting with the Safe contract. - - :return: the sorted participants' addresses - """ - return sorted(self.participants, key=str.lower) - - @property - def nb_participants(self) -> int: - """Get the number of participants.""" - participants = cast(List, self.db.get("participants", [])) - return len(participants) - - @property - def slashing_config(self) -> str: - """Get the slashing configuration.""" - return self.db.slashing_config - - @slashing_config.setter - def slashing_config(self, config: str) -> None: - """Set the slashing configuration.""" - self.db.slashing_config = config - - def update( - self, - synchronized_data_class: Optional[Type] = None, - **kwargs: Any, - ) -> "BaseSynchronizedData": - """Copy and update the current data.""" - self.db.update(**kwargs) - - class_ = ( - type(self) if synchronized_data_class is None else synchronized_data_class - ) - return class_(db=self.db) - - def create( - self, - synchronized_data_class: Optional[Type] = None, - ) -> "BaseSynchronizedData": - """Copy and update with new data. Set values are stored as sorted tuples to the db for determinism.""" - self.db.create() - class_ = ( - type(self) if synchronized_data_class is None else synchronized_data_class - ) - return class_(db=self.db) - - def __repr__(self) -> str: - """Return a string representation of the data.""" - return f"{self.__class__.__name__}(db={self._db})" - - @property - def keeper_randomness(self) -> float: - """Get the keeper's random number [0-1].""" - return ( - int(self.most_voted_randomness, base=16) / MAX_INT_256 - ) # DRAND uses sha256 values - - @property - def most_voted_randomness(self) -> str: - """Get the most_voted_randomness.""" - return cast(str, self.db.get_strict("most_voted_randomness")) - - @property - def most_voted_keeper_address(self) -> str: - """Get the most_voted_keeper_address.""" - return cast(str, self.db.get_strict("most_voted_keeper_address")) - - @property - def is_keeper_set(self) -> bool: - """Check whether keeper is set.""" - return self.db.get("most_voted_keeper_address", None) is not None - - @property - def blacklisted_keepers(self) -> Set[str]: - """Get the current cycle's blacklisted keepers who cannot submit a transaction.""" - raw = cast(str, self.db.get("blacklisted_keepers", "")) - return set(textwrap.wrap(raw, ADDRESS_LENGTH)) - - @property - def participant_to_selection(self) -> DeserializedCollection: - """Check whether keeper is set.""" - serialized = self.db.get_strict("participant_to_selection") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(DeserializedCollection, deserialized) - - @property - def participant_to_randomness(self) -> DeserializedCollection: - """Check whether keeper is set.""" - serialized = self.db.get_strict("participant_to_randomness") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(DeserializedCollection, deserialized) - - @property - def participant_to_votes(self) -> DeserializedCollection: - """Check whether keeper is set.""" - serialized = self.db.get_strict("participant_to_votes") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(DeserializedCollection, deserialized) - - @property - def safe_contract_address(self) -> str: - """Get the safe contract address.""" - return cast(str, self.db.get_strict("safe_contract_address")) - - -class _MetaAbstractRound(ABCMeta): - """A metaclass that validates AbstractRound's attributes.""" - - def __new__(mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any) -> Type: # type: ignore - """Initialize the class.""" - new_cls = super().__new__(mcs, name, bases, namespace, **kwargs) - - if ABC in bases: - # abstract class, return - return new_cls - if not issubclass(new_cls, AbstractRound): - # the check only applies to AbstractRound subclasses - return new_cls - - mcs._check_consistency(cast(Type[AbstractRound], new_cls)) - return new_cls - - @classmethod - def _check_consistency(mcs, abstract_round_cls: Type["AbstractRound"]) -> None: - """Check consistency of class attributes.""" - mcs._check_required_class_attributes(abstract_round_cls) - - @classmethod - def _check_required_class_attributes( - mcs, abstract_round_cls: Type["AbstractRound"] - ) -> None: - """Check that required class attributes are set.""" - if not hasattr(abstract_round_cls, "synchronized_data_class"): - raise AbstractRoundInternalError( - f"'synchronized_data_class' not set on {abstract_round_cls}" - ) - if not hasattr(abstract_round_cls, "payload_class"): - raise AbstractRoundInternalError( - f"'payload_class' not set on {abstract_round_cls}" - ) - - -class AbstractRound(Generic[EventType], ABC, metaclass=_MetaAbstractRound): - """ - This class represents an abstract round. - - A round is a state of the FSM App execution. It usually involves - interactions between participants in the FSM App, - although this is not enforced at this level of abstraction. - - Concrete classes must set: - - synchronized_data_class: the data class associated with this round; - - payload_class: the payload type that is allowed for this round; - - Optionally, round_id can be defined, although it is recommended to use the autogenerated id. - """ - - __pattern = re.compile(r"(? None: - """Initialize the round.""" - self._synchronized_data = synchronized_data - self.block_confirmations = 0 - self._previous_round_payload_class = previous_round_payload_class - self.context = context - - @classmethod - def auto_round_id(cls) -> str: - """ - Get round id automatically. - - This method returns the auto generated id from the class name if the - class variable behaviour_id is not set on the child class. - Otherwise, it returns the class variable behaviour_id. - """ - return ( - cls.round_id - if isinstance(cls.round_id, str) - else cls.__pattern.sub("_", cls.__name__).lower() - ) - - @property # type: ignore - def round_id(self) -> str: - """Get round id.""" - return self.auto_round_id() - - @property - def synchronized_data(self) -> BaseSynchronizedData: - """Get the synchronized data.""" - return self._synchronized_data - - def check_transaction(self, transaction: Transaction) -> None: - """ - Check transaction against the current state. - - :param transaction: the transaction - """ - self.check_payload_type(transaction) - self.check_payload(transaction.payload) - - def process_transaction(self, transaction: Transaction) -> None: - """ - Process a transaction. - - By convention, the payload handler should be a method - of the class that is named '{payload_name}'. - - :param transaction: the transaction. - """ - self.check_payload_type(transaction) - self.process_payload(transaction.payload) - - @abstractmethod - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """ - Process the end of the block. - - The role of this method is check whether the round - is considered ended. - - If the round is ended, the return value is - - the final result of the round. - - the event that triggers a transition. If None, the period - in which the round was executed is considered ended. - - This is done after each block because we consider the consensus engine's - block, and not the transaction, as the smallest unit - on which the consensus is reached; in other words, - each read operation on the state should be done - only after each block, and not after each transaction. - """ - - def check_payload_type(self, transaction: Transaction) -> None: - """ - Check the transaction is of the allowed transaction type. - - :param transaction: the transaction - :raises: TransactionTypeNotRecognizedError if the transaction can be - applied to the current state. - """ - if self.payload_class is None: - raise TransactionTypeNotRecognizedError( - "current round does not allow transactions" - ) - - payload_class = type(transaction.payload) - - if payload_class is self._previous_round_payload_class: - raise LateArrivingTransaction( - f"request '{transaction.payload}' is from previous round; skipping" - ) - - if payload_class is not self.payload_class: - raise TransactionTypeNotRecognizedError( - f"request '{payload_class}' not recognized; only {self.payload_class} is supported" - ) - - def check_majority_possible_with_new_voter( - self, - votes_by_participant: Dict[str, BaseTxPayload], - new_voter: str, - new_vote: BaseTxPayload, - nb_participants: int, - exception_cls: Type[ABCIAppException] = ABCIAppException, - ) -> None: - """ - Check that a Byzantine majority is achievable, once a new vote is added. - - :param votes_by_participant: a mapping from a participant to its vote, - before the new vote is added - :param new_voter: the new voter - :param new_vote: the new vote - :param nb_participants: the total number of participants - :param exception_cls: the class of the exception to raise in case the - check fails. - :raises: exception_cls: in case the check does not pass. - """ - # check preconditions - enforce( - new_voter not in votes_by_participant, - "voter has already voted", - ABCIAppInternalError, - ) - enforce( - len(votes_by_participant) <= nb_participants - 1, - "nb_participants not consistent with votes_by_participants", - ABCIAppInternalError, - ) - - # copy the input dictionary to avoid side effects - votes_by_participant = copy(votes_by_participant) - - # add the new vote - votes_by_participant[new_voter] = new_vote - - self.check_majority_possible( - votes_by_participant, nb_participants, exception_cls=exception_cls - ) - - def check_majority_possible( - self, - votes_by_participant: Dict[str, BaseTxPayload], - nb_participants: int, - exception_cls: Type[ABCIAppException] = ABCIAppException, - ) -> None: - """ - Check that a Byzantine majority is still achievable. - - The idea is that, even if all the votes have not been delivered yet, - it can be deduced whether a quorum cannot be reached due to - divergent preferences among the voters and due to a too small - number of other participants whose vote has not been delivered yet. - - The check fails iff: - - nb_remaining_votes + largest_nb_votes < quorum - - That is, if the number of remaining votes is not enough to make - the most voted item so far to exceed the quorum. - - Preconditions on the input: - - the size of votes_by_participant should not be greater than - "nb_participants - 1" voters - - new voter must not be in the current votes_by_participant - - :param votes_by_participant: a mapping from a participant to its vote - :param nb_participants: the total number of participants - :param exception_cls: the class of the exception to raise in case the - check fails. - :raises exception_cls: in case the check does not pass. - """ - enforce( - nb_participants > 0 and len(votes_by_participant) <= nb_participants, - "nb_participants not consistent with votes_by_participants", - ABCIAppInternalError, - ) - if len(votes_by_participant) == 0: - return - - votes = votes_by_participant.values() - vote_count = Counter(tuple(sorted(v.data.items())) for v in votes) - largest_nb_votes = max(vote_count.values()) - nb_votes_received = sum(vote_count.values()) - nb_remaining_votes = nb_participants - nb_votes_received - - if ( - nb_remaining_votes + largest_nb_votes - < self.synchronized_data.consensus_threshold - ): - raise exception_cls( - f"cannot reach quorum={self.synchronized_data.consensus_threshold}, " - f"number of remaining votes={nb_remaining_votes}, number of most voted item's votes={largest_nb_votes}" - ) - - def is_majority_possible( - self, votes_by_participant: Dict[str, BaseTxPayload], nb_participants: int - ) -> bool: - """ - Return true if a Byzantine majority is achievable, false otherwise. - - :param votes_by_participant: a mapping from a participant to its vote - :param nb_participants: the total number of participants - :return: True if the majority is still possible, false otherwise. - """ - try: - self.check_majority_possible(votes_by_participant, nb_participants) - except ABCIAppException: - return False - return True - - @abstractmethod - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - - @abstractmethod - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - - -class DegenerateRound(AbstractRound, ABC): - """ - This class represents the finished round during operation. - - It is a sink round. - """ - - payload_class = None - synchronized_data_class = BaseSynchronizedData - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - raise NotImplementedError( # pragma: nocover - "DegenerateRound should not be used in operation." - ) - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - raise NotImplementedError( # pragma: nocover - "DegenerateRound should not be used in operation." - ) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """End block.""" - raise NotImplementedError( # pragma: nocover - "DegenerateRound should not be used in operation." - ) - - -class CollectionRound(AbstractRound, ABC): - """ - CollectionRound. - - This class represents abstract logic for collection based rounds where - the round object needs to collect data from different agents. The data - might for example be from a voting round or estimation round. - - `_allow_rejoin_payloads` is used to allow agents not currently active to - deliver a payload. - """ - - _allow_rejoin_payloads: bool = False - - def __init__(self, *args: Any, **kwargs: Any): - """Initialize the collection round.""" - super().__init__(*args, **kwargs) - self.collection: Dict[str, BaseTxPayload] = {} - - @staticmethod - def serialize_collection( - collection: DeserializedCollection, - ) -> SerializedCollection: - """Deserialize a serialized collection.""" - return {address: payload.json for address, payload in collection.items()} - - @staticmethod - def deserialize_collection( - serialized: SerializedCollection, - ) -> DeserializedCollection: - """Deserialize a serialized collection.""" - return { - address: BaseTxPayload.from_json(payload_json) - for address, payload_json in serialized.items() - } - - @property - def serialized_collection(self) -> SerializedCollection: - """A collection with the addresses mapped to serialized payloads.""" - return self.serialize_collection(self.collection) - - @property - def accepting_payloads_from(self) -> FrozenSet[str]: - """Accepting from the active set, or also from (re)joiners""" - if self._allow_rejoin_payloads: - return self.synchronized_data.all_participants - return self.synchronized_data.participants - - @property - def payloads(self) -> List[BaseTxPayload]: - """Get all agent payloads""" - return list(self.collection.values()) - - @property - def payload_values_count(self) -> Counter: - """Get count of payload values.""" - return Counter(map(lambda p: p.values, self.payloads)) - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - if payload.round_count != self.synchronized_data.round_count: - raise ABCIAppInternalError( - f"Expected round count {self.synchronized_data.round_count} and got {payload.round_count}." - ) - - sender = payload.sender - if sender not in self.accepting_payloads_from: - raise ABCIAppInternalError( - f"{sender} not in list of participants: {sorted(self.accepting_payloads_from)}" - ) - - if sender in self.collection: - raise ABCIAppInternalError( - f"sender {sender} has already sent value for round: {self.round_id}" - ) - - self.collection[sender] = payload - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check Payload""" - - # NOTE: the TransactionNotValidError is intercepted in ABCIRoundHandler.deliver_tx - # which means it will be logged instead of raised - if payload.round_count != self.synchronized_data.round_count: - raise TransactionNotValidError( - f"Expected round count {self.synchronized_data.round_count} and got {payload.round_count}." - ) - - sender_in_participant_set = payload.sender in self.accepting_payloads_from - if not sender_in_participant_set: - raise TransactionNotValidError( - f"{payload.sender} not in list of participants: {sorted(self.accepting_payloads_from)}" - ) - - if payload.sender in self.collection: - raise TransactionNotValidError( - f"sender {payload.sender} has already sent value for round: {self.round_id}" - ) - - -class _CollectUntilAllRound(CollectionRound, ABC): - """ - _CollectUntilAllRound - - This class represents abstract logic for when rounds need to collect payloads from all agents. - - This round should only be used when non-BFT behaviour is acceptable. - """ - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check Payload""" - if payload.round_count != self.synchronized_data.round_count: - raise TransactionNotValidError( - f"Expected round count {self.synchronized_data.round_count} and got {payload.round_count}." - ) - - if payload.sender in self.collection: - raise TransactionNotValidError( - f"sender {payload.sender} has already sent value for round: {self.round_id}" - ) - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - try: - self.check_payload(payload) - except TransactionNotValidError as e: - raise ABCIAppInternalError(e.args[0]) from e - - self.collection[payload.sender] = payload - - @property - def collection_threshold_reached( - self, - ) -> bool: - """Check that the collection threshold has been reached.""" - return len(self.collection) >= self.synchronized_data.max_participants - - -class CollectDifferentUntilAllRound(_CollectUntilAllRound, ABC): - """ - CollectDifferentUntilAllRound - - This class represents logic for rounds where a round needs to collect - different payloads from each agent. - - This round should only be used for registration of new agents when there is synchronization of the db. - """ - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check Payload""" - new = payload.values - existing = [payload_.values for payload_ in self.collection.values()] - - if payload.sender not in self.collection and new in existing: - raise TransactionNotValidError( - f"`CollectDifferentUntilAllRound` encountered a value '{new}' that already exists. " - f"All values: {existing}" - ) - - super().check_payload(payload) - - -class CollectSameUntilAllRound(_CollectUntilAllRound, ABC): - """ - This class represents logic for when a round needs to collect the same payload from all the agents. - - This round should only be used for registration of new agents when there is no synchronization of the db. - """ - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check Payload""" - new = payload.values - existing_ = [payload_.values for payload_ in self.collection.values()] - - if ( - payload.sender not in self.collection - and len(self.collection) - and new not in existing_ - ): - raise TransactionNotValidError( - f"`CollectSameUntilAllRound` encountered a value '{new}' " - f"which is not the same as the already existing one: '{existing_[0]}'" - ) - - super().check_payload(payload) - - @property - def common_payload( - self, - ) -> Any: - """Get the common payload among the agents.""" - return self.common_payload_values[0] - - @property - def common_payload_values( - self, - ) -> Tuple[Any, ...]: - """Get the common payload among the agents.""" - most_common_payload_values, max_votes = self.payload_values_count.most_common( - 1 - )[0] - if max_votes < self.synchronized_data.max_participants: - raise ABCIAppInternalError( - f"{max_votes} votes are not enough for `CollectSameUntilAllRound`. Expected: " - f"`n_votes = max_participants = {self.synchronized_data.max_participants}`" - ) - return most_common_payload_values - - -class CollectSameUntilThresholdRound(CollectionRound, ABC): - """ - CollectSameUntilThresholdRound - - This class represents logic for rounds where a round needs to collect - same payload from k of n agents. - - `done_event` is emitted when a) the collection threshold (k of n) is reached, - and b) the most voted payload has non-empty attributes. In this case all - payloads are saved under `collection_key` and the most voted payload attributes - are saved under `selection_key`. - - `none_event` is emitted when a) the collection threshold (k of n) is reached, - and b) the most voted payload has only empty attributes. - - `no_majority_event` is emitted when it is impossible to reach a k of n majority. - """ - - done_event: Any - no_majority_event: Any - none_event: Any - collection_key: str - selection_key: Union[str, Tuple[str, ...]] - - @property - def threshold_reached( - self, - ) -> bool: - """Check if the threshold has been reached.""" - counts = self.payload_values_count.values() - return any( - count >= self.synchronized_data.consensus_threshold for count in counts - ) - - @property - def most_voted_payload( - self, - ) -> Any: - """ - Get the most voted payload value. - - Kept for backward compatibility. - """ - return self.most_voted_payload_values[0] - - @property - def most_voted_payload_values( - self, - ) -> Tuple[Any, ...]: - """Get the most voted payload values.""" - most_voted_payload_values, max_votes = self.payload_values_count.most_common()[ - 0 - ] - if max_votes < self.synchronized_data.consensus_threshold: - raise ABCIAppInternalError("not enough votes") - return most_voted_payload_values - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.threshold_reached and any( - [val is not None for val in self.most_voted_payload_values] - ): - if isinstance(self.selection_key, tuple): - data = dict(zip(self.selection_key, self.most_voted_payload_values)) - data[self.collection_key] = self.serialized_collection - else: - data = { - self.collection_key: self.serialized_collection, - self.selection_key: self.most_voted_payload, - } - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **data, - ) - return synchronized_data, self.done_event - if self.threshold_reached and not any( - [val is not None for val in self.most_voted_payload_values] - ): - return self.synchronized_data, self.none_event - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, self.no_majority_event - return None - - -class OnlyKeeperSendsRound(AbstractRound, ABC): - """ - OnlyKeeperSendsRound - - This class represents logic for rounds where only one agent sends a - payload. - - `done_event` is emitted when a) the keeper payload has been received and b) - the keeper payload has non-empty attributes. In this case all attributes are saved - under `payload_key`. - - `fail_event` is emitted when a) the keeper payload has been received and b) - the keeper payload has only empty attributes - """ - - keeper_payload: Optional[BaseTxPayload] = None - done_event: Any - fail_event: Any - payload_key: Union[str, Tuple[str, ...]] - - def process_payload(self, payload: BaseTxPayload) -> None: - """Handle a deploy safe payload.""" - if payload.round_count != self.synchronized_data.round_count: - raise ABCIAppInternalError( - f"Expected round count {self.synchronized_data.round_count} and got {payload.round_count}." - ) - - sender = payload.sender - - if sender not in self.synchronized_data.participants: - raise ABCIAppInternalError( - f"{sender} not in list of participants: {sorted(self.synchronized_data.participants)}" - ) - - if sender != self.synchronized_data.most_voted_keeper_address: - raise ABCIAppInternalError(f"{sender} not elected as keeper.") - - if self.keeper_payload is not None: - raise ABCIAppInternalError("keeper already set the payload.") - - self.keeper_payload = payload - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check a deploy safe payload can be applied to the current state.""" - if payload.round_count != self.synchronized_data.round_count: - raise TransactionNotValidError( - f"Expected round count {self.synchronized_data.round_count} and got {payload.round_count}." - ) - - sender = payload.sender - sender_in_participant_set = sender in self.synchronized_data.participants - if not sender_in_participant_set: - raise TransactionNotValidError( - f"{sender} not in list of participants: {sorted(self.synchronized_data.participants)}" - ) - - sender_is_elected_sender = ( - sender == self.synchronized_data.most_voted_keeper_address - ) - if not sender_is_elected_sender: - raise TransactionNotValidError(f"{sender} not elected as keeper.") - - if self.keeper_payload is not None: - raise TransactionNotValidError("keeper payload value already set.") - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.keeper_payload is not None and any( - [val is not None for val in self.keeper_payload.values] - ): - if isinstance(self.payload_key, tuple): - data = dict(zip(self.payload_key, self.keeper_payload.values)) - else: - data = { - self.payload_key: self.keeper_payload.values[0], - } - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **data, - ) - return synchronized_data, self.done_event - if self.keeper_payload is not None and not any( - [val is not None for val in self.keeper_payload.values] - ): - return self.synchronized_data, self.fail_event - return None - - -class VotingRound(CollectionRound, ABC): - """ - VotingRound - - This class represents logic for rounds where a round needs votes from - agents. Votes are in the form of `True` (positive), `False` (negative) - and `None` (abstain). The round ends when k of n agents make the same vote. - - `done_event` is emitted when a) the collection threshold (k of n) is reached - with k positive votes. In this case all payloads are saved under `collection_key`. - - `negative_event` is emitted when a) the collection threshold (k of n) is reached - with k negative votes. - - `none_event` is emitted when a) the collection threshold (k of n) is reached - with k abstain votes. - - `no_majority_event` is emitted when it is impossible to reach a k of n majority for - either of the options. - """ - - done_event: Any - negative_event: Any - none_event: Any - no_majority_event: Any - collection_key: str - - @property - def vote_count(self) -> Counter: - """Get agent payload vote count""" - - def parse_payload(payload: Any) -> Optional[bool]: - if not hasattr(payload, "vote"): - raise ValueError(f"payload {payload} has no attribute `vote`") - return payload.vote - - return Counter(parse_payload(payload) for payload in self.collection.values()) - - @property - def positive_vote_threshold_reached(self) -> bool: - """Check that the vote threshold has been reached.""" - return self.vote_count[True] >= self.synchronized_data.consensus_threshold - - @property - def negative_vote_threshold_reached(self) -> bool: - """Check that the vote threshold has been reached.""" - return self.vote_count[False] >= self.synchronized_data.consensus_threshold - - @property - def none_vote_threshold_reached(self) -> bool: - """Check that the vote threshold has been reached.""" - return self.vote_count[None] >= self.synchronized_data.consensus_threshold - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.positive_vote_threshold_reached: - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{self.collection_key: self.serialized_collection}, - ) - return synchronized_data, self.done_event - if self.negative_vote_threshold_reached: - return self.synchronized_data, self.negative_event - if self.none_vote_threshold_reached: - return self.synchronized_data, self.none_event - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, self.no_majority_event - return None - - -class CollectDifferentUntilThresholdRound(CollectionRound, ABC): - """ - CollectDifferentUntilThresholdRound - - This class represents logic for rounds where a round needs to collect - different payloads from k of n agents. - - `done_event` is emitted when a) the required block confirmations - have been met, and b) the collection threshold (k of n) is reached. In - this case all payloads are saved under `collection_key`. - - Extended `required_block_confirmations` to allow for arrival of more - payloads. - """ - - done_event: Any - collection_key: str - required_block_confirmations: int = 0 - - @property - def collection_threshold_reached( - self, - ) -> bool: - """Check if the threshold has been reached.""" - return len(self.collection) >= self.synchronized_data.consensus_threshold - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.collection_threshold_reached: - self.block_confirmations += 1 - if ( - self.collection_threshold_reached - and self.block_confirmations > self.required_block_confirmations - ): - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{ - self.collection_key: self.serialized_collection, - }, - ) - return synchronized_data, self.done_event - - return None - - -class CollectNonEmptyUntilThresholdRound(CollectDifferentUntilThresholdRound, ABC): - """ - CollectNonEmptyUntilThresholdRound - - This class represents logic for rounds where a round needs to collect - optionally different payloads from k of n agents, where we only keep the non-empty attributes. - - `done_event` is emitted when a) the required block confirmations - have been met, b) the collection threshold (k of n) is reached, and - c) some non-empty attribute values have been collected. In this case - all payloads are saved under `collection_key`. Under `selection_key` - the non-empty attribute values are stored. - - `none_event` is emitted when a) the required block confirmations - have been met, b) the collection threshold (k of n) is reached, and - c) no non-empty attribute values have been collected. - - Attention: A `none_event` might be triggered even though some of the - remaining n-k agents might send non-empty attributes! Extended - `required_block_confirmations` can alleviate this somewhat. - """ - - none_event: Any - selection_key: Union[str, Tuple[str, ...]] - - def _get_non_empty_values(self) -> Dict[str, Tuple[Any, ...]]: - """Get the non-empty values from the payload, for all attributes.""" - non_empty_values: Dict[str, List[List[Any]]] = {} - - for sender, payload in self.collection.items(): - if sender not in non_empty_values: - non_empty_values[sender] = [ - value for value in payload.values if value is not None - ] - if len(non_empty_values[sender]) == 0: - del non_empty_values[sender] - continue - non_empty_values_ = { - sender: tuple(li) for sender, li in non_empty_values.items() - } - return non_empty_values_ - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.collection_threshold_reached: - self.block_confirmations += 1 - if ( - self.collection_threshold_reached - and self.block_confirmations > self.required_block_confirmations - ): - non_empty_values = self._get_non_empty_values() - - if isinstance(self.selection_key, tuple): - data: Dict[str, Any] = { - sender: dict(zip(self.selection_key, values)) - for sender, values in non_empty_values.items() - } - else: - data = { - self.selection_key: { - sender: values[0] for sender, values in non_empty_values.items() - }, - } - data[self.collection_key] = self.serialized_collection - - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **data, - ) - - if all([len(tu) == 0 for tu in non_empty_values]): - return self.synchronized_data, self.none_event - return synchronized_data, self.done_event - return None - - -AppState = Type[AbstractRound] -AbciAppTransitionFunction = Dict[AppState, Dict[EventType, AppState]] -EventToTimeout = Dict[EventType, float] - - -@dataclass(order=True) -class TimeoutEvent(Generic[EventType]): - """Timeout event.""" - - deadline: datetime.datetime - entry_count: int - event: EventType = field(compare=False) - cancelled: bool = field(default=False, compare=False) - - -class Timeouts(Generic[EventType]): - """Class to keep track of pending timeouts.""" - - def __init__(self) -> None: - """Initialize.""" - # The entry count serves as a tie-breaker so that two tasks with - # the same priority are returned in the order they were added - self._counter = itertools.count() - - # The timeout priority queue keeps the earliest deadline at the top. - self._heap: List[TimeoutEvent[EventType]] = [] - - # Mapping from entry id to task - self._entry_finder: Dict[int, TimeoutEvent[EventType]] = {} - - @property - def size(self) -> int: - """Get the size of the timeout queue.""" - return len(self._heap) - - def add_timeout(self, deadline: datetime.datetime, event: EventType) -> int: - """Add a timeout.""" - entry_count = next(self._counter) - timeout_event = TimeoutEvent[EventType](deadline, entry_count, event) - heapq.heappush(self._heap, timeout_event) - self._entry_finder[entry_count] = timeout_event - return entry_count - - def cancel_timeout(self, entry_count: int) -> None: - """ - Remove a timeout. - - :param entry_count: the entry id to remove. - :raises: KeyError: if the entry count is not found. - """ - if entry_count in self._entry_finder: - self._entry_finder[entry_count].cancelled = True - - def pop_earliest_cancelled_timeouts(self) -> None: - """Pop earliest cancelled timeouts.""" - if self.size == 0: - return - entry = self._heap[0] # heap peak - while entry.cancelled: - self.pop_timeout() - if self.size == 0: - break - entry = self._heap[0] - - def get_earliest_timeout(self) -> Tuple[datetime.datetime, Any]: - """Get the earliest timeout-event pair.""" - entry = self._heap[0] - return entry.deadline, entry.event - - def pop_timeout(self) -> Tuple[datetime.datetime, Any]: - """Remove and return the earliest timeout-event pair.""" - entry = heapq.heappop(self._heap) - del self._entry_finder[entry.entry_count] - return entry.deadline, entry.event - - -class _MetaAbciApp(ABCMeta): - """A metaclass that validates AbciApp's attributes.""" - - bg_round_added: bool = False - - def __new__(mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any) -> Type: # type: ignore - """Initialize the class.""" - new_cls = super().__new__(mcs, name, bases, namespace, **kwargs) - - if ABC in bases: - # abstract class, return - return new_cls - if not issubclass(new_cls, AbciApp): - # the check only applies to AbciApp subclasses - return new_cls - - if not mcs.bg_round_added: - mcs._add_pending_offences_bg_round(new_cls) - mcs.bg_round_added = True - - mcs._check_consistency(cast(Type[AbciApp], new_cls)) - - return new_cls - - @classmethod - def _check_consistency(mcs, abci_app_cls: Type["AbciApp"]) -> None: - """Check consistency of class attributes.""" - mcs._check_required_class_attributes(abci_app_cls) - mcs._check_initial_states_and_final_states(abci_app_cls) - mcs._check_consistency_outgoing_transitions_from_non_final_states(abci_app_cls) - mcs._check_db_constraints_consistency(abci_app_cls) - - @classmethod - def _check_required_class_attributes(mcs, abci_app_cls: Type["AbciApp"]) -> None: - """Check that required class attributes are set.""" - if not hasattr(abci_app_cls, "initial_round_cls"): - raise ABCIAppInternalError("'initial_round_cls' field not set") - if not hasattr(abci_app_cls, "transition_function"): - raise ABCIAppInternalError("'transition_function' field not set") - - @classmethod - def _check_initial_states_and_final_states( - mcs, - abci_app_cls: Type["AbciApp"], - ) -> None: - """ - Check that initial states and final states are consistent. - - I.e.: - - check that all the initial states are in the set of states specified - by the transition function. - - check that the initial state has outgoing transitions - - check that the initial state does not trigger timeout events. This is - because we need at least one block/timestamp to start timeouts. - - check that initial states are not final states. - - check that the set of final states is a proper subset of the set of - states. - - check that a final state does not have outgoing transitions. - - :param abci_app_cls: the AbciApp class - """ - initial_round_cls = abci_app_cls.initial_round_cls - initial_states = abci_app_cls.initial_states - transition_function = abci_app_cls.transition_function - final_states = abci_app_cls.final_states - states = abci_app_cls.get_all_rounds() - - enforce( - initial_states == set() or initial_round_cls in initial_states, - f"initial round class {initial_round_cls} is not in the set of " - f"initial states: {initial_states}", - ) - enforce( - initial_round_cls in states - and all(initial_state in states for initial_state in initial_states), - "initial states must be in the set of states", - ) - - true_initial_states = ( - initial_states if initial_states != set() else {initial_round_cls} - ) - enforce( - all( - initial_state not in final_states - for initial_state in true_initial_states - ), - "initial states cannot be final states", - ) - - unknown_final_states = set.difference(final_states, states) - enforce( - len(unknown_final_states) == 0, - f"the following final states are not in the set of states:" - f" {unknown_final_states}", - ) - - enforce( - all( - len(transition_function[final_state]) == 0 - for final_state in final_states - ), - "final states cannot have outgoing transitions", - ) - - enforce( - all( - issubclass(final_state, DegenerateRound) for final_state in final_states - ), - "final round classes must be subclasses of the DegenerateRound class", - ) - - @classmethod - def _check_db_constraints_consistency(mcs, abci_app_cls: Type["AbciApp"]) -> None: - """Check that the pre and post conditions on the db are consistent with the initial and final states.""" - expected = abci_app_cls.initial_states - actual = abci_app_cls.db_pre_conditions.keys() - is_pre_conditions_set = len(actual) != 0 - invalid_initial_states = ( - set.difference(expected, actual) if is_pre_conditions_set else set() - ) - enforce( - len(invalid_initial_states) == 0, - f"db pre conditions contain invalid initial states: {invalid_initial_states}", - ) - expected = abci_app_cls.final_states - actual = abci_app_cls.db_post_conditions.keys() - is_post_conditions_set = len(actual) != 0 - invalid_final_states = ( - set.difference(expected, actual) if is_post_conditions_set else set() - ) - enforce( - len(invalid_final_states) == 0, - f"db post conditions contain invalid final states: {invalid_final_states}", - ) - all_pre_conditions = { - value - for values in abci_app_cls.db_pre_conditions.values() - for value in values - } - all_post_conditions = { - value - for values in abci_app_cls.db_post_conditions.values() - for value in values - } - enforce( - len(all_pre_conditions.intersection(all_post_conditions)) == 0, - "db pre and post conditions intersect", - ) - intersection = abci_app_cls.default_db_preconditions.intersection( - all_pre_conditions - ) - enforce( - len(intersection) == 0, - f"db pre conditions contain value that is a default pre condition: {intersection}", - ) - intersection = abci_app_cls.default_db_preconditions.intersection( - all_post_conditions - ) - enforce( - len(intersection) == 0, - f"db post conditions contain value that is a default post condition: {intersection}", - ) - - @classmethod - def _check_consistency_outgoing_transitions_from_non_final_states( - mcs, abci_app_cls: Type["AbciApp"] - ) -> None: - """ - Check consistency of outgoing transitions from non-final states. - - In particular, check that all non-final states have: - - at least one non-timeout transition. - - at most one timeout transition - - :param abci_app_cls: the AbciApp class - """ - states = abci_app_cls.get_all_rounds() - event_to_timeout = abci_app_cls.event_to_timeout - - non_final_states = states.difference(abci_app_cls.final_states) - timeout_events = set(event_to_timeout.keys()) - for non_final_state in non_final_states: - outgoing_transitions = abci_app_cls.transition_function[non_final_state] - - outgoing_events = set(outgoing_transitions.keys()) - outgoing_timeout_events = set.intersection(outgoing_events, timeout_events) - outgoing_nontimeout_events = set.difference(outgoing_events, timeout_events) - - enforce( - len(outgoing_timeout_events) < 2, - f"non-final state {non_final_state} cannot have more than one " - f"outgoing timeout event, got: " - f"{', '.join(map(str, outgoing_timeout_events))}", - ) - enforce( - len(outgoing_nontimeout_events) > 0, - f"non-final state {non_final_state} must have at least one " - f"non-timeout transition", - ) - - @classmethod - def _add_pending_offences_bg_round(cls, abci_app_cls: Type["AbciApp"]) -> None: - """Add the pending offences synchronization background round.""" - config: BackgroundAppConfig = BackgroundAppConfig(PendingOffencesRound) - abci_app_cls.add_background_app(config) - - -class BackgroundAppType(Enum): - """ - The type of a background app. - - Please note that the values correspond to the priority in which the background apps should be processed - when updating rounds. - """ - - TERMINATING = 0 - EVER_RUNNING = 1 - NORMAL = 2 - INCORRECT = 3 - - @staticmethod - def correct_types() -> Set[str]: - """Return the correct types only.""" - return set(BackgroundAppType.__members__) - {BackgroundAppType.INCORRECT.name} - - -@dataclass(frozen=True) -class BackgroundAppConfig(Generic[EventType]): - """ - Necessary configuration for a background app. - - For a deeper understanding of the various types of background apps and how the config influences - the generated background app's type, please refer to the `BackgroundApp` class. - The `specify_type` method provides further insight on the subject matter. - """ - - # the class of the background round - round_cls: AppState - # the abci app of the background round - # the abci app must specify a valid transition function if the round is not of an ever-running type - abci_app: Optional[Type["AbciApp"]] = None - # the start event of the background round - # if no event or transition function is specified, then the round is running in the background forever - start_event: Optional[EventType] = None - # the end event of the background round - # if not specified, then the round is terminating the abci app - end_event: Optional[EventType] = None - - -class BackgroundApp(Generic[EventType]): - """A background app.""" - - def __init__( - self, - config: BackgroundAppConfig, - ) -> None: - """Initialize the BackgroundApp.""" - given_args = locals() - - self.config = config - self.round_cls: AppState = config.round_cls - self.transition_function: Optional[AbciAppTransitionFunction] = ( - config.abci_app.transition_function if config.abci_app is not None else None - ) - self.start_event: Optional[EventType] = config.start_event - self.end_event: Optional[EventType] = config.end_event - - self.type = self.specify_type() - if self.type == BackgroundAppType.INCORRECT: # pragma: nocover - raise ValueError( - f"Background app has not been initialized correctly with {given_args}. " - f"Cannot match with any of the possible background apps' types: {BackgroundAppType.correct_types()}" - ) - _logger.debug( - f"Created background app of type '{self.type}' using {given_args}." - ) - self._background_round: Optional[AbstractRound] = None - - def __eq__(self, other: Any) -> bool: # pragma: no cover - """Custom equality comparing operator.""" - if not isinstance(other, BackgroundApp): - return False - - return self.config == other.config - - def __hash__(self) -> int: - """Custom hashing operator""" - return hash(self.config) - - def specify_type(self) -> BackgroundAppType: - """Specify the type of the background app.""" - if ( - self.start_event is None - and self.end_event is None - and self.transition_function is None - ): - self.transition_function = {} - return BackgroundAppType.EVER_RUNNING - if ( - self.start_event is not None - and self.end_event is None - and self.transition_function is not None - ): - return BackgroundAppType.TERMINATING - if ( - self.start_event is not None - and self.end_event is not None - and self.transition_function is not None - ): - return BackgroundAppType.NORMAL - return BackgroundAppType.INCORRECT # pragma: nocover - - def setup( - self, initial_synchronized_data: BaseSynchronizedData, context: SkillContext - ) -> None: - """Set up the background round.""" - round_cls = cast(Type[AbstractRound], self.round_cls) - self._background_round = round_cls( - initial_synchronized_data, - context, - ) - - @property - def background_round(self) -> AbstractRound: - """Get the background round.""" - if self._background_round is None: # pragma: nocover - raise ValueError(f"Background round with class `{self.round_cls}` not set!") - return self._background_round - - def process_transaction(self, transaction: Transaction, dry: bool = False) -> bool: - """Process a transaction.""" - - payload_class = type(transaction.payload) - bg_payload_class = cast(AppState, self.round_cls).payload_class - if payload_class is bg_payload_class: - processor = ( - self.background_round.check_transaction - if dry - else self.background_round.process_transaction - ) - processor(transaction) - return True - return False - - -@dataclass -class TransitionBackup: - """Holds transition related information as a backup in case we want to transition back from a background app.""" - - round: Optional[AbstractRound] = None - round_cls: Optional[AppState] = None - transition_function: Optional[AbciAppTransitionFunction] = None - - -class AbciApp( - Generic[EventType], ABC, metaclass=_MetaAbciApp -): # pylint: disable=too-many-instance-attributes - """ - Base class for ABCI apps. - - Concrete classes of this class implement the ABCI App. - """ - - initial_round_cls: AppState - initial_states: Set[AppState] = set() - transition_function: AbciAppTransitionFunction - final_states: Set[AppState] = set() - event_to_timeout: EventToTimeout = {} - cross_period_persisted_keys: FrozenSet[str] = frozenset() - background_apps: Set[BackgroundApp] = set() - default_db_preconditions: Set[str] = BaseSynchronizedData.default_db_keys - db_pre_conditions: Dict[AppState, Set[str]] = {} - db_post_conditions: Dict[AppState, Set[str]] = {} - _is_abstract: bool = True - - def __init__( - self, - synchronized_data: BaseSynchronizedData, - logger: logging.Logger, - context: SkillContext, - ): - """Initialize the AbciApp.""" - - synchronized_data_class = self.initial_round_cls.synchronized_data_class - synchronized_data = synchronized_data_class(db=synchronized_data.db) - - self._initial_synchronized_data = synchronized_data - self.logger = logger - self.context = context - self._current_round_cls: Optional[AppState] = None - self._current_round: Optional[AbstractRound] = None - self._last_round: Optional[AbstractRound] = None - self._previous_rounds: List[AbstractRound] = [] - self._current_round_height: int = 0 - self._round_results: List[BaseSynchronizedData] = [] - self._last_timestamp: Optional[datetime.datetime] = None - self._current_timeout_entries: List[int] = [] - self._timeouts = Timeouts[EventType]() - self._transition_backup = TransitionBackup() - self._switched = False - - @classmethod - def is_abstract(cls) -> bool: - """Return if the abci app is abstract.""" - return cls._is_abstract - - @classmethod - def add_background_app( - cls, - config: BackgroundAppConfig, - ) -> Type["AbciApp"]: - """ - Sets the background related class variables. - - For a deeper understanding of the various types of background apps and how the inputs of this method influence - the generated background app's type, please refer to the `BackgroundApp` class. - The `specify_type` method provides further insight on the subject matter. - - :param config: the background app's configuration. - :return: the `AbciApp` with the new background app contained in the `background_apps` set. - """ - background_app: BackgroundApp = BackgroundApp(config) - cls.background_apps.add(background_app) - cross_period_keys = ( - config.abci_app.cross_period_persisted_keys - if config.abci_app is not None - else frozenset() - ) - cls.cross_period_persisted_keys = cls.cross_period_persisted_keys.union( - cross_period_keys - ) - return cls - - @property - def synchronized_data(self) -> BaseSynchronizedData: - """Return the current synchronized data.""" - latest_result = self.latest_result or self._initial_synchronized_data - if self._current_round_cls is None: - return latest_result - synchronized_data_class = self._current_round_cls.synchronized_data_class - result = ( - synchronized_data_class(db=latest_result.db) - if isclass(synchronized_data_class) - and issubclass(synchronized_data_class, BaseSynchronizedData) - else latest_result - ) - return result - - @classmethod - def get_all_rounds(cls) -> Set[AppState]: - """Get all the round states.""" - return set(cls.transition_function) - - @classmethod - def get_all_events(cls) -> Set[EventType]: - """Get all the events.""" - events: Set[EventType] = set() - for _, transitions in cls.transition_function.items(): - events.update(transitions.keys()) - return events - - @staticmethod - def _get_rounds_from_transition_function( - transition_function: Optional[AbciAppTransitionFunction], - ) -> Set[AppState]: - """Get rounds from a transition function.""" - if transition_function is None: - return set() - result: Set[AppState] = set() - for start, transitions in transition_function.items(): - result.add(start) - result.update(transitions.values()) - return result - - @classmethod - def get_all_round_classes( - cls, - bg_round_cls: Set[Type[AbstractRound]], - include_background_rounds: bool = False, - ) -> Set[AppState]: - """Get all round classes.""" - full_fn = deepcopy(cls.transition_function) - - if include_background_rounds: - for app in cls.background_apps: - if ( - app.type != BackgroundAppType.EVER_RUNNING - and app.round_cls in bg_round_cls - ): - transition_fn = cast( - AbciAppTransitionFunction, app.transition_function - ) - full_fn.update(transition_fn) - - return cls._get_rounds_from_transition_function(full_fn) - - @property - def bg_apps_prioritized(self) -> Tuple[List[BackgroundApp], ...]: - """Get the background apps grouped and prioritized by their types.""" - n_correct_types = len(BackgroundAppType.correct_types()) - grouped_prioritized: Tuple[List, ...] = ([],) * n_correct_types - for app in self.background_apps: - # reminder: the values correspond to the priority of the background apps - for priority in range(n_correct_types): - if app.type == BackgroundAppType(priority): - grouped_prioritized[priority].append(app) - - return grouped_prioritized - - @property - def last_timestamp(self) -> datetime.datetime: - """Get last timestamp.""" - if self._last_timestamp is None: - raise ABCIAppInternalError("last timestamp is None") - return self._last_timestamp - - def _setup_background(self) -> None: - """Set up the background rounds.""" - for app in self.background_apps: - app.setup(self._initial_synchronized_data, self.context) - - def _get_synced_value( - self, - db_key: str, - sync_classes: Set[Type[BaseSynchronizedData]], - default: Any = None, - ) -> Any: - """Get the value of a specific database key using the synchronized data.""" - for cls in sync_classes: - # try to find the value using the synchronized data as suggested in #2131 - synced_data = cls(db=self.synchronized_data.db) - try: - res = getattr(synced_data, db_key) - except AttributeError: - # if the property does not exist in the db try the next synced data class - continue - except ValueError: - # if the property raised because of using `get_strict` and the key not being present in the db - break - - # if there is a property with the same name as the key in the db, return the result, normalized - return AbciAppDB.normalize(res) - - # as a last resort, try to get the value from the db - return self.synchronized_data.db.get(db_key, default) - - def setup(self) -> None: - """Set up the behaviour.""" - self.schedule_round(self.initial_round_cls) - self._setup_background() - # iterate through all the rounds and get all the unique synced data classes - sync_classes = { - _round.synchronized_data_class for _round in self.transition_function - } - # Add `BaseSynchronizedData` in case it does not exist (TODO: investigate and remove as it might always exist) - sync_classes.add(BaseSynchronizedData) - # set the cross-period persisted keys; avoid raising when the first period ends without a key in the db - update = { - db_key: self._get_synced_value(db_key, sync_classes) - for db_key in self.cross_period_persisted_keys - } - self.synchronized_data.db.update(**update) - - def _log_start(self) -> None: - """Log the entering in the round.""" - self.logger.info( - f"Entered in the '{self.current_round.round_id}' round for period " - f"{self.synchronized_data.period_count}" - ) - - def _log_end(self, event: EventType) -> None: - """Log the exiting from the round.""" - self.logger.info( - f"'{self.current_round.round_id}' round is done with event: {event}" - ) - - def _extend_previous_rounds_with_current_round(self) -> None: - self._previous_rounds.append(self.current_round) - self._current_round_height += 1 - - def schedule_round(self, round_cls: AppState) -> None: - """ - Schedule a round class. - - this means: - - cancel timeout events belonging to the current round; - - instantiate the new round class and set it as current round; - - create new timeout events and schedule them according to the latest - timestamp. - - :param round_cls: the class of the new round. - """ - self.logger.debug("scheduling new round: %s", round_cls) - for entry_id in self._current_timeout_entries: - self._timeouts.cancel_timeout(entry_id) - - self._current_timeout_entries = [] - next_events = list(self.transition_function.get(round_cls, {}).keys()) - for event in next_events: - timeout = self.event_to_timeout.get(event, None) - # if first round, last_timestamp is None. - # This means we do not schedule timeout events, - # but we allow timeout events from the initial state - # in case of concatenation. - if timeout is not None and self._last_timestamp is not None: - # last timestamp can be in the past relative to last seen block - # time if we're scheduling from within update_time - deadline = self.last_timestamp + datetime.timedelta(0, timeout) - entry_id = self._timeouts.add_timeout(deadline, event) - self.logger.debug( - "scheduling timeout of %s seconds for event %s with deadline %s", - timeout, - event, - deadline, - ) - self._current_timeout_entries.append(entry_id) - - self._last_round = self._current_round - self._current_round_cls = round_cls - self._current_round = round_cls( - self.synchronized_data, - self.context, - ( - self._last_round.payload_class - if self._last_round is not None - and self._last_round.payload_class - != self._current_round_cls.payload_class - # when transitioning to a round with the same payload type we set None - # as otherwise it will allow no tx to be submitted - else None - ), - ) - self._log_start() - self.synchronized_data.db.increment_round_count() # ROUND_COUNT_DEFAULT is -1 - - @property - def current_round(self) -> AbstractRound: - """Get the current round.""" - if self._current_round is None: - raise ValueError("current_round not set!") - return self._current_round - - @property - def current_round_id(self) -> Optional[str]: - """Get the current round id.""" - return self._current_round.round_id if self._current_round else None - - @property - def current_round_height(self) -> int: - """Get the current round height.""" - return self._current_round_height - - @property - def last_round_id(self) -> Optional[str]: - """Get the last round id.""" - return self._last_round.round_id if self._last_round else None - - @property - def is_finished(self) -> bool: - """Check whether the AbciApp execution has finished.""" - return self._current_round is None - - @property - def latest_result(self) -> Optional[BaseSynchronizedData]: - """Get the latest result of the round.""" - return None if len(self._round_results) == 0 else self._round_results[-1] - - def cleanup_timeouts(self) -> None: - """ - Remove all timeouts. - - Note that this is method is meant to be used only when performing recovery. - Calling it in normal execution will result in unexpected behaviour. - """ - self._timeouts = Timeouts[EventType]() - self._current_timeout_entries = [] - self._last_timestamp = None - - def check_transaction(self, transaction: Transaction) -> None: - """Check a transaction.""" - - self.process_transaction(transaction, dry=True) - - def process_transaction(self, transaction: Transaction, dry: bool = False) -> None: - """ - Process a transaction. - - The background rounds run concurrently with other (normal) rounds. - First we check if the transaction is meant for a background round, - if not we forward it to the current round object. - - :param transaction: the transaction. - :param dry: whether the transaction should only be checked and not processed. - """ - - for app in self.background_apps: - processed = app.process_transaction(transaction, dry) - if processed: - return - - processor = ( - self.current_round.check_transaction - if dry - else self.current_round.process_transaction - ) - processor(transaction) - - def _resolve_bg_transition( - self, app: BackgroundApp, event: EventType - ) -> Tuple[bool, Optional[AppState]]: - """ - Resolve a background app's transition. - - First check whether the event is a special start event. - If that's the case, proceed with the corresponding background app's transition function, - regardless of what the current round is. - - :param app: the background app instance. - :param event: the event for the transition. - :return: the new app state. - """ - - if ( - app.type in (BackgroundAppType.NORMAL, BackgroundAppType.TERMINATING) - and event == app.start_event - ): - app.transition_function = cast( - AbciAppTransitionFunction, app.transition_function - ) - app.round_cls = cast(AppState, app.round_cls) - next_round_cls = app.transition_function[app.round_cls].get(event, None) - if next_round_cls is None: # pragma: nocover - return True, None - - # we backup the current round so we can return back to normal, in case the end event is received later - self._transition_backup.round = self._current_round - self._transition_backup.round_cls = self._current_round_cls - # we switch the current transition function, with the background app's transition function - self._transition_backup.transition_function = deepcopy( - self.transition_function - ) - self.transition_function = app.transition_function - self.logger.info( - f"The {event} event was produced, transitioning to " - f"`{next_round_cls.auto_round_id()}`." - ) - return True, next_round_cls - - return False, None - - def _adjust_transition_fn(self, event: EventType) -> None: - """ - Adjust the transition function if necessary. - - Check whether the event is a special end event. - If that's the case, reset the transition function back to normal. - This method is meant to be called after resolving the next round transition, given an event. - - :param event: the emitted event. - """ - if self._transition_backup.transition_function is None: - return - - for app in self.background_apps: - if app.type == BackgroundAppType.NORMAL and event == app.end_event: - self._current_round = self._transition_backup.round - self._transition_backup.round = None - self._current_round_cls = self._transition_backup.round_cls - self._transition_backup.round_cls = None - backup_fn = cast( - AbciAppTransitionFunction, - self._transition_backup.transition_function, - ) - self.transition_function = deepcopy(backup_fn) - self._transition_backup.transition_function = None - self._switched = True - self.logger.info( - f"The {app.end_event} event was produced. Switching back to the normal FSM." - ) - - def _resolve_transition(self, event: EventType) -> Optional[Type[AbstractRound]]: - """Resolve the transitioning based on the given event.""" - for app in self.background_apps: - matched, next_round_cls = self._resolve_bg_transition(app, event) - if matched: - return next_round_cls - - self._adjust_transition_fn(event) - - current_round_cls = cast(AppState, self._current_round_cls) - next_round_cls = self.transition_function[current_round_cls].get(event, None) - if next_round_cls is None: - return None - - return next_round_cls - - def process_event( - self, event: EventType, result: Optional[BaseSynchronizedData] = None - ) -> None: - """Process a round event.""" - if self._current_round_cls is None: - self.logger.warning( - f"Cannot process event '{event}' as current state is not set" - ) - return - - next_round_cls = self._resolve_transition(event) - self._extend_previous_rounds_with_current_round() - # if there is no result, we duplicate the state since the round was preemptively ended - result = self.current_round.synchronized_data if result is None else result - self._round_results.append(result) - - self._log_end(event) - if next_round_cls is not None: - self.schedule_round(next_round_cls) - return - - if self._switched: - self._switched = False - return - - self.logger.warning("AbciApp has reached a dead end.") - self._current_round_cls = None - self._current_round = None - - def update_time(self, timestamp: datetime.datetime) -> None: - """ - Observe timestamp from last block. - - :param timestamp: the latest block's timestamp. - """ - self.logger.debug("arrived block with timestamp: %s", timestamp) - self.logger.debug("current AbciApp time: %s", self._last_timestamp) - self._timeouts.pop_earliest_cancelled_timeouts() - - if self._timeouts.size == 0: - # if no pending timeouts, then it is safe to - # move forward the last known timestamp to the - # latest block's timestamp. - self.logger.debug("no pending timeout, move time forward") - self._last_timestamp = timestamp - return - - earliest_deadline, _ = self._timeouts.get_earliest_timeout() - while earliest_deadline <= timestamp: - # the earliest deadline is expired. Pop it from the - # priority queue and process the timeout event. - expired_deadline, timeout_event = self._timeouts.pop_timeout() - self.logger.warning( - "expired deadline %s with event %s at AbciApp time %s", - expired_deadline, - timeout_event, - timestamp, - ) - - # the last timestamp now becomes the expired deadline - # clearly, it is earlier than the current highest known - # timestamp that comes from the consensus engine. - # However, we need it to correctly simulate the timeouts - # of the next rounds. (for now we set it to timestamp to explore - # the impact) - self._last_timestamp = timestamp - self.logger.warning( - "current AbciApp time after expired deadline: %s", self.last_timestamp - ) - - self.process_event(timeout_event) - - self._timeouts.pop_earliest_cancelled_timeouts() - if self._timeouts.size == 0: - break - earliest_deadline, _ = self._timeouts.get_earliest_timeout() - - # at this point, there is no timeout event left to be triggered, - # so it is safe to move forward the last known timestamp to the - # new block's timestamp - self._last_timestamp = timestamp - self.logger.debug("final AbciApp time: %s", self._last_timestamp) - - def cleanup( - self, - cleanup_history_depth: int, - cleanup_history_depth_current: Optional[int] = None, - ) -> None: - """Clear data.""" - if len(self._round_results) != len(self._previous_rounds): - raise ABCIAppInternalError("Inconsistent round lengths") # pragma: nocover - # we need at least the last round result, and for symmetry we impose the same condition - # on previous rounds and state.db - cleanup_history_depth = max(cleanup_history_depth, MIN_HISTORY_DEPTH) - self._previous_rounds = self._previous_rounds[-cleanup_history_depth:] - self._round_results = self._round_results[-cleanup_history_depth:] - self.synchronized_data.db.cleanup( - cleanup_history_depth, cleanup_history_depth_current - ) - - def cleanup_current_histories(self, cleanup_history_depth_current: int) -> None: - """Reset the parameter histories for the current entry (period), keeping only the latest values for each parameter.""" - self.synchronized_data.db.cleanup_current_histories( - cleanup_history_depth_current - ) - - -class OffenseType(Enum): - """ - The types of offenses. - - The values of the enum represent the seriousness of the offence. - Offense types with values >1000 are considered serious. - See also `is_light_offence` and `is_serious_offence` functions. - """ - - NO_OFFENCE = -2 - CUSTOM = -1 - VALIDATOR_DOWNTIME = 0 - INVALID_PAYLOAD = 1 - BLACKLISTED = 2 - SUSPECTED = 3 - UNKNOWN = SERIOUS_OFFENCE_ENUM_MIN - DOUBLE_SIGNING = SERIOUS_OFFENCE_ENUM_MIN + 1 - LIGHT_CLIENT_ATTACK = SERIOUS_OFFENCE_ENUM_MIN + 2 - - -def is_light_offence(offence_type: OffenseType) -> bool: - """Check if an offence type is light.""" - return 0 <= offence_type.value < SERIOUS_OFFENCE_ENUM_MIN - - -def is_serious_offence(offence_type: OffenseType) -> bool: - """Check if an offence type is serious.""" - return offence_type.value >= SERIOUS_OFFENCE_ENUM_MIN - - -def light_offences() -> Iterator[OffenseType]: - """Get the light offences.""" - return filter(is_light_offence, OffenseType) - - -def serious_offences() -> Iterator[OffenseType]: - """Get the serious offences.""" - return filter(is_serious_offence, OffenseType) - - -class AvailabilityWindow: - """ - A cyclic array with a maximum length that holds boolean values. - - When an element is added to the array and the maximum length has been reached, - the oldest element is removed. Two attributes `num_positive` and `num_negative` - reflect the number of positive and negative elements in the AvailabilityWindow, - they are updated every time a new element is added. - """ - - def __init__(self, max_length: int) -> None: - """ - Initializes the `AvailabilityWindow` instance. - - :param max_length: the maximum length of the cyclic array. - """ - if max_length < 1: - raise ValueError( - f"An `AvailabilityWindow` with a `max_length` {max_length} < 1 is not valid." - ) - - self._max_length = max_length - self._window: Deque[bool] = deque(maxlen=max_length) - self._num_positive = 0 - self._num_negative = 0 - - def __eq__(self, other: Any) -> bool: - """Compare `AvailabilityWindow` objects.""" - if isinstance(other, AvailabilityWindow): - return self.to_dict() == other.to_dict() - return False - - def has_bad_availability_rate(self, threshold: float = 0.95) -> bool: - """Whether the agent on which the window belongs to has a bad availability rate or not.""" - return self._num_positive >= ceil(self._max_length * threshold) - - def _update_counters(self, positive: bool, removal: bool = False) -> None: - """Updates the `num_positive` and `num_negative` counters.""" - update_amount = -1 if removal else 1 - - if positive: - if self._num_positive == 0 and update_amount == -1: # pragma: no cover - return - self._num_positive += update_amount - else: - if self._num_negative == 0 and update_amount == -1: # pragma: no cover - return - self._num_negative += update_amount - - def add(self, value: bool) -> None: - """ - Adds a new boolean value to the cyclic array. - - If the maximum length has been reached, the oldest element is removed. - - :param value: The boolean value to add to the cyclic array. - """ - if len(self._window) == self._max_length and self._max_length > 0: - # we have filled the window, we need to pop the oldest element - # and update the score accordingly - oldest_value = self._window.popleft() - self._update_counters(oldest_value, removal=True) - - self._window.append(value) - self._update_counters(value) - - def to_dict(self) -> Dict[str, int]: - """Returns a dictionary representation of the `AvailabilityWindow` instance.""" - return { - "max_length": self._max_length, - # Please note that the value cannot be represented if the max length of the availability window is > 14_285 - "array": ( - int("".join(str(int(flag)) for flag in self._window), base=2) - if len(self._window) - else 0 - ), - "num_positive": self._num_positive, - "num_negative": self._num_negative, - } - - @staticmethod - def _validate_key( - data: Dict[str, int], key: str, validator: Callable[[int], bool] - ) -> None: - """Validate the given key in the data.""" - value = data.get(key, None) - if value is None: - raise ValueError(f"Missing required key: {key}.") - - if not isinstance(value, int): - raise ValueError(f"{key} must be of type int.") - - if not validator(value): - raise ValueError(f"{key} has invalid value {value}.") - - @staticmethod - def _validate(data: Dict[str, int]) -> None: - """Check if the input can be properly mapped to the class attributes.""" - if not isinstance(data, dict): - raise TypeError(f"Expected dict, got {type(data)}") - - attribute_to_validator = { - "max_length": lambda x: x > 0, - "array": lambda x: 0 <= x < 2 ** data["max_length"], - "num_positive": lambda x: x >= 0, - "num_negative": lambda x: x >= 0, - } - - errors = [] - for attribute, validator in attribute_to_validator.items(): - try: - AvailabilityWindow._validate_key(data, attribute, validator) - except ValueError as e: - errors.append(str(e)) - - if errors: - raise ValueError("Invalid input:\n" + "\n".join(errors)) - - @classmethod - def from_dict(cls, data: Dict[str, int]) -> "AvailabilityWindow": - """Initializes an `AvailabilityWindow` instance from a dictionary.""" - cls._validate(data) - - # convert the serialized array to a binary string - binary_number = bin(data["array"])[2:] - # convert each character in the binary string to a flag - flags = (bool(int(digit)) for digit in binary_number) - - instance = cls(max_length=data["max_length"]) - instance._window.extend(flags) - instance._num_positive = data["num_positive"] - instance._num_negative = data["num_negative"] - return instance - - -@dataclass -class OffenceStatus: - """A class that holds information about offence status for an agent.""" - - validator_downtime: AvailabilityWindow = field( - default_factory=lambda: AvailabilityWindow(NUMBER_OF_BLOCKS_TRACKED) - ) - invalid_payload: AvailabilityWindow = field( - default_factory=lambda: AvailabilityWindow(NUMBER_OF_ROUNDS_TRACKED) - ) - blacklisted: AvailabilityWindow = field( - default_factory=lambda: AvailabilityWindow(NUMBER_OF_ROUNDS_TRACKED) - ) - suspected: AvailabilityWindow = field( - default_factory=lambda: AvailabilityWindow(NUMBER_OF_ROUNDS_TRACKED) - ) - num_unknown_offenses: int = 0 - num_double_signed: int = 0 - num_light_client_attack: int = 0 - custom_offences_amount: int = 0 - - def slash_amount(self, light_unit_amount: int, serious_unit_amount: int) -> int: - """Get the slash amount of the current status.""" - offence_types = [] - - if self.validator_downtime.has_bad_availability_rate(): - offence_types.append(OffenseType.VALIDATOR_DOWNTIME) - if self.invalid_payload.has_bad_availability_rate(): - offence_types.append(OffenseType.INVALID_PAYLOAD) - if self.blacklisted.has_bad_availability_rate(): - offence_types.append(OffenseType.BLACKLISTED) - if self.suspected.has_bad_availability_rate(): - offence_types.append(OffenseType.SUSPECTED) - offence_types.extend([OffenseType.UNKNOWN] * self.num_unknown_offenses) - offence_types.extend([OffenseType.UNKNOWN] * self.num_double_signed) - offence_types.extend([OffenseType.UNKNOWN] * self.num_light_client_attack) - - light_multiplier = 0 - serious_multiplier = 0 - for offence_type in offence_types: - light_multiplier += bool(is_light_offence(offence_type)) - serious_multiplier += bool(is_serious_offence(offence_type)) - - return ( - light_multiplier * light_unit_amount - + serious_multiplier * serious_unit_amount - + self.custom_offences_amount - ) - - -class OffenseStatusEncoder(json.JSONEncoder): - """A custom JSON encoder for the offence status dictionary.""" - - def default(self, o: Any) -> Any: - """The default JSON encoder.""" - if is_dataclass(o): - return asdict(o) - if isinstance(o, AvailabilityWindow): - return o.to_dict() - return super().default(o) - - -class OffenseStatusDecoder(json.JSONDecoder): - """A custom JSON decoder for the offence status dictionary.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the custom JSON decoder.""" - super().__init__(object_hook=self.hook, *args, **kwargs) - - @staticmethod - def hook( - data: Dict[str, Any] - ) -> Union[AvailabilityWindow, OffenceStatus, Dict[str, OffenceStatus]]: - """Perform the custom decoding.""" - # if this is an `AvailabilityWindow` - window_attributes = sorted(AvailabilityWindow(1).to_dict().keys()) - if window_attributes == sorted(data.keys()): - return AvailabilityWindow.from_dict(data) - - # if this is an `OffenceStatus` - status_attributes = ( - OffenceStatus.__annotations__.keys() # pylint: disable=no-member - ) - if sorted(status_attributes) == sorted(data.keys()): - return OffenceStatus(**data) - - return data - - -@dataclass(frozen=True, eq=True) -class PendingOffense: - """A dataclass to represent offences that need to be addressed.""" - - accused_agent_address: str - round_count: int - offense_type: OffenseType - last_transition_timestamp: float - time_to_live: float - # only takes effect if the `OffenseType` is of type `CUSTOM`, otherwise it is ignored - custom_amount: int = 0 - - def __post_init__(self) -> None: - """Post initialization for offence type conversion in case it is given as an `int`.""" - if isinstance(self.offense_type, int): - super().__setattr__("offense_type", OffenseType(self.offense_type)) - - -class SlashingNotConfiguredError(Exception): - """Custom exception raised when slashing configuration is requested but is not available.""" - - -DEFAULT_PENDING_OFFENCE_TTL = 2 * 60 * 60 # 1 hour - - -class RoundSequence: # pylint: disable=too-many-instance-attributes - """ - This class represents a sequence of rounds - - It is a generic class that keeps track of the current round - of the consensus period. It receives 'deliver_tx' requests - from the ABCI handlers and forwards them to the current - active round instance, which implements the ABCI app logic. - It also schedules the next round (if any) whenever a round terminates. - """ - - class _BlockConstructionState(Enum): - """ - Phases of an ABCI-based block construction. - - WAITING_FOR_BEGIN_BLOCK: the app is ready to accept - "begin_block" requests from the consensus engine node. - Then, it transitions into the 'WAITING_FOR_DELIVER_TX' phase. - WAITING_FOR_DELIVER_TX: the app is building the block - by accepting "deliver_tx" requests, and waits - until the "end_block" request. - Then, it transitions into the 'WAITING_FOR_COMMIT' phase. - WAITING_FOR_COMMIT: the app finished the construction - of the block, but it is waiting for the "commit" - request from the consensus engine node. - Then, it transitions into the 'WAITING_FOR_BEGIN_BLOCK' phase. - """ - - WAITING_FOR_BEGIN_BLOCK = "waiting_for_begin_block" - WAITING_FOR_DELIVER_TX = "waiting_for_deliver_tx" - WAITING_FOR_COMMIT = "waiting_for_commit" - - def __init__(self, context: SkillContext, abci_app_cls: Type[AbciApp]): - """Initialize the round.""" - self._blockchain = Blockchain() - self._syncing_up = True - self._context = context - self._block_construction_phase = ( - RoundSequence._BlockConstructionState.WAITING_FOR_BEGIN_BLOCK - ) - - self._block_builder = BlockBuilder() - self._abci_app_cls = abci_app_cls - self._abci_app: Optional[AbciApp] = None - self._last_round_transition_timestamp: Optional[datetime.datetime] = None - self._last_round_transition_height = 0 - self._last_round_transition_root_hash = b"" - self._last_round_transition_tm_height: Optional[int] = None - self._tm_height: Optional[int] = None - self._block_stall_deadline: Optional[datetime.datetime] = None - self._terminating_round_called: bool = False - # a mapping of the validators' addresses to their agent addresses - # we create a mapping to avoid calculating the agent address from the validator address every time we need it - # since this is an operation that will be performed every time we want to create an offence - self._validator_to_agent: Dict[str, str] = {} - # a mapping of the agents' addresses to their offence status - self._offence_status: Dict[str, OffenceStatus] = {} - self._slashing_enabled = False - self.pending_offences: Set[PendingOffense] = set() - - def enable_slashing(self) -> None: - """Enable slashing.""" - self._slashing_enabled = True - - @property - def validator_to_agent(self) -> Dict[str, str]: - """Get the mapping of the validators' addresses to their agent addresses.""" - if self._validator_to_agent: - return self._validator_to_agent - raise SlashingNotConfiguredError( - "The mapping of the validators' addresses to their agent addresses has not been set." - ) - - @validator_to_agent.setter - def validator_to_agent(self, validator_to_agent: Dict[str, str]) -> None: - """Set the mapping of the validators' addresses to their agent addresses.""" - if self._validator_to_agent: - raise ValueError( - "The mapping of the validators' addresses to their agent addresses can only be set once. " - f"Attempted to set with {validator_to_agent} but it has content already: {self._validator_to_agent}." - ) - self._validator_to_agent = validator_to_agent - - @property - def offence_status(self) -> Dict[str, OffenceStatus]: - """Get the mapping of the agents' addresses to their offence status.""" - if self._offence_status: - return self._offence_status - raise SlashingNotConfiguredError( # pragma: nocover - "The mapping of the agents' addresses to their offence status has not been set." - ) - - @offence_status.setter - def offence_status(self, offence_status: Dict[str, OffenceStatus]) -> None: - """Set the mapping of the agents' addresses to their offence status.""" - self.abci_app.logger.debug(f"Setting offence status to: {offence_status}") - self._offence_status = offence_status - self.store_offence_status() - - def add_pending_offence(self, pending_offence: PendingOffense) -> None: - """ - Add a pending offence to the set of pending offences. - - Pending offences are offences that have been detected, but not yet agreed upon by the consensus. - A pending offence is removed from the set of pending offences and added to the OffenceStatus of a validator - when the majority of the agents agree on it. - - :param pending_offence: the pending offence to add - :return: None - """ - self.pending_offences.add(pending_offence) - - def sync_db_and_slashing(self, serialized_db_state: str) -> None: - """Sync the database and the slashing configuration.""" - self.abci_app.synchronized_data.db.sync(serialized_db_state) - offence_status = self.latest_synchronized_data.slashing_config - if offence_status: - # deserialize the offence status and load it to memory - self.offence_status = json.loads( - offence_status, - cls=OffenseStatusDecoder, - ) - - def serialized_offence_status(self) -> str: - """Serialize the offence status.""" - return json.dumps(self.offence_status, cls=OffenseStatusEncoder, sort_keys=True) - - def store_offence_status(self) -> None: - """Store the serialized offence status.""" - if not self._slashing_enabled: - # if slashing is not enabled, we do not update anything - return - encoded_status = self.serialized_offence_status() - self.latest_synchronized_data.slashing_config = encoded_status - self.abci_app.logger.debug(f"Updated db with: {encoded_status}") - self.abci_app.logger.debug(f"App hash now is: {self.root_hash.hex()}") - - def get_agent_address(self, validator: Validator) -> str: - """Get corresponding agent address from a `Validator` instance.""" - validator_address = validator.address.hex().upper() - - try: - return self.validator_to_agent[validator_address] - except KeyError as exc: - raise ValueError( - f"Requested agent address for an unknown validator address {validator_address}. " - f"Available validators are: {self.validator_to_agent.keys()}" - ) from exc - - def setup(self, *args: Any, **kwargs: Any) -> None: - """ - Set up the round sequence. - - :param args: the arguments to pass to the round constructor. - :param kwargs: the keyword-arguments to pass to the round constructor. - """ - kwargs["context"] = self._context - self._abci_app = self._abci_app_cls(*args, **kwargs) - self._abci_app.setup() - - def start_sync( - self, - ) -> None: # pragma: nocover - """ - Set `_syncing_up` flag to true. - - if the _syncing_up flag is set to true, the `async_act` method won't be executed. For more details refer to - https://github.com/valory-xyz/open-autonomy/issues/247#issuecomment-1012268656 - """ - self._syncing_up = True - - def end_sync( - self, - ) -> None: - """Set `_syncing_up` flag to false.""" - self._syncing_up = False - - @property - def syncing_up( - self, - ) -> bool: - """Return if the app is in sync mode.""" - return self._syncing_up - - @property - def abci_app(self) -> AbciApp: - """Get the AbciApp.""" - if self._abci_app is None: - raise ABCIAppInternalError("AbciApp not set") # pragma: nocover - return self._abci_app - - @property - def blockchain(self) -> Blockchain: - """Get the Blockchain instance.""" - return self._blockchain - - @blockchain.setter - def blockchain(self, _blockchain: Blockchain) -> None: - """Get the Blockchain instance.""" - self._blockchain = _blockchain - - @property - def height(self) -> int: - """Get the height.""" - return self._blockchain.height - - @property - def is_finished(self) -> bool: - """Check if a round sequence has finished.""" - return self.abci_app.is_finished - - def check_is_finished(self) -> None: - """Check if a round sequence has finished.""" - if self.is_finished: - raise ValueError( - "round sequence is finished, cannot accept new transactions" - ) - - @property - def current_round(self) -> AbstractRound: - """Get current round.""" - return self.abci_app.current_round - - @property - def current_round_id(self) -> Optional[str]: - """Get the current round id.""" - return self.abci_app.current_round_id - - @property - def current_round_height(self) -> int: - """Get the current round height.""" - return self.abci_app.current_round_height - - @property - def last_round_id(self) -> Optional[str]: - """Get the last round id.""" - return self.abci_app.last_round_id - - @property - def last_timestamp(self) -> datetime.datetime: - """Get the last timestamp.""" - last_timestamp = ( - self._blockchain.blocks[-1].timestamp - if self._blockchain.length != 0 - else None - ) - if last_timestamp is None: - raise ABCIAppInternalError("last timestamp is None") - return last_timestamp - - @property - def last_round_transition_timestamp( - self, - ) -> datetime.datetime: - """Returns the timestamp for last round transition.""" - if self._last_round_transition_timestamp is None: - raise ValueError( - "Trying to access `last_round_transition_timestamp` while no transition has been completed yet." - ) - - return self._last_round_transition_timestamp - - @property - def last_round_transition_height( - self, - ) -> int: - """Returns the height for last round transition.""" - if self._last_round_transition_height == 0: - raise ValueError( - "Trying to access `last_round_transition_height` while no transition has been completed yet." - ) - - return self._last_round_transition_height - - @property - def last_round_transition_root_hash( - self, - ) -> bytes: - """Returns the root hash for last round transition.""" - if self._last_round_transition_root_hash == b"": - # if called for the first chain initialization, return the hash resulting from the initial abci app's state - return self.root_hash - return self._last_round_transition_root_hash - - @property - def last_round_transition_tm_height(self) -> int: - """Returns the Tendermint height for last round transition.""" - if self._last_round_transition_tm_height is None: - raise ValueError( - "Trying to access Tendermint's last round transition height before any `end_block` calls." - ) - return self._last_round_transition_tm_height - - @property - def latest_synchronized_data(self) -> BaseSynchronizedData: - """Get the latest synchronized_data.""" - return self.abci_app.synchronized_data - - @property - def root_hash(self) -> bytes: - """ - Get the Merkle root hash of the application state. - - This is going to be the database's hash. - In this way, the app hash will be reflecting our application's state, - and will guarantee that all the agents on the chain apply the changes of the arriving blocks in the same way. - - :return: the root hash to be included as the Header.AppHash in the next block. - """ - return self.abci_app.synchronized_data.db.hash() - - @property - def tm_height(self) -> int: - """Get Tendermint's current height.""" - if self._tm_height is None: - raise ValueError( - "Trying to access Tendermint's current height before any `end_block` calls." - ) - return self._tm_height - - @tm_height.setter - def tm_height(self, _tm_height: int) -> None: - """Set Tendermint's current height.""" - self._tm_height = _tm_height - - @property - def block_stall_deadline_expired(self) -> bool: - """Get if the deadline for not having received any begin block requests from the Tendermint node has expired.""" - if self._block_stall_deadline is None: - return False - return datetime.datetime.now() > self._block_stall_deadline - - def set_block_stall_deadline(self) -> None: - """Use the local time of the agent and a predefined tolerance, to specify the expiration of the deadline.""" - self._block_stall_deadline = datetime.datetime.now() + datetime.timedelta( - seconds=BLOCKS_STALL_TOLERANCE - ) - - def init_chain(self, initial_height: int) -> None: - """Init chain.""" - # reduce `initial_height` by 1 to get block count offset as per Tendermint protocol - self._blockchain = Blockchain(initial_height - 1) - - def _track_tm_offences( - self, evidences: Evidences, last_commit_info: LastCommitInfo - ) -> None: - """Track offences provided by Tendermint, if there are any.""" - for vote_info in last_commit_info.votes: - agent_address = self.get_agent_address(vote_info.validator) - was_down = not vote_info.signed_last_block - self.offence_status[agent_address].validator_downtime.add(was_down) - - for byzantine_validator in evidences.byzantine_validators: - agent_address = self.get_agent_address(byzantine_validator.validator) - evidence_type = byzantine_validator.evidence_type - self.offence_status[agent_address].num_unknown_offenses += bool( - evidence_type == EvidenceType.UNKNOWN - ) - self.offence_status[agent_address].num_double_signed += bool( - evidence_type == EvidenceType.DUPLICATE_VOTE - ) - self.offence_status[agent_address].num_light_client_attack += bool( - evidence_type == EvidenceType.LIGHT_CLIENT_ATTACK - ) - - def _track_app_offences(self) -> None: - """Track offences provided by the app level, if there are any.""" - synced_data = self.abci_app.synchronized_data - for agent in self.offence_status.keys(): - blacklisted = agent in synced_data.blacklisted_keepers - suspected = agent in cast(tuple, synced_data.db.get("suspects", tuple())) - agent_status = self.offence_status[agent] - agent_status.blacklisted.add(blacklisted) - agent_status.suspected.add(suspected) - - def _handle_slashing_not_configured(self, exc: SlashingNotConfiguredError) -> None: - """Handle a `SlashingNotConfiguredError`.""" - # In the current slashing implementation, we do not track offences before setting the slashing - # configuration, i.e., before successfully sharing the tm configuration via ACN on registration. - # That is because we cannot slash an agent if we do not map their validator address to their agent address. - # Checking the number of participants will allow us to identify whether the registration round has finished, - # and therefore expect that the slashing configuration has been set if ACN registration is enabled. - if self.abci_app.synchronized_data.nb_participants: - _logger.error( - f"{exc} This error may occur when the ACN registration has not been successfully performed. " - "Have you set the `share_tm_config_on_startup` flag to `true` in the configuration?" - ) - self._slashing_enabled = False - _logger.warning("Slashing has been disabled!") - - def _try_track_offences( - self, evidences: Evidences, last_commit_info: LastCommitInfo - ) -> None: - """Try to track the offences. If an error occurs, log it, disable slashing, and warn about the latter.""" - try: - if self._slashing_enabled: - # only track offences if the first round has finished - # we avoid tracking offences in the first round - # because we do not have the slashing configuration synced yet - self._track_tm_offences(evidences, last_commit_info) - self._track_app_offences() - except SlashingNotConfiguredError as exc: - self._handle_slashing_not_configured(exc) - - def begin_block( - self, - header: Header, - evidences: Evidences, - last_commit_info: LastCommitInfo, - ) -> None: - """Begin block.""" - if self.is_finished: - raise ABCIAppInternalError( - "round sequence is finished, cannot accept new blocks" - ) - if ( - self._block_construction_phase - != RoundSequence._BlockConstructionState.WAITING_FOR_BEGIN_BLOCK - ): - raise ABCIAppInternalError( - f"cannot accept a 'begin_block' request. Current phase={self._block_construction_phase}" - ) - - # From now on, the ABCI app waits for 'deliver_tx' requests, until 'end_block' is received - self._block_construction_phase = ( - RoundSequence._BlockConstructionState.WAITING_FOR_DELIVER_TX - ) - self._block_builder.reset() - self._block_builder.header = header - self.abci_app.update_time(header.timestamp) - self.set_block_stall_deadline() - self.abci_app.logger.debug( - "Created a new local deadline for the next `begin_block` request from the Tendermint node: " - f"{self._block_stall_deadline}" - ) - self._try_track_offences(evidences, last_commit_info) - - def deliver_tx(self, transaction: Transaction) -> None: - """ - Deliver a transaction. - - Appends the transaction to build the block on 'end_block' later. - :param transaction: the transaction. - :raises: an Error otherwise. - """ - if ( - self._block_construction_phase - != RoundSequence._BlockConstructionState.WAITING_FOR_DELIVER_TX - ): - raise ABCIAppInternalError( - f"cannot accept a 'deliver_tx' request. Current phase={self._block_construction_phase}" - ) - - self.abci_app.check_transaction(transaction) - self.abci_app.process_transaction(transaction) - self._block_builder.add_transaction(transaction) - - def end_block(self) -> None: - """Process the 'end_block' request.""" - if ( - self._block_construction_phase - != RoundSequence._BlockConstructionState.WAITING_FOR_DELIVER_TX - ): - raise ABCIAppInternalError( - f"cannot accept a 'end_block' request. Current phase={self._block_construction_phase}" - ) - # The ABCI app waits for the commit - self._block_construction_phase = ( - RoundSequence._BlockConstructionState.WAITING_FOR_COMMIT - ) - - def commit(self) -> None: - """Process the 'commit' request.""" - if ( - self._block_construction_phase - != RoundSequence._BlockConstructionState.WAITING_FOR_COMMIT - ): - raise ABCIAppInternalError( - f"cannot accept a 'commit' request. Current phase={self._block_construction_phase}" - ) - block = self._block_builder.get_block() - try: - if self._blockchain.is_init: - # There are occasions where we wait for an init_chain() before accepting blocks. - # This can happen during hard reset, where we might've reset the local blockchain, - # But are still receiving requests from the not yet reset tendermint node. - # We only process blocks on an initialized local blockchain. - # The local blockchain gets initialized upon receiving an init_chain request from - # the tendermint node. In cases where we don't want to wait for the init_chain req, - # one can create a Blockchain instance with `is_init=True`, i.e. the default args. - self._blockchain.add_block(block) - self._update_round() - else: - self.abci_app.logger.warning( - f"Received block with height {block.header.height} before the blockchain was initialized." - ) - # The ABCI app now waits again for the next block - self._block_construction_phase = ( - RoundSequence._BlockConstructionState.WAITING_FOR_BEGIN_BLOCK - ) - except AddBlockError as exception: - raise exception - - def reset_blockchain(self, is_replay: bool = False, is_init: bool = False) -> None: - """ - Reset blockchain after tendermint reset. - - :param is_replay: whether we are resetting the blockchain while replaying blocks. - :param is_init: whether to process blocks before receiving an init_chain req from tendermint. - """ - if is_replay: - self._block_construction_phase = ( - RoundSequence._BlockConstructionState.WAITING_FOR_BEGIN_BLOCK - ) - self._blockchain = Blockchain(is_init=is_init) - - def _get_round_result( - self, - ) -> Optional[Tuple[BaseSynchronizedData, Any]]: - """ - Get the round's result. - - Give priority to: - 1. terminating bg rounds - 2. ever running bg rounds - 3. normal bg rounds - 4. normal rounds - - :return: the round's result. - """ - for prioritized_group in self.abci_app.bg_apps_prioritized: - for app in prioritized_group: - result = app.background_round.end_block() - if ( - result is None - or app.type == BackgroundAppType.TERMINATING - and self._terminating_round_called - ): - continue - if ( - app.type == BackgroundAppType.TERMINATING - and not self._terminating_round_called - ): - self._terminating_round_called = True - return result - return self.abci_app.current_round.end_block() - - def _update_round(self) -> None: - """ - Update a round. - - Check whether the round has finished. If so, get the new round and set it as the current round. - If a termination app's round has returned a result, then the other apps' rounds are ignored. - """ - result = self._get_round_result() - - if result is None: - # neither the background rounds, nor the current round returned, so no update needs to be made - return - - # update the offence status at the end of each round - # this is done to ensure that the offence status is always up-to-date & in sync - # the next step is a no-op if slashing is not enabled - self.store_offence_status() - - self._last_round_transition_timestamp = self._blockchain.last_block.timestamp - self._last_round_transition_height = self.height - self._last_round_transition_root_hash = self.root_hash - self._last_round_transition_tm_height = self.tm_height - - round_result, event = result - self.abci_app.logger.debug( - f"updating round, current_round {self.current_round.round_id}, event: {event}, round result {round_result}" - ) - self.abci_app.process_event(event, result=round_result) - - def _reset_to_default_params(self) -> None: - """Resets the instance params to their default value.""" - self._last_round_transition_timestamp = None - self._last_round_transition_height = 0 - self._last_round_transition_root_hash = b"" - self._last_round_transition_tm_height = None - self._tm_height = None - self._slashing_enabled = False - self.pending_offences = set() - - def reset_state( - self, - restart_from_round: str, - round_count: int, - serialized_db_state: Optional[str] = None, - ) -> None: - """ - This method resets the state of RoundSequence to the beginning of the period. - - Note: This is intended to be used for agent <-> tendermint communication recovery only! - - :param restart_from_round: from which round to restart the abci. - This round should be the first round in the last period. - :param round_count: the round count at the beginning of the period -1. - :param serialized_db_state: the state of the database at the beginning of the period. - If provided, the database will be reset to this state. - """ - self._reset_to_default_params() - self.abci_app.synchronized_data.db.round_count = round_count - if serialized_db_state is not None: - self.sync_db_and_slashing(serialized_db_state) - # Furthermore, that hash is then in turn used as the init hash when the tm network is reset. - self._last_round_transition_root_hash = self.root_hash - - self.abci_app.cleanup_timeouts() - round_id_to_cls = { - cls.auto_round_id(): cls for cls in self.abci_app.transition_function - } - restart_from_round_cls = round_id_to_cls.get(restart_from_round, None) - if restart_from_round_cls is None: - raise ABCIAppInternalError( - "Cannot reset state. The Tendermint recovery parameters are incorrect. " - "Did you update the `restart_from_round` with an incorrect round id? " - f"Found {restart_from_round}, but the app's transition function has the following round ids: " - f"{set(round_id_to_cls.keys())}." - ) - self.abci_app.schedule_round(restart_from_round_cls) - - -@dataclass(frozen=True) -class PendingOffencesPayload(BaseTxPayload): - """Represent a transaction payload for pending offences.""" - - accused_agent_address: str - offense_round: int - offense_type_value: int - last_transition_timestamp: float - time_to_live: float - custom_amount: int - - -class PendingOffencesRound(CollectSameUntilThresholdRound): - """Defines the pending offences background round, which runs concurrently with other rounds to sync the offences.""" - - payload_class = PendingOffencesPayload - synchronized_data_class = BaseSynchronizedData - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the `PendingOffencesRound`.""" - super().__init__(*args, **kwargs) - self._latest_round_processed = -1 - - @property - def offence_status(self) -> Dict[str, OffenceStatus]: - """Get the offence status from the round sequence.""" - return self.context.state.round_sequence.offence_status - - def end_block(self) -> None: - """ - Process the end of the block for the pending offences background round. - - It is important to note that this is a non-standard type of round, meaning it does not emit any events. - Instead, it continuously runs in the background. - The objective of this round is to consistently monitor the received pending offences - and achieve a consensus among the agents. - """ - if not self.threshold_reached: - return - - offence = PendingOffense(*self.most_voted_payload_values) - - # an offence should only be tracked once, not every time a payload is processed after the threshold is reached - if self._latest_round_processed == offence.round_count: - return - - # add synchronized offence to the offence status - # only `INVALID_PAYLOAD` offence types are supported at the moment as pending offences: - # https://github.com/valory-xyz/open-autonomy/blob/6831d6ebaf10ea8e3e04624b694c7f59a6d05bb4/packages/valory/skills/abstract_round_abci/handlers.py#L215-L222 # noqa - invalid = offence.offense_type == OffenseType.INVALID_PAYLOAD - self.offence_status[offence.accused_agent_address].invalid_payload.add(invalid) - - # if the offence is of custom type, then add the custom amount to it - if offence.offense_type == OffenseType.CUSTOM: - self.offence_status[ - offence.accused_agent_address - ].custom_offences_amount += offence.custom_amount - elif offence.custom_amount != 0: - self.context.logger.warning( - f"Custom amount for {offence=} will not take effect as it is not of `CUSTOM` type." - ) - - self._latest_round_processed = offence.round_count diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/behaviour_utils.py b/trader_old/vendor/valory/skills/abstract_round_abci/behaviour_utils.py deleted file mode 100644 index 43f929834..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/behaviour_utils.py +++ /dev/null @@ -1,2356 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 helper classes for behaviours.""" - - -import datetime -import inspect -import json -import pprint -import re -import sys -from abc import ABC, ABCMeta, abstractmethod -from enum import Enum -from functools import partial -from typing import ( - Any, - Callable, - Dict, - Generator, - List, - Optional, - Tuple, - Type, - Union, - cast, -) - -import pytz -from aea.exceptions import enforce -from aea.mail.base import EnvelopeContext -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue -from aea.skills.behaviours import SimpleBehaviour - -from packages.open_aea.protocols.signing import SigningMessage -from packages.open_aea.protocols.signing.custom_types import ( - RawMessage, - RawTransaction, - SignedTransaction, - Terms, -) -from packages.valory.connections.http_client.connection import ( - PUBLIC_ID as HTTP_CLIENT_PUBLIC_ID, -) -from packages.valory.connections.ipfs.connection import PUBLIC_ID as IPFS_CONNECTION_ID -from packages.valory.connections.p2p_libp2p_client.connection import ( - PUBLIC_ID as P2P_LIBP2P_CLIENT_PUBLIC_ID, -) -from packages.valory.contracts.service_registry.contract import ( # noqa: F401 # pylint: disable=unused-import - ServiceRegistryContract, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.protocols.ipfs.dialogues import IpfsDialogue, IpfsDialogues -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.protocols.tendermint import TendermintMessage -from packages.valory.skills.abstract_round_abci.base import ( - AbstractRound, - BaseSynchronizedData, - BaseTxPayload, - LEDGER_API_ADDRESS, - OK_CODE, - RoundSequence, - Transaction, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue, - ContractApiDialogues, - HttpDialogue, - HttpDialogues, - LedgerApiDialogue, - LedgerApiDialogues, - SigningDialogues, - TendermintDialogues, -) -from packages.valory.skills.abstract_round_abci.io_.ipfs import ( - IPFSInteract, - IPFSInteractionError, -) -from packages.valory.skills.abstract_round_abci.io_.load import CustomLoaderType, Loader -from packages.valory.skills.abstract_round_abci.io_.store import ( - CustomStorerType, - Storer, - SupportedFiletype, - SupportedObjectType, -) -from packages.valory.skills.abstract_round_abci.models import ( - BaseParams, - Requests, - SharedState, - TendermintRecoveryParams, -) - - -# TODO: port registration code from registration_abci to here - - -NON_200_RETURN_CODE_DURING_RESET_THRESHOLD = 3 -GENESIS_TIME_FMT = "%Y-%m-%dT%H:%M:%S.%fZ" -INITIAL_APP_HASH = "" -INITIAL_HEIGHT = "0" -TM_REQ_TIMEOUT = 5 # 5 seconds -FLASHBOTS_LEDGER_ID = "ethereum_flashbots" -SOLANA_LEDGER_ID = "solana" - - -class SendException(Exception): - """Exception raised if the 'try_send' to an AsyncBehaviour failed.""" - - -class TimeoutException(Exception): - """Exception raised when a timeout during AsyncBehaviour occurs.""" - - -class BaseBehaviourInternalError(Exception): - """Internal error due to a bad implementation of the BaseBehaviour.""" - - def __init__(self, message: str, *args: Any) -> None: - """Initialize the error object.""" - super().__init__("internal error: " + message, *args) - - -class AsyncBehaviour(ABC): - """ - MixIn behaviour class that support limited asynchronous programming. - - An AsyncBehaviour can be in three states: - - READY: no suspended 'async_act' execution; - - RUNNING: 'act' called, and waiting for a message - - WAITING_TICK: 'act' called, and waiting for the next 'act' call - """ - - class AsyncState(Enum): - """Enumeration of AsyncBehaviour states.""" - - READY = "ready" - RUNNING = "running" - WAITING_MESSAGE = "waiting_message" - - def __init__(self) -> None: - """Initialize the async behaviour.""" - self.__state = self.AsyncState.READY - self.__generator_act: Optional[Generator] = None - - # temporary variables for the waiting message state - self.__stopped: bool = True - self.__notified: bool = False - self.__message: Any = None - self.__setup_called: bool = False - - @abstractmethod - def async_act(self) -> Generator: - """Do the act, supporting asynchronous execution.""" - - @abstractmethod - def async_act_wrapper(self) -> Generator: - """Do the act, supporting asynchronous execution.""" - - @property - def state(self) -> AsyncState: - """Get the 'async state'.""" - return self.__state - - @property - def is_notified(self) -> bool: - """Returns whether the behaviour has been notified about the arrival of a message.""" - return self.__notified - - @property - def received_message(self) -> Any: - """Returns the message the behaviour has received. "__message" should be None if not availble or already consumed.""" - return self.__message - - def _on_sent_message(self) -> None: - """To be called after the message received is consumed. Removes the already sent notification and message.""" - self.__notified = False - self.__message = None - - @property - def is_stopped(self) -> bool: - """Check whether the behaviour has stopped.""" - return self.__stopped - - def __get_generator_act(self) -> Generator: - """Get the _generator_act.""" - if self.__generator_act is None: - raise ValueError("generator act not set!") # pragma: nocover - return self.__generator_act - - def try_send(self, message: Any) -> None: - """ - Try to send a message to a waiting behaviour. - - It will be sent only if the behaviour is actually waiting for a message, - and it was not already notified. - - :param message: a Python object. - :raises: SendException if the behaviour was not waiting for a message, - or if it was already notified. - """ - in_waiting_message_state = self.__state == self.AsyncState.WAITING_MESSAGE - already_notified = self.__notified - enforce( - in_waiting_message_state and not already_notified, - "cannot send message", - exception_class=SendException, - ) - self.__notified = True - self.__message = message - - @classmethod - def wait_for_condition( - cls, condition: Callable[[], bool], timeout: Optional[float] = None - ) -> Generator[None, None, None]: - """Wait for a condition to happen. - - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - - :param condition: the condition to wait for - :param timeout: the maximum amount of time to wait - :yield: None - """ - if timeout is not None: - deadline = datetime.datetime.now() + datetime.timedelta(0, timeout) - else: - deadline = datetime.datetime.max - - while not condition(): - if timeout is not None and datetime.datetime.now() > deadline: - raise TimeoutException() - yield - - def sleep(self, seconds: float) -> Any: - """ - Delay execution for a given number of seconds. - - The argument may be a floating point number for subsecond precision. - This is a local method that does not depend on the global clock, so the - usage of datetime.now() is acceptable here. - - :param seconds: the seconds - :yield: None - """ - deadline = datetime.datetime.now() + datetime.timedelta(0, seconds) - - def _wait_until() -> bool: - return datetime.datetime.now() > deadline - - yield from self.wait_for_condition(_wait_until) - - def wait_for_message( - self, - condition: Callable = lambda message: True, - timeout: Optional[float] = None, - ) -> Any: - """ - Wait for message. - - Care must be taken. This method does not handle concurrent requests. - Use directly after a request is being sent. - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - - :param condition: a callable - :param timeout: max time to wait (in seconds) - :return: a message - :yield: None - """ - if timeout is not None: - deadline = datetime.datetime.now() + datetime.timedelta(0, timeout) - else: - deadline = datetime.datetime.max - - self.__state = self.AsyncState.WAITING_MESSAGE - try: - message = None - while message is None or not condition(message): - message = yield - if timeout is not None and datetime.datetime.now() > deadline: - raise TimeoutException() - message = cast(Message, message) - return message - finally: - self.__state = self.AsyncState.RUNNING - - def setup(self) -> None: # noqa: B027 # flake8 suggest make it abstract - """Setup behaviour.""" - - def act(self) -> None: - """Do the act.""" - # call setup only the first time act is called - if not self.__setup_called: - self.setup() - self.__setup_called = True - - if self.__state == self.AsyncState.READY: - self.__call_act_first_time() - return - if self.__state == self.AsyncState.WAITING_MESSAGE: - self.__handle_waiting_for_message() - return - enforce(self.__state == self.AsyncState.RUNNING, "not in 'RUNNING' state") - self.__handle_tick() - - def stop(self) -> None: - """Stop the execution of the behaviour.""" - if self.__stopped or self.__state == self.AsyncState.READY: - return - self.__get_generator_act().close() - self.__state = self.AsyncState.READY - self.__stopped = True - - def __call_act_first_time(self) -> None: - """Call the 'async_act' method for the first time.""" - self.__stopped = False - self.__state = self.AsyncState.RUNNING - try: - self.__generator_act = self.async_act_wrapper() - # if the method 'async_act' was not a generator function - # (i.e. no 'yield' or 'yield from' statement) - # just return - if not inspect.isgenerator(self.__generator_act): - self.__state = self.AsyncState.READY - return - # trigger first execution, up to next 'yield' statement - self.__get_generator_act().send(None) - except StopIteration: - # this may happen if the generator is empty - self.__state = self.AsyncState.READY - - def __handle_waiting_for_message(self) -> None: - """Handle an 'act' tick, when waiting for a message.""" - # if there is no message coming, skip. - if self.__notified: - try: - self.__get_generator_act().send(self.__message) - except StopIteration: - self.__handle_stop_iteration() - finally: - # wait for the next message - self.__notified = False - self.__message = None - - def __handle_tick(self) -> None: - """Handle an 'act' tick.""" - try: - self.__get_generator_act().send(None) - except StopIteration: - self.__handle_stop_iteration() - - def __handle_stop_iteration(self) -> None: - """ - Handle 'StopIteration' exception. - - The exception means that the 'async_act' - generator function terminated the execution, - and therefore the state needs to be reset. - """ - self.__state = self.AsyncState.READY - - -class IPFSBehaviour(SimpleBehaviour, ABC): - """Behaviour for interactions with IPFS.""" - - def __init__(self, **kwargs: Any): - """Initialize an `IPFSBehaviour`.""" - super().__init__(**kwargs) - loader_cls = kwargs.pop("loader_cls", Loader) - storer_cls = kwargs.pop("storer_cls", Storer) - self._ipfs_interact = IPFSInteract(loader_cls, storer_cls) - - def _build_ipfs_message( - self, - performative: IpfsMessage.Performative, - timeout: Optional[float] = None, - **kwargs: Any, - ) -> Tuple[IpfsMessage, IpfsDialogue]: - """Builds an IPFS message.""" - ipfs_dialogues = cast(IpfsDialogues, self.context.ipfs_dialogues) - message, dialogue = ipfs_dialogues.create( - counterparty=str(IPFS_CONNECTION_ID), - performative=performative, - timeout=timeout, - **kwargs, - ) - return message, dialogue - - def _build_ipfs_store_file_req( # pylint: disable=too-many-arguments - self, - filename: str, - obj: SupportedObjectType, - multiple: bool = False, - filetype: Optional[SupportedFiletype] = None, - custom_storer: Optional[CustomStorerType] = None, - timeout: Optional[float] = None, - **kwargs: Any, - ) -> Tuple[IpfsMessage, IpfsDialogue]: - """ - Builds a STORE_FILES ipfs message. - - :param filename: the file name to store obj in. If "multiple" is True, filename will be the name of the dir. - :param obj: the object(s) to serialize and store in IPFS as "filename". - :param multiple: whether obj should be stored as multiple files, i.e. directory. - :param custom_storer: a custom serializer for "obj". - :param timeout: timeout for the request. - :returns: the ipfs message, and its corresponding dialogue. - """ - serialized_objects = self._ipfs_interact.store( - filename, obj, multiple, filetype, custom_storer, **kwargs - ) - message, dialogue = self._build_ipfs_message( - performative=IpfsMessage.Performative.STORE_FILES, # type: ignore - files=serialized_objects, - timeout=timeout, - ) - return message, dialogue - - def _build_ipfs_get_file_req( - self, - ipfs_hash: str, - timeout: Optional[float] = None, - ) -> Tuple[IpfsMessage, IpfsDialogue]: - """ - Builds a GET_FILES IPFS request. - - :param ipfs_hash: the ipfs hash of the file/dir to download. - :param timeout: timeout for the request. - :returns: the ipfs message, and its corresponding dialogue. - """ - message, dialogue = self._build_ipfs_message( - performative=IpfsMessage.Performative.GET_FILES, # type: ignore - ipfs_hash=ipfs_hash, - timeout=timeout, - ) - return message, dialogue - - def _deserialize_ipfs_objects( # pylint: disable=too-many-arguments - self, - serialized_objects: Dict[str, str], - filetype: Optional[SupportedFiletype] = None, - custom_loader: CustomLoaderType = None, - ) -> Optional[SupportedObjectType]: - """Deserialize objects received from IPFS.""" - deserialized_object = self._ipfs_interact.load( - serialized_objects, filetype, custom_loader - ) - return deserialized_object - - -class CleanUpBehaviour(SimpleBehaviour, ABC): - """Class for clean-up related functionality of behaviours.""" - - def __init__(self, **kwargs: Any): # pylint: disable=super-init-not-called - """Initialize a base behaviour.""" - SimpleBehaviour.__init__(self, **kwargs) - - def clean_up(self) -> None: - """ - Clean up the resources due to a 'stop' event. - - It can be optionally implemented by the concrete classes. - """ - - def handle_late_messages(self, behaviour_id: str, message: Message) -> None: - """ - Handle late arriving messages. - - Runs from another behaviour, even if the behaviour implementing the method has been exited. - It can be optionally implemented by the concrete classes. - - :param behaviour_id: the id of the behaviour in which the message belongs to. - :param message: the late arriving message to handle. - """ - request_nonce = message.dialogue_reference[0] - self.context.logger.warning( - f"No callback defined for request with nonce: {request_nonce}, arriving for behaviour: {behaviour_id}" - ) - - -class RPCResponseStatus(Enum): - """A custom status of an RPC response.""" - - SUCCESS = 1 - INCORRECT_NONCE = 2 - UNDERPRICED = 3 - INSUFFICIENT_FUNDS = 4 - ALREADY_KNOWN = 5 - UNCLASSIFIED_ERROR = 6 - SIMULATION_FAILED = 7 - - -class _MetaBaseBehaviour(ABCMeta): - """A metaclass that validates BaseBehaviour's attributes.""" - - def __new__(mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any) -> Type: # type: ignore - """Initialize the class.""" - new_cls = super().__new__(mcs, name, bases, namespace, **kwargs) - - if ABC in bases: - # abstract class, return - return new_cls - if not issubclass(new_cls, BaseBehaviour): - # the check only applies to AbciApp subclasses - return new_cls - - mcs._check_consistency(cast(Type[BaseBehaviour], new_cls)) - return new_cls - - @classmethod - def _check_consistency(mcs, base_behaviour_cls: Type["BaseBehaviour"]) -> None: - """Check consistency of class attributes.""" - mcs._check_required_class_attributes(base_behaviour_cls) - - @classmethod - def _check_required_class_attributes( - mcs, base_behaviour_cls: Type["BaseBehaviour"] - ) -> None: - """Check that required class attributes are set.""" - if not hasattr(base_behaviour_cls, "matching_round"): - raise BaseBehaviourInternalError( - f"'matching_round' not set on {base_behaviour_cls}" - ) - - -class BaseBehaviour( - AsyncBehaviour, IPFSBehaviour, CleanUpBehaviour, ABC, metaclass=_MetaBaseBehaviour -): - """ - This class represents the base class for FSM behaviours - - A behaviour is a state of the FSM App execution. It usually involves - interactions between participants in the FSM App, - although this is not enforced at this level of abstraction. - - Concrete classes must set: - - matching_round: the round class matching the behaviour; - - Optionally, behaviour_id can be defined, although it is recommended to use the autogenerated id. - """ - - __pattern = re.compile(r"(? str: - """ - Get behaviour id automatically. - - This method returns the auto generated id from the class name if the - class variable behaviour_id is not set on the child class. - Otherwise, it returns the class variable behaviour_id. - """ - return ( - cls.behaviour_id - if isinstance(cls.behaviour_id, str) - else cls.__pattern.sub("_", cls.__name__).lower() - ) - - @property # type: ignore - def behaviour_id(self) -> str: - """Get behaviour id.""" - return self.auto_behaviour_id() - - @property - def params(self) -> BaseParams: - """Return the params.""" - return self.context.params - - @property - def shared_state(self) -> SharedState: - """Return the round sequence.""" - return self.context.state - - @property - def round_sequence(self) -> RoundSequence: - """Return the round sequence.""" - return self.shared_state.round_sequence - - @property - def synchronized_data(self) -> BaseSynchronizedData: - """Return the synchronized data.""" - return self.shared_state.synchronized_data - - @property - def tm_communication_unhealthy(self) -> bool: - """Return if the Tendermint communication is not healthy anymore.""" - return self.round_sequence.block_stall_deadline_expired - - def check_in_round(self, round_id: str) -> bool: - """Check that we entered a specific round.""" - return self.round_sequence.current_round_id == round_id - - def check_in_last_round(self, round_id: str) -> bool: - """Check that we entered a specific round.""" - return self.round_sequence.last_round_id == round_id - - def check_not_in_round(self, round_id: str) -> bool: - """Check that we are not in a specific round.""" - return not self.check_in_round(round_id) - - def check_not_in_last_round(self, round_id: str) -> bool: - """Check that we are not in a specific round.""" - return not self.check_in_last_round(round_id) - - def check_round_has_finished(self, round_id: str) -> bool: - """Check that the round has finished.""" - return self.check_in_last_round(round_id) - - def check_round_height_has_changed(self, round_height: int) -> bool: - """Check that the round height has changed.""" - return self.round_sequence.current_round_height != round_height - - def is_round_ended(self, round_id: str) -> Callable[[], bool]: - """Get a callable to check whether the current round has ended.""" - return partial(self.check_not_in_round, round_id) - - def wait_until_round_end( - self, timeout: Optional[float] = None - ) -> Generator[None, None, None]: - """ - Wait until the ABCI application exits from a round. - - :param timeout: the timeout for the wait - :yield: None - """ - round_id = self.matching_round.auto_round_id() - round_height = self.round_sequence.current_round_height - if self.check_not_in_round(round_id) and self.check_not_in_last_round(round_id): - raise ValueError( - f"Should be in matching round ({round_id}) or last round ({self.round_sequence.last_round_id}), " - f"actual round {self.round_sequence.current_round_id}!" - ) - yield from self.wait_for_condition( - partial(self.check_round_height_has_changed, round_height), timeout=timeout - ) - - def wait_from_last_timestamp(self, seconds: float) -> Any: - """ - Delay execution for a given number of seconds from the last timestamp. - - The argument may be a floating point number for subsecond precision. - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - - :param seconds: the seconds - :yield: None - """ - if seconds < 0: - raise ValueError("Can only wait for a positive amount of time") - deadline = self.round_sequence.abci_app.last_timestamp + datetime.timedelta( - seconds=seconds - ) - - def _wait_until() -> bool: - return datetime.datetime.now() > deadline - - yield from self.wait_for_condition(_wait_until) - - def is_done(self) -> bool: - """Check whether the behaviour is done.""" - return self._is_done - - def set_done(self) -> None: - """Set the behaviour to done.""" - self._is_done = True - - def send_a2a_transaction( - self, payload: BaseTxPayload, resetting: bool = False - ) -> Generator: - """ - Send transaction and wait for the response, and repeat until not successful. - - :param: payload: the payload to send - :param: resetting: flag indicating if we are resetting Tendermint nodes in this round. - :yield: the responses - """ - stop_condition = self.is_round_ended(self.matching_round.auto_round_id()) - round_count = self.synchronized_data.round_count - object.__setattr__(payload, "round_count", round_count) - yield from self._send_transaction( - payload, - resetting, - stop_condition=stop_condition, - ) - - def async_act_wrapper(self) -> Generator: - """Do the act, supporting asynchronous execution.""" - if not self._is_started: - self._log_start() - self._is_started = True - try: - if self.round_sequence.syncing_up: - yield from self._check_sync() - else: - yield from self.async_act() - except StopIteration: - self.clean_up() - self.set_done() - self._log_end() - return - - if self._is_done: - self._log_end() - - def _check_sync( - self, - ) -> Generator[None, None, None]: - """Check if agent has completed sync.""" - self.context.logger.info("Synchronizing with Tendermint...") - for _ in range(self.context.params.tendermint_max_retries): - self.context.logger.debug( - "Checking status @ " + self.context.params.tendermint_url + "/status", - ) - status = yield from self._get_status() - try: - json_body = json.loads(status.body.decode()) - remote_height = int( - json_body["result"]["sync_info"]["latest_block_height"] - ) - local_height = int(self.round_sequence.height) - _is_sync_complete = local_height == remote_height - if _is_sync_complete: - self.context.logger.info( - f"local height == remote == {local_height}; Synchronization complete." - ) - self.round_sequence.end_sync() - # we set the block stall deadline here because we pinged the /status endpoint - # and received a response from tm, which means that the communication is fine - self.round_sequence.set_block_stall_deadline() - return - yield from self.sleep(self.context.params.tendermint_check_sleep_delay) - except (json.JSONDecodeError, KeyError): # pragma: nocover - self.context.logger.debug( - "Tendermint not accepting transactions yet, trying again!" - ) - yield from self.sleep(self.context.params.tendermint_check_sleep_delay) - - self.context.logger.error("Could not synchronize with Tendermint!") - - def _log_start(self) -> None: - """Log the entering in the behaviour.""" - self.context.logger.info(f"Entered in the '{self.name}' behaviour") - - def _log_end(self) -> None: - """Log the exiting from the behaviour.""" - self.context.logger.info(f"'{self.name}' behaviour is done") - - @classmethod - def _get_request_nonce_from_dialogue(cls, dialogue: Dialogue) -> str: - """Get the request nonce for the request, from the protocol's dialogue.""" - return dialogue.dialogue_label.dialogue_reference[0] - - def _send_transaction( # pylint: disable=too-many-arguments,too-many-locals,too-many-statements - self, - payload: BaseTxPayload, - resetting: bool = False, - stop_condition: Callable[[], bool] = lambda: False, - request_timeout: Optional[float] = None, - request_retry_delay: Optional[float] = None, - tx_timeout: Optional[float] = None, - max_attempts: Optional[int] = None, - ) -> Generator: - """ - Send transaction and wait for the response, repeat until not successful. - - Steps: - - Request the signature of the payload to the Decision Maker - - Send the transaction to the 'price-estimation' app via the Tendermint - node, and wait/repeat until the transaction is not mined. - - Happy-path full flow of the messages. - - get_signature: - AbstractRoundAbci skill -> (SigningMessage | SIGN_MESSAGE) -> DecisionMaker - DecisionMaker -> (SigningMessage | SIGNED_MESSAGE) -> AbstractRoundAbci skill - - _submit_tx: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - _wait_until_transaction_delivered: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - :param: payload: the payload to send - :param: resetting: flag indicating if we are resetting Tendermint nodes in this round. - :param: stop_condition: the condition to be checked to interrupt the - waiting loop. - :param: request_timeout: the timeout for the requests - :param: request_retry_delay: the delay to wait after failed requests - :param: tx_timeout: the timeout to wait for tx delivery - :param: max_attempts: max retry attempts - :yield: the responses - """ - request_timeout = ( - self.params.request_timeout if request_timeout is None else request_timeout - ) - request_retry_delay = ( - self.params.request_retry_delay - if request_retry_delay is None - else request_retry_delay - ) - tx_timeout = self.params.tx_timeout if tx_timeout is None else tx_timeout - max_attempts = ( - self.params.max_attempts if max_attempts is None else max_attempts - ) - while not stop_condition(): - self.context.logger.debug( - f"Trying to send payload: {pprint.pformat(payload.json)}" - ) - signature_bytes = yield from self.get_signature(payload.encode()) - transaction = Transaction(payload, signature_bytes) - try: - response = yield from self._submit_tx( - transaction.encode(), timeout=request_timeout - ) - # There is no guarantee that beyond this line will be executed for a given behaviour execution. - # The tx could lead to a round transition which exits us from the behaviour execution. - # It's unlikely to happen anywhere before line 538 but there it is very likely to not - # yield in time before the behaviour is finished. As a result logs below might not show - # up on the happy execution path. - except TimeoutException: - self.context.logger.warning( - f"Timeout expired for submit tx. Retrying in {request_retry_delay} seconds..." - ) - payload = payload.with_new_id() - yield from self.sleep(request_retry_delay) - continue - response = cast(HttpMessage, response) - non_200_code = not self._check_http_return_code_200(response) - if non_200_code and ( - self._non_200_return_code_count - > NON_200_RETURN_CODE_DURING_RESET_THRESHOLD - or not resetting - ): - self.context.logger.error( - f"Received return code != 200 with response {response} with body {str(response.body)}. " - f"Retrying in {request_retry_delay} seconds..." - ) - elif non_200_code and resetting: - self._non_200_return_code_count += 1 - if non_200_code: - payload = payload.with_new_id() - yield from self.sleep(request_retry_delay) - continue - try: - json_body = json.loads(response.body) - except json.JSONDecodeError as e: # pragma: nocover - raise ValueError( - f"Unable to decode response: {response} with body {str(response.body)}" - ) from e - self.context.logger.debug(f"JSON response: {pprint.pformat(json_body)}") - tx_hash = json_body["result"]["hash"] - if json_body["result"]["code"] != OK_CODE: - self.context.logger.error( - f"Received tendermint code != 0. Retrying in {request_retry_delay} seconds..." - ) - yield from self.sleep(request_retry_delay) - continue # pragma: nocover - - try: - is_delivered, res = yield from self._wait_until_transaction_delivered( - tx_hash, - timeout=tx_timeout, - max_attempts=max_attempts, - request_retry_delay=request_retry_delay, - ) - except TimeoutException: - self.context.logger.warning( - f"Timeout expired for wait until transaction delivered. " - f"Retrying in {request_retry_delay} seconds..." - ) - payload = payload.with_new_id() - yield from self.sleep(request_retry_delay) - continue # pragma: nocover - - if is_delivered: - self.context.logger.debug("A2A transaction delivered!") - break - if isinstance(res, HttpMessage) and self._is_invalid_transaction(res): - self.context.logger.error( - f"Tx sent but not delivered. Invalid transaction - not trying again! Response = {res}" - ) - break - # otherwise, repeat until done, or until stop condition is true - if isinstance(res, HttpMessage) and self._tx_not_found(tx_hash, res): - self.context.logger.warning(f"Tx {tx_hash} not found! Response = {res}") - else: - self.context.logger.warning( - f"Tx sent but not delivered. Response = {res}" - ) - payload = payload.with_new_id() - self.context.logger.debug( - "Stop condition is true, no more attempts to send the transaction." - ) - - @staticmethod - def _is_invalid_transaction(res: HttpMessage) -> bool: - """Check if the transaction is invalid.""" - try: - error_codes = ["TransactionNotValidError"] - body_ = json.loads(res.body) - return any( - [error_code in body_["tx_result"]["info"] for error_code in error_codes] - ) - except Exception: # pylint: disable=broad-except # pragma: nocover - return False - - @staticmethod - def _tx_not_found(tx_hash: str, res: HttpMessage) -> bool: - """Check if the transaction could not be found.""" - try: - error = json.loads(res.body)["error"] - not_found_field_to_text = { - "code": -32603, - "message": "Internal error", - "data": f"tx ({tx_hash}) not found", - } - return all( - [ - text == error[field] - for field, text in not_found_field_to_text.items() - ] - ) - except Exception: # pylint: disable=broad-except # pragma: nocover - return False - - def _send_signing_request( - self, raw_message: bytes, is_deprecated_mode: bool = False - ) -> None: - """ - Send a signing request. - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (SigningMessage | SIGN_MESSAGE) -> DecisionMaker - DecisionMaker -> (SigningMessage | SIGNED_MESSAGE) -> AbstractRoundAbci skill - - :param raw_message: raw message bytes - :param is_deprecated_mode: is deprecated flag. - """ - signing_dialogues = cast(SigningDialogues, self.context.signing_dialogues) - signing_msg, signing_dialogue = signing_dialogues.create( - counterparty=self.context.decision_maker_address, - performative=SigningMessage.Performative.SIGN_MESSAGE, - raw_message=RawMessage( - self.context.default_ledger_id, - raw_message, - is_deprecated_mode=is_deprecated_mode, - ), - terms=Terms( - ledger_id=self.context.default_ledger_id, - sender_address="", - counterparty_address="", - amount_by_currency_id={}, - quantities_by_good_id={}, - nonce="", - ), - ) - request_nonce = self._get_request_nonce_from_dialogue(signing_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - self.context.decision_maker_message_queue.put_nowait(signing_msg) - - def _send_transaction_signing_request( - self, raw_transaction: RawTransaction, terms: Terms - ) -> None: - """ - Send a transaction signing request. - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (SigningMessage | SIGN_TRANSACTION) -> DecisionMaker - DecisionMaker -> (SigningMessage | SIGNED_TRANSACTION) -> AbstractRoundAbci skill - - :param raw_transaction: raw transaction data - :param terms: signing terms - """ - signing_dialogues = cast(SigningDialogues, self.context.signing_dialogues) - signing_msg, signing_dialogue = signing_dialogues.create( - counterparty=self.context.decision_maker_address, - performative=SigningMessage.Performative.SIGN_TRANSACTION, - raw_transaction=raw_transaction, - terms=terms, - ) - request_nonce = self._get_request_nonce_from_dialogue(signing_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - self.context.decision_maker_message_queue.put_nowait(signing_msg) - - def _send_transaction_request( - self, - signing_msg: SigningMessage, - use_flashbots: bool = False, - target_block_numbers: Optional[List[int]] = None, - chain_id: Optional[str] = None, - raise_on_failed_simulation: bool = False, - ) -> None: - """ - Send transaction request. - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (LedgerApiMessage | SEND_SIGNED_TRANSACTION) -> Ledger connection - Ledger connection -> (LedgerApiMessage | TRANSACTION_DIGEST) -> AbstractRoundAbci skill - - :param signing_msg: signing message - :param use_flashbots: whether to use flashbots for the transaction or not - :param target_block_numbers: the target block numbers in case we are using flashbots - :param chain_id: the chain name to use for the ledger call - :param raise_on_failed_simulation: whether to raise an exception if the simulation fails or not. - """ - ledger_api_dialogues = cast( - LedgerApiDialogues, self.context.ledger_api_dialogues - ) - - create_kwargs: Dict[ - str, Union[str, SignedTransaction, List[SignedTransaction]] - ] = dict( - counterparty=LEDGER_API_ADDRESS, - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, - ) - if chain_id: - kwargs = LedgerApiMessage.Kwargs({"chain_id": chain_id}) - create_kwargs.update(dict(kwargs=kwargs)) - - if use_flashbots: - _kwargs = { - "chain_id": chain_id, - "raise_on_failed_simulation": raise_on_failed_simulation, - "use_all_builders": True, # TODO: make this a proper parameter - } - if target_block_numbers is not None: - _kwargs["target_block_numbers"] = target_block_numbers # type: ignore - create_kwargs.update( - dict( - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS, - # we do not support sending multiple signed txs and receiving multiple tx hashes yet - signed_transactions=LedgerApiMessage.SignedTransactions( - ledger_id=FLASHBOTS_LEDGER_ID, - signed_transactions=[signing_msg.signed_transaction.body], - ), - kwargs=LedgerApiMessage.Kwargs(_kwargs), - ) - ) - else: - create_kwargs.update( - dict( - signed_transaction=signing_msg.signed_transaction, - ) - ) - - ledger_api_msg, ledger_api_dialogue = ledger_api_dialogues.create( - **create_kwargs - ) - ledger_api_dialogue = cast(LedgerApiDialogue, ledger_api_dialogue) - request_nonce = self._get_request_nonce_from_dialogue(ledger_api_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - self.context.outbox.put_message(message=ledger_api_msg) - self.context.logger.debug("Sending transaction to ledger...") - - def _send_transaction_receipt_request( - self, - tx_digest: str, - retry_timeout: Optional[int] = None, - retry_attempts: Optional[int] = None, - **kwargs: Any, - ) -> None: - """ - Send transaction receipt request. - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (LedgerApiMessage | GET_TRANSACTION_RECEIPT) -> Ledger connection - Ledger connection -> (LedgerApiMessage | TRANSACTION_RECEIPT) -> AbstractRoundAbci skill - - :param tx_digest: transaction digest string - :param retry_timeout: retry timeout in seconds - :param retry_attempts: number of retry attempts - """ - ledger_api_dialogues = cast( - LedgerApiDialogues, self.context.ledger_api_dialogues - ) - ledger_api_msg, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=LEDGER_API_ADDRESS, - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, - transaction_digest=LedgerApiMessage.TransactionDigest( - ledger_id=self.context.default_ledger_id, body=tx_digest - ), - retry_timeout=retry_timeout, - retry_attempts=retry_attempts, - kwargs=LedgerApiMessage.Kwargs(kwargs), - ) - ledger_api_dialogue = cast(LedgerApiDialogue, ledger_api_dialogue) - request_nonce = self._get_request_nonce_from_dialogue(ledger_api_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - self.context.outbox.put_message(message=ledger_api_msg) - self.context.logger.debug( - f"Sending transaction receipt request for tx_digest='{tx_digest}'..." - ) - - def _handle_signing_failure(self) -> None: - """Handle signing failure.""" - self.context.logger.error("The transaction could not be signed!") - - def _submit_tx( - self, tx_bytes: bytes, timeout: Optional[float] = None - ) -> Generator[None, None, HttpMessage]: - """Send a broadcast_tx_sync request. - - Happy-path full flow of the messages. - - _do_request: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - :param tx_bytes: transaction bytes - :param timeout: timeout seconds - :yield: HttpMessage object - :return: http response - """ - request_message, http_dialogue = self._build_http_request_message( - "GET", - self.context.params.tendermint_url - + f"/broadcast_tx_sync?tx=0x{tx_bytes.hex()}", - ) - result = yield from self._do_request( - request_message, http_dialogue, timeout=timeout - ) - return result - - def _get_tx_info( - self, tx_hash: str, timeout: Optional[float] = None - ) -> Generator[None, None, HttpMessage]: - """ - Get transaction info from tx hash. - - Happy-path full flow of the messages. - - _do_request: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - :param tx_hash: transaction hash - :param timeout: timeout in seconds - :yield: HttpMessage object - :return: http response - """ - request_message, http_dialogue = self._build_http_request_message( - "GET", - self.context.params.tendermint_url + f"/tx?hash=0x{tx_hash}", - ) - result = yield from self._do_request( - request_message, http_dialogue, timeout=timeout - ) - return result - - def _get_status(self) -> Generator[None, None, HttpMessage]: - """ - Get Tendermint node's status. - - Happy-path full flow of the messages. - - _do_request: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - :yield: HttpMessage object - :return: http response from tendermint - """ - request_message, http_dialogue = self._build_http_request_message( - "GET", - self.context.params.tendermint_url + "/status", - ) - result = yield from self._do_request(request_message, http_dialogue) - return result - - def _get_netinfo( - self, timeout: Optional[float] = None - ) -> Generator[None, None, HttpMessage]: - """Makes a GET request to it's tendermint node's /net_info endpoint.""" - request_message, http_dialogue = self._build_http_request_message( - method="GET", url=f"{self.context.params.tendermint_url}/net_info" - ) - result = yield from self._do_request(request_message, http_dialogue, timeout) - return result - - def num_active_peers( - self, timeout: Optional[float] = None - ) -> Generator[None, None, Optional[int]]: - """Returns the number of active peers in the network.""" - try: - http_response = yield from self._get_netinfo(timeout) - http_ok = 200 - if http_response.status_code != http_ok: - # a bad response was received, we cannot retrieve the number of active peers - self.context.logger.warning( - f"`/net_info` responded with status {http_response.status_code}." - ) - return None - - res_body = json.loads(http_response.body) - num_peers_str = res_body.get("result", {}).get("n_peers", None) - if num_peers_str is None: - return None - num_peers = int(num_peers_str) - # num_peers hold the number of peers the tm node we are - # making the TX to currently has an active connection - # we add 1 because the node we are making the request through - # is not accounted for in this number - return num_peers + 1 - except TimeoutException: - self.context.logger.warning( - f"Couldn't retrieve `/net_info` response in {timeout}s." - ) - return None - - def get_callback_request(self) -> Callable[[Message, "BaseBehaviour"], None]: - """Wrapper for callback request which depends on whether the message has not been handled on time. - - :return: the request callback. - """ - - def callback_request( - message: Message, current_behaviour: BaseBehaviour - ) -> None: - """The callback request.""" - if self.is_stopped: - self.context.logger.debug( - "Dropping message as behaviour has stopped: %s", message - ) - elif self != current_behaviour: - self.handle_late_messages(self.behaviour_id, message) - elif self.state == AsyncBehaviour.AsyncState.WAITING_MESSAGE: - self.try_send(message) - else: - self.context.logger.warning( - "Could not send message to FSMBehaviour: %s", message - ) - - return callback_request - - def get_http_response( - self, - method: str, - url: str, - content: Optional[bytes] = None, - headers: Optional[Dict[str, str]] = None, - parameters: Optional[Dict[str, str]] = None, - ) -> Generator[None, None, HttpMessage]: - """ - Send an http request message from the skill context. - - This method is skill-specific, and therefore - should not be used elsewhere. - - Happy-path full flow of the messages. - - _do_request: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - :param method: the http request method (i.e. 'GET' or 'POST'). - :param url: the url to send the message to. - :param content: the payload. - :param headers: headers to be included. - :param parameters: url query parameters. - :yield: HttpMessage object - :return: the http message and the http dialogue - """ - http_message, http_dialogue = self._build_http_request_message( - method=method, - url=url, - content=content, - headers=headers, - parameters=parameters, - ) - response = yield from self._do_request(http_message, http_dialogue) - return response - - def _do_request( - self, - request_message: HttpMessage, - http_dialogue: HttpDialogue, - timeout: Optional[float] = None, - ) -> Generator[None, None, HttpMessage]: - """ - Do a request and wait the response, asynchronously. - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - :param request_message: The request message - :param http_dialogue: the HTTP dialogue associated to the request - :param timeout: seconds to wait for the reply. - :yield: HttpMessage object - :return: the response message - """ - self.context.outbox.put_message(message=request_message) - request_nonce = self._get_request_nonce_from_dialogue(http_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - # notify caller by propagating potential timeout exception. - response = yield from self.wait_for_message(timeout=timeout) - return response - - def _build_http_request_message( - self, - method: str, - url: str, - content: Optional[bytes] = None, - headers: Optional[Dict[str, str]] = None, - parameters: Optional[Dict[str, str]] = None, - ) -> Tuple[HttpMessage, HttpDialogue]: - """ - Send an http request message from the skill context. - - This method is skill-specific, and therefore - should not be used elsewhere. - - :param method: the http request method (i.e. 'GET' or 'POST'). - :param url: the url to send the message to. - :param content: the payload. - :param headers: headers to be included. - :param parameters: url query parameters. - :return: the http message and the http dialogue - """ - if parameters: - url = url + "?" - for key, val in parameters.items(): - url += f"{key}={val}&" - url = url[:-1] - - header_string = "" - if headers: - for key, val in headers.items(): - header_string += f"{key}: {val}\r\n" - - # context - http_dialogues = cast(HttpDialogues, self.context.http_dialogues) - - # http request message - request_http_message, http_dialogue = http_dialogues.create( - counterparty=str(HTTP_CLIENT_PUBLIC_ID), - performative=HttpMessage.Performative.REQUEST, - method=method, - url=url, - headers=header_string, - version="", - body=b"" if content is None else content, - ) - request_http_message = cast(HttpMessage, request_http_message) - http_dialogue = cast(HttpDialogue, http_dialogue) - return request_http_message, http_dialogue - - def _wait_until_transaction_delivered( - self, - tx_hash: str, - timeout: Optional[float] = None, - max_attempts: Optional[int] = None, - request_retry_delay: Optional[float] = None, - ) -> Generator[None, None, Tuple[bool, Optional[HttpMessage]]]: - """ - Wait until transaction is delivered. - - Happy-path full flow of the messages. - - _get_tx_info: - AbstractRoundAbci skill -> (HttpMessage | REQUEST) -> Http client connection - Http client connection -> (HttpMessage | RESPONSE) -> AbstractRoundAbci skill - - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - - :param tx_hash: the transaction hash to check. - :param timeout: timeout - :param: request_retry_delay: the delay to wait after failed requests - :param: max_attempts: the maximun number of attempts - :yield: None - :return: True if it is delivered successfully, False otherwise - """ - if timeout is not None: - deadline = datetime.datetime.now() + datetime.timedelta(0, timeout) - else: - deadline = datetime.datetime.max - request_retry_delay = ( - self.params.request_retry_delay - if request_retry_delay is None - else request_retry_delay - ) - max_attempts = ( - self.params.max_attempts if max_attempts is None else max_attempts - ) - - response = None - for _ in range(max_attempts): - request_timeout = ( - (deadline - datetime.datetime.now()).total_seconds() - if timeout is not None - else None - ) - if request_timeout is not None and request_timeout < 0: - raise TimeoutException() - - response = yield from self._get_tx_info(tx_hash, timeout=request_timeout) - if response.status_code != 200: - yield from self.sleep(request_retry_delay) - continue - - try: - json_body = json.loads(response.body) - except json.JSONDecodeError as e: # pragma: nocover - raise ValueError( - f"Unable to decode response: {response} with body {str(response.body)}" - ) from e - tx_result = json_body["result"]["tx_result"] - return tx_result["code"] == OK_CODE, response - - return False, response - - @classmethod - def _check_http_return_code_200(cls, response: HttpMessage) -> bool: - """Check the HTTP response has return code 200.""" - return response.status_code == 200 - - def _get_default_terms(self) -> Terms: - """ - Get default transaction terms. - - :return: terms - """ - terms = Terms( - ledger_id=self.context.default_ledger_id, - sender_address=self.context.agent_address, - counterparty_address=self.context.agent_address, - amount_by_currency_id={}, - quantities_by_good_id={}, - nonce="", - ) - return terms - - def get_signature( - self, message: bytes, is_deprecated_mode: bool = False - ) -> Generator[None, None, str]: - """ - Get signature for message. - - Happy-path full flow of the messages. - - _send_signing_request: - AbstractRoundAbci skill -> (SigningMessage | SIGN_MESSAGE) -> DecisionMaker - DecisionMaker -> (SigningMessage | SIGNED_MESSAGE) -> AbstractRoundAbci skill - - :param message: message bytes - :param is_deprecated_mode: is deprecated mode flag - :yield: SigningMessage object - :return: message signature - """ - self._send_signing_request(message, is_deprecated_mode) - signature_response = yield from self.wait_for_message() - signature_response = cast(SigningMessage, signature_response) - if signature_response.performative == SigningMessage.Performative.ERROR: - self._handle_signing_failure() - raise RuntimeError("Internal error: failure during signing.") - signature_bytes = signature_response.signed_message.body - return signature_bytes - - def send_raw_transaction( - self, - transaction: RawTransaction, - use_flashbots: bool = False, - target_block_numbers: Optional[List[int]] = None, - raise_on_failed_simulation: bool = False, - chain_id: Optional[str] = None, - ) -> Generator[ - None, - Union[None, SigningMessage, LedgerApiMessage], - Tuple[Optional[str], RPCResponseStatus], - ]: - """ - Send raw transactions to the ledger for mining. - - Happy-path full flow of the messages. - - _send_transaction_signing_request: - AbstractRoundAbci skill -> (SigningMessage | SIGN_TRANSACTION) -> DecisionMaker - DecisionMaker -> (SigningMessage | SIGNED_TRANSACTION) -> AbstractRoundAbci skill - - _send_transaction_request: - AbstractRoundAbci skill -> (LedgerApiMessage | SEND_SIGNED_TRANSACTION) -> Ledger connection - Ledger connection -> (LedgerApiMessage | TRANSACTION_DIGEST) -> AbstractRoundAbci skill - - :param transaction: transaction data - :param use_flashbots: whether to use flashbots for the transaction or not - :param target_block_numbers: the target block numbers in case we are using flashbots - :param raise_on_failed_simulation: whether to raise an exception if the transaction fails the simulation or not - :param chain_id: the chain name to use for the ledger call - :yield: SigningMessage object - :return: transaction hash - """ - if chain_id is None: - chain_id = self.params.default_chain_id - - terms = Terms( - chain_id, - self.context.agent_address, - counterparty_address="", - amount_by_currency_id={}, - quantities_by_good_id={}, - nonce="", - ) - self.context.logger.info( - f"Sending signing request to ledger '{chain_id}' for transaction: {transaction}..." - ) - self._send_transaction_signing_request(transaction, terms) - signature_response = yield from self.wait_for_message() - signature_response = cast(SigningMessage, signature_response) - tx_hash_backup = signature_response.signed_transaction.body.get("hash") - if ( - signature_response.performative - != SigningMessage.Performative.SIGNED_TRANSACTION - ): - self.context.logger.error( - f"Error when requesting transaction signature: {signature_response}" - ) - return None, RPCResponseStatus.UNCLASSIFIED_ERROR - self.context.logger.info( - f"Received signature response: {signature_response}\n Sending transaction..." - ) - self._send_transaction_request( - signature_response, - use_flashbots, - target_block_numbers, - chain_id, - raise_on_failed_simulation, - ) - transaction_digest_msg = yield from self.wait_for_message() - transaction_digest_msg = cast(LedgerApiMessage, transaction_digest_msg) - performative = transaction_digest_msg.performative - if performative not in ( - LedgerApiMessage.Performative.TRANSACTION_DIGEST, - LedgerApiMessage.Performative.TRANSACTION_DIGESTS, - ): - error = f"Error when requesting transaction digest: {transaction_digest_msg.message}" - self.context.logger.error(error) - return tx_hash_backup, self.__parse_rpc_error(error) - - tx_hash = ( - # we do not support sending multiple messages and receiving multiple tx hashes yet - transaction_digest_msg.transaction_digests.transaction_digests[0] - if performative == LedgerApiMessage.Performative.TRANSACTION_DIGESTS - else transaction_digest_msg.transaction_digest.body - ) - - self.context.logger.info( - f"Transaction sent! Received transaction digest: {tx_hash}" - ) - - if tx_hash != tx_hash_backup: - # this should never happen - self.context.logger.error( - f"Unexpected error! The signature response's hash `{tx_hash_backup}` " - f"does not match the one received from the transaction response `{tx_hash}`!" - ) - return None, RPCResponseStatus.UNCLASSIFIED_ERROR - - return tx_hash, RPCResponseStatus.SUCCESS - - def get_transaction_receipt( - self, - tx_digest: str, - retry_timeout: Optional[int] = None, - retry_attempts: Optional[int] = None, - chain_id: Optional[str] = None, - ) -> Generator[None, None, Optional[Dict]]: - """ - Get transaction receipt. - - Happy-path full flow of the messages. - - _send_transaction_receipt_request: - AbstractRoundAbci skill -> (LedgerApiMessage | GET_TRANSACTION_RECEIPT) -> Ledger connection - Ledger connection -> (LedgerApiMessage | TRANSACTION_RECEIPT) -> AbstractRoundAbci skill - - :param tx_digest: transaction digest received from raw transaction. - :param retry_timeout: retry timeout. - :param retry_attempts: number of retry attempts allowed. - :yield: LedgerApiMessage object - :return: transaction receipt data - """ - if chain_id is None: - chain_id = self.params.default_chain_id - self._send_transaction_receipt_request( - tx_digest, retry_timeout, retry_attempts, chain_id=chain_id - ) - transaction_receipt_msg = yield from self.wait_for_message() - if ( - transaction_receipt_msg.performative == LedgerApiMessage.Performative.ERROR - ): # pragma: nocover - self.context.logger.error( - f"Error when requesting transaction receipt: {transaction_receipt_msg.message}" - ) - return None - tx_receipt = transaction_receipt_msg.transaction_receipt.receipt - return tx_receipt - - def get_ledger_api_response( - self, - performative: LedgerApiMessage.Performative, - ledger_callable: str, - **kwargs: Any, - ) -> Generator[None, None, LedgerApiMessage]: - """ - Request data from ledger api - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (LedgerApiMessage | LedgerApiMessage.Performative) -> Ledger connection - Ledger connection -> (LedgerApiMessage | LedgerApiMessage.Performative) -> AbstractRoundAbci skill - - :param performative: the message performative - :param ledger_callable: the callable to call on the contract - :param kwargs: keyword argument for the contract api request - :return: the contract api response - :yields: the contract api response - """ - ledger_api_dialogues = cast( - LedgerApiDialogues, self.context.ledger_api_dialogues - ) - kwargs = { - "performative": performative, - "counterparty": LEDGER_API_ADDRESS, - "ledger_id": self.context.default_ledger_id, - "callable": ledger_callable, - "kwargs": LedgerApiMessage.Kwargs(kwargs), - "args": tuple(), - } - ledger_api_msg, ledger_api_dialogue = ledger_api_dialogues.create(**kwargs) - ledger_api_dialogue = cast( - LedgerApiDialogue, - ledger_api_dialogue, - ) - ledger_api_dialogue.terms = self._get_default_terms() - request_nonce = self._get_request_nonce_from_dialogue(ledger_api_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - self.context.outbox.put_message(message=ledger_api_msg) - response = yield from self.wait_for_message() - return response - - def get_contract_api_response( - self, - performative: ContractApiMessage.Performative, - contract_address: Optional[str], - contract_id: str, - contract_callable: str, - ledger_id: Optional[str] = None, - **kwargs: Any, - ) -> Generator[None, None, ContractApiMessage]: - """ - Request contract safe transaction hash - - Happy-path full flow of the messages. - - AbstractRoundAbci skill -> (ContractApiMessage | ContractApiMessage.Performative) -> Ledger connection (contract dispatcher) - Ledger connection (contract dispatcher) -> (ContractApiMessage | ContractApiMessage.Performative) -> AbstractRoundAbci skill - - :param performative: the message performative - :param contract_address: the contract address - :param contract_id: the contract id - :param contract_callable: the callable to call on the contract - :param ledger_id: the ledger id, if not specified, the default ledger id is used - :param kwargs: keyword argument for the contract api request - :return: the contract api response - :yields: the contract api response - """ - contract_api_dialogues = cast( - ContractApiDialogues, self.context.contract_api_dialogues - ) - kwargs = { - "performative": performative, - "counterparty": LEDGER_API_ADDRESS, - "ledger_id": ledger_id or self.context.default_ledger_id, - "contract_id": contract_id, - "callable": contract_callable, - "kwargs": ContractApiMessage.Kwargs(kwargs), - } - if contract_address is not None: - kwargs["contract_address"] = contract_address - contract_api_msg, contract_api_dialogue = contract_api_dialogues.create( - **kwargs - ) - contract_api_dialogue = cast( - ContractApiDialogue, - contract_api_dialogue, - ) - contract_api_dialogue.terms = self._get_default_terms() - request_nonce = self._get_request_nonce_from_dialogue(contract_api_dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - self.context.outbox.put_message(message=contract_api_msg) - response = yield from self.wait_for_message() - return response - - @staticmethod - def __parse_rpc_error(error: str) -> RPCResponseStatus: - """Parse an RPC error and return an `RPCResponseStatus`""" - if "replacement transaction underpriced" in error: - return RPCResponseStatus.UNDERPRICED - if "nonce too low" in error: - return RPCResponseStatus.INCORRECT_NONCE - if "insufficient funds" in error: - return RPCResponseStatus.INSUFFICIENT_FUNDS - if "already known" in error: - return RPCResponseStatus.ALREADY_KNOWN - if "Simulation failed for bundle" in error: - return RPCResponseStatus.SIMULATION_FAILED - return RPCResponseStatus.UNCLASSIFIED_ERROR - - def _acn_request_from_pending( - self, performative: TendermintMessage.Performative - ) -> Generator: - """Perform an ACN request to each one of the agents which have not sent a response yet.""" - not_responded_yet = { - address - for address, deliverable in self.shared_state.address_to_acn_deliverable.items() - if deliverable is None - } - - if len(not_responded_yet) == 0: - return - - self.context.logger.debug(f"Need ACN response from {not_responded_yet}.") - for address in not_responded_yet: - self.context.logger.debug(f"Sending ACN request to {address}.") - dialogues = cast(TendermintDialogues, self.context.tendermint_dialogues) - message, _ = dialogues.create( - counterparty=address, performative=performative - ) - message = cast(TendermintMessage, message) - context = EnvelopeContext(connection_id=P2P_LIBP2P_CLIENT_PUBLIC_ID) - self.context.outbox.put_message(message=message, context=context) - - # we wait for the `address_to_acn_deliverable` to be populated with the responses (done by the tm handler) - yield from self.sleep(self.params.sleep_time) - - def _perform_acn_request( - self, performative: TendermintMessage.Performative - ) -> Generator[None, None, Any]: - """Perform an ACN request. - - Waits `sleep_time` to receive a common response from the majority of the agents. - Retries `max_attempts` times only for the agents which have not responded yet. - - :param performative: the ACN request performative. - :return: the result that the majority of the agents sent. If majority cannot be reached, returns `None`. - """ - # reset the ACN deliverables at the beginning of a new request - self.shared_state.address_to_acn_deliverable = self.shared_state.acn_container() - - result = None - for i in range(self.params.max_attempts): - self.context.logger.debug( - f"ACN attempt {i + 1}/{self.params.max_attempts}." - ) - yield from self._acn_request_from_pending(performative) - - result = self.shared_state.get_acn_result() - if result is not None: - break - - return result - - def request_recovery_params(self, should_log: bool) -> Generator[None, None, bool]: - """Request the Tendermint recovery parameters from the other agents via the ACN.""" - - if should_log: - self.context.logger.info( - "Requesting the Tendermint recovery parameters from the other agents via the ACN..." - ) - - performative = TendermintMessage.Performative.GET_RECOVERY_PARAMS - acn_result = yield from self._perform_acn_request(performative) # type: ignore - - if acn_result is None: - if should_log: - self.context.logger.warning( - "No majority has been reached for the Tendermint recovery parameters request via the ACN." - ) - return False - - self.shared_state.tm_recovery_params = acn_result - if should_log: - self.context.logger.info( - f"Updated the Tendermint recovery parameters from the other agents via the ACN: {acn_result}" - ) - return True - - @property - def hard_reset_sleep(self) -> float: - """ - Amount of time to sleep before and after performing a hard reset. - - We sleep for half the reset pause duration as there are no immediate transactions on either side of the reset. - - :returns: the amount of time to sleep in seconds - """ - return self.params.reset_pause_duration / 2 - - def _start_reset(self, on_startup: bool = False) -> Generator: - """ - Start tendermint reset. - - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - - :param on_startup: Whether we are resetting on the start of the agent. - :yield: None - """ - if self._check_started is None and not self._is_healthy: - if not on_startup: - # if we are on startup we don't need to wait for the reset pause duration - # as the reset is being performed to update the tm config. - yield from self.wait_from_last_timestamp(self.hard_reset_sleep) - self._check_started = datetime.datetime.now() - self._timeout = self.params.max_healthcheck - self._is_healthy = False - yield - - def _end_reset( - self, - ) -> None: - """End tendermint reset. - - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - """ - self._check_started = None - self._timeout = -1.0 - self._is_healthy = True - - def _is_timeout_expired(self) -> bool: - """Check if the timeout expired. - - This is a local method that does not depend on the global clock, - so the usage of datetime.now() is acceptable here. - - :return: bool - """ - if self._check_started is None or self._is_healthy: - return False - return datetime.datetime.now() > self._check_started + datetime.timedelta( - 0, self._timeout - ) - - def _get_reset_params(self, default: bool) -> Optional[Dict[str, str]]: - """Get the parameters for a hard reset request to Tendermint.""" - if default: - return None - - last_round_transition_timestamp = ( - self.round_sequence.last_round_transition_timestamp - ) - genesis_time = last_round_transition_timestamp.astimezone(pytz.UTC).strftime( - GENESIS_TIME_FMT - ) - return { - "genesis_time": genesis_time, - "initial_height": INITIAL_HEIGHT, - "period_count": str(self.synchronized_data.period_count), - } - - def reset_tendermint_with_wait( # pylint: disable=too-many-locals, too-many-statements - self, - on_startup: bool = False, - is_recovery: bool = False, - ) -> Generator[None, None, bool]: - """ - Performs a hard reset (unsafe-reset-all) on the tendermint node. - - :param on_startup: whether we are resetting on the start of the agent. - :param is_recovery: whether the reset is being performed to recover the agent <-> tm communication. - :yields: None - :returns: whether the reset was successful. - """ - yield from self._start_reset(on_startup=on_startup) - if self._is_timeout_expired(): - # if the Tendermint node cannot update the app then the app cannot work - raise RuntimeError("Error resetting tendermint node.") - - if not self._is_healthy: - self.context.logger.info( - f"Resetting tendermint node at end of period={self.synchronized_data.period_count}." - ) - - backup_blockchain = self.round_sequence.blockchain - self.round_sequence.reset_blockchain() - reset_params = self._get_reset_params(on_startup) - request_message, http_dialogue = self._build_http_request_message( - "GET", - self.params.tendermint_com_url + "/hard_reset", - parameters=reset_params, - ) - result = yield from self._do_request(request_message, http_dialogue) - try: - response = json.loads(result.body.decode()) - if response.get("status"): - self.context.logger.debug(response.get("message")) - self.context.logger.info("Resetting tendermint node successful!") - is_replay = response.get("is_replay", False) - if is_replay: - # in case of replay, the local blockchain should be set up differently. - self.round_sequence.reset_blockchain( - is_replay=is_replay, is_init=True - ) - for handler_name in self.context.handlers.__dict__.keys(): - dialogues = getattr(self.context, f"{handler_name}_dialogues") - dialogues.cleanup() - if not is_recovery: - # in case of successful reset we store the reset params in the shared state, - # so that in the future if the communication with tendermint breaks, and we need to - # perform a hard reset to restore it, we can use these as the right ones - round_count = self.synchronized_data.db.round_count - 1 - # in case we need to reset in order to recover agent <-> tm communication - # we store this round as the one to start from - restart_from_round = self.matching_round - self.shared_state.tm_recovery_params = TendermintRecoveryParams( - reset_params=reset_params, - round_count=round_count, - reset_from_round=restart_from_round.auto_round_id(), - serialized_db_state=self.shared_state.synchronized_data.db.serialize(), - ) - self.round_sequence.abci_app.cleanup( - self.params.cleanup_history_depth, - self.params.cleanup_history_depth_current, - ) - self._end_reset() - - else: - msg = response.get("message") - self.round_sequence.blockchain = backup_blockchain - self.context.logger.error(f"Error resetting: {msg}") - yield from self.sleep(self.params.sleep_time) - return False - except json.JSONDecodeError: - self.context.logger.error( - "Error communicating with tendermint com server." - ) - self.round_sequence.blockchain = backup_blockchain - yield from self.sleep(self.params.sleep_time) - return False - - status = yield from self._get_status() - try: - json_body = json.loads(status.body.decode()) - except json.JSONDecodeError: - self.context.logger.error( - "Tendermint not accepting transactions yet, trying again!" - ) - yield from self.sleep(self.params.sleep_time) - return False - - remote_height = int(json_body["result"]["sync_info"]["latest_block_height"]) - local_height = self.round_sequence.height - if local_height != remote_height: - self.context.logger.warning( - f"local height ({local_height}) != remote height ({remote_height}); retrying..." - ) - yield from self.sleep(self.params.sleep_time) - return False - - self.context.logger.info( - f"local height == remote height == {local_height}; continuing execution..." - ) - if not on_startup: - # if we are on startup we don't need to wait for the reset pause duration - # as the reset is being performed to update the tm config. - yield from self.wait_from_last_timestamp(self.hard_reset_sleep) - self._is_healthy = False - return True - - def send_to_ipfs( # pylint: disable=too-many-arguments - self, - filename: str, - obj: SupportedObjectType, - multiple: bool = False, - filetype: Optional[SupportedFiletype] = None, - custom_storer: Optional[CustomStorerType] = None, - timeout: Optional[float] = None, - **kwargs: Any, - ) -> Generator[None, None, Optional[str]]: - """ - Store an object on IPFS. - - :param filename: the file name to store obj in. If "multiple" is True, filename will be the name of the dir. - :param obj: the object(s) to serialize and store in IPFS as "filename". - :param multiple: whether obj should be stored as multiple files, i.e. directory. - :param filetype: the file type of the object being downloaded. - :param custom_storer: a custom serializer for "obj". - :param timeout: timeout for the request. - :returns: the downloaded object, corresponding to ipfs_hash. - """ - try: - message, dialogue = self._build_ipfs_store_file_req( - filename, - obj, - multiple, - filetype, - custom_storer, - timeout, - **kwargs, - ) - ipfs_message = yield from self._do_ipfs_request(dialogue, message, timeout) - if ipfs_message.performative != IpfsMessage.Performative.IPFS_HASH: - self.context.logger.error( - f"Expected performative {IpfsMessage.Performative.IPFS_HASH} but got {ipfs_message.performative}." - ) - return None - ipfs_hash = ipfs_message.ipfs_hash - self.context.logger.info( - f"Successfully stored {filename} to IPFS with hash: {ipfs_hash}" - ) - return ipfs_hash - except IPFSInteractionError as e: # pragma: no cover - self.context.logger.error( - f"An error occurred while trying to send a file to IPFS: {str(e)}" - ) - return None - - def get_from_ipfs( # pylint: disable=too-many-arguments - self, - ipfs_hash: str, - filetype: Optional[SupportedFiletype] = None, - custom_loader: CustomLoaderType = None, - timeout: Optional[float] = None, - ) -> Generator[None, None, Optional[SupportedObjectType]]: - """ - Gets an object from IPFS. - - :param ipfs_hash: the ipfs hash of the file/dir to download. - :param filetype: the file type of the object being downloaded. - :param custom_loader: a custom deserializer for the object received from IPFS. - :param timeout: timeout for the request. - :returns: the downloaded object, corresponding to ipfs_hash. - """ - try: - message, dialogue = self._build_ipfs_get_file_req(ipfs_hash, timeout) - ipfs_message = yield from self._do_ipfs_request(dialogue, message, timeout) - if ipfs_message.performative != IpfsMessage.Performative.FILES: - self.context.logger.error( - f"Expected performative {IpfsMessage.Performative.FILES} but got {ipfs_message.performative}." - ) - return None - serialized_objects = ipfs_message.files - deserialized_objects = self._deserialize_ipfs_objects( - serialized_objects, filetype, custom_loader - ) - self.context.logger.info( - f"Retrieved {len(ipfs_message.files)} objects from ipfs." - ) - return deserialized_objects - except IPFSInteractionError as e: - self.context.logger.error( - f"An error occurred while trying to fetch a file from IPFS: {str(e)}" - ) - return None - - def _do_ipfs_request( - self, - dialogue: IpfsDialogue, - message: IpfsMessage, - timeout: Optional[float] = None, - ) -> Generator[None, None, IpfsMessage]: - """Performs an IPFS request, and asynchronosuly waits for response.""" - self.context.outbox.put_message(message=message) - request_nonce = self._get_request_nonce_from_dialogue(dialogue) - cast(Requests, self.context.requests).request_id_to_callback[ - request_nonce - ] = self.get_callback_request() - # notify caller by propagating potential timeout exception. - response = yield from self.wait_for_message(timeout=timeout) - ipfs_message = cast(IpfsMessage, response) - return ipfs_message - - -class TmManager(BaseBehaviour): - """Util class to be used for managing the tendermint node.""" - - _active_generator: Optional[Generator] = None - _hard_reset_sleep = 20.0 # 20s - _max_reset_retry = 5 - - # TODO: TmManager is not a BaseBehaviour. It should be - # redesigned! - matching_round = Type[AbstractRound] - - def __init__(self, **kwargs: Any): - """Initialize the `TmManager`.""" - super().__init__(**kwargs) - # whether the initiation of a tm fix has been logged - self.informed: bool = False - self.acn_communication_attempted: bool = False - - def async_act(self) -> Generator: - """The behaviour act.""" - self.context.logger.error( - f"{type(self).__name__}'s async_act was called. " - f"This is not allowed as this class is not a behaviour. " - f"Exiting the agent." - ) - error_code = 1 - yield - sys.exit(error_code) - - @property - def is_acting(self) -> bool: - """This method returns whether there is an active fix being applied.""" - return self._active_generator is not None - - @property - def hard_reset_sleep(self) -> float: - """ - Amount of time to sleep before and after performing a hard reset. - - We don't need to wait for half the reset pause duration, like in normal cases where we perform a hard reset. - - :returns: the amount of time to sleep in seconds - """ - return self._hard_reset_sleep - - def _gentle_reset(self) -> Generator[None, None, None]: - """Perform a gentle reset of the Tendermint node.""" - self.context.logger.debug("Performing a gentle reset...") - request_message, http_dialogue = self._build_http_request_message( - "GET", - self.params.tendermint_com_url + "/gentle_reset", - ) - yield from self._do_request(request_message, http_dialogue) - - def _handle_unhealthy_tm(self) -> Generator: - """This method handles the case when the tendermint node is unhealthy.""" - if not self.informed: - self.context.logger.warning( - "The local deadline for the next `begin_block` request from the Tendermint node has expired! " - "Trying to reset local Tendermint node as there could be something wrong with the communication." - ) - self.informed = True - - if not self.gentle_reset_attempted: - self.gentle_reset_attempted = True - yield from self._gentle_reset() - yield from self._check_sync() - return - - is_multi_agent_service = self.synchronized_data.max_participants > 1 - if is_multi_agent_service: - # since we have reached this point, that means that the cause of blocks not being received - # cannot be fixed with a simple gentle reset, - # therefore, we request the recovery parameters via the ACN, and if we succeed, we use them to recover - # we do not need to request the recovery parameters if this is a single-agent service - acn_communication_success = yield from self.request_recovery_params( - should_log=not self.acn_communication_attempted - ) - if not acn_communication_success: - if not self.acn_communication_attempted: - self.context.logger.error( - "Failed to get the recovery parameters via the ACN. Cannot reset Tendermint." - ) - self.acn_communication_attempted = True - return - - recovery_params = self.shared_state.tm_recovery_params - self.round_sequence.reset_state( - restart_from_round=recovery_params.reset_from_round, - round_count=recovery_params.round_count, - serialized_db_state=recovery_params.serialized_db_state, - ) - - for _ in range(self._max_reset_retry): - reset_successfully = yield from self.reset_tendermint_with_wait( - on_startup=True, - is_recovery=True, - ) - if reset_successfully: - self.context.logger.info("Tendermint reset was successfully performed.") - # we sleep to give some time for tendermint to start sending us blocks - # otherwise we might end-up assuming that tendermint is still not working. - # Note that the wait_from_last_timestamp() in reset_tendermint_with_wait() - # doesn't guarantee us this, since the block stall deadline is greater than the - # hard_reset_sleep, 60s vs 20s. In other words, we haven't received a block for at - # least 60s, so wait_from_last_timestamp() will return immediately. - # By setting "on_startup" to True in the reset_tendermint_with_wait() call above, - # wait_from_last_timestamp() will not be called at all. - yield from self.sleep(self.hard_reset_sleep) - self.gentle_reset_attempted = False - return - - self.context.logger.error("Failed to reset tendermint.") - - def _get_reset_params(self, default: bool) -> Optional[Dict[str, str]]: - """ - Get the parameters for a hard reset request when trying to recover agent <-> tendermint communication. - - :param default: ignored for this use case. - :returns: the reset params. - """ - # we get the params from the latest successful reset, if they are not available, - # i.e. no successful reset has been performed, we return None. - # Returning None means default params will be used. - return self.shared_state.tm_recovery_params.reset_params - - def get_callback_request(self) -> Callable[[Message, "BaseBehaviour"], None]: - """Wrapper for callback_request(), overridden to remove checks not applicable to TmManager.""" - - def callback_request( - message: Message, _current_behaviour: BaseBehaviour - ) -> None: - """ - This method gets called when a response for a prior request is received. - - Overridden to remove the check that checks whether the behaviour that made the request is still active. - The received message gets passed to the behaviour that invoked it, in this case it's always the TmManager. - - :param message: the response. - :param _current_behaviour: not used, left in to satisfy the interface. - :return: none - """ - if self.state == AsyncBehaviour.AsyncState.WAITING_MESSAGE: - self.try_send(message) - else: - self.context.logger.warning( - "Could not send message to TmManager: %s", message - ) - - return callback_request - - def try_fix(self) -> None: - """This method tries to fix an unhealthy tendermint node.""" - if self._active_generator is None: - # There is no active generator set, we need to create one. - # A generator being active means that a reset operation is - # being performed. - self._active_generator = self._handle_unhealthy_tm() - try: - # if the behaviour is waiting for a message - # we check whether one has arrived, and if it has - # we send it to the generator. - if self.state == self.AsyncState.WAITING_MESSAGE: - if self.is_notified: - self._active_generator.send(self.received_message) - self._on_sent_message() - # note that if the behaviour is waiting for - # a message, we deliberately don't send a tick - # this was done to have consistency between - # the act here, and acts on normal AsyncBehaviours - return - # this will run the active generator until - # the first yield statement is encountered - self._active_generator.send(None) - - except StopIteration: - # the generator is finished - self.context.logger.debug("Applying tendermint fix finished.") - self._active_generator = None - # the following is required because the message - # 'tick' might be the last one the generator needs - # to complete. In that scenario, we need to call - # the callback here - if self.is_notified: - self._on_sent_message() - - -class DegenerateBehaviour(BaseBehaviour, ABC): - """An abstract matching behaviour for final and degenerate rounds.""" - - matching_round: Type[AbstractRound] - is_degenerate: bool = True - sleep_time_before_exit = 5.0 - - def async_act(self) -> Generator: - """Exit the agent with error when a degenerate round is reached.""" - self.context.logger.error( - "The execution reached a degenerate behaviour. " - "This means a degenerate round has been reached during " - "the execution of the ABCI application. Please check the " - "functioning of the ABCI app." - ) - self.context.logger.error( - f"Sleeping {self.sleep_time_before_exit} seconds before exiting." - ) - yield from self.sleep(self.sleep_time_before_exit) - error_code = 1 - sys.exit(error_code) - - -def make_degenerate_behaviour( - round_cls: Type[AbstractRound], -) -> Type[DegenerateBehaviour]: - """Make a degenerate behaviour class.""" - - class NewDegenerateBehaviour(DegenerateBehaviour): - """A newly defined degenerate behaviour class.""" - - matching_round = round_cls - - new_behaviour_cls = NewDegenerateBehaviour - new_behaviour_cls.__name__ = f"DegenerateBehaviour_{round_cls.auto_round_id()}" # pylint: disable=attribute-defined-outside-init - return new_behaviour_cls diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/behaviours.py b/trader_old/vendor/valory/skills/abstract_round_abci/behaviours.py deleted file mode 100644 index fcf69ea0c..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/behaviours.py +++ /dev/null @@ -1,409 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the behaviours for the 'abstract_round_abci' skill.""" - -from abc import ABC, ABCMeta -from collections import defaultdict -from dataclasses import asdict -from typing import ( - AbstractSet, - Any, - Dict, - Generator, - Generic, - List, - Optional, - Set, - Tuple, - Type, - cast, -) - -from aea.skills.base import Behaviour - -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciApp, - AbstractRound, - EventType, - PendingOffencesPayload, - PendingOffencesRound, - PendingOffense, - RoundSequence, -) -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - BaseBehaviour, - TmManager, - make_degenerate_behaviour, -) -from packages.valory.skills.abstract_round_abci.models import SharedState - - -SLASHING_BACKGROUND_BEHAVIOUR_ID = "slashing_check_behaviour" -TERMINATION_BACKGROUND_BEHAVIOUR_ID = "background_behaviour" - - -BehaviourType = Type[BaseBehaviour] -Action = Optional[str] -TransitionFunction = Dict[BehaviourType, Dict[Action, BehaviourType]] - - -class _MetaRoundBehaviour(ABCMeta): - """A metaclass that validates AbstractRoundBehaviour's attributes.""" - - are_background_behaviours_set: bool = False - - def __new__(mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any) -> Type: # type: ignore - """Initialize the class.""" - new_cls = super().__new__(mcs, name, bases, namespace, **kwargs) - - if ABC in bases: - # abstract class, return - return new_cls - if not issubclass(new_cls, AbstractRoundBehaviour): - # the check only applies to AbstractRoundBehaviour subclasses - return new_cls - - mcs.are_background_behaviours_set = bool( - new_cls.background_behaviours_cls - {PendingOffencesBehaviour} - ) - mcs._check_consistency(cast(AbstractRoundBehaviour, new_cls)) - return new_cls - - @classmethod - def _check_consistency(mcs, behaviour_cls: "AbstractRoundBehaviour") -> None: - """Check consistency of class attributes.""" - mcs._check_all_required_classattributes_are_set(behaviour_cls) - mcs._check_behaviour_id_uniqueness(behaviour_cls) - mcs._check_initial_behaviour_in_set_of_behaviours(behaviour_cls) - mcs._check_matching_round_consistency(behaviour_cls) - - @classmethod - def _check_all_required_classattributes_are_set( - mcs, behaviour_cls: "AbstractRoundBehaviour" - ) -> None: - """Check that all the required class attributes are set.""" - try: - _ = behaviour_cls.abci_app_cls - _ = behaviour_cls.behaviours - _ = behaviour_cls.initial_behaviour_cls - except AttributeError as e: - raise ABCIAppInternalError(*e.args) from None - - @classmethod - def _check_behaviour_id_uniqueness( - mcs, behaviour_cls: "AbstractRoundBehaviour" - ) -> None: - """Check that behaviour ids are unique across behaviours.""" - behaviour_id_to_behaviour = defaultdict(lambda: []) - for behaviour_class in behaviour_cls.behaviours: - behaviour_id_to_behaviour[behaviour_class.auto_behaviour_id()].append( - behaviour_class - ) - if len(behaviour_id_to_behaviour[behaviour_class.auto_behaviour_id()]) > 1: - behaviour_classes_names = [ - _behaviour_cls.__name__ - for _behaviour_cls in behaviour_id_to_behaviour[ - behaviour_class.auto_behaviour_id() - ] - ] - raise ABCIAppInternalError( - f"behaviours {behaviour_classes_names} have the same behaviour id '{behaviour_class.auto_behaviour_id()}'" - ) - - @classmethod - def _check_matching_round_consistency( - mcs, behaviour_cls: "AbstractRoundBehaviour" - ) -> None: - """Check that matching rounds are: (1) unique across behaviour, and (2) covering.""" - matching_bg_round_classes = { - behaviour_cls.matching_round - for behaviour_cls in behaviour_cls.background_behaviours_cls - } - round_to_behaviour: Dict[Type[AbstractRound], List[BehaviourType]] = { - round_cls: [] - for round_cls in behaviour_cls.abci_app_cls.get_all_round_classes( - matching_bg_round_classes, - mcs.are_background_behaviours_set, - ) - } - - # check uniqueness - for b in behaviour_cls.behaviours: - behaviours = round_to_behaviour.get(b.matching_round, None) - if behaviours is None: - raise ABCIAppInternalError( - f"Behaviour {b.behaviour_id!r} specifies unknown {b.matching_round!r} as a matching round. " - "Please make sure that the round is implemented and belongs to the FSM. " - f"If {b.behaviour_id!r} is a background behaviour, please make sure that it is set correctly, " - f"by overriding the corresponding attribute of the chained skill's behaviour." - ) - behaviours.append(b) - if len(behaviours) > 1: - behaviour_cls_ids = [ - behaviour_cls_.auto_behaviour_id() for behaviour_cls_ in behaviours - ] - raise ABCIAppInternalError( - f"behaviours {behaviour_cls_ids} have the same matching round '{b.matching_round.auto_round_id()}'" - ) - - # check covering - for round_cls, behaviours in round_to_behaviour.items(): - if round_cls in behaviour_cls.abci_app_cls.final_states: - if len(behaviours) != 0: - raise ABCIAppInternalError( - f"round {round_cls.auto_round_id()} is a final round it shouldn't have any matching behaviours." - ) - elif len(behaviours) == 0: - raise ABCIAppInternalError( - f"round {round_cls.auto_round_id()} is not a matching round of any behaviour" - ) - - @classmethod - def _check_initial_behaviour_in_set_of_behaviours( - mcs, behaviour_cls: "AbstractRoundBehaviour" - ) -> None: - """Check the initial behaviour is in the set of behaviours.""" - if behaviour_cls.initial_behaviour_cls not in behaviour_cls.behaviours: - raise ABCIAppInternalError( - f"initial behaviour {behaviour_cls.initial_behaviour_cls.auto_behaviour_id()} is not in the set of behaviours" - ) - - -class PendingOffencesBehaviour(BaseBehaviour): - """A behaviour responsible for checking whether there are any pending offences.""" - - matching_round = PendingOffencesRound - - @property - def round_sequence(self) -> RoundSequence: - """Get the round sequence from the shared state.""" - return cast(SharedState, self.context.state).round_sequence - - @property - def pending_offences(self) -> Set[PendingOffense]: - """Get the pending offences from the round sequence.""" - return self.round_sequence.pending_offences - - def has_pending_offences(self) -> bool: - """Check if there are any pending offences.""" - return bool(len(self.pending_offences)) - - def async_act(self) -> Generator: - """ - Checks the pending offences. - - This behaviour simply checks if the set of pending offences is not empty. - When it’s not empty, it pops the offence from the set, and sends it to the rest of the agents via a payload - - :return: None - :yield: None - """ - yield from self.wait_for_condition(self.has_pending_offences) - offence = self.pending_offences.pop() - offence_detected_log = ( - f"An offence of type {offence.offense_type.name} has been detected " - f"for agent with address {offence.accused_agent_address} during round {offence.round_count}. " - ) - offence_expiration = offence.last_transition_timestamp + offence.time_to_live - last_timestamp = self.round_sequence.last_round_transition_timestamp - - if offence_expiration < last_timestamp.timestamp(): - ignored_log = "Offence will be ignored as it has expired." - self.context.logger.info(offence_detected_log + ignored_log) - return - - sharing_log = "Sharing offence with the other agents." - self.context.logger.info(offence_detected_log + sharing_log) - - payload = PendingOffencesPayload( - self.context.agent_address, *asdict(offence).values() - ) - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - self.set_done() - - -class AbstractRoundBehaviour( # pylint: disable=too-many-instance-attributes - Behaviour, ABC, Generic[EventType], metaclass=_MetaRoundBehaviour -): - """This behaviour implements an abstract round behaviour.""" - - abci_app_cls: Type[AbciApp[EventType]] - behaviours: AbstractSet[BehaviourType] - initial_behaviour_cls: BehaviourType - background_behaviours_cls: Set[BehaviourType] = {PendingOffencesBehaviour} # type: ignore - - def __init__(self, **kwargs: Any) -> None: - """Initialize the behaviour.""" - super().__init__(**kwargs) - self._behaviour_id_to_behaviours: Dict[ - str, BehaviourType - ] = self._get_behaviour_id_to_behaviour_mapping(self.behaviours) - self._round_to_behaviour: Dict[ - Type[AbstractRound], BehaviourType - ] = self._get_round_to_behaviour_mapping(self.behaviours) - - self.current_behaviour: Optional[BaseBehaviour] = None - self.background_behaviours: Set[BaseBehaviour] = set() - self.tm_manager: Optional[TmManager] = None - # keep track of last round height so to detect changes - self._last_round_height = 0 - - # this variable remembers the actual next transition - # when we cannot preemptively interrupt the current behaviour - # because it has not a matching round. - self._next_behaviour_cls: Optional[BehaviourType] = None - - @classmethod - def _get_behaviour_id_to_behaviour_mapping( - cls, behaviours: AbstractSet[BehaviourType] - ) -> Dict[str, BehaviourType]: - """Get behaviour id to behaviour mapping.""" - result: Dict[str, BehaviourType] = {} - for behaviour_cls in behaviours: - behaviour_id = behaviour_cls.auto_behaviour_id() - if behaviour_id in result: - raise ValueError( - f"cannot have two behaviours with the same id; got {behaviour_cls} and {result[behaviour_id]} both with id '{behaviour_id}'" - ) - result[behaviour_id] = behaviour_cls - return result - - @classmethod - def _get_round_to_behaviour_mapping( - cls, behaviours: AbstractSet[BehaviourType] - ) -> Dict[Type[AbstractRound], BehaviourType]: - """Get round-to-behaviour mapping.""" - result: Dict[Type[AbstractRound], BehaviourType] = {} - for behaviour_cls in behaviours: - round_cls = behaviour_cls.matching_round - if round_cls in result: - raise ValueError( - f"the behaviours '{behaviour_cls.auto_behaviour_id()}' and '{result[round_cls].auto_behaviour_id()}' point to the same matching round '{round_cls.auto_round_id()}'" - ) - result[round_cls] = behaviour_cls - - # iterate over rounds and map final (i.e. degenerate) rounds - # to the degenerate behaviour class - for final_round_cls in cls.abci_app_cls.final_states: - new_degenerate_behaviour = make_degenerate_behaviour(final_round_cls) - new_degenerate_behaviour.matching_round = final_round_cls - result[final_round_cls] = new_degenerate_behaviour - - return result - - def instantiate_behaviour_cls(self, behaviour_cls: BehaviourType) -> BaseBehaviour: - """Instantiate the behaviours class.""" - return behaviour_cls( - name=behaviour_cls.auto_behaviour_id(), skill_context=self.context - ) - - def _setup_background(self) -> None: - """Set up the background behaviours.""" - params = cast(BaseBehaviour, self.current_behaviour).params - for background_cls in self.background_behaviours_cls: - background_cls = cast(Type[BaseBehaviour], background_cls) - - if ( - not params.use_termination - and background_cls.auto_behaviour_id() - == TERMINATION_BACKGROUND_BEHAVIOUR_ID - ) or ( - not params.use_slashing - and background_cls.auto_behaviour_id() - == SLASHING_BACKGROUND_BEHAVIOUR_ID - or background_cls == PendingOffencesBehaviour - ): - # comparing with the behaviour id is not entirely safe, as there is a potential for conflicts - # if a user creates a behaviour with the same name - continue - - self.background_behaviours.add( - self.instantiate_behaviour_cls(background_cls) - ) - - def setup(self) -> None: - """Set up the behaviours.""" - self.current_behaviour = self.instantiate_behaviour_cls( - self.initial_behaviour_cls - ) - self.tm_manager = self.instantiate_behaviour_cls(TmManager) # type: ignore - self._setup_background() - - def teardown(self) -> None: - """Tear down the behaviour""" - - def _background_act(self) -> None: - """Call the act wrapper for the background behaviours.""" - for behaviour in self.background_behaviours: - behaviour.act_wrapper() - - def act(self) -> None: - """Implement the behaviour.""" - tm_manager = cast(TmManager, self.tm_manager) - if tm_manager.tm_communication_unhealthy or tm_manager.is_acting: - # tendermint is not healthy, or we are already applying a fix. - # try_fix() internally uses generators, that's why it's relevant - # to know whether a fix is already being applied. - # It might happen that tendermint is healthy, but the fix is not yet finished. - tm_manager.try_fix() - return - - tm_manager.informed = False - tm_manager.acn_communication_attempted = False - self._process_current_round() - if self.current_behaviour is None: - return - - self.current_behaviour.act_wrapper() - if self.current_behaviour.is_done(): - self.current_behaviour.clean_up() - self.current_behaviour = None - - self._background_act() - - def _process_current_round(self) -> None: - """Process current ABCIApp round.""" - current_round_height = self.context.state.round_sequence.current_round_height - if ( - self.current_behaviour is not None - and self._last_round_height == current_round_height - ): - # round has not changed - do nothing - return - self._last_round_height = current_round_height - current_round_cls = type(self.context.state.round_sequence.current_round) - - # each round has a behaviour associated to it - next_behaviour_cls = self._round_to_behaviour[current_round_cls] - - # stop the current behaviour and replace it with the new behaviour - if self.current_behaviour is not None: - current_behaviour = cast(BaseBehaviour, self.current_behaviour) - current_behaviour.clean_up() - current_behaviour.stop() - self.context.logger.debug( - "overriding transition: current behaviour: '%s', next behaviour: '%s'", - self.current_behaviour.behaviour_id if self.current_behaviour else None, - next_behaviour_cls.auto_behaviour_id(), - ) - - self.current_behaviour = self.instantiate_behaviour_cls(next_behaviour_cls) diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/common.py b/trader_old/vendor/valory/skills/abstract_round_abci/common.py deleted file mode 100644 index c6ee52e46..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/common.py +++ /dev/null @@ -1,231 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the behaviours, round and payloads for the 'abstract_round_abci' skill.""" - -import hashlib -import random -from abc import ABC -from math import floor -from typing import Any, Dict, Generator, List, Optional, Type, Union, cast - -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.utils import VerifyDrand - - -RandomnessObservation = Optional[Dict[str, Union[str, int]]] - - -drand_check = VerifyDrand() - - -def random_selection(elements: List[Any], randomness: float) -> str: - """ - Select a random element from a list. - - :param: elements: a list of elements to choose among - :param: randomness: a random number in the [0,1) interval - :return: a randomly chosen element - """ - if not elements: - raise ValueError("No elements to randomly select among") - if randomness < 0 or randomness >= 1: - raise ValueError("Randomness should lie in the [0,1) interval") - random_position = floor(randomness * len(elements)) - return elements[random_position] - - -class RandomnessBehaviour(BaseBehaviour, ABC): - """Behaviour to collect randomness values from DRAND service for keeper agent selection.""" - - payload_class: Type[BaseTxPayload] - - def failsafe_randomness( - self, - ) -> Generator[None, None, RandomnessObservation]: - """ - This methods provides a failsafe for randomness retrieval. - - :return: derived randomness - :yields: derived randomness - """ - ledger_api_response = yield from self.get_ledger_api_response( - performative=LedgerApiMessage.Performative.GET_STATE, # type: ignore - ledger_callable="get_block", - block_identifier="latest", - ) - - if ( - ledger_api_response.performative == LedgerApiMessage.Performative.ERROR - or "hash" not in ledger_api_response.state.body - ): - return None - - randomness = hashlib.sha256( - cast(str, ledger_api_response.state.body.get("hash")).encode() - + str(self.params.service_id).encode() - ).hexdigest() - return {"randomness": randomness, "round": 0} - - def get_randomness_from_api( - self, - ) -> Generator[None, None, RandomnessObservation]: - """Retrieve randomness from given api specs.""" - api_specs = self.context.randomness_api.get_spec() - response = yield from self.get_http_response( - method=api_specs["method"], - url=api_specs["url"], - ) - observation = self.context.randomness_api.process_response(response) - if observation is not None: - self.context.logger.info("Verifying DRAND values...") - check, error = drand_check.verify(observation, self.params.drand_public_key) - if check: - self.context.logger.info("DRAND check successful.") - else: - self.context.logger.error(f"DRAND check failed, {error}.") - return None - return observation - - def async_act(self) -> Generator: - """ - Retrieve randomness from API. - - Steps: - - Do a http request to the API. - - Retry until receiving valid values for randomness or retries exceed. - - If retrieved values are valid continue else generate randomness from chain. - """ - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - if self.context.randomness_api.is_retries_exceeded(): - self.context.logger.warning("Cannot retrieve randomness from api.") - self.context.logger.info("Generating randomness from chain...") - observation = yield from self.failsafe_randomness() - if observation is None: - self.context.logger.error( - "Could not generate randomness from chain!" - ) - return - else: - self.context.logger.info("Retrieving DRAND values from api...") - observation = yield from self.get_randomness_from_api() - self.context.logger.info(f"Retrieved DRAND values: {observation}.") - - if observation: - payload = self.payload_class( # type: ignore - self.context.agent_address, - round_id=observation["round"], - randomness=observation["randomness"], - ) - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - else: - self.context.logger.error( - f"Could not get randomness from {self.context.randomness_api.api_id}" - ) - yield from self.sleep( - self.context.randomness_api.retries_info.suggested_sleep_time - ) - self.context.randomness_api.increment_retries() - - def clean_up(self) -> None: - """ - Clean up the resources due to a 'stop' event. - - It can be optionally implemented by the concrete classes. - """ - self.context.randomness_api.reset_retries() - - -class SelectKeeperBehaviour(BaseBehaviour, ABC): - """Select the keeper agent.""" - - payload_class: Type[BaseTxPayload] - - def _select_keeper(self) -> str: - """ - Select a new keeper randomly. - - 1. Sort the list of participants who are not blacklisted as keepers. - 2. Randomly shuffle it. - 3. Pick the first keeper in order. - 4. If he has already been selected, pick the next one. - - :return: the selected keeper's address. - """ - # Get all the participants who have not been blacklisted as keepers - non_blacklisted = ( - self.synchronized_data.participants - - self.synchronized_data.blacklisted_keepers - ) - if not non_blacklisted: - raise RuntimeError( - "Cannot continue if all the keepers have been blacklisted!" - ) - - # Sorted list of participants who are not blacklisted as keepers - relevant_set = sorted(list(non_blacklisted)) - - # Random seeding and shuffling of the set - random.seed(self.synchronized_data.keeper_randomness) - random.shuffle(relevant_set) - - # If the keeper is not set yet, pick the first address - keeper_address = relevant_set[0] - - # If the keeper has been already set, select the next. - if ( - self.synchronized_data.is_keeper_set - and len(self.synchronized_data.participants) > 1 - ): - old_keeper_index = relevant_set.index( - self.synchronized_data.most_voted_keeper_address - ) - keeper_address = relevant_set[(old_keeper_index + 1) % len(relevant_set)] - - self.context.logger.info(f"Selected a new keeper: {keeper_address}.") - - return keeper_address - - def async_act(self) -> Generator: - """ - Do the action. - - Steps: - - Select a keeper randomly. - - Send the transaction with the keeper and wait for it to be mined. - - Wait until ABCI application transitions to the next round. - - Go to the next behaviour state (set done event). - """ - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - payload = self.payload_class( # type: ignore - self.context.agent_address, self._select_keeper() - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/dialogues.py b/trader_old/vendor/valory/skills/abstract_round_abci/dialogues.py deleted file mode 100644 index 7f0b53a38..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/dialogues.py +++ /dev/null @@ -1,368 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the classes required for dialogue management.""" - -from typing import Any, Optional, Type - -from aea.exceptions import enforce -from aea.helpers.transaction.base import Terms -from aea.protocols.base import Address, Message -from aea.protocols.dialogue.base import Dialogue as BaseDialogue -from aea.protocols.dialogue.base import DialogueLabel as BaseDialogueLabel -from aea.skills.base import Model - -from packages.open_aea.protocols.signing.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.open_aea.protocols.signing.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.protocols.abci.dialogues import AbciDialogue as BaseAbciDialogue -from packages.valory.protocols.abci.dialogues import AbciDialogues as BaseAbciDialogues -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.contract_api.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.protocols.contract_api.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.protocols.http.dialogues import HttpDialogue as BaseHttpDialogue -from packages.valory.protocols.http.dialogues import HttpDialogues as BaseHttpDialogues -from packages.valory.protocols.ipfs.dialogues import IpfsDialogue as BaseIpfsDialogue -from packages.valory.protocols.ipfs.dialogues import IpfsDialogues as BaseIpfsDialogues -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.protocols.ledger_api.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.protocols.ledger_api.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.protocols.tendermint.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.protocols.tendermint.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue - - -class AbciDialogues(Model, BaseAbciDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return AbciDialogue.Role.CLIENT - - BaseAbciDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - ) - - -HttpDialogue = BaseHttpDialogue - - -class HttpDialogues(Model, BaseHttpDialogues): - """This class keeps track of all http dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return BaseHttpDialogue.Role.CLIENT - - BaseHttpDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - ) - - -SigningDialogue = BaseSigningDialogue - - -class SigningDialogues(Model, BaseSigningDialogues): - """This class keeps track of all signing dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return BaseSigningDialogue.Role.SKILL - - BaseSigningDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - ) - - -class LedgerApiDialogue( # pylint: disable=too-few-public-methods - BaseLedgerApiDialogue -): - """The dialogue class maintains state of a dialogue and manages it.""" - - __slots__ = ("_terms",) - - def __init__( - self, - dialogue_label: BaseDialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[LedgerApiMessage] = LedgerApiMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - BaseLedgerApiDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - self._terms = None # type: Optional[Terms] - - @property - def terms(self) -> Terms: - """Get the terms.""" - if self._terms is None: - raise ValueError("Terms not set!") - return self._terms - - @terms.setter - def terms(self, terms: Terms) -> None: - """Set the terms.""" - enforce(self._terms is None, "Terms already set!") - self._terms = terms - - -class LedgerApiDialogues(Model, BaseLedgerApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return BaseLedgerApiDialogue.Role.AGENT - - BaseLedgerApiDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - dialogue_class=LedgerApiDialogue, - ) - - -class ContractApiDialogue( # pylint: disable=too-few-public-methods - BaseContractApiDialogue -): - """The dialogue class maintains state of a dialogue and manages it.""" - - __slots__ = ("_terms",) - - def __init__( - self, - dialogue_label: BaseDialogueLabel, - self_address: Address, - role: BaseDialogue.Role, - message_class: Type[ContractApiMessage] = ContractApiMessage, - ) -> None: - """ - Initialize a dialogue. - - :param dialogue_label: the identifier of the dialogue - :param self_address: the address of the entity for whom this dialogue is maintained - :param role: the role of the agent this dialogue is maintained for - :param message_class: the message class - """ - BaseContractApiDialogue.__init__( - self, - dialogue_label=dialogue_label, - self_address=self_address, - role=role, - message_class=message_class, - ) - self._terms = None # type: Optional[Terms] - - @property - def terms(self) -> Terms: - """Get the terms.""" - if self._terms is None: - raise ValueError("Terms not set!") - return self._terms - - @terms.setter - def terms(self, terms: Terms) -> None: - """Set the terms.""" - enforce(self._terms is None, "Terms already set!") - self._terms = terms - - -class ContractApiDialogues(Model, BaseContractApiDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize dialogues.""" - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return ContractApiDialogue.Role.AGENT - - BaseContractApiDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - dialogue_class=ContractApiDialogue, - ) - - -TendermintDialogue = BaseTendermintDialogue - - -class TendermintDialogues(Model, BaseTendermintDialogues): - """The dialogues class keeps track of all dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return TendermintDialogue.Role.AGENT - - BaseTendermintDialogues.__init__( - self, - self_address=self.context.agent_address, - role_from_first_message=role_from_first_message, - ) - - -IpfsDialogue = BaseIpfsDialogue - - -class IpfsDialogues(Model, BaseIpfsDialogues): - """A class to keep track of IPFS dialogues.""" - - def __init__(self, **kwargs: Any) -> None: - """ - Initialize dialogues. - - :param kwargs: keyword arguments - """ - Model.__init__(self, **kwargs) - - def role_from_first_message( # pylint: disable=unused-argument - message: Message, receiver_address: Address - ) -> BaseDialogue.Role: - """Infer the role of the agent from an incoming/outgoing first message - - :param message: an incoming/outgoing first message - :param receiver_address: the address of the receiving agent - :return: The role of the agent - """ - return IpfsDialogue.Role.SKILL - - BaseIpfsDialogues.__init__( - self, - self_address=str(self.skill_id), - role_from_first_message=role_from_first_message, - ) diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/handlers.py b/trader_old/vendor/valory/skills/abstract_round_abci/handlers.py deleted file mode 100644 index 88cf072e6..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/handlers.py +++ /dev/null @@ -1,790 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the handler for the 'abstract_round_abci' skill.""" - -import ipaddress -import json -from abc import ABC -from calendar import timegm -from dataclasses import asdict -from enum import Enum -from typing import Any, Callable, Dict, FrozenSet, List, Optional, cast - -from aea.configurations.data_types import PublicId -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue, Dialogues -from aea.skills.base import Handler - -from packages.open_aea.protocols.signing import SigningMessage -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import Events, ValidatorUpdates -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.protocols.tendermint.dialogues import ( - TendermintDialogue, - TendermintDialogues, -) -from packages.valory.protocols.tendermint.message import TendermintMessage -from packages.valory.skills.abstract_abci.handlers import ABCIHandler -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AddBlockError, - DEFAULT_PENDING_OFFENCE_TTL, - ERROR_CODE, - LateArrivingTransaction, - OK_CODE, - OffenseType, - PendingOffense, - SignatureNotValidError, - Transaction, - TransactionNotValidError, - TransactionTypeNotRecognizedError, -) -from packages.valory.skills.abstract_round_abci.behaviours import AbstractRoundBehaviour -from packages.valory.skills.abstract_round_abci.dialogues import AbciDialogue -from packages.valory.skills.abstract_round_abci.models import ( - Requests, - SharedState, - TendermintRecoveryParams, -) - - -def exception_to_info_msg(exception: Exception) -> str: - """Transform an exception to an info string message.""" - return f"{exception.__class__.__name__}: {str(exception)}" - - -class ABCIRoundHandler(ABCIHandler): - """ABCI handler.""" - - SUPPORTED_PROTOCOL = AbciMessage.protocol_id - - def info(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """ - Handle the 'info' request. - - As per Tendermint spec (https://github.com/tendermint/spec/blob/038f3e025a19fed9dc96e718b9834ab1b545f136/spec/abci/abci.md#info): - - - Return information about the application state. - - Used to sync Tendermint with the application during a handshake that happens on startup. - - The returned app_version will be included in the Header of every block. - - Tendermint expects last_block_app_hash and last_block_height to be updated during Commit, ensuring that Commit is never called twice for the same block height. - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - # some arbitrary information - info_data = "" - # the application software semantic version - version = "" - # the application protocol version - app_version = 0 - # latest block for which the app has called Commit - last_block_height = self.context.state.round_sequence.height - # latest result of Commit - last_block_app_hash = self.context.state.round_sequence.root_hash - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_INFO, - target_message=message, - info_data=info_data, - version=version, - app_version=app_version, - last_block_height=last_block_height, - last_block_app_hash=last_block_app_hash, - ) - return cast(AbciMessage, reply) - - def init_chain(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """ - Handle a message of REQUEST_INIT_CHAIN performative. - - As per Tendermint spec (https://github.com/tendermint/spec/blob/038f3e025a19fed9dc96e718b9834ab1b545f136/spec/abci/abci.md#initchain): - - - Called once upon genesis. - - If ResponseInitChain.Validators is empty, the initial validator set will be the RequestInitChain.Validators. - - If ResponseInitChain.Validators is not empty, it will be the initial validator set (regardless of what is in RequestInitChain.Validators). - - This allows the app to decide if it wants to accept the initial validator set proposed by tendermint (ie. in the genesis file), or if it wants to use a different one (perhaps computed based on some application specific information in the genesis file). - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - # Initial validator set (optional). - validators: List = [] - # Get the root hash of the last round transition as the initial application hash. - # If no round transitions have occurred yet, `last_root_hash` returns the hash of the initial abci app's state. - # `init_chain` will be called between resets when restarting again. - app_hash = self.context.state.round_sequence.last_round_transition_root_hash - cast(SharedState, self.context.state).round_sequence.init_chain( - message.initial_height - ) - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_INIT_CHAIN, - target_message=message, - validators=ValidatorUpdates(validators), - app_hash=app_hash, - ) - return cast(AbciMessage, reply) - - def begin_block(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """Handle the 'begin_block' request.""" - cast(SharedState, self.context.state).round_sequence.begin_block( - message.header, message.byzantine_validators, message.last_commit_info - ) - return super().begin_block(message, dialogue) - - def check_tx(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """Handle the 'check_tx' request.""" - transaction_bytes = message.tx - # check we can decode the transaction - try: - transaction = Transaction.decode(transaction_bytes) - transaction.verify(self.context.default_ledger_id) - cast(SharedState, self.context.state).round_sequence.check_is_finished() - except ( - SignatureNotValidError, - TransactionNotValidError, - TransactionTypeNotRecognizedError, - ) as exception: - self._log_exception(exception) - return self._check_tx_failed( - message, dialogue, exception_to_info_msg(exception) - ) - except LateArrivingTransaction as exception: # pragma: nocover - self.context.logger.debug(exception_to_info_msg(exception)) - return self._check_tx_failed( - message, dialogue, exception_to_info_msg(exception) - ) - - # return check_tx success - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, - target_message=message, - code=OK_CODE, - data=b"", - log="", - info="check_tx succeeded", - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, reply) - - def settle_pending_offence( - self, accused_agent_address: Optional[str], invalid: bool - ) -> None: - """Add an invalid pending offence or a no-offence for the given accused agent address, if possible.""" - if accused_agent_address is None: - # only add the offence if we know and can verify the sender, - # otherwise someone could pretend to be someone else, which may lead to wrong punishments - return - - round_sequence = cast(SharedState, self.context.state).round_sequence - - try: - last_round_transition_timestamp = timegm( - round_sequence.last_round_transition_timestamp.utctimetuple() - ) - except ValueError: # pragma: no cover - # do not add an offence if no round transition has been completed yet - return - - offence_type = ( - OffenseType.INVALID_PAYLOAD if invalid else OffenseType.NO_OFFENCE - ) - pending_offense = PendingOffense( - accused_agent_address, - round_sequence.current_round_height, - offence_type, - last_round_transition_timestamp, - DEFAULT_PENDING_OFFENCE_TTL, - ) - round_sequence.add_pending_offence(pending_offense) - - def deliver_tx(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """Handle the 'deliver_tx' request.""" - transaction_bytes = message.tx - round_sequence = cast(SharedState, self.context.state).round_sequence - payload_sender: Optional[str] = None - try: - transaction = Transaction.decode(transaction_bytes) - transaction.verify(self.context.default_ledger_id) - payload_sender = transaction.payload.sender - round_sequence.check_is_finished() - round_sequence.deliver_tx(transaction) - except ( - SignatureNotValidError, - TransactionNotValidError, - TransactionTypeNotRecognizedError, - ) as exception: - self._log_exception(exception) - # the transaction is invalid, it's potentially an offence, so we add it to the list of pending offences - self.settle_pending_offence(payload_sender, invalid=True) - return self._deliver_tx_failed( - message, dialogue, exception_to_info_msg(exception) - ) - except LateArrivingTransaction as exception: # pragma: nocover - self.context.logger.debug(exception_to_info_msg(exception)) - return self._deliver_tx_failed( - message, dialogue, exception_to_info_msg(exception) - ) - - # the invalid payloads' availability window needs to be populated with the negative values as well - self.settle_pending_offence(payload_sender, invalid=False) - - # return deliver_tx success - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, - target_message=message, - code=OK_CODE, - data=b"", - log="", - info="deliver_tx succeeded", - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, reply) - - def end_block(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """Handle the 'end_block' request.""" - self.context.state.round_sequence.tm_height = message.height - cast(SharedState, self.context.state).round_sequence.end_block() - return super().end_block(message, dialogue) - - def commit(self, message: AbciMessage, dialogue: AbciDialogue) -> AbciMessage: - """ - Handle the 'commit' request. - - As per Tendermint spec (https://github.com/tendermint/spec/blob/038f3e025a19fed9dc96e718b9834ab1b545f136/spec/abci/abci.md#commit): - - Empty request meant to signal to the app it can write state transitions to state. - - - Persist the application state. - - Return a Merkle root hash of the application state. - - It's critical that all application instances return the same hash. If not, they will not be able to agree on the next block, because the hash is included in the next block! - - :param message: the ABCI request. - :param dialogue: the ABCI dialogue. - :return: the response. - """ - try: - cast(SharedState, self.context.state).round_sequence.commit() - except AddBlockError as exception: - self._log_exception(exception) - raise exception - # The Merkle root hash of the application state. - data = self.context.state.round_sequence.root_hash - # Blocks below this height may be removed. Defaults to 0 (retain all). - retain_height = 0 - # return commit success - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_COMMIT, - target_message=message, - data=data, - retain_height=retain_height, - ) - return cast(AbciMessage, reply) - - @classmethod - def _check_tx_failed( - cls, message: AbciMessage, dialogue: AbciDialogue, info: str = "" - ) -> AbciMessage: - """Handle a failed check_tx request.""" - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_CHECK_TX, - target_message=message, - code=ERROR_CODE, - data=b"", - log="", - info=info, - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, reply) - - @classmethod - def _deliver_tx_failed( - cls, message: AbciMessage, dialogue: AbciDialogue, info: str = "" - ) -> AbciMessage: - """Handle a failed deliver_tx request.""" - reply = dialogue.reply( - performative=AbciMessage.Performative.RESPONSE_DELIVER_TX, - target_message=message, - code=ERROR_CODE, - data=b"", - log="", - info=info, - gas_wanted=0, - gas_used=0, - events=Events([]), - codespace="", - ) - return cast(AbciMessage, reply) - - def _log_exception(self, exception: Exception) -> None: - """Log an exception.""" - self.context.logger.error(exception_to_info_msg(exception)) - - -class AbstractResponseHandler(Handler, ABC): - """ - Abstract response Handler. - - This abstract handler works in tandem with the 'Requests' model. - Whenever a message of 'response' type arrives, the handler - tries to dispatch it to a pending request previously registered - in 'Requests' by some other code in the same skill. - - The concrete classes must set the 'allowed_response_performatives' - class attribute to the (frozen)set of performative the developer - wants the handler to handle. - """ - - allowed_response_performatives: FrozenSet[Message.Performative] - - def setup(self) -> None: - """Set up the handler.""" - - def teardown(self) -> None: - """Tear down the handler.""" - - def handle(self, message: Message) -> None: - """ - Handle the response message. - - Steps: - 1. Try to recover the 'dialogues' instance, for the protocol - of this handler, from the skill context. The attribute name used to - read the attribute is computed by '_get_dialogues_attribute_name()' - method. If no dialogues instance is found, log a message and return. - 2. Try to recover the dialogue; if no dialogue is present, log a message - and return. - 3. Check whether the performative is in the set of allowed performative; - if not, log a message and return. - 4. Try to recover the callback of the request associated to the response - from the 'Requests' model; if no callback is present, log a message - and return. - 5. If the above check have passed, then call the callback with the - received message. - - :param message: the message to handle. - """ - protocol_dialogues = self._recover_protocol_dialogues() - if protocol_dialogues is None: - self._handle_missing_dialogues() - return - protocol_dialogues = cast(Dialogues, protocol_dialogues) - - protocol_dialogue = cast(Optional[Dialogue], protocol_dialogues.update(message)) - if protocol_dialogue is None: - self._handle_unidentified_dialogue(message) - return - - if message.performative not in self.allowed_response_performatives: - self._handle_unallowed_performative(message) - return - - request_nonce = protocol_dialogue.dialogue_label.dialogue_reference[0] - ctx_requests = cast(Requests, self.context.requests) - - try: - callback = cast( - Callable, - ctx_requests.request_id_to_callback.pop(request_nonce), - ) - except KeyError as e: - raise ABCIAppInternalError( - f"No callback defined for request with nonce: {request_nonce}" - ) from e - - self._log_message_handling(message) - current_behaviour = cast( - AbstractRoundBehaviour, self.context.behaviours.main - ).current_behaviour - callback(message, current_behaviour) - - def _get_dialogues_attribute_name(self) -> str: - """ - Get dialogues attribute name. - - By convention, the Dialogues model of the skill follows - the template '{protocol_name}_dialogues'. - - Override this method accordingly if the name of hte Dialogues - model is different. - - :return: the dialogues attribute name. - """ - return cast(PublicId, self.SUPPORTED_PROTOCOL).name + "_dialogues" - - def _recover_protocol_dialogues(self) -> Optional[Dialogues]: - """ - Recover protocol dialogues from supported protocol id. - - :return: the dialogues, or None if the dialogues object was not found. - """ - attribute = self._get_dialogues_attribute_name() - return getattr(self.context, attribute, None) - - def _handle_missing_dialogues(self) -> None: - """Handle missing dialogues in context.""" - expected_attribute_name = self._get_dialogues_attribute_name() - self.context.logger.warning( - "Cannot find Dialogues object in skill context with attribute name: %s", - expected_attribute_name, - ) - - def _handle_unidentified_dialogue(self, message: Message) -> None: - """ - Handle an unidentified dialogue. - - :param message: the unidentified message to be handled - """ - self.context.logger.warning( - "Received invalid message: unidentified dialogue. message=%s", message - ) - - def _handle_unallowed_performative(self, message: Message) -> None: - """ - Handle a message with an unallowed response performative. - - Log an error message saying that the handler did not expect requests - but only responses. - - :param message: the message - """ - self.context.logger.warning( - "Received invalid message: unallowed performative. message=%s.", message - ) - - def _log_message_handling(self, message: Message) -> None: - """Log the handling of the message.""" - self.context.logger.debug( - "Calling registered callback with message=%s", message - ) - - -class HttpHandler(AbstractResponseHandler): - """The HTTP response handler.""" - - SUPPORTED_PROTOCOL: Optional[PublicId] = HttpMessage.protocol_id - allowed_response_performatives = frozenset({HttpMessage.Performative.RESPONSE}) - - -class SigningHandler(AbstractResponseHandler): - """Implement the transaction handler.""" - - SUPPORTED_PROTOCOL: Optional[PublicId] = SigningMessage.protocol_id - allowed_response_performatives = frozenset( - { - SigningMessage.Performative.SIGNED_MESSAGE, - SigningMessage.Performative.SIGNED_TRANSACTION, - SigningMessage.Performative.ERROR, - } - ) - - -class LedgerApiHandler(AbstractResponseHandler): - """Implement the ledger handler.""" - - SUPPORTED_PROTOCOL: Optional[PublicId] = LedgerApiMessage.protocol_id - allowed_response_performatives = frozenset( - { - LedgerApiMessage.Performative.BALANCE, - LedgerApiMessage.Performative.RAW_TRANSACTION, - LedgerApiMessage.Performative.TRANSACTION_DIGEST, - LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - LedgerApiMessage.Performative.ERROR, - LedgerApiMessage.Performative.STATE, - } - ) - - -class ContractApiHandler(AbstractResponseHandler): - """Implement the contract api handler.""" - - SUPPORTED_PROTOCOL: Optional[PublicId] = ContractApiMessage.protocol_id - allowed_response_performatives = frozenset( - { - ContractApiMessage.Performative.RAW_TRANSACTION, - ContractApiMessage.Performative.RAW_MESSAGE, - ContractApiMessage.Performative.ERROR, - ContractApiMessage.Performative.STATE, - } - ) - - -class TendermintHandler(Handler): - """ - The Tendermint config-sharing request / response handler. - - This handler is used to share the information necessary - to set up the Tendermint network. The agents use it during - the RegistrationStartupBehaviour, and communicate with - each other over the Agent Communication Network using a - p2p_libp2p or p2p_libp2p_client connection. - - This handler does NOT use the ABCI connection. - """ - - SUPPORTED_PROTOCOL: Optional[PublicId] = TendermintMessage.protocol_id - - class LogMessages(Enum): - """Log messages used in the TendermintHandler""" - - unidentified_dialogue = "Unidentified Tendermint dialogue" - no_addresses_retrieved_yet = "No registered addresses retrieved yet" - not_in_registered_addresses = "Sender not registered for on-chain service" - sending_request_response = "Sending Tendermint request response" - failed_to_parse_address = "Failed to parse Tendermint network address" - failed_to_parse_params = ( - "Failed to parse Tendermint recovery parameters from message" - ) - collected_config_info = "Collected Tendermint config info" - collected_params = "Collected Tendermint recovery parameters" - received_error_without_target_message = ( - "Received error message but could not retrieve target message" - ) - received_error_response = "Received error response" - sending_error_response = "Sending error response" - performative_not_recognized = "Performative not recognized" - - def __str__(self) -> str: # pragma: no cover - """For ease of use in formatted string literals""" - return self.value - - def setup(self) -> None: - """Set up the handler.""" - - def teardown(self) -> None: - """Tear down the handler.""" - - @property - def initial_tm_configs(self) -> Dict[str, Dict[str, Any]]: - """A mapping of the other agents' addresses to their initial Tendermint configuration.""" - return self.context.state.initial_tm_configs - - @initial_tm_configs.setter - def initial_tm_configs(self, configs: Dict[str, Dict[str, Any]]) -> None: - """A mapping of the other agents' addresses to their initial Tendermint configuration.""" - self.context.state.initial_tm_configs = configs - - @property - def dialogues(self) -> Optional[TendermintDialogues]: - """Tendermint config-sharing request / response protocol dialogues""" - - attribute = cast(PublicId, self.SUPPORTED_PROTOCOL).name + "_dialogues" - return getattr(self.context, attribute, None) - - def handle(self, message: Message) -> None: - """Handle incoming Tendermint config-sharing messages""" - - dialogues = cast(TendermintDialogues, self.dialogues) - dialogue = cast(TendermintDialogue, dialogues.update(message)) - - if dialogue is None: - log_message = self.LogMessages.unidentified_dialogue.value - self.context.logger.error(f"{log_message}: {message}") - return - - message = cast(TendermintMessage, message) - handler_name = f"_{message.performative.value}" - handler = getattr(self, handler_name, None) - if handler is None: - log_message = self.LogMessages.performative_not_recognized.value - self.context.logger.error(f"{log_message}: {message}") - return - - handler(message, dialogue) - - def _reply_with_tendermint_error( - self, - message: TendermintMessage, - dialogue: TendermintDialogue, - error_message: str, - ) -> None: - """Reply with Tendermint config-sharing error""" - response = dialogue.reply( - performative=TendermintMessage.Performative.ERROR, - target_message=message, - error_code=TendermintMessage.ErrorCode.INVALID_REQUEST, - error_msg=error_message, - error_data={}, - ) - self.context.outbox.put_message(response) - log_message = self.LogMessages.sending_error_response.value - log_message += f". Received: {message}, replied: {response}" - self.context.logger.error(log_message) - - def _not_registered_error( - self, message: TendermintMessage, dialogue: TendermintDialogue - ) -> None: - """Check if sender is among on-chain registered addresses""" - # do not respond to errors to avoid loops - log_message = self.LogMessages.not_in_registered_addresses.value - self.context.logger.error(f"{log_message}: {message}") - self._reply_with_tendermint_error(message, dialogue, log_message) - - def _check_registered( - self, message: TendermintMessage, dialogue: TendermintDialogue - ) -> bool: - """Check if the sender is registered on-chain and if not, reply with an error""" - others_addresses = self.context.state.acn_container() - if message.sender in others_addresses: - return True - - self._not_registered_error(message, dialogue) - return False - - def _get_genesis_info( - self, message: TendermintMessage, dialogue: TendermintDialogue - ) -> None: - """Handler Tendermint config-sharing request message""" - - if not self._check_registered(message, dialogue): - return - info = self.initial_tm_configs.get(self.context.agent_address, None) - if info is None: - log_message = self.LogMessages.no_addresses_retrieved_yet.value - self.context.logger.info(f"{log_message}: {message}") - self._reply_with_tendermint_error(message, dialogue, log_message) - return - - response = dialogue.reply( - performative=TendermintMessage.Performative.GENESIS_INFO, - target_message=message, - info=json.dumps(info), - ) - self.context.outbox.put_message(message=response) - log_message = self.LogMessages.sending_request_response.value - self.context.logger.info(f"{log_message}: {response}") - - def _get_recovery_params( - self, message: TendermintMessage, dialogue: TendermintDialogue - ) -> None: - """Handle a request message for the recovery parameters.""" - if not self._check_registered(message, dialogue): - return - - shared_state = cast(SharedState, self.context.state) - recovery_params = shared_state.tm_recovery_params - response = dialogue.reply( - performative=TendermintMessage.Performative.RECOVERY_PARAMS, - target_message=message, - params=json.dumps(asdict(recovery_params)), - ) - self.context.outbox.put_message(message=response) - log_message = self.LogMessages.sending_request_response.value - self.context.logger.info(f"{log_message}: {response}") - - def _genesis_info( - self, message: TendermintMessage, dialogue: TendermintDialogue - ) -> None: - """Process Tendermint config-sharing response messages""" - - if not self._check_registered(message, dialogue): - return - - try: # validate message contains a valid address - validator_config = json.loads(message.info) - self.context.logger.info(f"Validator config received: {validator_config}") - hostname = cast(str, validator_config["hostname"]) - if hostname != "localhost" and not hostname.startswith("node"): - ipaddress.ip_network(hostname) - except (KeyError, ValueError) as e: - log_message = self.LogMessages.failed_to_parse_address.value - self.context.logger.error(f"{log_message}: {e} {message}") - self._reply_with_tendermint_error(message, dialogue, log_message) - return - - initial_tm_configs = self.initial_tm_configs - initial_tm_configs[message.sender] = validator_config - self.initial_tm_configs = initial_tm_configs - log_message = self.LogMessages.collected_config_info.value - self.context.logger.info(f"{log_message}: {message}") - dialogues = cast(TendermintDialogues, self.dialogues) - dialogues.dialogue_stats.add_dialogue_endstate( - TendermintDialogue.EndState.COMMUNICATED, dialogue.is_self_initiated - ) - - def _recovery_params( - self, message: TendermintMessage, dialogue: TendermintDialogue - ) -> None: - """Process params-sharing response messages.""" - - if not self._check_registered(message, dialogue): - return - - try: - recovery_params = json.loads(message.params) - shared_state = cast(SharedState, self.context.state) - shared_state.address_to_acn_deliverable[ - message.sender - ] = TendermintRecoveryParams(**recovery_params) - except (json.JSONDecodeError, TypeError) as exc: - log_message = self.LogMessages.failed_to_parse_params.value - self.context.logger.error(f"{log_message}: {exc} {message}") - self._reply_with_tendermint_error(message, dialogue, log_message) - return - - log_message = self.LogMessages.collected_params.value - self.context.logger.info(f"{log_message}: {message}") - dialogues = cast(TendermintDialogues, self.dialogues) - dialogues.dialogue_stats.add_dialogue_endstate( - TendermintDialogue.EndState.COMMUNICATED, dialogue.is_self_initiated - ) - - def _error(self, message: TendermintMessage, dialogue: TendermintDialogue) -> None: - """Handle error message as response""" - - target_message = dialogue.get_message_by_id(message.target) - if not target_message: - log_message = self.LogMessages.received_error_without_target_message.value - self.context.logger.error(log_message) - return - - log_message = self.LogMessages.received_error_response.value - log_message += f". Received: {message}, in reply to: {target_message}" - self.context.logger.error(log_message) - dialogues = cast(TendermintDialogues, self.dialogues) - dialogues.dialogue_stats.add_dialogue_endstate( - TendermintDialogue.EndState.NOT_COMMUNICATED, dialogue.is_self_initiated - ) - - -class IpfsHandler(AbstractResponseHandler): - """A class for handling IPFS messages.""" - - SUPPORTED_PROTOCOL: Optional[PublicId] = IpfsMessage.protocol_id - allowed_response_performatives = frozenset( - { - IpfsMessage.Performative.IPFS_HASH, - IpfsMessage.Performative.FILES, - IpfsMessage.Performative.ERROR, - } - ) diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/io_/__init__.py b/trader_old/vendor/valory/skills/abstract_round_abci/io_/__init__.py deleted file mode 100644 index 346ca66a6..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/io_/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 package contains all the input-output operations logic of the behaviours.""" # pragma: nocover diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/io_/ipfs.py b/trader_old/vendor/valory/skills/abstract_round_abci/io_/ipfs.py deleted file mode 100644 index cfd914c60..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/io_/ipfs.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 all the interaction operations of the behaviours with IPFS.""" - - -import os -from typing import Any, Dict, Optional, Type - -from packages.valory.skills.abstract_round_abci.io_.load import ( - CustomLoaderType, - Loader, - SupportedFiletype, - SupportedObjectType, -) -from packages.valory.skills.abstract_round_abci.io_.store import ( - CustomStorerType, - Storer, -) - - -class IPFSInteractionError(Exception): - """A custom exception for IPFS interaction errors.""" - - -class IPFSInteract: - """Class for interacting with IPFS.""" - - def __init__(self, loader_cls: Type = Loader, storer_cls: Type = Storer): - """Initialize an `IPFSInteract` object.""" - # Set loader/storer class. - self._loader_cls = loader_cls - self._storer_cls = storer_cls - - def store( - self, - filepath: str, - obj: SupportedObjectType, - multiple: bool, - filetype: Optional[SupportedFiletype] = None, - custom_storer: Optional[CustomStorerType] = None, - **kwargs: Any, - ) -> Dict[str, str]: - """Temporarily store a file locally, in order to send it to IPFS and retrieve a hash, and then delete it.""" - filepath = os.path.normpath(filepath) - if multiple: - # Add trailing slash in order to treat path as a folder. - filepath = os.path.join(filepath, "") - storer = self._storer_cls(filetype, custom_storer, filepath) - - try: - name_to_obj = storer.store(obj, multiple, **kwargs) - return name_to_obj - except Exception as e: # pylint: disable=broad-except - raise IPFSInteractionError(str(e)) from e - - def load( # pylint: disable=too-many-arguments - self, - serialized_objects: Dict[str, str], - filetype: Optional[SupportedFiletype] = None, - custom_loader: CustomLoaderType = None, - ) -> SupportedObjectType: - """Deserialize objects received via IPFS.""" - loader = self._loader_cls(filetype, custom_loader) - try: - deserialized_objects = loader.load(serialized_objects) - return deserialized_objects - except Exception as e: # pylint: disable=broad-except - raise IPFSInteractionError(str(e)) from e diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/io_/load.py b/trader_old/vendor/valory/skills/abstract_round_abci/io_/load.py deleted file mode 100644 index c9ceafb09..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/io_/load.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 all the loading operations of the behaviours.""" - -import json -from abc import ABC, abstractmethod -from typing import Any, Callable, Dict, Optional - -from packages.valory.skills.abstract_round_abci.io_.store import ( - CustomObjectType, - NativelySupportedSingleObjectType, - SupportedFiletype, - SupportedObjectType, - SupportedSingleObjectType, -) - - -CustomLoaderType = Optional[Callable[[str], CustomObjectType]] -SupportedLoaderType = Callable[[str], SupportedSingleObjectType] - - -class AbstractLoader(ABC): - """An abstract `Loader` class.""" - - @abstractmethod - def load_single_object( - self, serialized_object: str - ) -> NativelySupportedSingleObjectType: - """Load a single object.""" - - def load(self, serialized_objects: Dict[str, str]) -> SupportedObjectType: - """ - Load one or more serialized objects. - - :param serialized_objects: A mapping of filenames to serialized object they contained. - :return: the loaded file(s). - """ - if len(serialized_objects) == 0: - # no objects are present, raise an error - raise ValueError('"serialized_objects" does not contain any objects') - - objects = {} - for filename, body in serialized_objects.items(): - objects[filename] = self.load_single_object(body) - - if len(objects) > 1: - # multiple object are present - # we return them as mapping of - # names and their value - return objects - - # one object is present, we simply return it as an object, i.e. without its name - _name, deserialized_body = objects.popitem() - return deserialized_body - - -class JSONLoader(AbstractLoader): - """A JSON file loader.""" - - def load_single_object( - self, serialized_object: str - ) -> NativelySupportedSingleObjectType: - """Read a json file. - - :param serialized_object: the file serialized into a JSON string. - :return: the deserialized json file's content. - """ - try: - deserialized_file = json.loads(serialized_object) - return deserialized_file - except json.JSONDecodeError as e: # pragma: no cover - raise IOError( - f"File '{serialized_object}' has an invalid JSON encoding!" - ) from e - except ValueError as e: # pragma: no cover - raise IOError( - f"There is an encoding error in the '{serialized_object}' file!" - ) from e - - -class Loader(AbstractLoader): - """Class which loads objects.""" - - def __init__(self, filetype: Optional[Any], custom_loader: CustomLoaderType): - """Initialize a `Loader`.""" - self._filetype = filetype - self._custom_loader = custom_loader - self.__filetype_to_loader: Dict[SupportedFiletype, SupportedLoaderType] = { - SupportedFiletype.JSON: JSONLoader().load_single_object, - } - - def load_single_object(self, serialized_object: str) -> SupportedSingleObjectType: - """Load a single file.""" - loader = self._get_single_loader_from_filetype() - return loader(serialized_object) - - def _get_single_loader_from_filetype(self) -> SupportedLoaderType: - """Get an object loader from a given filetype or keep a custom loader.""" - if self._filetype is not None: - return self.__filetype_to_loader[self._filetype] - - if self._custom_loader is not None: # pragma: no cover - return self._custom_loader - - raise ValueError( # pragma: no cover - "Please provide either a supported filetype or a custom loader function." - ) diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/io_/paths.py b/trader_old/vendor/valory/skills/abstract_round_abci/io_/paths.py deleted file mode 100644 index 40b89233b..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/io_/paths.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 all the path related operations of the behaviours.""" - - -import os - - -def create_pathdirs(path: str) -> None: - """Create the non-existing directories of a given path. - - :param path: the given path. - """ - dirname = os.path.dirname(path) - - if dirname: - os.makedirs(dirname, exist_ok=True) diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/io_/store.py b/trader_old/vendor/valory/skills/abstract_round_abci/io_/store.py deleted file mode 100644 index 588dc3629..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/io_/store.py +++ /dev/null @@ -1,153 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 all the storing operations of the behaviours.""" - - -import json -import os.path -from abc import ABC, abstractmethod -from enum import Enum, auto -from typing import Any, Callable, Dict, Optional, TypeVar, Union, cast - -from packages.valory.skills.abstract_round_abci.io_.paths import create_pathdirs - - -StoredJSONType = Union[dict, list] -NativelySupportedSingleObjectType = StoredJSONType -NativelySupportedMultipleObjectsType = Dict[str, NativelySupportedSingleObjectType] -NativelySupportedObjectType = Union[ - NativelySupportedSingleObjectType, NativelySupportedMultipleObjectsType -] -NativelySupportedStorerType = Callable[[str, NativelySupportedObjectType, Any], None] -CustomObjectType = TypeVar("CustomObjectType") -CustomStorerType = Callable[[str, CustomObjectType, Any], None] -SupportedSingleObjectType = Union[NativelySupportedObjectType, CustomObjectType] -SupportedMultipleObjectsType = Dict[str, SupportedSingleObjectType] -SupportedObjectType = Union[SupportedSingleObjectType, SupportedMultipleObjectsType] -SupportedStorerType = Union[NativelySupportedStorerType, CustomStorerType] -NativelySupportedJSONStorerType = Callable[ - [str, Union[StoredJSONType, Dict[str, StoredJSONType]], Any], None -] - - -class SupportedFiletype(Enum): - """Enum for the supported filetypes of the IPFS interacting methods.""" - - JSON = auto() - - -class AbstractStorer(ABC): - """An abstract `Storer` class.""" - - def __init__(self, path: str): - """Initialize an abstract storer.""" - self._path = path - # Create the dirs of the path if it does not exist. - create_pathdirs(path) - - @abstractmethod - def serialize_object( - self, filename: str, obj: SupportedSingleObjectType, **kwargs: Any - ) -> Dict[str, str]: - """Store a single file.""" - - def store( - self, obj: SupportedObjectType, multiple: bool, **kwargs: Any - ) -> Dict[str, str]: - """Serialize one or multiple objects.""" - serialized_files: Dict[str, str] = {} - if multiple: - if not isinstance(obj, dict): # pragma: no cover - raise ValueError( - f"Cannot store multiple files of type {type(obj)}!" - f"Should be a dictionary of filenames mapped to their objects." - ) - for filename, single_obj in obj.items(): - filename = os.path.join(self._path, filename) - serialized_file = self.serialize_object(filename, single_obj, **kwargs) - serialized_files.update(**serialized_file) - else: - serialized_file = self.serialize_object(self._path, obj, **kwargs) - serialized_files.update(**serialized_file) - return serialized_files - - -class JSONStorer(AbstractStorer): - """A JSON file storer.""" - - def serialize_object( - self, filename: str, obj: NativelySupportedSingleObjectType, **kwargs: Any - ) -> Dict[str, str]: - """ - Serialize an object to JSON. - - :param filename: under which name the provided object should be serialized. Note that it will appear in IPFS with this name. - :param obj: the object to store. - :returns: a dict mapping the name to the serialized object. - """ - if not any(isinstance(obj, type_) for type_ in (dict, list)): - raise ValueError( # pragma: no cover - f"`JSONStorer` cannot be used with a {type(obj)}! Only with a {StoredJSONType}" - ) - try: - serialized_object = json.dumps(obj, ensure_ascii=False, indent=4) - name_to_obj = {filename: serialized_object} - return name_to_obj - except (TypeError, OSError) as e: # pragma: no cover - raise IOError(str(e)) from e - - -class Storer(AbstractStorer): - """Class which serializes objects.""" - - def __init__( - self, - filetype: Optional[Any], - custom_storer: Optional[CustomStorerType], - path: str, - ): - """Initialize a `Storer`.""" - super().__init__(path) - self._filetype = filetype - self._custom_storer = custom_storer - self._filetype_to_storer: Dict[Enum, SupportedStorerType] = { - SupportedFiletype.JSON: cast( - NativelySupportedJSONStorerType, JSONStorer(path).serialize_object - ), - } - - def serialize_object( - self, filename: str, obj: NativelySupportedObjectType, **kwargs: Any - ) -> Dict[str, str]: - """Store a single object.""" - storer = self._get_single_storer_from_filetype() - return storer(filename, obj, **kwargs) # type: ignore - - def _get_single_storer_from_filetype(self) -> SupportedStorerType: - """Get an object storer from a given filetype or keep a custom storer.""" - if self._filetype is not None: - return self._filetype_to_storer[self._filetype] - - if self._custom_storer is not None: # pragma: no cover - return self._custom_storer - - raise ValueError( # pragma: no cover - "Please provide either a supported filetype or a custom storing function." - ) diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/models.py b/trader_old/vendor/valory/skills/abstract_round_abci/models.py deleted file mode 100644 index 27304eb37..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/models.py +++ /dev/null @@ -1,893 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the core models for all the ABCI apps.""" - -import inspect -import json -from abc import ABC, ABCMeta -from collections import Counter -from dataclasses import dataclass -from enum import Enum -from pathlib import Path -from time import time -from typing import ( - Any, - Callable, - Dict, - List, - Optional, - OrderedDict, - Tuple, - Type, - cast, - get_type_hints, -) - -from aea.configurations.data_types import PublicId -from aea.exceptions import enforce -from aea.skills.base import Model, SkillContext - -from packages.valory.protocols.http.message import HttpMessage -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppDB, - BaseSynchronizedData, - OffenceStatus, - ROUND_COUNT_DEFAULT, - RoundSequence, - VALUE_NOT_PROVIDED, - get_name, -) -from packages.valory.skills.abstract_round_abci.utils import ( - check, - check_type, - consensus_threshold, - get_data_from_nested_dict, - get_value_with_type, -) - - -MIN_RESET_PAUSE_DURATION = 10 -NUMBER_OF_RETRIES: int = 5 -DEFAULT_BACKOFF_FACTOR: float = 2.0 -DEFAULT_TYPE_NAME: str = "str" -DEFAULT_CHAIN = "ethereum" - - -class FrozenMixin: # pylint: disable=too-few-public-methods - """Mixin for classes to enforce read-only attributes.""" - - _frozen: bool = False - - def __delattr__(self, *args: Any) -> None: - """Override __delattr__ to make object immutable.""" - if self._frozen: - raise AttributeError( - "This object is frozen! To unfreeze switch `self._frozen` via `__dict__`." - ) - super().__delattr__(*args) - - def __setattr__(self, *args: Any) -> None: - """Override __setattr__ to make object immutable.""" - if self._frozen: - raise AttributeError( - "This object is frozen! To unfreeze switch `self._frozen` via `__dict__`." - ) - super().__setattr__(*args) - - -class TypeCheckMixin: # pylint: disable=too-few-public-methods - """Mixin for data classes & models to enforce attribute types on construction.""" - - def __post_init__(self) -> None: - """Check that the type of the provided attributes is correct.""" - for attr, type_ in get_type_hints(self).items(): - value = getattr(self, attr) - check_type(attr, value, type_) - - @classmethod - def _ensure(cls, key: str, kwargs: Dict, type_: Any) -> Any: - """Get and ensure the configuration field is not None (if no default is provided) and of correct type.""" - enforce("skill_context" in kwargs, "Only use on models!") - skill_id = kwargs["skill_context"].skill_id - enforce( - key in kwargs, - f"'{key}' of type '{type_}' required, but it is not set in `models.params.args` of `skill.yaml` of `{skill_id}`", - ) - value = kwargs.pop(key) - try: - check_type(key, value, type_) - except TypeError: # pragma: nocover - enforce( - False, - f"'{key}' must be a {type_}, but type {type(value)} was found in `models.params.args` of `skill.yaml` of `{skill_id}`", - ) - return value - - -@dataclass(frozen=True) -class GenesisBlock(TypeCheckMixin): - """A dataclass to store the genesis block.""" - - max_bytes: str - max_gas: str - time_iota_ms: str - - def to_json(self) -> Dict[str, str]: - """Get a GenesisBlock instance as a json dictionary.""" - return { - "max_bytes": self.max_bytes, - "max_gas": self.max_gas, - "time_iota_ms": self.time_iota_ms, - } - - -@dataclass(frozen=True) -class GenesisEvidence(TypeCheckMixin): - """A dataclass to store the genesis evidence.""" - - max_age_num_blocks: str - max_age_duration: str - max_bytes: str - - def to_json(self) -> Dict[str, str]: - """Get a GenesisEvidence instance as a json dictionary.""" - return { - "max_age_num_blocks": self.max_age_num_blocks, - "max_age_duration": self.max_age_duration, - "max_bytes": self.max_bytes, - } - - -@dataclass(frozen=True) -class GenesisValidator(TypeCheckMixin): - """A dataclass to store the genesis validator.""" - - pub_key_types: Tuple[str, ...] - - def to_json(self) -> Dict[str, List[str]]: - """Get a GenesisValidator instance as a json dictionary.""" - return {"pub_key_types": list(self.pub_key_types)} - - -@dataclass(frozen=True) -class GenesisConsensusParams(TypeCheckMixin): - """A dataclass to store the genesis consensus parameters.""" - - block: GenesisBlock - evidence: GenesisEvidence - validator: GenesisValidator - version: dict - - @classmethod - def from_json_dict(cls, json_dict: dict) -> "GenesisConsensusParams": - """Get a GenesisConsensusParams instance from a json dictionary.""" - block = GenesisBlock(**json_dict["block"]) - evidence = GenesisEvidence(**json_dict["evidence"]) - validator = GenesisValidator(tuple(json_dict["validator"]["pub_key_types"])) - return cls(block, evidence, validator, json_dict["version"]) - - def to_json(self) -> Dict[str, Any]: - """Get a GenesisConsensusParams instance as a json dictionary.""" - return { - "block": self.block.to_json(), - "evidence": self.evidence.to_json(), - "validator": self.validator.to_json(), - "version": self.version, - } - - -@dataclass(frozen=True) -class GenesisConfig(TypeCheckMixin): - """A dataclass to store the genesis configuration.""" - - genesis_time: str - chain_id: str - consensus_params: GenesisConsensusParams - voting_power: str - - @classmethod - def from_json_dict(cls, json_dict: dict) -> "GenesisConfig": - """Get a GenesisConfig instance from a json dictionary.""" - consensus_params = GenesisConsensusParams.from_json_dict( - json_dict["consensus_params"] - ) - return cls( - json_dict["genesis_time"], - json_dict["chain_id"], - consensus_params, - json_dict["voting_power"], - ) - - def to_json(self) -> Dict[str, Any]: - """Get a GenesisConfig instance as a json dictionary.""" - return { - "genesis_time": self.genesis_time, - "chain_id": self.chain_id, - "consensus_params": self.consensus_params.to_json(), - "voting_power": self.voting_power, - } - - -class BaseParams( - Model, FrozenMixin, TypeCheckMixin -): # pylint: disable=too-many-instance-attributes - """Parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """ - Initialize the parameters object. - - The genesis configuration should be a dictionary with the following format: - genesis_time: str - chain_id: str - consensus_params: - block: - max_bytes: str - max_gas: str - time_iota_ms: str - evidence: - max_age_num_blocks: str - max_age_duration: str - max_bytes: str - validator: - pub_key_types: List[str] - version: dict - voting_power: str - - :param args: positional arguments - :param kwargs: keyword arguments - """ - self.genesis_config: GenesisConfig = GenesisConfig.from_json_dict( - self._ensure("genesis_config", kwargs, dict) - ) - self.service_id: str = self._ensure("service_id", kwargs, str) - self.tendermint_url: str = self._ensure("tendermint_url", kwargs, str) - self.max_healthcheck: int = self._ensure("max_healthcheck", kwargs, int) - self.round_timeout_seconds: float = self._ensure( - "round_timeout_seconds", kwargs, float - ) - self.sleep_time: int = self._ensure("sleep_time", kwargs, int) - self.retry_timeout: int = self._ensure("retry_timeout", kwargs, int) - self.retry_attempts: int = self._ensure("retry_attempts", kwargs, int) - self.keeper_timeout: float = self._ensure("keeper_timeout", kwargs, float) - self.reset_pause_duration: int = self._ensure_gte( - "reset_pause_duration", kwargs, int, min_value=MIN_RESET_PAUSE_DURATION - ) - self.drand_public_key: str = self._ensure("drand_public_key", kwargs, str) - self.tendermint_com_url: str = self._ensure("tendermint_com_url", kwargs, str) - self.tendermint_max_retries: int = self._ensure( - "tendermint_max_retries", kwargs, int - ) - self.tendermint_check_sleep_delay: int = self._ensure( - "tendermint_check_sleep_delay", kwargs, int - ) - self.reset_tendermint_after: int = self._ensure( - "reset_tendermint_after", kwargs, int - ) - self.cleanup_history_depth: int = self._ensure( - "cleanup_history_depth", kwargs, int - ) - self.cleanup_history_depth_current: Optional[int] = self._ensure( - "cleanup_history_depth_current", kwargs, Optional[int] - ) - self.request_timeout: float = self._ensure("request_timeout", kwargs, float) - self.request_retry_delay: float = self._ensure( - "request_retry_delay", kwargs, float - ) - self.tx_timeout: float = self._ensure("tx_timeout", kwargs, float) - self.max_attempts: int = self._ensure("max_attempts", kwargs, int) - self.service_registry_address: Optional[str] = self._ensure( - "service_registry_address", kwargs, Optional[str] - ) - self.on_chain_service_id: Optional[int] = self._ensure( - "on_chain_service_id", kwargs, Optional[int] - ) - self.share_tm_config_on_startup: bool = self._ensure( - "share_tm_config_on_startup", kwargs, bool - ) - self.tendermint_p2p_url: str = self._ensure("tendermint_p2p_url", kwargs, str) - self.use_termination: bool = self._ensure("use_termination", kwargs, bool) - self.use_slashing: bool = self._ensure("use_slashing", kwargs, bool) - self.slash_cooldown_hours: int = self._ensure( - "slash_cooldown_hours", kwargs, int - ) - self.slash_threshold_amount: int = self._ensure( - "slash_threshold_amount", kwargs, int - ) - self.light_slash_unit_amount: int = self._ensure( - "light_slash_unit_amount", kwargs, int - ) - self.serious_slash_unit_amount: int = self._ensure( - "serious_slash_unit_amount", kwargs, int - ) - self.setup_params: Dict[str, Any] = self._ensure("setup", kwargs, dict) - # TODO add to all configs - self.default_chain_id: str = kwargs.get("default_chain_id", DEFAULT_CHAIN) - - # we sanitize for null values as these are just kept for schema definitions - skill_id = kwargs["skill_context"].skill_id - super().__init__(*args, **kwargs) - - if not self.context.is_abstract_component: - # setup data are mandatory for non-abstract skills, - # and they should always contain at least `all_participants` and `safe_contract_address` - self._ensure_setup( - { - get_name(BaseSynchronizedData.safe_contract_address): str, - get_name(BaseSynchronizedData.all_participants): List[str], - get_name(BaseSynchronizedData.consensus_threshold): cast( - Type, Optional[int] - ), - }, - skill_id, - ) - self._frozen = True - - def _ensure_setup( - self, necessary_params: Dict[str, Type], skill_id: PublicId - ) -> Any: - """Ensure that the `setup` params contain all the `necessary_keys` and have the correct types.""" - enforce(bool(self.setup_params), "`setup` params contain no values!") - - for key, type_ in necessary_params.items(): - # check that the key is present, note that None is acceptable for optional keys - value = self.setup_params.get(key, VALUE_NOT_PROVIDED) - if value is VALUE_NOT_PROVIDED: - fail_msg = f"Value for `{key}` missing from the `setup` params." - enforce(False, fail_msg) - - # check that the value is of the correct type - try: - check_type(key, value, type_) - except TypeError: # pragma: nocover - enforce( - False, - f"'{key}' must be a {type_}, but type {type(value)} was found in `models.params.args.setup` " - f"of `skill.yaml` of `{skill_id}`", - ) - - def _ensure_gte( - self, key: str, kwargs: Dict[str, Any], type_: Type, min_value: Any - ) -> Any: - """Ensure that the value for the key is greater than or equal to the provided min_value.""" - err = check(min_value, type_) - enforce( - err is None, - f"min_value must be of type {type_.__name__}, but got {type(min_value).__name__}.", - ) - value = self._ensure(key, kwargs, type_) - enforce( - value >= min_value, f"`{key}` must be greater than or equal to {min_value}." - ) - return value - - -class _MetaSharedState(ABCMeta): - """A metaclass that validates SharedState's attributes.""" - - def __new__(mcs, name: str, bases: Tuple, namespace: Dict, **kwargs: Any) -> Type: # type: ignore - """Initialize the class.""" - new_cls = super().__new__(mcs, name, bases, namespace, **kwargs) - - if ABC in bases: - # abstract class, return - return new_cls - if not issubclass(new_cls, SharedState): - # the check only applies to SharedState subclasses - return new_cls - - mcs._check_consistency(cast(Type[SharedState], new_cls)) - return new_cls - - @classmethod - def _check_consistency(mcs, shared_state_cls: Type["SharedState"]) -> None: - """Check consistency of class attributes.""" - mcs._check_required_class_attributes(shared_state_cls) - - @classmethod - def _check_required_class_attributes( - mcs, shared_state_cls: Type["SharedState"] - ) -> None: - """Check that required class attributes are set.""" - if not hasattr(shared_state_cls, "abci_app_cls"): - raise AttributeError(f"'abci_app_cls' not set on {shared_state_cls}") - abci_app_cls = shared_state_cls.abci_app_cls - if not inspect.isclass(abci_app_cls): - raise AttributeError(f"The object `{abci_app_cls}` is not a class") - if not issubclass(abci_app_cls, AbciApp): - cls_name = AbciApp.__name__ - cls_module = AbciApp.__module__ - raise AttributeError( - f"The class {abci_app_cls} is not an instance of {cls_module}.{cls_name}" - ) - - -class SharedState(Model, ABC, metaclass=_MetaSharedState): # type: ignore - """Keep the current shared state of the skill.""" - - abci_app_cls: Type[AbciApp] - - def __init__( - self, - *args: Any, - skill_context: SkillContext, - **kwargs: Any, - ) -> None: - """Initialize the state.""" - self.abci_app_cls._is_abstract = skill_context.is_abstract_component - self._round_sequence: Optional[RoundSequence] = None - # a mapping of the agents' addresses to their initial Tendermint configuration, to be retrieved via ACN - self.initial_tm_configs: Dict[str, Optional[Dict[str, Any]]] = {} - # a mapping of the other agents' addresses to ACN deliverables - self.address_to_acn_deliverable: Dict[str, Any] = {} - self.tm_recovery_params: TendermintRecoveryParams = TendermintRecoveryParams( - self.abci_app_cls.initial_round_cls.auto_round_id() - ) - kwargs["skill_context"] = skill_context - super().__init__(*args, **kwargs) - - def setup_slashing(self, validator_to_agent: Dict[str, str]) -> None: - """Initialize the structures required for slashing.""" - configured_agents = set(self.initial_tm_configs.keys()) - agents_mapped = set(validator_to_agent.values()) - diff = agents_mapped.symmetric_difference(configured_agents) - if diff: - raise ValueError( - f"Trying to use the mapping `{validator_to_agent}`, which contains validators for non-configured " - "agents and/or does not contain validators for some configured agents. " - f"The agents which have been configured via ACN are `{configured_agents}` and the diff was for {diff}." - ) - self.round_sequence.validator_to_agent = validator_to_agent - self.round_sequence.offence_status = { - agent: OffenceStatus() for agent in agents_mapped - } - - def get_validator_address(self, agent_address: str) -> str: - """Get the validator address of an agent.""" - if agent_address not in self.synchronized_data.all_participants: - raise ValueError( - f"The validator address of non-participating agent `{agent_address}` was requested." - ) - - try: - agent_config = self.initial_tm_configs[agent_address] - except KeyError as e: - raise ValueError( - "SharedState's setup was not performed successfully." - ) from e - - if agent_config is None: - raise ValueError( - f"ACN registration has not been successfully performed for agent `{agent_address}`. " - "Have you set the `share_tm_config_on_startup` flag to `true` in the configuration?" - ) - - validator_address = agent_config.get("address", None) - if validator_address is None: - raise ValueError( - f"The tendermint configuration for agent `{agent_address}` is invalid: `{agent_config}`." - ) - - return validator_address - - def acn_container(self) -> Dict[str, Any]: - """Create a container for ACN results, i.e., a mapping from others' addresses to `None`.""" - ourself = {self.context.agent_address} - others_addresses = self.synchronized_data.all_participants - ourself - - return dict.fromkeys(others_addresses) - - def setup(self) -> None: - """Set up the model.""" - self._round_sequence = RoundSequence(self.context, self.abci_app_cls) - setup_params = cast(BaseParams, self.context.params).setup_params - self.round_sequence.setup( - BaseSynchronizedData( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists(setup_params), - cross_period_persisted_keys=self.abci_app_cls.cross_period_persisted_keys, - logger=self.context.logger, - ) - ), - self.context.logger, - ) - if not self.context.is_abstract_component: - self.initial_tm_configs = dict.fromkeys( - self.synchronized_data.all_participants - ) - - @property - def round_sequence(self) -> RoundSequence: - """Get the round_sequence.""" - if self._round_sequence is None: - raise ValueError("round sequence not available") - return self._round_sequence - - @property - def synchronized_data(self) -> BaseSynchronizedData: - """Get the latest synchronized_data if available.""" - return self.round_sequence.latest_synchronized_data - - def get_acn_result(self) -> Any: - """Get the majority of the ACN deliverables.""" - if len(self.address_to_acn_deliverable) == 0: - return None - - # the current agent does not participate, so we need `nb_participants - 1` - threshold = consensus_threshold(self.synchronized_data.nb_participants - 1) - counter = Counter(self.address_to_acn_deliverable.values()) - most_common_value, n_appearances = counter.most_common(1)[0] - - if n_appearances < threshold: - return None - - self.context.logger.debug( - f"ACN result is '{most_common_value}' from '{self.address_to_acn_deliverable}'." - ) - return most_common_value - - -class Requests(Model, FrozenMixin): - """Keep the current pending requests.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the state.""" - # mapping from dialogue reference nonce to a callback - self.request_id_to_callback: Dict[str, Callable] = {} - super().__init__(*args, **kwargs) - self._frozen = True - - -class UnexpectedResponseError(Exception): - """Exception class for unexpected responses from Apis.""" - - -@dataclass -class ResponseInfo(TypeCheckMixin): - """A dataclass to hold all the information related to the response.""" - - response_key: Optional[str] - response_index: Optional[int] - response_type: str - error_key: Optional[str] - error_index: Optional[int] - error_type: str - error_data: Any = None - - @classmethod - def from_json_dict(cls, kwargs: Dict) -> "ResponseInfo": - """Initialize a response info object from kwargs.""" - response_key: Optional[str] = kwargs.pop("response_key", None) - response_index: Optional[int] = kwargs.pop("response_index", None) - response_type: str = kwargs.pop("response_type", DEFAULT_TYPE_NAME) - error_key: Optional[str] = kwargs.pop("error_key", None) - error_index: Optional[int] = kwargs.pop("error_index", None) - error_type: str = kwargs.pop("error_type", DEFAULT_TYPE_NAME) - return cls( - response_key, - response_index, - response_type, - error_key, - error_index, - error_type, - ) - - -@dataclass -class RetriesInfo(TypeCheckMixin): - """A dataclass to hold all the information related to the retries.""" - - retries: int - backoff_factor: float - retries_attempted: int = 0 - - @classmethod - def from_json_dict(cls, kwargs: Dict) -> "RetriesInfo": - """Initialize a retries info object from kwargs.""" - retries: int = kwargs.pop("retries", NUMBER_OF_RETRIES) - backoff_factor: float = kwargs.pop("backoff_factor", DEFAULT_BACKOFF_FACTOR) - return cls(retries, backoff_factor) - - @property - def suggested_sleep_time(self) -> float: - """The suggested amount of time to sleep.""" - return self.backoff_factor**self.retries_attempted - - -@dataclass(frozen=True) -class TendermintRecoveryParams(TypeCheckMixin): - """ - A dataclass to hold all parameters related to agent <-> tendermint recovery procedures. - - This must be frozen so that we make sure it does not get edited. - """ - - reset_from_round: str - round_count: int = ROUND_COUNT_DEFAULT - reset_params: Optional[Dict[str, str]] = None - serialized_db_state: Optional[str] = None - - def __hash__(self) -> int: - """Hash the object.""" - return hash( - self.reset_from_round - + str(self.round_count) - + str(self.serialized_db_state) - + json.dumps(self.reset_params, sort_keys=True) - ) - - -class ApiSpecs(Model, FrozenMixin, TypeCheckMixin): - """A model that wraps APIs to get cryptocurrency prices.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize ApiSpecsModel.""" - self.url: str = self._ensure("url", kwargs, str) - self.api_id: str = self._ensure("api_id", kwargs, str) - self.method: str = self._ensure("method", kwargs, str) - self.headers: Dict[str, str] = dict( - self._ensure("headers", kwargs, OrderedDict[str, str]) - ) - self.parameters: Dict[str, str] = dict( - self._ensure("parameters", kwargs, OrderedDict[str, str]) - ) - self.response_info = ResponseInfo.from_json_dict(kwargs) - self.retries_info = RetriesInfo.from_json_dict(kwargs) - super().__init__(*args, **kwargs) - self._frozen = True - - def get_spec( - self, - ) -> Dict: - """Returns dictionary containing api specifications.""" - - return { - "url": self.url, - "method": self.method, - "headers": self.headers, - "parameters": self.parameters, - } - - def _log_response(self, decoded_response: str) -> None: - """Log the decoded response message using error level.""" - pretty_json_str = json.dumps(decoded_response, indent=4) - self.context.logger.error(f"Response: {pretty_json_str}") - - @staticmethod - def _parse_response( - response_data: Any, - response_keys: Optional[str], - response_index: Optional[int], - response_type: str, - ) -> Any: - """Parse a response from an API.""" - if response_keys is not None: - response_data = get_data_from_nested_dict(response_data, response_keys) - - if response_index is not None: - response_data = response_data[response_index] - - return get_value_with_type(response_data, response_type) - - def _get_error_from_response(self, response_data: Any) -> Any: - """Try to get an error from the response.""" - try: - return self._parse_response( - response_data, - self.response_info.error_key, - self.response_info.error_index, - self.response_info.error_type, - ) - except (KeyError, IndexError, TypeError): - self.context.logger.error( - f"Could not parse error using the given key(s) ({self.response_info.error_key}) " - f"and index ({self.response_info.error_index})!" - ) - return None - - def _parse_response_data(self, response_data: Any) -> Any: - """Get the response data.""" - try: - return self._parse_response( - response_data, - self.response_info.response_key, - self.response_info.response_index, - self.response_info.response_type, - ) - except (KeyError, IndexError, TypeError) as e: - raise UnexpectedResponseError from e - - def process_response(self, response: HttpMessage) -> Any: - """Process response from api.""" - decoded_response = response.body.decode() - self.response_info.error_data = None - - try: - response_data = json.loads(decoded_response) - except json.JSONDecodeError: - self.context.logger.error("Could not parse the response body!") - self._log_response(decoded_response) - return None - - try: - return self._parse_response_data(response_data) - except UnexpectedResponseError: - self.context.logger.error( - f"Could not access response using the given key(s) ({self.response_info.response_key}) " - f"and index ({self.response_info.response_index})!" - ) - self._log_response(decoded_response) - self.response_info.error_data = self._get_error_from_response(response_data) - return None - - def increment_retries(self) -> None: - """Increment the retries counter.""" - self.retries_info.retries_attempted += 1 - - def reset_retries(self) -> None: - """Reset the retries counter.""" - self.retries_info.retries_attempted = 0 - - def is_retries_exceeded(self) -> bool: - """Check if the retries amount has been exceeded.""" - return self.retries_info.retries_attempted > self.retries_info.retries - - -class BenchmarkBlockTypes(Enum): - """Benchmark block types.""" - - LOCAL = "local" - CONSENSUS = "consensus" - TOTAL = "total" - - -class BenchmarkBlock: - """ - Benchmark - - This class represents logic to measure the code block using a - context manager. - """ - - start: float - total_time: float - block_type: str - - def __init__(self, block_type: str) -> None: - """Benchmark for single round.""" - self.block_type = block_type - self.start = 0 - self.total_time = 0 - - def __enter__( - self, - ) -> None: - """Enter context.""" - self.start = time() - - def __exit__(self, *args: List, **kwargs: Dict) -> None: - """Exit context""" - self.total_time = time() - self.start - - -class BenchmarkBehaviour: - """ - BenchmarkBehaviour - - This class represents logic to benchmark a single behaviour. - """ - - local_data: Dict[str, BenchmarkBlock] - - def __init__( - self, - ) -> None: - """Initialize Benchmark behaviour object.""" - self.local_data = {} - - def _measure(self, block_type: str) -> BenchmarkBlock: - """ - Returns a BenchmarkBlock object. - - :param block_type: type of block (e.g. local, consensus, request) - :return: BenchmarkBlock - """ - - if block_type not in self.local_data: - self.local_data[block_type] = BenchmarkBlock(block_type) - - return self.local_data[block_type] - - def local( - self, - ) -> BenchmarkBlock: - """Measure local block.""" - return self._measure(BenchmarkBlockTypes.LOCAL.value) - - def consensus( - self, - ) -> BenchmarkBlock: - """Measure consensus block.""" - return self._measure(BenchmarkBlockTypes.CONSENSUS.value) - - -class BenchmarkTool(Model, TypeCheckMixin, FrozenMixin): - """ - BenchmarkTool - - Tool to benchmark ABCI apps. - """ - - benchmark_data: Dict[str, BenchmarkBehaviour] - log_dir: Path - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Benchmark tool for rounds behaviours.""" - self.benchmark_data = {} - log_dir_ = self._ensure("log_dir", kwargs, str) - self.log_dir = Path(log_dir_) - super().__init__(*args, **kwargs) - self._frozen = True - - def measure(self, behaviour: str) -> BenchmarkBehaviour: - """Measure time to complete round.""" - if behaviour not in self.benchmark_data: - self.benchmark_data[behaviour] = BenchmarkBehaviour() - return self.benchmark_data[behaviour] - - @property - def data( - self, - ) -> List: - """Returns formatted data.""" - - behavioural_data = [] - for behaviour, tool in self.benchmark_data.items(): - data = {k: v.total_time for k, v in tool.local_data.items()} - data[BenchmarkBlockTypes.TOTAL.value] = sum(data.values()) - behavioural_data.append({"behaviour": behaviour, "data": data}) - - return behavioural_data - - def save(self, period: int = 0, reset: bool = True) -> None: - """Save logs to a file.""" - - try: - self.log_dir.mkdir(exist_ok=True) - agent_dir = self.log_dir / self.context.agent_address - agent_dir.mkdir(exist_ok=True) - filepath = agent_dir / f"{period}.json" - - with open(str(filepath), "w+", encoding="utf-8") as outfile: - json.dump(self.data, outfile) - self.context.logger.debug(f"Saving benchmarking data for period: {period}") - - except PermissionError as e: # pragma: nocover - self.context.logger.error(f"Error saving benchmark data:\n{e}") - - if reset: - self.reset() - - def reset( - self, - ) -> None: - """Reset benchmark data""" - self.benchmark_data.clear() diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/skill.yaml b/trader_old/vendor/valory/skills/abstract_round_abci/skill.yaml deleted file mode 100644 index 7264c012a..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/skill.yaml +++ /dev/null @@ -1,164 +0,0 @@ -name: abstract_round_abci -author: valory -version: 0.1.0 -type: skill -description: abstract round-based ABCI application -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeievb7bhfm46p5adx3x4gvsynjpq35fcrrapzn5m2whcdt4ufxfvfq - __init__.py: bafybeihxbinbrvhj2edqthpzc2mywfzxzkf7l4v5uj6ubwnffrwgzelmre - abci_app_chain.py: bafybeibhzrixbp5x26wqhb6ogtr3af5lc4tax7lcsvk4v5rvg4psrq5yzi - base.py: bafybeihm7lf4nfqcwfvs4antge2l7eyc7vrafaw6p5canlxwy4qy4akwme - behaviour_utils.py: bafybeidhnu2ucjhlluwthpl4d6374nzmvjopy7byc2uyirajb3kswfggle - behaviours.py: bafybeifzbzy2ppabm6dpgvbsuvpgduyg7g7rei6u4ouy3nnak5top5be5u - common.py: bafybeib4coyhaxvpup7m25lsab2lpebv2wrkjp2cwihuitxmaibo6u6z2m - dialogues.py: bafybeid5sgrfa7ghnnjpssltgtey5gzt5kc2jlaitffaukvhhdbhrzcjti - handlers.py: bafybeidgby4h72qgcp3civ3c55oz3k7s4gdbkcotwhqjsbft6ylbaenjxy - io_/__init__.py: bafybeihv6ytxeo5jkbdlqjum4pfo4aaluvw4m7c55k5xncvvs7ubrlokhy - io_/ipfs.py: bafybeiffdxdt36rcwu5tyfav2umvw3hvlfjwbys3626p2g2gdlfi7djzly - io_/load.py: bafybeigkywwlsheqvd4gpyfwaxqzkkb2ih2poyicqk7e7n2mrsghxzyns4 - io_/paths.py: bafybeicfno2l4vwtmjcm3rzpp6tqi3xlkof47pypf5teecad22d44u2ple - io_/store.py: bafybeig24lslvhf7amim55ig5zzre4z45pcx3r2ozlagg3mtbr6rry2wpu - models.py: bafybeiaffpzuduwwo367cqm4uzl46mq34pdspq57o5itdb5ivyi4s743by - test_tools/__init__.py: bafybeibayeahoo73eztt2chpwi45taj2uv3dxbpyn47ksqfjoepjyaoca4 - test_tools/abci_app.py: bafybeigmrjzxfoc63xgecyngdecz4msvze4aw2iejcjewatjefjbvdlmce - test_tools/base.py: bafybeibef4lclyecne5qj4zaxnaxaqzwpxjaitqqmddgsiezduhb7pfxly - test_tools/common.py: bafybeibxlx7es632kdoeivfrjahns3kknkxfmw4rj2dcxjwqm5j6vx25sq - test_tools/integration.py: bafybeifqq3bx46hz2deph3usvrt7u45tpsapvocofd2zu3yh7rfl5nlmzq - test_tools/rounds.py: bafybeie576yxtiramzt5czpt4hnv76gfetzio2t3k5kprhdhvbpfddbaem - tests/__init__.py: bafybeie54sgqid64dyarbcttz3nnmyympyrtdyxy4lcc7c7yjxhefodbgq - tests/conftest.py: bafybeiauvmnuetxooprdsy3vlys3pha6x2rfg7acr3xrdfffr7onlmnave - tests/data/__init__.py: bafybeifmqjnrqgbau4tshhdtrosru7xyjky72ljlrf3ynrk76fxjcsgfpi - tests/data/dummy_abci/__init__.py: bafybeiaoqyjlgez5gkvutl22ihebcjk3zskve5gdt5wbap5zkmhehoddca - tests/data/dummy_abci/behaviours.py: bafybeibei4ngebbktuq6a2uvwhrulgkvn6uhaj5k3a75zihkxwnfarqh4m - tests/data/dummy_abci/dialogues.py: bafybeiaswubmqa7trhajbjn34okmpftk2sehsqrjg7znzrrd7j32xzx4vq - tests/data/dummy_abci/handlers.py: bafybeifik3ftljs63u7nm4gadxpqbcvqj53p7qftzzzfto3ioad57k3x3u - tests/data/dummy_abci/models.py: bafybeiear3i45wbaylrkbnm2fbtqorxx56glul36piuah7m7jb56f5rpoq - tests/data/dummy_abci/payloads.py: bafybeiczldqiumb7prcusb7l5vb575vschwyseyigpupvteldfyz7h6fyi - tests/data/dummy_abci/rounds.py: bafybeihhheznpcntg4z5cdd7dysnivo2g4x5biv7blriyiyoouqp6xf5aq - tests/test_abci_app_chain.py: bafybeihqvjkcwkwxowhb3umtk52us4pd5f6nbppw4ycx76oljw4j3j7xpa - tests/test_base.py: bafybeihtx2ktf6uck2l6yw72lvnvm5y224vlgawxette75cluc6juedeqe - tests/test_base_rounds.py: bafybeiadkpwuhz6y5k5ffvoqvyi6nqetf5ov5bmodejge7yvscm6yqzpse - tests/test_behaviours.py: bafybeibxxev34avddvezqumr56k7txmqkubl2c5u6y7ydjqn6kp3wabbvq - tests/test_behaviours_utils.py: bafybeidkxzhu26r2shkblz2l3syzc62uet4cxrdbschnf7vuwuuior6xkm - tests/test_common.py: bafybeiekicwjh3vu5kqppictya2bmqm3p5dcauj7cvsiunvhhultpzmyla - tests/test_dialogues.py: bafybeigpfrslqaz2yullyehia5bsl7cmy2qqxtz627ig7rbrypw5xfzeum - tests/test_handlers.py: bafybeih64lmsukci3oc5mwi636gntyx243xnbzwx64dwjxittch77qyqsu - tests/test_io/__init__.py: bafybeid3sssvbbyju4snrdssxyafleuo57sqyuepl25btxcbuj3p5oonsm - tests/test_io/test_ipfs.py: bafybeidm6f6naq6y7ntoivrqon2bkwdvd2dqru467fxqvgonv5oq5huhra - tests/test_io/test_load.py: bafybeidgnxt5rt67ackbcgi5vnlliedxakcnzgihogplolck7kp57pc6iy - tests/test_io/test_store.py: bafybeid2zbdjtgbplenacudk6re7si7dloqs2u7faqt7vhapjipjuw35ku - tests/test_models.py: bafybeicrbu6xtprfgwjs3msa3idilwqe3ymz5zx6xm326huhspzrdngrwi - tests/test_tools/__init__.py: bafybeiew6gu4pgp2sjevq4dbnmv2ail5dph7vj4yi7h3eae4gzx7vj7cbq - tests/test_tools/base.py: bafybeihi7ax53326dhin3riwwwk3bouqvsoeq26han4nspodzj6hrk3gia - tests/test_tools/test_base.py: bafybeie2hox7v6sy677grl6awq57ouliohpwhmlvrypz5rqcz5gxsxn24y - tests/test_tools/test_common.py: bafybeieauphpcqm5on7d2u2lc5lrf3esbhojp6sxlf7phrlmpqy5cfoitq - tests/test_tools/test_integration.py: bafybeidxkvb2kizi7djrpuw446dqxo2v5s7j2dbdrdpfmnd2ggezaxbnkm - tests/test_tools/test_rounds.py: bafybeibaoj4miysneipgukz7xufs47vpv5rds3ptgmu3yxlcl7gjss6ccm - tests/test_utils.py: bafybeift6igxoan2bnuexps7rrdl25jmlniqujw3odnir3cgjy4oukjjfq - utils.py: bafybeidbha3c3tcxo4lhucyx2x6yra4z2p2fp6sucqqzhxanbvgrraykbi -fingerprint_ignore_patterns: [] -connections: -- valory/abci:0.1.0:bafybeia6etkacvqend7xj6viejkqgo7ozu3yn4yg3qezfthf2xhrjjwse4 -- valory/http_client:0.23.0:bafybeihi772xgzpqeipp3fhmvpct4y6e6tpjp4sogwqrnf3wqspgeilg4u -- valory/ipfs:0.1.0:bafybeigcijdbwgdekow5c2ikeltetoteabfp52ewy3xfkd7ygaqbl7j3ke -- valory/ledger:0.19.0:bafybeig7woeog4srdby75hpjkmx4rhpkzncbf4h2pm5r6varsp26pf2uhu -- valory/p2p_libp2p_client:0.1.0:bafybeid3xg5k2ol5adflqloy75ibgljmol6xsvzvezebsg7oudxeeolz7e -contracts: -- valory/service_registry:0.1.0:bafybeiaop64kwdoetxtedoehabmsalojmms7ihuoqcdwxtwb2hk5i6bzye -protocols: -- open_aea/signing:1.0.0:bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi -- valory/abci:0.1.0:bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -- valory/ipfs:0.1.0:bafybeiftxi2qhreewgsc5wevogi7yc5g6hbcbo4uiuaibauhv3nhfcdtvm -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -- valory/tendermint:0.1.0:bafybeig4mi3vmlv5zpbjbfuzcgida6j5f2nhrpedxicmrrfjweqc5r7cra -skills: -- valory/abstract_abci:0.1.0:bafybeieeaseuy5rbbw465knz27vccvpkfge43q7isl7fkdlfapwd7bpi24 -behaviours: - main: - args: {} - class_name: AbstractRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - api_specs: - args: {} - class_name: ApiSpecs - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: - eth_typing: {} - hypothesis: - version: ==6.21.6 - ipfshttpclient: - version: ==0.8.0a2 - open-aea-cli-ipfs: - version: ==1.53.0 - open-aea-test-autonomy: - version: ==0.14.14.post1 - protobuf: - version: <4.25.0,>=4.21.6 - py-ecc: - version: ==6.0.0 - pytest: - version: ==7.2.1 - pytz: - version: ==2022.2.1 - requests: - version: <2.31.2,>=2.28.1 - typing_extensions: - version: '>=3.10.0.2' -is_abstract: true -customs: [] diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/__init__.py b/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/__init__.py deleted file mode 100644 index 33f9dae86..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for abstract_round_abci derived skills.""" # pragma: nocover diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/abci_app.py b/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/abci_app.py deleted file mode 100644 index 10e126096..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/abci_app.py +++ /dev/null @@ -1,203 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""ABCI App test tools.""" - - -from abc import ABC -from enum import Enum -from typing import Dict, Tuple, Type, Union -from unittest.mock import MagicMock - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbstractRound, - BaseSynchronizedData, - BaseTxPayload, - DegenerateRound, -) - - -class _ConcreteRound(AbstractRound, ABC): - """ConcreteRound""" - - synchronized_data_class = BaseSynchronizedData - payload_attribute = "" - - def end_block(self) -> Union[None, Tuple[MagicMock, MagicMock]]: - """End block.""" - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - - -class ConcreteRoundA(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - def end_block(self) -> Tuple[MagicMock, MagicMock]: - """End block.""" - return MagicMock(), MagicMock() - - -class ConcreteRoundB(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteRoundC(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteBackgroundRound(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteBackgroundSlashingRound(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteTerminationRoundA(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteTerminationRoundB(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteTerminationRoundC(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteSlashingRoundA(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteSlashingRoundB(_ConcreteRound): - """Dummy instantiation of the AbstractRound class.""" - - payload_class = BaseTxPayload - - -class ConcreteEvents(Enum): - """Defines dummy events to be used for testing purposes.""" - - TERMINATE = "terminate" - PENDING_OFFENCE = "pending_offence" - SLASH_START = "slash_start" - SLASH_END = "slash_end" - A = "a" - B = "b" - C = "c" - D = "c" - TIMEOUT = "timeout" - - def __str__(self) -> str: - """Get the string representation of the event.""" - return self.value - - -class TerminationAppTest(AbciApp[ConcreteEvents]): - """A dummy Termination abci for testing purposes.""" - - initial_round_cls: Type[AbstractRound] = ConcreteBackgroundRound - transition_function: Dict[ - Type[AbstractRound], Dict[ConcreteEvents, Type[AbstractRound]] - ] = { - ConcreteBackgroundRound: { - ConcreteEvents.TERMINATE: ConcreteTerminationRoundA, - }, - ConcreteTerminationRoundA: { - ConcreteEvents.A: ConcreteTerminationRoundA, - ConcreteEvents.B: ConcreteTerminationRoundB, - ConcreteEvents.C: ConcreteTerminationRoundC, - }, - ConcreteTerminationRoundB: { - ConcreteEvents.B: ConcreteTerminationRoundB, - ConcreteEvents.TIMEOUT: ConcreteTerminationRoundA, - }, - ConcreteTerminationRoundC: { - ConcreteEvents.C: ConcreteTerminationRoundA, - ConcreteEvents.TIMEOUT: ConcreteTerminationRoundC, - }, - } - - -class SlashingAppTest(AbciApp[ConcreteEvents]): - """A dummy Slashing abci for testing purposes.""" - - initial_round_cls: Type[AbstractRound] = ConcreteBackgroundSlashingRound - transition_function: Dict[ - Type[AbstractRound], Dict[ConcreteEvents, Type[AbstractRound]] - ] = { - ConcreteBackgroundSlashingRound: { - ConcreteEvents.SLASH_START: ConcreteSlashingRoundA, - }, - ConcreteSlashingRoundA: {ConcreteEvents.D: ConcreteSlashingRoundB}, - ConcreteSlashingRoundB: { - ConcreteEvents.SLASH_END: DegenerateRound, - }, - } - - -class AbciAppTest(AbciApp[ConcreteEvents]): - """A dummy AbciApp for testing purposes.""" - - TIMEOUT: float = 1.0 - - initial_round_cls: Type[AbstractRound] = ConcreteRoundA - transition_function: Dict[ - Type[AbstractRound], Dict[ConcreteEvents, Type[AbstractRound]] - ] = { - ConcreteRoundA: { - ConcreteEvents.A: ConcreteRoundA, - ConcreteEvents.B: ConcreteRoundB, - ConcreteEvents.C: ConcreteRoundC, - }, - ConcreteRoundB: { - ConcreteEvents.B: ConcreteRoundB, - ConcreteEvents.TIMEOUT: ConcreteRoundA, - }, - ConcreteRoundC: { - ConcreteEvents.C: ConcreteRoundA, - ConcreteEvents.TIMEOUT: ConcreteRoundC, - }, - } - event_to_timeout: Dict[ConcreteEvents, float] = { - ConcreteEvents.TIMEOUT: TIMEOUT, - } diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/base.py b/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/base.py deleted file mode 100644 index 30640e941..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/base.py +++ /dev/null @@ -1,444 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/abstract_round_abci skill's behaviours.""" -import json -from abc import ABC -from copy import copy -from enum import Enum -from pathlib import Path -from tempfile import TemporaryDirectory -from typing import Any, Dict, Type, cast -from unittest import mock -from unittest.mock import MagicMock - -from aea.helpers.transaction.base import SignedMessage -from aea.test_tools.test_skill import BaseSkillTestCase - -from packages.open_aea.protocols.signing import SigningMessage -from packages.valory.connections.http_client.connection import ( - PUBLIC_ID as HTTP_CLIENT_PUBLIC_ID, -) -from packages.valory.connections.ledger.connection import ( - PUBLIC_ID as LEDGER_CONNECTION_PUBLIC_ID, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import ( - AbstractRound, - BaseSynchronizedData, - BaseTxPayload, - OK_CODE, - _MetaPayload, -) -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler, - HttpHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, -) - - -# pylint: disable=protected-access,too-few-public-methods,consider-using-with - - -class FSMBehaviourBaseCase(BaseSkillTestCase, ABC): - """Base case for testing FSMBehaviour classes.""" - - path_to_skill: Path - behaviour: AbstractRoundBehaviour - ledger_handler: LedgerApiHandler - http_handler: HttpHandler - contract_handler: ContractApiHandler - signing_handler: SigningHandler - tendermint_handler: TendermintHandler - old_tx_type_to_payload_cls: Dict[str, Type[BaseTxPayload]] - benchmark_dir: TemporaryDirectory - default_ledger: str = "ethereum" - - @classmethod - def setup_class(cls, **kwargs: Any) -> None: - """Setup the test class.""" - if not hasattr(cls, "path_to_skill"): - raise ValueError(f"No `path_to_skill` set on {cls}") # pragma: nocover - # works once https://github.com/valory-xyz/open-aea/issues/492 is fixed - # we need to store the current value of the meta-class attribute - # _MetaPayload.transaction_type_to_payload_cls, and restore it - # in the teardown function. We do a shallow copy so we avoid - # to modify the old mapping during the execution of the tests. - cls.old_tx_type_to_payload_cls = copy(_MetaPayload.registry) - _MetaPayload.registry = {} - super().setup_class(**kwargs) # pylint: disable=no-value-for-parameter - assert ( - cls._skill.skill_context._agent_context is not None - ), "Agent context not set" # nosec - cls._skill.skill_context._agent_context.identity._default_address_key = ( - cls.default_ledger - ) - cls._skill.skill_context._agent_context._default_ledger_id = cls.default_ledger - behaviour = cls._skill.skill_context.behaviours.main - assert isinstance( - behaviour, AbstractRoundBehaviour - ), f"{behaviour} is not of type {AbstractRoundBehaviour}" - cls.behaviour = behaviour - for attr, handler, handler_type in [ - ("http_handler", cls._skill.skill_context.handlers.http, HttpHandler), - ( - "signing_handler", - cls._skill.skill_context.handlers.signing, - SigningHandler, - ), - ( - "contract_handler", - cls._skill.skill_context.handlers.contract_api, - ContractApiHandler, - ), - ( - "ledger_handler", - cls._skill.skill_context.handlers.ledger_api, - LedgerApiHandler, - ), - ( - "tendermint_handler", - cls._skill.skill_context.handlers.tendermint, - TendermintHandler, - ), - ]: - assert isinstance( - handler, handler_type - ), f"{handler} is not of type {handler_type}" - setattr(cls, attr, handler) - - if kwargs.get("param_overrides") is not None: - for param_name, param_value in kwargs["param_overrides"].items(): - cls.behaviour.context.params.__dict__[param_name] = param_value - - def setup(self, **kwargs: Any) -> None: - """ - Set up the test method. - - Called each time before a test method is called. - - :param kwargs: the keyword arguments passed to _prepare_skill - """ - super().setup(**kwargs) - self.behaviour.setup() - self._skill.skill_context.state.setup() - self._skill.skill_context.state.round_sequence.end_sync() - - self.benchmark_dir = TemporaryDirectory() - self._skill.skill_context.benchmark_tool.__dict__["log_dir"] = Path( - self.benchmark_dir.name - ) - assert ( # nosec - cast(BaseBehaviour, self.behaviour.current_behaviour).behaviour_id - == self.behaviour.initial_behaviour_cls.auto_behaviour_id() - ) - - def fast_forward_to_behaviour( - self, - behaviour: AbstractRoundBehaviour, - behaviour_id: str, - synchronized_data: BaseSynchronizedData, - ) -> None: - """Fast forward the FSM to a behaviour.""" - next_behaviour = {s.auto_behaviour_id(): s for s in behaviour.behaviours}[ - behaviour_id - ] - next_behaviour = cast(Type[BaseBehaviour], next_behaviour) - behaviour.current_behaviour = next_behaviour( - name=next_behaviour.auto_behaviour_id(), skill_context=behaviour.context - ) - self.skill.skill_context.state.round_sequence.abci_app._round_results.append( - synchronized_data - ) - self.skill.skill_context.state.round_sequence.abci_app._extend_previous_rounds_with_current_round() - self.skill.skill_context.behaviours.main._last_round_height = ( - self.skill.skill_context.state.round_sequence.abci_app.current_round_height - ) - self.skill.skill_context.state.round_sequence.abci_app._current_round_cls = ( - next_behaviour.matching_round - ) - # consensus parameters will not be available if the current skill is abstract - consensus_params = getattr( - self.skill.skill_context.params, "consensus_params", None - ) - self.skill.skill_context.state.round_sequence.abci_app._current_round = ( - next_behaviour.matching_round(synchronized_data, consensus_params) - ) - - def mock_ledger_api_request( - self, request_kwargs: Dict, response_kwargs: Dict - ) -> None: - """ - Mock http request. - - :param request_kwargs: keyword arguments for request check. - :param response_kwargs: keyword arguments for mock response. - """ - - self.assert_quantity_in_outbox(1) - actual_ledger_api_message = self.get_message_from_outbox() - assert actual_ledger_api_message is not None, "No message in outbox." # nosec - has_attributes, error_str = self.message_has_attributes( - actual_message=actual_ledger_api_message, - message_type=LedgerApiMessage, - to=str(LEDGER_CONNECTION_PUBLIC_ID), - sender=str(self.skill.skill_context.skill_id), - **request_kwargs, - ) - - assert has_attributes, error_str # nosec - incoming_message = self.build_incoming_message( - message_type=LedgerApiMessage, - dialogue_reference=( - actual_ledger_api_message.dialogue_reference[0], - "stub", - ), - target=actual_ledger_api_message.message_id, - message_id=-1, - to=str(self.skill.skill_context.skill_id), - sender=str(LEDGER_CONNECTION_PUBLIC_ID), - ledger_id=str(LEDGER_CONNECTION_PUBLIC_ID), - **response_kwargs, - ) - self.ledger_handler.handle(incoming_message) - self.behaviour.act_wrapper() - - def mock_contract_api_request( - self, contract_id: str, request_kwargs: Dict, response_kwargs: Dict - ) -> None: - """ - Mock http request. - - :param contract_id: contract id. - :param request_kwargs: keyword arguments for request check. - :param response_kwargs: keyword arguments for mock response. - """ - - self.assert_quantity_in_outbox(1) - actual_contract_ledger_message = self.get_message_from_outbox() - assert ( # nosec - actual_contract_ledger_message is not None - ), "No message in outbox." - has_attributes, error_str = self.message_has_attributes( - actual_message=actual_contract_ledger_message, - message_type=ContractApiMessage, - to=str(LEDGER_CONNECTION_PUBLIC_ID), - sender=str(self.skill.skill_context.skill_id), - ledger_id="ethereum", - contract_id=contract_id, - message_id=1, - **request_kwargs, - ) - assert has_attributes, error_str # nosec - self.behaviour.act_wrapper() - - incoming_message = self.build_incoming_message( - message_type=ContractApiMessage, - dialogue_reference=( - actual_contract_ledger_message.dialogue_reference[0], - "stub", - ), - target=actual_contract_ledger_message.message_id, - message_id=-1, - to=str(self.skill.skill_context.skill_id), - sender=str(LEDGER_CONNECTION_PUBLIC_ID), - ledger_id="ethereum", - contract_id="mock_contract_id", - **response_kwargs, - ) - self.contract_handler.handle(incoming_message) - self.behaviour.act_wrapper() - - def mock_http_request(self, request_kwargs: Dict, response_kwargs: Dict) -> None: - """ - Mock http request. - - :param request_kwargs: keyword arguments for request check. - :param response_kwargs: keyword arguments for mock response. - """ - - self.assert_quantity_in_outbox(1) - actual_http_message = self.get_message_from_outbox() - assert actual_http_message is not None, "No message in outbox." # nosec - has_attributes, error_str = self.message_has_attributes( - actual_message=actual_http_message, - message_type=HttpMessage, - performative=HttpMessage.Performative.REQUEST, - to=str(HTTP_CLIENT_PUBLIC_ID), - sender=str(self.skill.skill_context.skill_id), - **request_kwargs, - ) - assert has_attributes, error_str # nosec - self.behaviour.act_wrapper() - self.assert_quantity_in_outbox(0) - incoming_message = self.build_incoming_message( - message_type=HttpMessage, - dialogue_reference=(actual_http_message.dialogue_reference[0], "stub"), - performative=HttpMessage.Performative.RESPONSE, - target=actual_http_message.message_id, - message_id=-1, - to=str(self.skill.skill_context.skill_id), - sender=str(HTTP_CLIENT_PUBLIC_ID), - **response_kwargs, - ) - self.http_handler.handle(incoming_message) - self.behaviour.act_wrapper() - - def mock_signing_request(self, request_kwargs: Dict, response_kwargs: Dict) -> None: - """Mock signing request.""" - self.assert_quantity_in_decision_making_queue(1) - actual_signing_message = self.get_message_from_decision_maker_inbox() - assert actual_signing_message is not None, "No message in outbox." # nosec - has_attributes, error_str = self.message_has_attributes( - actual_message=actual_signing_message, - message_type=SigningMessage, - to=self.skill.skill_context.decision_maker_address, - sender=str(self.skill.skill_context.skill_id), - **request_kwargs, - ) - assert has_attributes, error_str # nosec - incoming_message = self.build_incoming_message( - message_type=SigningMessage, - dialogue_reference=(actual_signing_message.dialogue_reference[0], "stub"), - target=actual_signing_message.message_id, - message_id=-1, - to=str(self.skill.skill_context.skill_id), - sender=self.skill.skill_context.decision_maker_address, - **response_kwargs, - ) - self.signing_handler.handle(incoming_message) - self.behaviour.act_wrapper() - - def mock_a2a_transaction( - self, - ) -> None: - """Performs mock a2a transaction.""" - - self.mock_signing_request( - request_kwargs=dict( - performative=SigningMessage.Performative.SIGN_MESSAGE, - ), - response_kwargs=dict( - performative=SigningMessage.Performative.SIGNED_MESSAGE, - signed_message=SignedMessage( - ledger_id="ethereum", body="stub_signature" - ), - ), - ) - - self.mock_http_request( - request_kwargs=dict( - method="GET", - headers="", - version="", - body=b"", - ), - response_kwargs=dict( - version="", - status_code=200, - status_text="", - headers="", - body=json.dumps({"result": {"hash": "", "code": OK_CODE}}).encode( - "utf-8" - ), - ), - ) - self.mock_http_request( - request_kwargs=dict( - method="GET", - headers="", - version="", - body=b"", - ), - response_kwargs=dict( - version="", - status_code=200, - status_text="", - headers="", - body=json.dumps({"result": {"tx_result": {"code": OK_CODE}}}).encode( - "utf-8" - ), - ), - ) - - def end_round(self, done_event: Enum) -> None: - """Ends round early to cover `wait_for_end` generator.""" - current_behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - if current_behaviour is None: - return - current_behaviour = cast(BaseBehaviour, current_behaviour) - abci_app = current_behaviour.context.state.round_sequence.abci_app - old_round = abci_app._current_round - abci_app._last_round = old_round - abci_app._current_round = abci_app.transition_function[ - current_behaviour.matching_round - ][done_event](abci_app.synchronized_data, context=MagicMock()) - abci_app._previous_rounds.append(old_round) - abci_app._current_round_height += 1 - self.behaviour._process_current_round() - - def _test_done_flag_set(self) -> None: - """Test that, when round ends, the 'done' flag is set.""" - current_behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert not current_behaviour.is_done() # nosec - with mock.patch.object( - self.behaviour.context.state, "_round_sequence" - ) as mock_round_sequence: - mock_round_sequence.last_round_id = cast( - AbstractRound, current_behaviour.matching_round - ).auto_round_id() - current_behaviour.act_wrapper() - assert current_behaviour.is_done() # nosec - - @classmethod - def teardown_class(cls) -> None: - """Teardown the test class.""" - if getattr(cls, "old_tx_type_to_payload_cls", False): - _MetaPayload.registry = cls.old_tx_type_to_payload_cls - - def teardown(self, **kwargs: Any) -> None: - """Teardown.""" - super().teardown(**kwargs) - self.benchmark_dir.cleanup() - - -class DummyContext: - """Dummy Context class for testing shared state initialization.""" - - class params: - """Dummy param variable.""" - - round_timeout_seconds: float = 1.0 - - _skill: MagicMock = MagicMock() - logger: MagicMock = MagicMock() - skill_id = "dummy_skill_id" - - @property - def is_abstract_component(self) -> bool: - """Mock for is_abstract.""" - return True diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/common.py b/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/common.py deleted file mode 100644 index 8fdab2638..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/common.py +++ /dev/null @@ -1,432 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Test common classes.""" -import binascii -import json -import time -from pathlib import Path -from typing import Any, Set, Type, cast -from unittest import mock - -import pytest -from aea.exceptions import AEAActException -from aea.skills.base import SkillContext - -from packages.valory.protocols.contract_api.custom_types import State -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - BaseSynchronizedData, -) -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) - - -PACKAGE_DIR = Path(__file__).parent.parent -DRAND_VALUE = { - "round": 1416669, - "randomness": "f6be4bf1fa229f22340c1a5b258f809ac4af558200775a67dacb05f0cb258a11", - "signature": ( - "b44d00516f46da3a503f9559a634869b6dc2e5d839e46ec61a090e3032172954929a5" - "d9bd7197d7739fe55db770543c71182562bd0ad20922eb4fe6b8a1062ed21df3b68de" - "44694eb4f20b35262fa9d63aa80ad3f6172dd4d33a663f21179604" - ), - "previous_signature": ( - "903c60a4b937a804001032499a855025573040cb86017c38e2b1c3725286756ce8f33" - "61188789c17336beaf3f9dbf84b0ad3c86add187987a9a0685bc5a303e37b008fba8c" - "44f02a416480dd117a3ff8b8075b1b7362c58af195573623187463" - ), -} - - -class CommonBaseCase(FSMBehaviourBaseCase): - """Base case for testing PriceEstimation FSMBehaviour.""" - - path_to_skill = PACKAGE_DIR = Path(__file__).parent.parent - - -class BaseRandomnessBehaviourTest(CommonBaseCase): - """Test RandomnessBehaviour.""" - - randomness_behaviour_class: Type[BaseBehaviour] - next_behaviour_class: Type[BaseBehaviour] - done_event: Any - - def test_randomness_behaviour( - self, - ) -> None: - """Test RandomnessBehaviour.""" - - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.act_wrapper() - self.mock_http_request( - request_kwargs=dict( - method="GET", - headers="", - version="", - body=b"", - url="https://drand.cloudflare.com/public/latest", - ), - response_kwargs=dict( - version="", - status_code=200, - status_text="", - headers="", - body=json.dumps(DRAND_VALUE).encode("utf-8"), - ), - ) - - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(self.done_event) - - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == self.next_behaviour_class.auto_behaviour_id() - - def test_invalid_drand_value( - self, - ) -> None: - """Test invalid drand values.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.act_wrapper() - - drand_value = DRAND_VALUE.copy() - drand_value["randomness"] = binascii.hexlify(b"randomness_hex").decode() - self.mock_http_request( - request_kwargs=dict( - method="GET", - headers="", - version="", - body=b"", - url="https://drand.cloudflare.com/public/latest", - ), - response_kwargs=dict( - version="", - status_code=200, - status_text="", - headers="", - body=json.dumps(drand_value).encode(), - ), - ) - - def test_invalid_response( - self, - ) -> None: - """Test invalid json response.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.act_wrapper() - - self.mock_http_request( - request_kwargs=dict( - method="GET", - headers="", - version="", - body=b"", - url="https://drand.cloudflare.com/public/latest", - ), - response_kwargs=dict( - version="", status_code=200, status_text="", headers="", body=b"" - ), - ) - self.behaviour.act_wrapper() - time.sleep(1) - self.behaviour.act_wrapper() - - def test_max_retries_reached_fallback( - self, - ) -> None: - """Test with max retries reached.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.context.randomness_api.__dict__["_frozen"] = False - with mock.patch.object( - self.behaviour.context.randomness_api, - "is_retries_exceeded", - return_value=True, - ): - self.behaviour.act_wrapper() - self.mock_ledger_api_request( - request_kwargs=dict( - performative=LedgerApiMessage.Performative.GET_STATE - ), - response_kwargs=dict( - performative=LedgerApiMessage.Performative.STATE, - state=State(ledger_id="ethereum", body={"hash": "0xa"}), - ), - ) - - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(self.done_event) - - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert ( - behaviour.behaviour_id == self.next_behaviour_class.auto_behaviour_id() - ) - self.behaviour.context.randomness_api.__dict__["_frozen"] = True - - def test_max_retries_reached_fallback_fail( - self, - ) -> None: - """Test with max retries reached.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.context.randomness_api.__dict__["_frozen"] = False - with mock.patch.object( - self.behaviour.context.randomness_api, - "is_retries_exceeded", - return_value=True, - ): - self.behaviour.act_wrapper() - self.mock_ledger_api_request( - request_kwargs=dict( - performative=LedgerApiMessage.Performative.GET_STATE - ), - response_kwargs=dict( - performative=LedgerApiMessage.Performative.ERROR, - state=State(ledger_id="ethereum", body={}), - ), - ) - - self.behaviour.act_wrapper() - self.behaviour.context.randomness_api.__dict__["_frozen"] = True - - def test_max_retries_reached_fallback_fail_case_2( - self, - ) -> None: - """Test with max retries reached.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.context.randomness_api.__dict__["_frozen"] = False - with mock.patch.object( - self.behaviour.context.randomness_api, - "is_retries_exceeded", - return_value=True, - ): - self.behaviour.act_wrapper() - self.mock_ledger_api_request( - request_kwargs=dict( - performative=LedgerApiMessage.Performative.GET_STATE - ), - response_kwargs=dict( - performative=LedgerApiMessage.Performative.STATE, - state=State(ledger_id="ethereum", body={}), - ), - ) - - self.behaviour.act_wrapper() - self.behaviour.context.randomness_api.__dict__["_frozen"] = True - - def test_clean_up( - self, - ) -> None: - """Test when `observed` value is none.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.randomness_behaviour_class.auto_behaviour_id(), - BaseSynchronizedData(AbciAppDB(setup_data={})), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.randomness_behaviour_class.auto_behaviour_id() - ) - self.behaviour.context.randomness_api.retries_info.retries_attempted = ( # pylint: disable=protected-access - 1 - ) - assert self.behaviour.current_behaviour is not None - self.behaviour.current_behaviour.clean_up() - assert ( - self.behaviour.context.randomness_api.retries_info.retries_attempted # pylint: disable=protected-access - == 0 - ) - - -class BaseSelectKeeperBehaviourTest(CommonBaseCase): - """Test SelectKeeperBehaviour.""" - - select_keeper_behaviour_class: Type[BaseBehaviour] - next_behaviour_class: Type[BaseBehaviour] - done_event: Any - _synchronized_data: Type[BaseSynchronizedData] = BaseSynchronizedData - - @mock.patch.object(SkillContext, "agent_address", new_callable=mock.PropertyMock) - @pytest.mark.parametrize( - "blacklisted_keepers", - ( - set(), - {"a_1"}, - {"test_agent_address" + "t" * 24}, - {"a_1" + "t" * 39, "a_2" + "t" * 39, "test_agent_address" + "t" * 24}, - ), - ) - def test_select_keeper( - self, agent_address_mock: mock.Mock, blacklisted_keepers: Set[str] - ) -> None: - """Test select keeper agent.""" - agent_address_mock.return_value = "test_agent_address" + "t" * 24 - participants = ( - self.skill.skill_context.agent_address, - "a_1" + "t" * 39, - "a_2" + "t" * 39, - ) - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.select_keeper_behaviour_class.auto_behaviour_id(), - synchronized_data=self._synchronized_data( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - participants=participants, - most_voted_randomness="56cbde9e9bbcbdcaf92f183c678eaa5288581f06b1c9c7f884ce911776727688", - blacklisted_keepers="".join(blacklisted_keepers), - ) - ), - ) - ), - ) - assert self.behaviour.current_behaviour is not None - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.select_keeper_behaviour_class.auto_behaviour_id() - ) - - if ( - self.behaviour.current_behaviour.synchronized_data.participants - - self.behaviour.current_behaviour.synchronized_data.blacklisted_keepers - ): - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(self.done_event) - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.next_behaviour_class.auto_behaviour_id() - ) - else: - with pytest.raises( - AEAActException, - match="Cannot continue if all the keepers have been blacklisted!", - ): - self.behaviour.act_wrapper() - - def test_select_keeper_preexisting_keeper( - self, - ) -> None: - """Test select keeper agent.""" - participants = (self.skill.skill_context.agent_address, "a_1", "a_2") - preexisting_keeper = next(iter(participants)) - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.select_keeper_behaviour_class.auto_behaviour_id(), - synchronized_data=self._synchronized_data( - AbciAppDB( - setup_data=dict( - participants=[participants], - most_voted_randomness=[ - "56cbde9e9bbcbdcaf92f183c678eaa5288581f06b1c9c7f884ce911776727688" - ], - most_voted_keeper_address=[preexisting_keeper], - ), - ) - ), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.select_keeper_behaviour_class.auto_behaviour_id() - ) - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(self.done_event) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == self.next_behaviour_class.auto_behaviour_id() diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/integration.py b/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/integration.py deleted file mode 100644 index 913413985..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/integration.py +++ /dev/null @@ -1,301 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Integration tests for various transaction settlement skill's failure modes.""" - - -import asyncio -import os -import tempfile -import time -from abc import ABC -from pathlib import Path -from threading import Thread -from typing import Any, Callable, Dict, List, Optional, Tuple, cast - -from aea.crypto.wallet import Wallet -from aea.decision_maker.base import DecisionMaker -from aea.decision_maker.default import DecisionMakerHandler -from aea.identity.base import Identity -from aea.mail.base import Envelope -from aea.multiplexer import Multiplexer -from aea.protocols.base import Address, Message -from aea.skills.base import Handler -from web3 import HTTPProvider, Web3 -from web3.providers import BaseProvider - -from packages.valory.skills.abstract_round_abci.base import BaseSynchronizedData -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.handlers import SigningHandler -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) - - -# pylint: disable=protected-access,too-many-ancestors,unbalanced-tuple-unpacking,too-many-locals,consider-using-with,unspecified-encoding,too-many-arguments,unidiomatic-typecheck - -HandlersType = List[Optional[Handler]] -ExpectedContentType = List[ - Optional[ - Dict[ - str, - Any, - ] - ] -] -ExpectedTypesType = List[ - Optional[ - Dict[ - str, - Any, - ] - ] -] - - -class IntegrationBaseCase(FSMBehaviourBaseCase, ABC): - """Base test class for integration tests.""" - - running_loop: asyncio.AbstractEventLoop - thread_loop: Thread - multiplexer: Multiplexer - decision_maker: DecisionMaker - agents: Dict[str, Address] = { - "0xBcd4042DE499D14e55001CcbB24a551F3b954096": "0xf214f2b2cd398c806f84e317254e0f0b801d0643303237d97a22a48e01628897", - "0x71bE63f3384f5fb98995898A86B02Fb2426c5788": "0x701b615bbdfb9de65240bc28bd21bbc0d996645a3dd57e7b12bc2bdf6f192c82", - "0xFABB0ac9d68B0B445fB7357272Ff202C5651694a": "0xa267530f49f8280200edf313ee7af6b827f2a8bce2897751d06a843f644967b1", - "0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec": "0x47c99abed3324a2707c28affff1267e45918ec8c3f20b8aa892e8b065d2942dd", - } - current_agent: Address - ROOT_DIR: Path - make_ledger_api_connection_callable: Callable - - @classmethod - def _setup_class(cls, **kwargs: Any) -> None: - """Setup class.""" - - @classmethod - def setup_class(cls, **kwargs: Any) -> None: - """Setup.""" - super().setup_class() - - # set up a multiplexer with the required connections - cls.running_loop = asyncio.new_event_loop() - cls.thread_loop = Thread(target=cls.running_loop.run_forever) - cls.thread_loop.start() - cls.multiplexer = Multiplexer( - [cls.make_ledger_api_connection_callable()], loop=cls.running_loop - ) - cls.multiplexer.connect() - - # hardhat configuration - # setup decision maker - with tempfile.TemporaryDirectory() as temp_dir: - fp = os.path.join(temp_dir, "key.txt") - f = open(fp, "w") - f.write(cls.agents[next(iter(cls.agents))]) - f.close() - wallet = Wallet(private_key_paths={"ethereum": str(fp)}) - identity = Identity( - "test_agent_name", - addresses=wallet.addresses, - public_keys=wallet.public_keys, - default_address_key="ethereum", - ) - cls._skill._skill_context._agent_context._identity = identity - cls.current_agent = identity.address - - cls.decision_maker = DecisionMaker( - decision_maker_handler=DecisionMakerHandler(identity, wallet, {}) - ) - cls._skill._skill_context._agent_context._decision_maker_message_queue = ( - cls.decision_maker.message_in_queue - ) - cls._skill.skill_context._agent_context._decision_maker_address = ( - "decision_maker" - ) - - @classmethod - def teardown_class(cls) -> None: - """Tear down the multiplexer.""" - cls.multiplexer.disconnect() - cls.running_loop.call_soon_threadsafe(cls.running_loop.stop) - cls.thread_loop.join() - super().teardown_class() - - def get_message_from_decision_maker_inbox(self) -> Optional[Message]: - """Get message from decision maker inbox.""" - if self._skill.skill_context.decision_maker_message_queue.empty(): - return None - return self._skill.skill_context.decision_maker_message_queue.protected_get( - self.decision_maker._queue_access_code, block=True - ) - - def process_message_cycle( - self, - handler: Optional[Handler] = None, - expected_content: Optional[Dict] = None, - expected_types: Optional[Dict] = None, - mining_interval_secs: float = 0, - ) -> Optional[Message]: - """ - Processes one request-response type message cycle. - - Steps: - 1. Calls act on behaviour to generate outgoing message - 2. Checks for message in outbox - 3. Sends message to multiplexer and waits for response. - 4. Passes message to handler - 5. Calls act on behaviour to process incoming message - - :param handler: the handler to handle a potential incoming message - :param expected_content: the content to be expected - :param expected_types: the types to be expected - :param mining_interval_secs: the mining interval used in the tests - :return: the incoming message - """ - if expected_types and tuple(expected_types)[0] == "transaction_receipt": - time.sleep(mining_interval_secs) # pragma: no cover - self.behaviour.act_wrapper() - incoming_message = None - - if type(handler) == SigningHandler: - self.assert_quantity_in_decision_making_queue(1) - message = self.get_message_from_decision_maker_inbox() - assert message is not None, "No message in outbox." # nosec - self.decision_maker.handle(message) - if handler is not None: - incoming_message = self.decision_maker.message_out_queue.get(block=True) - assert isinstance(incoming_message, Message) # nosec - else: - self.assert_quantity_in_outbox(1) - message = self.get_message_from_outbox() - assert message is not None, "No message in outbox." # nosec - self.multiplexer.put( - Envelope( - to=message.to, - sender=message.sender, - message=message, - context=None, - ) - ) - if handler is not None: - envelope = self.multiplexer.get(block=True) - assert envelope is not None, "No envelope" # nosec - incoming_message = envelope.message - assert isinstance(incoming_message, Message) # nosec - - if handler is not None: - assert incoming_message is not None # nosec - if expected_content is not None: - assert all( # nosec - [ - incoming_message._body.get(key, None) == value - for key, value in expected_content.items() - ] - ), f"Actual content: {incoming_message._body}, expected: {expected_content}" - - if expected_types is not None: - assert all( # nosec - [ - type(incoming_message._body.get(key, None)) == value_type - for key, value_type in expected_types.items() - ] - ), "Content type mismatch" - handler.handle(incoming_message) - return incoming_message - return None - - def process_n_messages( - self, - ncycles: int, - synchronized_data: Optional[BaseSynchronizedData] = None, - behaviour_id: Optional[str] = None, - handlers: Optional[HandlersType] = None, - expected_content: Optional[ExpectedContentType] = None, - expected_types: Optional[ExpectedTypesType] = None, - fail_send_a2a: bool = False, - mining_interval_secs: float = 0, - ) -> Tuple[Optional[Message], ...]: - """ - Process n message cycles. - - :param behaviour_id: the behaviour to fast forward to - :param ncycles: the number of message cycles to process - :param synchronized_data: a synchronized_data - :param handlers: a list of handlers - :param expected_content: the expected_content - :param expected_types: the expected type - :param fail_send_a2a: flag that indicates whether we want to simulate a failure in the `send_a2a_transaction` - :param mining_interval_secs: the mining interval used in the tests. - - :return: tuple of incoming messages - """ - handlers = [None] * ncycles if handlers is None else handlers - expected_content = ( - [None] * ncycles if expected_content is None else expected_content - ) - expected_types = [None] * ncycles if expected_types is None else expected_types - assert ( # nosec - len(expected_content) == len(expected_types) - and len(expected_content) == len(handlers) - and len(expected_content) == ncycles - ), "Number of cycles, handlers, contents and types does not match" - - if behaviour_id is not None and synchronized_data is not None: - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=behaviour_id, - synchronized_data=synchronized_data, - ) - assert ( # nosec - cast(BaseBehaviour, self.behaviour.current_behaviour).behaviour_id - == behaviour_id - ) - - incoming_messages = [] - for i in range(ncycles): - incoming_message = self.process_message_cycle( - handlers[i], - expected_content[i], - expected_types[i], - mining_interval_secs, - ) - incoming_messages.append(incoming_message) - - self.behaviour.act_wrapper() - if not fail_send_a2a: - self.mock_a2a_transaction() - return tuple(incoming_messages) - - -class HardHatHelperIntegration(IntegrationBaseCase, ABC): # pragma: no cover - """Base test class for integration tests with HardHat provider.""" - - hardhat_provider: BaseProvider - - @classmethod - def setup_class(cls, **kwargs: Any) -> None: - """Setup.""" - super().setup_class() - - # create an API for HardHat - cls.hardhat_provider = Web3( - provider=HTTPProvider("http://localhost:8545") - ).provider diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/rounds.py b/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/rounds.py deleted file mode 100644 index 77f50c83d..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/test_tools/rounds.py +++ /dev/null @@ -1,599 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Test tools for testing rounds.""" - -import re -from copy import deepcopy -from dataclasses import dataclass -from enum import Enum -from typing import ( - Any, - Callable, - FrozenSet, - Generator, - List, - Mapping, - Optional, - Tuple, - Type, -) -from unittest import mock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciAppDB, - AbstractRound, - BaseSynchronizedData, - BaseTxPayload, - CollectDifferentUntilAllRound, - CollectDifferentUntilThresholdRound, - CollectNonEmptyUntilThresholdRound, - CollectSameUntilAllRound, - CollectSameUntilThresholdRound, - CollectionRound, - OnlyKeeperSendsRound, - TransactionNotValidError, - VotingRound, -) - - -MAX_PARTICIPANTS: int = 4 - - -def get_participants() -> FrozenSet[str]: - """Participants""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -class DummyEvent(Enum): - """Dummy Event""" - - DONE = "done" - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - RESET_TIMEOUT = "reset_timeout" - NEGATIVE = "negative" - NONE = "none" - FAIL = "fail" - - -@dataclass(frozen=True) -class DummyTxPayload(BaseTxPayload): - """Dummy Transaction Payload.""" - - value: Optional[str] = None - vote: Optional[bool] = None - - -class DummySynchronizedData(BaseSynchronizedData): - """Dummy synchronized data for tests.""" - - -def get_dummy_tx_payloads( - participants: FrozenSet[str], - value: Any = None, - vote: Optional[bool] = False, - is_value_none: bool = False, - is_vote_none: bool = False, -) -> List[DummyTxPayload]: - """Returns a list of DummyTxPayload objects.""" - return [ - DummyTxPayload( - sender=agent, - value=(value or agent) if not is_value_none else value, - vote=vote if not is_vote_none else None, - ) - for agent in sorted(participants) - ] - - -class DummyRound(AbstractRound): - """Dummy round.""" - - payload_class = DummyTxPayload - payload_attribute = "value" - synchronized_data_class = BaseSynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """end_block method.""" - - -class DummyCollectionRound(CollectionRound, DummyRound): - """Dummy Class for CollectionRound""" - - -class DummyCollectDifferentUntilAllRound(CollectDifferentUntilAllRound, DummyRound): - """Dummy Class for CollectDifferentUntilAllRound""" - - -class DummyCollectSameUntilAllRound(CollectSameUntilAllRound, DummyRound): - """Dummy Class for CollectSameUntilThresholdRound""" - - -class DummyCollectDifferentUntilThresholdRound( - CollectDifferentUntilThresholdRound, DummyRound -): - """Dummy Class for CollectDifferentUntilThresholdRound""" - - -class DummyCollectSameUntilThresholdRound(CollectSameUntilThresholdRound, DummyRound): - """Dummy Class for CollectSameUntilThresholdRound""" - - -class DummyOnlyKeeperSendsRound(OnlyKeeperSendsRound, DummyRound): - """Dummy Class for OnlyKeeperSendsRound""" - - fail_event = "FAIL_EVENT" - - -class DummyVotingRound(VotingRound, DummyRound): - """Dummy Class for VotingRound""" - - -class DummyCollectNonEmptyUntilThresholdRound( - CollectNonEmptyUntilThresholdRound, DummyRound -): - """Dummy Class for `CollectNonEmptyUntilThresholdRound`""" - - -class BaseRoundTestClass: # pylint: disable=too-few-public-methods - """Base test class.""" - - synchronized_data: BaseSynchronizedData - participants: FrozenSet[str] - - _synchronized_data_class: Type[BaseSynchronizedData] - _event_class: Any - - def setup( - self, - ) -> None: - """Setup test class.""" - - self.participants = get_participants() - self.synchronized_data = self._synchronized_data_class( - db=AbciAppDB( - setup_data=dict( - participants=[tuple(self.participants)], - all_participants=[tuple(self.participants)], - consensus_threshold=[3], - safe_contract_address=["test_address"], - ), - ) - ) - - def _test_no_majority_event(self, round_obj: AbstractRound) -> None: - """Test the NO_MAJORITY event.""" - with mock.patch.object(round_obj, "is_majority_possible", return_value=False): - result = round_obj.end_block() - assert result is not None - _, event = result - assert event == self._event_class.NO_MAJORITY - - @staticmethod - def _complete_run( - test_runner: Generator, iter_count: int = MAX_PARTICIPANTS - ) -> None: - """ - This method represents logic to execute test logic defined in _test_round method. - - _test_round should follow these steps - - 1. process first payload - 2. yield test_round - 3. test collection, end_block and thresholds - 4. process rest of the payloads - 5. yield test_round - 6. yield synchronized_data, event ( returned from end_block ) - 7. test synchronized_data and event - - :param test_runner: test runner - :param iter_count: iter_count - """ - - for _ in range(iter_count): - next(test_runner) - - -class BaseCollectDifferentUntilAllRoundTest( # pylint: disable=too-few-public-methods - BaseRoundTestClass -): - """Tests for rounds derived from CollectDifferentUntilAllRound.""" - - def _test_round( - self, - test_round: CollectDifferentUntilAllRound, - round_payloads: List[BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - ) -> Generator: - """Test round.""" - - first_payload = round_payloads.pop(0) - test_round.process_payload(first_payload) - - yield test_round - assert test_round.collection[first_payload.sender] == first_payload - assert not test_round.collection_threshold_reached - assert test_round.end_block() is None - - for payload in round_payloads: - test_round.process_payload(payload) - yield test_round - assert test_round.collection_threshold_reached - - actual_next_synchronized_data = synchronized_data_update_fn( - deepcopy(self.synchronized_data), test_round - ) - - res = test_round.end_block() - yield res - if exit_event is None: - assert res is exit_event - else: - assert res is not None - synchronized_data, event = res - for behaviour_attr_getter in synchronized_data_attr_checks: - assert behaviour_attr_getter( - synchronized_data - ) == behaviour_attr_getter(actual_next_synchronized_data) - assert event == exit_event - yield - - -class BaseCollectSameUntilAllRoundTest( - BaseRoundTestClass -): # pylint: disable=too-few-public-methods - """Tests for rounds derived from CollectSameUntilAllRound.""" - - def _test_round( # pylint: disable=too-many-arguments,too-many-locals - self, - test_round: CollectSameUntilAllRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - most_voted_payload: Any, - exit_event: Any, - finished: bool, - ) -> Generator: - """Test rounds derived from CollectionRound.""" - - (_, first_payload), *payloads = round_payloads.items() - - test_round.process_payload(first_payload) - yield test_round - assert test_round.collection[first_payload.sender] == first_payload - assert not test_round.collection_threshold_reached - assert test_round.end_block() is None - - with pytest.raises( - ABCIAppInternalError, - match="internal error: 1 votes are not enough for `CollectSameUntilAllRound`. " - f"Expected: `n_votes = max_participants = {MAX_PARTICIPANTS}`", - ): - _ = test_round.common_payload - - for _, payload in payloads: - test_round.process_payload(payload) - yield test_round - if finished: - assert test_round.collection_threshold_reached - assert test_round.common_payload == most_voted_payload - - actual_next_synchronized_data = synchronized_data_update_fn( - deepcopy(self.synchronized_data), test_round - ) - res = test_round.end_block() - yield res - assert res is not None - - synchronized_data, event = res - - for behaviour_attr_getter in synchronized_data_attr_checks: - assert behaviour_attr_getter(synchronized_data) == behaviour_attr_getter( - actual_next_synchronized_data - ), f"Mismatch in synchronized_data. Actual:\n{behaviour_attr_getter(synchronized_data)}\nExpected:\n{behaviour_attr_getter(actual_next_synchronized_data)}" - assert event == exit_event - yield - - -class BaseCollectSameUntilThresholdRoundTest( # pylint: disable=too-few-public-methods - BaseRoundTestClass -): - """Tests for rounds derived from CollectSameUntilThresholdRound.""" - - def _test_round( # pylint: disable=too-many-arguments,too-many-locals - self, - test_round: CollectSameUntilThresholdRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - most_voted_payload: Any, - exit_event: Any, - ) -> Generator: - """Test rounds derived from CollectionRound.""" - - (_, first_payload), *payloads = round_payloads.items() - - test_round.process_payload(first_payload) - yield test_round - assert test_round.collection[first_payload.sender] == first_payload - assert not test_round.threshold_reached - assert test_round.end_block() is None - - self._test_no_majority_event(test_round) - with pytest.raises(ABCIAppInternalError, match="not enough votes"): - _ = test_round.most_voted_payload - - for _, payload in payloads: - test_round.process_payload(payload) - yield test_round - assert test_round.threshold_reached - assert test_round.most_voted_payload == most_voted_payload - - actual_next_synchronized_data = synchronized_data_update_fn( - deepcopy(self.synchronized_data), test_round - ) - res = test_round.end_block() - yield res - assert res is not None - - synchronized_data, event = res - - for behaviour_attr_getter in synchronized_data_attr_checks: - assert behaviour_attr_getter(synchronized_data) == behaviour_attr_getter( - actual_next_synchronized_data - ), f"Mismatch in synchronized_data. Actual:\n{behaviour_attr_getter(synchronized_data)}\nExpected:\n{behaviour_attr_getter(actual_next_synchronized_data)}" - assert event == exit_event - yield - - -class BaseOnlyKeeperSendsRoundTest( # pylint: disable=too-few-public-methods - BaseRoundTestClass -): - """Tests for rounds derived from OnlyKeeperSendsRound.""" - - def _test_round( - self, - test_round: OnlyKeeperSendsRound, - keeper_payloads: BaseTxPayload, - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - ) -> Generator: - """Test for rounds derived from OnlyKeeperSendsRound.""" - - assert test_round.end_block() is None - assert test_round.keeper_payload is None - - test_round.process_payload(keeper_payloads) - yield test_round - assert test_round.keeper_payload is not None - - yield test_round - actual_next_synchronized_data = synchronized_data_update_fn( - deepcopy(self.synchronized_data), test_round - ) - res = test_round.end_block() - yield res - assert res is not None - - synchronized_data, event = res - - for behaviour_attr_getter in synchronized_data_attr_checks: - assert behaviour_attr_getter(synchronized_data) == behaviour_attr_getter( - actual_next_synchronized_data - ), f"Mismatch in synchronized_data. Actual:\n{behaviour_attr_getter(synchronized_data)}\nExpected:\n{behaviour_attr_getter(actual_next_synchronized_data)}" - assert event == exit_event - yield - - -class BaseVotingRoundTest(BaseRoundTestClass): # pylint: disable=too-few-public-methods - """Tests for rounds derived from VotingRound.""" - - def _test_round( # pylint: disable=too-many-arguments,too-many-locals - self, - test_round: VotingRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - threshold_check: Callable, - ) -> Generator: - """Test for rounds derived from VotingRound.""" - - (_, first_payload), *payloads = round_payloads.items() - - test_round.process_payload(first_payload) - yield test_round - assert not threshold_check(test_round) # negative_vote_threshold_reached - assert test_round.end_block() is None - self._test_no_majority_event(test_round) - - for _, payload in payloads: - test_round.process_payload(payload) - yield test_round - assert threshold_check(test_round) - - actual_next_synchronized_data = synchronized_data_update_fn( - deepcopy(self.synchronized_data), test_round - ) - res = test_round.end_block() - yield res - assert res is not None - - synchronized_data, event = res - - for behaviour_attr_getter in synchronized_data_attr_checks: - assert behaviour_attr_getter(synchronized_data) == behaviour_attr_getter( - actual_next_synchronized_data - ), f"Mismatch in synchronized_data. Actual:\n{behaviour_attr_getter(synchronized_data)}\nExpected:\n{behaviour_attr_getter(actual_next_synchronized_data)}" - assert event == exit_event - yield - - def _test_voting_round_positive( - self, - test_round: VotingRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - ) -> Generator: - """Test for rounds derived from VotingRound.""" - - return self._test_round( - test_round, - round_payloads, - synchronized_data_update_fn, - synchronized_data_attr_checks, - exit_event, - threshold_check=lambda x: x.positive_vote_threshold_reached, - ) - - def _test_voting_round_negative( - self, - test_round: VotingRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - ) -> Generator: - """Test for rounds derived from VotingRound.""" - - return self._test_round( - test_round, - round_payloads, - synchronized_data_update_fn, - synchronized_data_attr_checks, - exit_event, - threshold_check=lambda x: x.negative_vote_threshold_reached, - ) - - def _test_voting_round_none( - self, - test_round: VotingRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - ) -> Generator: - """Test for rounds derived from VotingRound.""" - - return self._test_round( - test_round, - round_payloads, - synchronized_data_update_fn, - synchronized_data_attr_checks, - exit_event, - threshold_check=lambda x: x.none_vote_threshold_reached, - ) - - -class BaseCollectDifferentUntilThresholdRoundTest( # pylint: disable=too-few-public-methods - BaseRoundTestClass -): - """Tests for rounds derived from CollectDifferentUntilThresholdRound.""" - - def _test_round( - self, - test_round: CollectDifferentUntilThresholdRound, - round_payloads: Mapping[str, BaseTxPayload], - synchronized_data_update_fn: Callable, - synchronized_data_attr_checks: List[Callable], - exit_event: Any, - ) -> Generator: - """Test for rounds derived from CollectDifferentUntilThresholdRound.""" - - (_, first_payload), *payloads = round_payloads.items() - - test_round.process_payload(first_payload) - yield test_round - assert not test_round.collection_threshold_reached - assert test_round.end_block() is None - - for _, payload in payloads: - test_round.process_payload(payload) - yield test_round - assert test_round.collection_threshold_reached - - actual_next_synchronized_data = synchronized_data_update_fn( - deepcopy(self.synchronized_data), test_round - ) - - res = test_round.end_block() - yield res - assert res is not None - - synchronized_data, event = res - - for behaviour_attr_getter in synchronized_data_attr_checks: - assert behaviour_attr_getter(synchronized_data) == behaviour_attr_getter( - actual_next_synchronized_data - ), f"Mismatch in synchronized_data. Actual:\n{behaviour_attr_getter(synchronized_data)}\nExpected:\n{behaviour_attr_getter(actual_next_synchronized_data)}" - assert event == exit_event - yield - - -class BaseCollectNonEmptyUntilThresholdRound( # pylint: disable=too-few-public-methods - BaseCollectDifferentUntilThresholdRoundTest -): - """Tests for rounds derived from `CollectNonEmptyUntilThresholdRound`.""" - - -class _BaseRoundTestClass(BaseRoundTestClass): # pylint: disable=too-few-public-methods - """Base test class.""" - - synchronized_data: BaseSynchronizedData - participants: FrozenSet[str] - tx_payloads: List[DummyTxPayload] - - _synchronized_data_class = DummySynchronizedData - - def setup( - self, - ) -> None: - """Setup test class.""" - - super().setup() - self.tx_payloads = get_dummy_tx_payloads(self.participants) - - @staticmethod - def _test_payload_with_wrong_round_count( - test_round: AbstractRound, - value: Optional[str] = None, - vote: Optional[bool] = None, - ) -> None: - """Test errors raised by payloads with wrong round count.""" - payload_with_wrong_round_count = DummyTxPayload("sender", value, vote) - object.__setattr__(payload_with_wrong_round_count, "round_count", 0) - with pytest.raises( - TransactionNotValidError, - match=re.escape("Expected round count -1 and got 0."), - ): - test_round.check_payload(payload=payload_with_wrong_round_count) - - with pytest.raises( - ABCIAppInternalError, - match=re.escape("Expected round count -1 and got 0."), - ): - test_round.process_payload(payload=payload_with_wrong_round_count) diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/__init__.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/__init__.py deleted file mode 100644 index 7561108a8..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/abstract_round_abci skill.""" - -from hypothesis import settings # pragma: nocover - - -CI = "CI" # pragma: nocover - -settings.register_profile(CI, deadline=5000) # pragma: nocover diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/conftest.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/conftest.py deleted file mode 100644 index 5dde4f1b0..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/conftest.py +++ /dev/null @@ -1,116 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Conftest module for io tests.""" - -import os -import shutil -from contextlib import suppress -from pathlib import Path -from typing import Dict, Generator - -import pytest -from hypothesis import settings - -from packages.valory.skills.abstract_round_abci.io_.store import StoredJSONType -from packages.valory.skills.abstract_round_abci.models import MIN_RESET_PAUSE_DURATION - - -# pylint: skip-file - - -CI = "CI" -PACKAGE_DIR = Path(__file__).parent.parent -settings.register_profile(CI, deadline=5000) -profile_name = ("default", "CI")[bool(os.getenv("CI"))] - - -@pytest.fixture -def dummy_obj() -> StoredJSONType: - """A dummy custom object to test the storing with.""" - return {"test_col": ["test_val_1", "test_val_2"]} - - -@pytest.fixture -def dummy_multiple_obj(dummy_obj: StoredJSONType) -> Dict[str, StoredJSONType]: - """Many dummy custom objects to test the storing with.""" - return {f"test_obj_{i}": dummy_obj for i in range(10)} - - -@pytest.fixture(scope="session", autouse=True) -def hypothesis_cleanup() -> Generator: - """Fixture to remove hypothesis directory after tests.""" - yield - hypothesis_dir = PACKAGE_DIR / ".hypothesis" - if hypothesis_dir.exists(): - with suppress(OSError, PermissionError): # pragma: nocover - shutil.rmtree(hypothesis_dir) - - -# We do not care about these keys but need to set them in the behaviours' tests, -# because `packages.valory.skills.abstract_round_abci.models._ensure` is used. -irrelevant_genesis_config = { - "consensus_params": { - "block": {"max_bytes": "str", "max_gas": "str", "time_iota_ms": "str"}, - "evidence": { - "max_age_num_blocks": "str", - "max_age_duration": "str", - "max_bytes": "str", - }, - "validator": {"pub_key_types": ["str"]}, - "version": {}, - }, - "genesis_time": "str", - "chain_id": "str", - "voting_power": "str", -} -irrelevant_config = { - "tendermint_url": "str", - "max_healthcheck": 0, - "round_timeout_seconds": 0.0, - "sleep_time": 0, - "retry_timeout": 0, - "retry_attempts": 0, - "keeper_timeout": 0.0, - "reset_pause_duration": MIN_RESET_PAUSE_DURATION, - "drand_public_key": "str", - "tendermint_com_url": "str", - "tendermint_max_retries": 0, - "reset_tendermint_after": 0, - "cleanup_history_depth": 0, - "voting_power": 0, - "tendermint_check_sleep_delay": 0, - "cleanup_history_depth_current": None, - "request_timeout": 0.0, - "request_retry_delay": 0.0, - "tx_timeout": 0.0, - "max_attempts": 0, - "service_registry_address": None, - "on_chain_service_id": None, - "share_tm_config_on_startup": False, - "tendermint_p2p_url": "str", - "setup": {}, - "genesis_config": irrelevant_genesis_config, - "use_termination": False, - "use_slashing": False, - "slash_cooldown_hours": 3, - "slash_threshold_amount": 10_000_000_000_000_000, - "light_slash_unit_amount": 5_000_000_000_000_000, - "serious_slash_unit_amount": 8_000_000_000_000_000, -} diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/__init__.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/__init__.py deleted file mode 100644 index 7266f7868..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for abstract_round_abci/test_tools""" diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/__init__.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/__init__.py deleted file mode 100644 index c378e8c43..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/__init__.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 the implementation of the default skill.""" - -from pathlib import Path - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("dummy/dummy_abci:0.1.0") -PATH_TO_SKILL = Path(__file__).parent diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/behaviours.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/behaviours.py deleted file mode 100644 index ee99805c6..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/behaviours.py +++ /dev/null @@ -1,158 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 package contains round behaviours of DummyAbciApp.""" - -from abc import ABC -from collections import deque -from typing import Deque, Generator, Set, Type, cast - -from packages.valory.skills.abstract_round_abci.base import AbstractRound -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.abstract_round_abci.common import ( - RandomnessBehaviour, - SelectKeeperBehaviour, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.models import ( - Params, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.payloads import ( - DummyFinalPayload, - DummyKeeperSelectionPayload, - DummyRandomnessPayload, - DummyStartingPayload, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.rounds import ( - DummyAbciApp, - DummyFinalRound, - DummyKeeperSelectionRound, - DummyRandomnessRound, - DummyStartingRound, - SynchronizedData, -) - - -class DummyBaseBehaviour(BaseBehaviour, ABC): - """Base behaviour for the common apps' skill.""" - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return cast(SynchronizedData, super().synchronized_data) - - @property - def params(self) -> Params: - """Return the params.""" - return cast(Params, super().params) - - -class DummyStartingBehaviour(DummyBaseBehaviour): - """DummyStartingBehaviour""" - - behaviour_id: str = "dummy_starting" - matching_round: Type[AbstractRound] = DummyStartingRound - - def async_act(self) -> Generator: - """Do the act, supporting asynchronous execution.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - content = "dummy" - sender = self.context.agent_address - payload = DummyStartingPayload(sender=sender, content=content) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class DummyRandomnessBehaviour(RandomnessBehaviour): - """DummyRandomnessBehaviour""" - - behaviour_id: str = "dummy_randomness" - matching_round: Type[AbstractRound] = DummyRandomnessRound - payload_class = DummyRandomnessPayload - - -class DummyKeeperSelectionBehaviour(SelectKeeperBehaviour): - """DummyKeeperSelectionBehaviour""" - - behaviour_id: str = "dummy_keeper_selection" - matching_round: Type[AbstractRound] = DummyKeeperSelectionRound - payload_class = DummyKeeperSelectionPayload - - @staticmethod - def serialized_keepers(keepers: Deque[str], keeper_retries: int = 1) -> str: - """Get the keepers serialized.""" - if not keepers: - return "" - return keeper_retries.to_bytes(32, "big").hex() + "".join(keepers) - - def async_act(self) -> Generator: - """Do the act, supporting asynchronous execution.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - keepers = deque((self._select_keeper(),)) - payload = self.payload_class( - self.context.agent_address, self.serialized_keepers(keepers) - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class DummyFinalBehaviour(DummyBaseBehaviour): - """DummyFinalBehaviour""" - - behaviour_id: str = "dummy_final" - matching_round: Type[AbstractRound] = DummyFinalRound - - def async_act(self) -> Generator: - """Do the act, supporting asynchronous execution.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - content = True - sender = self.context.agent_address - payload = DummyFinalPayload(sender=sender, content=content) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class DummyRoundBehaviour(AbstractRoundBehaviour): - """DummyRoundBehaviour""" - - initial_behaviour_cls = DummyStartingBehaviour - abci_app_cls = DummyAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - DummyFinalBehaviour, # type: ignore - DummyKeeperSelectionBehaviour, # type: ignore - DummyRandomnessBehaviour, # type: ignore - DummyStartingBehaviour, # type: ignore - } diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/dialogues.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/dialogues.py deleted file mode 100644 index 24aa94dd7..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/dialogues.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 the dialogues of the DummyAbciApp.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/handlers.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/handlers.py deleted file mode 100644 index fc0edb2df..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/handlers.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 the handlers for the skill of DummyAbciApp.""" - -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIRoundHandler = BaseABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/models.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/models.py deleted file mode 100644 index 5fba375a7..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/models.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 the shared state for the abci skill of DummyAbciApp.""" - -from packages.valory.skills.abstract_round_abci.models import ApiSpecs, BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.rounds import ( - DummyAbciApp, -) - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = DummyAbciApp - - -Params = BaseParams -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool -RandomnessApi = ApiSpecs diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/payloads.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/payloads.py deleted file mode 100644 index bc4308ba6..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/payloads.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 the transaction payloads of the DummyAbciApp.""" - -from dataclasses import dataclass - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class DummyStartingPayload(BaseTxPayload): - """Represent a transaction payload for the DummyStartingRound.""" - - content: str - - -@dataclass(frozen=True) -class DummyRandomnessPayload(BaseTxPayload): - """Represent a transaction payload for the DummyRandomnessRound.""" - - round_id: int - randomness: str - - -@dataclass(frozen=True) -class DummyKeeperSelectionPayload(BaseTxPayload): - """Represent a transaction payload for the DummyKeeperSelectionRound.""" - - keepers: str - - -@dataclass(frozen=True) -class DummyFinalPayload(BaseTxPayload): - """Represent a transaction payload for the DummyFinalRound.""" - - content: bool diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/rounds.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/rounds.py deleted file mode 100644 index b3ee3bc17..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/rounds.py +++ /dev/null @@ -1,152 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 package contains the rounds of DummyAbciApp.""" - -from abc import ABC -from enum import Enum -from typing import FrozenSet, Optional, Set, Tuple, cast - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AbstractRound, - AppState, - BaseSynchronizedData, - CollectSameUntilAllRound, - CollectSameUntilThresholdRound, - EventToTimeout, - OnlyKeeperSendsRound, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.payloads import ( - DummyFinalPayload, - DummyKeeperSelectionPayload, - DummyRandomnessPayload, - DummyStartingPayload, -) - - -class Event(Enum): - """DummyAbciApp Events""" - - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - DONE = "done" - - -class SynchronizedData(BaseSynchronizedData): - """ - Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - -class DummyMixinRound(AbstractRound, ABC): - """DummyMixinRound""" - - done_event = Event.DONE - no_majority_event = Event.NO_MAJORITY - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return cast(SynchronizedData, self._synchronized_data) - - -class DummyStartingRound(CollectSameUntilAllRound, DummyMixinRound): - """DummyStartingRound""" - - round_id: str = "dummy_starting" - payload_class = DummyStartingPayload - payload_attribute: str = "dummy_starting" - synchronized_data_class = SynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - - if self.collection_threshold_reached: - synchronized_data = self.synchronized_data.update( - participants=tuple(sorted(self.collection)), - synchronized_data_class=SynchronizedData, - ) - return synchronized_data, Event.DONE - return None - - -class DummyRandomnessRound(CollectSameUntilThresholdRound, DummyMixinRound): - """DummyRandomnessRound""" - - round_id: str = "dummy_randomness" - payload_class = DummyRandomnessPayload - payload_attribute: str = "dummy_randomness" - collection_key = "participant_to_randomness" - selection_key = "most_voted_randomness" - synchronized_data_class = SynchronizedData - - -class DummyKeeperSelectionRound(CollectSameUntilThresholdRound, DummyMixinRound): - """DummyKeeperSelectionRound""" - - round_id: str = "dummy_keeper_selection" - payload_class = DummyKeeperSelectionPayload - payload_attribute: str = "dummy_keeper_selection" - collection_key = "participant_to_keeper" - selection_key = "most_voted_keeper" - synchronized_data_class = SynchronizedData - - -class DummyFinalRound(OnlyKeeperSendsRound, DummyMixinRound): - """DummyFinalRound""" - - round_id: str = "dummy_final" - payload_class = DummyFinalPayload - payload_attribute: str = "dummy_final" - synchronized_data_class = SynchronizedData - - -class DummyAbciApp(AbciApp[Event]): - """DummyAbciApp""" - - initial_round_cls: AppState = DummyStartingRound - transition_function: AbciAppTransitionFunction = { - DummyStartingRound: { - Event.DONE: DummyRandomnessRound, - Event.ROUND_TIMEOUT: DummyStartingRound, - Event.NO_MAJORITY: DummyStartingRound, - }, - DummyRandomnessRound: { - Event.DONE: DummyKeeperSelectionRound, - Event.ROUND_TIMEOUT: DummyRandomnessRound, - Event.NO_MAJORITY: DummyRandomnessRound, - }, - DummyKeeperSelectionRound: { - Event.DONE: DummyFinalRound, - Event.ROUND_TIMEOUT: DummyKeeperSelectionRound, - Event.NO_MAJORITY: DummyKeeperSelectionRound, - }, - DummyFinalRound: { - Event.DONE: DummyStartingRound, - Event.ROUND_TIMEOUT: DummyFinalRound, - Event.NO_MAJORITY: DummyFinalRound, - }, - } - final_states: Set[AppState] = set() - event_to_timeout: EventToTimeout = {} - cross_period_persisted_keys: FrozenSet[str] = frozenset() diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/skill.yaml b/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/skill.yaml deleted file mode 100644 index 4ac35e9e0..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/data/dummy_abci/skill.yaml +++ /dev/null @@ -1,148 +0,0 @@ -name: dummy_abci -author: dummy -version: 0.1.0 -type: skill -description: The scaffold skill is a scaffold for your own skill implementation. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeielxta5wbywv6cb2p65phk73zeodroif7imk33qc7sxgxrcelr62y - behaviours.py: bafybeicwwlex4z5ro6hrw5cdwxyp5742klcqsjwcn423wgg3jk6xclzwvi - dialogues.py: bafybeiaswubmqa7trhajbjn34okmpftk2sehsqrjg7znzrrd7j32xzx4vq - handlers.py: bafybeifik3ftljs63u7nm4gadxpqbcvqj53p7qftzzzfto3ioad57k3x3u - models.py: bafybeif4lp5i6an4z4kkquh3x3ttsvfctvsu5excmxahjywbbbo7g3js5y - payloads.py: bafybeidllmzsctg3m5jhawbt3kzk6ieodtvgwklrquqehtqtzzwhkxxg4a - rounds.py: bafybeiab5q6pzh544uuc672hksh4rv6a74dunt4ztdnqo4gw3hnzd452ti - tests/__init__.py: bafybeiaxqzwmh36bhquqztcyrkxjjkz5cctseqetglrwdezgnkjrtg2654 - tests/test_behaviours.py: bafybeich3uo67gdbxrxsivlrxfgpfuixupl6qtotxxp2qqpyqnck4i67eu - tests/test_dialogues.py: bafybeice2v4xnsjhhlnpbejnvpory5spmrewwcfsefzqzq3uhfyya5hypm - tests/test_handlers.py: bafybeidrfumnc743qh5s2ahf5rxu3rzrroygxwpbqa7jtqxg5kirjzedjm - tests/test_models.py: bafybeifuxjmpv3eet2zn7vc5btprakueqlk2ybc2fxgzbtiho5wdslkeb4 - tests/test_payloads.py: bafybeicvbisfw5prv6jw3is3vw6gehsplt3teyeo6dbeh37xazh4izeyhq - tests/test_rounds.py: bafybeihjepr2hubbgmb7jkeldbam3zmsgwn6nffif7zp4etqlv2bt5rsxy -fingerprint_ignore_patterns: [] -connections: [] -contracts: [] -protocols: [] -skills: -- valory/abstract_round_abci:0.1.0:bafybeifjnk2v3cw233ke5qhakurvdsex64c5runjctclrh7y64tyh7uqrq -behaviours: - main: - args: {} - class_name: DummyRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIRoundHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_duration: '172800000000000' - max_age_num_blocks: '100000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - genesis_time: '2022-05-20T16:00:21.735122717Z' - voting_power: '10' - keeper_timeout: 30.0 - max_healthcheck: 120 - reset_pause_duration: 10 - on_chain_service_id: null - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 30.0 - service_id: dummy - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - sleep_time: 1 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_url: http://localhost:26657 - request_timeout: 10.0 - request_retry_delay: 1.0 - tx_timeout: 10.0 - max_attempts: 10 - share_tm_config_on_startup: false - tendermint_p2p_url: localhost:26656 - use_termination: false - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10_000_000_000_000_000 - light_slash_unit_amount: 5_000_000_000_000_000 - serious_slash_unit_amount: 8_000_000_000_000_000 - class_name: Params - randomness_api: - args: - api_id: cloudflare - headers: {} - method: GET - parameters: {} - response_key: null - response_type: dict - retries: 5 - url: https://drand.cloudflare.com/public/latest - class_name: RandomnessApi - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: {} -is_abstract: false diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_abci_app_chain.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_abci_app_chain.py deleted file mode 100644 index 4a95580cf..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_abci_app_chain.py +++ /dev/null @@ -1,508 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the abci_app_chain.py module of the skill.""" - -# pylint: skip-file - -import logging -from typing import Dict, Set, Tuple, Type -from unittest.mock import MagicMock - -import pytest -from _pytest.logging import LogCaptureFixture -from aea.exceptions import AEAEnforceError - -from packages.valory.skills.abstract_round_abci.abci_app_chain import ( - AbciAppTransitionMapping, - chain, -) -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppDB, - AbstractRound, - AppState, - BaseSynchronizedData, - BaseTxPayload, - DegenerateRound, -) - - -def make_round_class(name: str, bases: Tuple = (AbstractRound,)) -> Type[AbstractRound]: - """Make a round class.""" - new_round_cls = type( - name, - bases, - { - "synchronized_data_class": MagicMock(), - "payload_class": MagicMock(), - "payload_attribute": MagicMock(), - }, - ) - setattr(new_round_cls, "round_id", name) # noqa: B010 - assert issubclass(new_round_cls, AbstractRound) # nosec - return new_round_cls - - -class TestAbciAppChaining: - """Test chaning of AbciApps.""" - - def setup(self) -> None: - """Setup test.""" - self.round_1a = make_round_class("round_1a") - self.round_1b = make_round_class("round_1b") - self.round_1b_dupe = make_round_class("round_1b") # duplicated round id - self.round_1c = make_round_class("round_1c", (DegenerateRound,)) - - self.round_2a = make_round_class("round_2a") - self.round_2b = make_round_class("round_2b") - self.round_2c = make_round_class("round_2c", (DegenerateRound,)) - self.round_2d = make_round_class("round_2d") - - self.round_3a = make_round_class("round_3a") - self.round_3b = make_round_class("round_3b") - self.round_3c = make_round_class("round_3c", (DegenerateRound,)) - - self.key_1 = "1" - self.key_2 = "2" - self.key_3 = "3" - - self.event_1a = "event_1a" - self.event_1b = "event_1b" - self.event_1c = "event_1c" - self.event_timeout1 = "timeout_1" - - self.event_2a = "event_2a" - self.event_2b = "event_2b" - self.event_2c = "event_2c" - self.event_timeout2 = "timeout_2" - - self.event_3a = "event_3a" - self.event_3b = "event_3b" - self.event_3c = "event_3c" - self.event_timeout3 = "timeout_3" - - self.timeout1 = 10.0 - self.timeout2 = 15.0 - self.timeout3 = 20.0 - - self.cross_period_persisted_keys_1 = frozenset({"1", "2"}) - self.cross_period_persisted_keys_2 = frozenset({"2", "3"}) - - class AbciApp1(AbciApp): - initial_round_cls = self.round_1a - transition_function = { - self.round_1a: { - self.event_timeout1: self.round_1a, - self.event_1b: self.round_1b, - }, - self.round_1b: { - self.event_1a: self.round_1a, - self.event_1c: self.round_1c, - }, - self.round_1c: {}, - } - final_states = {self.round_1c} - event_to_timeout = {self.event_timeout1: self.timeout1} - db_pre_conditions: Dict[AppState, Set[str]] = {self.round_1a: set()} - db_post_conditions: Dict[AppState, Set[str]] = {self.round_1c: {self.key_1}} - cross_period_persisted_keys = self.cross_period_persisted_keys_1 - - self.app1_class = AbciApp1 - - class AbciApp2(AbciApp): - initial_round_cls = self.round_2a - transition_function = { - self.round_2a: { - self.event_timeout2: self.round_2a, - self.event_2b: self.round_2b, - }, - self.round_2b: { - self.event_2a: self.round_2a, - self.event_2c: self.round_2c, - }, - self.round_2c: {}, - } - final_states = {self.round_2c} - event_to_timeout = {self.event_timeout2: self.timeout2} - db_pre_conditions: Dict[AppState, Set[str]] = {self.round_2a: {self.key_1}} - db_post_conditions: Dict[AppState, Set[str]] = {self.round_2c: {self.key_2}} - cross_period_persisted_keys = self.cross_period_persisted_keys_2 - - self.app2_class = AbciApp2 - - class AbciApp3(AbciApp): - initial_round_cls = self.round_3a - transition_function = { - self.round_3a: { - self.event_timeout3: self.round_3a, - self.event_3b: self.round_3b, - }, - self.round_3b: { - self.event_3a: self.round_3a, - self.event_3c: self.round_3c, - self.event_1a: self.round_3a, # duplicated event - }, - self.round_3c: {}, - } - final_states = {self.round_3c} - event_to_timeout = {self.event_timeout3: self.timeout3} - db_pre_conditions: Dict[AppState, Set[str]] = { - self.round_3a: {self.key_1, self.key_2} - } - db_post_conditions: Dict[AppState, Set[str]] = {self.round_3c: {self.key_3}} - - self.app3_class = AbciApp3 - - class AbciApp3Dupe(AbciApp): - initial_round_cls = self.round_3a - transition_function = { - self.round_3a: { - self.event_timeout3: self.round_3a, - self.event_3b: self.round_3b, - }, - self.round_1b_dupe: { # duplucated round id - self.event_3a: self.round_3a, - self.event_3c: self.round_3c, - self.event_1a: self.round_3a, # duplicated event - }, - self.round_3c: {}, - } - final_states = {self.round_3c} - event_to_timeout = {self.event_timeout3: self.timeout3} - db_post_conditions: Dict[AppState, Set[str]] = {self.round_3c: set()} - - self.app3_class_dupe = AbciApp3Dupe - - class AbciApp2Faulty1(AbciApp): - initial_round_cls = self.round_2a - transition_function = { - self.round_2a: { - self.event_timeout2: self.round_2a, - self.event_2b: self.round_2b, - }, - self.round_2b: { - self.event_2a: self.round_2a, - self.event_2c: self.round_2c, - }, - self.round_2c: {}, - } - final_states = {self.round_2c} - event_to_timeout = {self.event_timeout1: self.timeout2} - db_pre_conditions: Dict[AppState, Set[str]] = {self.round_2a: {self.key_1}} - db_post_conditions: Dict[AppState, Set[str]] = {self.round_2c: {self.key_2}} - - self.app2_class_faulty1 = AbciApp2Faulty1 - - def test_chain_two(self) -> None: - """Test the AbciApp chain function.""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_1a, - } - - ComposedAbciApp = chain( - (self.app1_class, self.app2_class), abci_app_transition_mapping - ) - - assert ComposedAbciApp.initial_round_cls == self.round_1a - assert ComposedAbciApp.transition_function == { - self.round_1a: { - self.event_timeout1: self.round_1a, - self.event_1b: self.round_1b, - }, - self.round_1b: { - self.event_1a: self.round_1a, - self.event_1c: self.round_2a, - }, - self.round_2a: { - self.event_timeout2: self.round_2a, - self.event_2b: self.round_2b, - }, - self.round_2b: { - self.event_2a: self.round_2a, - self.event_2c: self.round_1a, - }, - } - assert ComposedAbciApp.final_states == set() - assert ComposedAbciApp.event_to_timeout == { - self.event_timeout1: self.timeout1, - self.event_timeout2: self.timeout2, - } - assert ( - ComposedAbciApp.cross_period_persisted_keys - == self.cross_period_persisted_keys_1.union( - self.cross_period_persisted_keys_2 - ) - ) - - def test_chain_three(self) -> None: - """Test the AbciApp chain function.""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_3a, - } - - ComposedAbciApp = chain( - (self.app1_class, self.app2_class, self.app3_class), - abci_app_transition_mapping, - ) - - assert ComposedAbciApp.initial_round_cls == self.round_1a - assert ComposedAbciApp.transition_function == { - self.round_1a: { - self.event_timeout1: self.round_1a, - self.event_1b: self.round_1b, - }, - self.round_1b: { - self.event_1a: self.round_1a, - self.event_1c: self.round_2a, - }, - self.round_2a: { - self.event_timeout2: self.round_2a, - self.event_2b: self.round_2b, - }, - self.round_2b: { - self.event_2a: self.round_2a, - self.event_2c: self.round_3a, - }, - self.round_3a: { - self.event_timeout3: self.round_3a, - self.event_3b: self.round_3b, - }, - self.round_3b: { - self.event_3a: self.round_3a, - self.event_3c: self.round_3c, - self.event_1a: self.round_3a, - }, - self.round_3c: {}, - } - assert ComposedAbciApp.final_states == {self.round_3c} - assert ComposedAbciApp.event_to_timeout == { - self.event_timeout1: self.timeout1, - self.event_timeout2: self.timeout2, - self.event_timeout3: self.timeout3, - } - - def test_chain_two_negative_timeouts(self) -> None: - """Test the AbciApp chain function.""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_1a, - } - - with pytest.raises( - ValueError, match="but it is already defined in a prior app with timeout" - ): - _ = chain( - (self.app1_class, self.app2_class_faulty1), abci_app_transition_mapping - ) - - def test_chain_two_negative_mapping_initial_states(self) -> None: - """Test the AbciApp chain function.""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2b, - self.round_2c: self.round_1a, - } - - with pytest.raises(ValueError, match="Found non-initial state"): - _ = chain((self.app1_class, self.app2_class), abci_app_transition_mapping) - - def test_chain_two_negative_mapping_final_states(self) -> None: - """Test the AbciApp chain function.""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2b: self.round_1a, - } - - with pytest.raises(ValueError, match="Found non-final state"): - _ = chain((self.app1_class, self.app2_class), abci_app_transition_mapping) - - def test_chain_two_dupe(self) -> None: - """Test the AbciApp chain function.""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_1a, - } - with pytest.raises( - AEAEnforceError, - match=r"round ids in common between abci apps are not allowed.*", - ): - chain((self.app1_class, self.app3_class_dupe), abci_app_transition_mapping) - - def test_chain_with_abstract_abci_app_fails(self) -> None: - """Test chaining with an abstract AbciApp fails.""" - self.app2_class._is_abstract = False - self.app3_class._is_abstract = False - with pytest.raises( - AEAEnforceError, - match=r"found non-abstract AbciApp during chaining: \['AbciApp2', 'AbciApp3'\]", - ): - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_3a, - } - chain( - (self.app1_class, self.app2_class, self.app3_class), - abci_app_transition_mapping, - ) - - def test_synchronized_data_type(self, caplog: LogCaptureFixture) -> None: - """Test synchronized data type""" - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_1a, - } - - sentinel_app1 = object() - sentinel_app2 = object() - - def make_sync_data(sentinel: object) -> Type: - class SynchronizedData(BaseSynchronizedData): - @property - def dummy_attr(self) -> object: - return sentinel - - return SynchronizedData - - def make_concrete(round_cls: Type[AbstractRound]) -> Type[AbstractRound]: - class ConcreteRound(round_cls): # type: ignore - def check_payload(self, payload: BaseTxPayload) -> None: - pass - - def process_payload(self, payload: BaseTxPayload) -> None: - pass - - def end_block(self) -> None: - pass - - payload_class = None - - return ConcreteRound - - sync_data_cls_app1 = make_sync_data(sentinel_app1) - sync_data_cls_app2 = make_sync_data(sentinel_app2) - - # don't need to mock all of this since setup creates these classes - for abci_app_cls, sync_data_cls in ( - (self.app1_class, sync_data_cls_app1), - (self.app2_class, sync_data_cls_app2), - ): - synchronized_data = sync_data_cls(db=AbciAppDB(setup_data={})) - abci_app = abci_app_cls(synchronized_data, logging.getLogger(), MagicMock()) - for r in abci_app_cls.get_all_rounds(): - r.synchronized_data_class = sync_data_cls - - abci_app_cls = chain( - (self.app1_class, self.app2_class), abci_app_transition_mapping - ) - synchronized_data = sync_data_cls_app2(db=AbciAppDB(setup_data={})) - abci_app = abci_app_cls(synchronized_data, logging.getLogger(), MagicMock()) - - assert abci_app.initial_round_cls == self.round_1a - assert isinstance(abci_app.synchronized_data, sync_data_cls_app1) - assert abci_app.synchronized_data.dummy_attr == sentinel_app1 - - app2_classes = self.app2_class.get_all_rounds() - for round_ in sorted(abci_app.get_all_rounds(), key=str): - abci_app._round_results.append(abci_app.synchronized_data) - abci_app.schedule_round(make_concrete(round_)) - expected_cls = (sync_data_cls_app1, sync_data_cls_app2)[ - round_ in app2_classes - ] - assert isinstance(abci_app.synchronized_data, expected_cls) - expected_sentinel = (sentinel_app1, sentinel_app2)[round_ in app2_classes] - assert abci_app.synchronized_data.dummy_attr == expected_sentinel - - def test_precondition_for_next_app_missing_raises( - self, caplog: LogCaptureFixture - ) -> None: - """Test that when precondition for next AbciApp is missing an error is raised""" - - class AbciApp1(AbciApp): - initial_round_cls = self.round_1a - transition_function = { - self.round_1a: { - self.event_timeout1: self.round_1a, - self.event_1b: self.round_1b, - }, - self.round_1b: { - self.event_1a: self.round_1a, - self.event_1c: self.round_1c, - }, - self.round_1c: {}, - } - final_states = {self.round_1c} - event_to_timeout = {self.event_timeout1: self.timeout1} - db_pre_conditions: Dict[AppState, Set[str]] = {self.round_1a: set()} - db_post_conditions: Dict[AppState, Set[str]] = {self.round_1c: set()} - cross_period_persisted_keys = self.cross_period_persisted_keys_1 - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_1a, - } - - expected = "Pre conditions '.*' of app '.*' not a post condition of app '.*' or any preceding app in path .*." - with pytest.raises(ValueError, match=expected): - chain( - ( - AbciApp1, - self.app2_class, - ), - abci_app_transition_mapping, - ) - - def test_precondition_app_missing_raises(self, caplog: LogCaptureFixture) -> None: - """Test that missing precondition specification for next AbciApp is missing an error is raised""" - - class AbciApp2(AbciApp): - initial_round_cls = self.round_2a - transition_function = { - self.round_2a: { - self.event_timeout2: self.round_2a, - self.event_2b: self.round_2b, - }, - self.round_2b: { - self.event_2a: self.round_2a, - self.event_2c: self.round_2c, - }, - self.round_2c: {}, - } - final_states = {self.round_2c} - event_to_timeout = {self.event_timeout2: self.timeout2} - db_pre_conditions: Dict[AppState, Set[str]] = {} - db_post_conditions: Dict[AppState, Set[str]] = {self.round_2c: {self.key_2}} - cross_period_persisted_keys = self.cross_period_persisted_keys_2 - - abci_app_transition_mapping: AbciAppTransitionMapping = { - self.round_1c: self.round_2a, - self.round_2c: self.round_1a, - } - - expected = "No pre-conditions have been set for .*! You need to explicitly specify them as empty if there are no pre-conditions for this FSM." - with pytest.raises(ValueError, match=expected): - chain((self.app1_class, AbciApp2), abci_app_transition_mapping) diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_base.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_base.py deleted file mode 100644 index c5ff0f49e..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_base.py +++ /dev/null @@ -1,3420 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the base.py module of the skill.""" - -import dataclasses -import datetime -import json -import logging -import re -import shutil -from abc import ABC -from calendar import timegm -from collections import deque -from contextlib import suppress -from copy import copy, deepcopy -from dataclasses import dataclass -from enum import Enum -from pathlib import Path -from time import sleep -from typing import ( - Any, - Callable, - Deque, - Dict, - FrozenSet, - Generator, - List, - Optional, - Set, - Tuple, - Type, - cast, -) -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from _pytest.logging import LogCaptureFixture -from aea.exceptions import AEAEnforceError -from aea_ledger_ethereum import EthereumCrypto -from hypothesis import HealthCheck, given, settings -from hypothesis.strategies import ( - DrawFn, - binary, - booleans, - builds, - composite, - data, - datetimes, - dictionaries, - floats, - integers, - just, - lists, - none, - one_of, - sampled_from, - text, -) - -import packages.valory.skills.abstract_round_abci.base as abci_base -from packages.valory.connections.abci.connection import MAX_READ_IN_BYTES -from packages.valory.protocols.abci.custom_types import ( - Evidence, - EvidenceType, - Evidences, - LastCommitInfo, - Timestamp, - Validator, - VoteInfo, -) -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppException, - ABCIAppInternalError, - AbciApp, - AbciAppDB, - AbciAppTransitionFunction, - AbstractRound, - AbstractRoundInternalError, - AddBlockError, - AppState, - AvailabilityWindow, - BaseSynchronizedData, - BaseTxPayload, - Block, - BlockBuilder, - Blockchain, - CollectionRound, - EventType, - LateArrivingTransaction, - OffenceStatus, - OffenseStatusDecoder, - OffenseStatusEncoder, - OffenseType, - RoundSequence, - SignatureNotValidError, - SlashingNotConfiguredError, - Timeouts, - Transaction, - TransactionTypeNotRecognizedError, - _MetaAbciApp, - _MetaAbstractRound, - _MetaPayload, - get_name, - light_offences, - serious_offences, -) -from packages.valory.skills.abstract_round_abci.test_tools.abci_app import ( - AbciAppTest, - ConcreteBackgroundRound, - ConcreteBackgroundSlashingRound, - ConcreteEvents, - ConcreteRoundA, - ConcreteRoundB, - ConcreteRoundC, - ConcreteSlashingRoundA, - ConcreteTerminationRoundA, - ConcreteTerminationRoundB, - ConcreteTerminationRoundC, - SlashingAppTest, - TerminationAppTest, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseRoundTestClass, - get_participants, -) -from packages.valory.skills.abstract_round_abci.tests.conftest import profile_name - - -# pylint: skip-file - - -settings.load_profile(profile_name) - - -PACKAGE_DIR = Path(__file__).parent.parent - - -DUMMY_CONCRETE_BACKGROUND_PAYLOAD = ConcreteBackgroundRound.payload_class( - sender="sender" -) - - -@pytest.fixture(scope="session", autouse=True) -def hypothesis_cleanup() -> Generator: - """Fixture to remove hypothesis directory after tests.""" - yield - hypothesis_dir = PACKAGE_DIR / ".hypothesis" - if hypothesis_dir.exists(): - with suppress(OSError, PermissionError): - shutil.rmtree(hypothesis_dir) - - -class BasePayload(BaseTxPayload, ABC): - """Base payload class for testing.""" - - -@dataclass(frozen=True) -class PayloadA(BasePayload): - """Payload class for payload type 'A'.""" - - -@dataclass(frozen=True) -class PayloadB(BasePayload): - """Payload class for payload type 'B'.""" - - -@dataclass(frozen=True) -class PayloadC(BasePayload): - """Payload class for payload type 'C'.""" - - -@dataclass(frozen=True) -class PayloadD(BasePayload): - """Payload class for payload type 'D'.""" - - -@dataclass(frozen=True) -class DummyPayload(BasePayload): - """Dummy payload class.""" - - dummy_attribute: int - - -@dataclass(frozen=True) -class TooBigPayload(BaseTxPayload): - """Base payload class for testing.""" - - dummy_field: str = "0" * 10**7 - - -class ObjectImitator: - """For custom __eq__ implementation testing""" - - def __init__(self, other: Any): - """Copying references to class attr, and instance attr""" - - for attr, value in vars(other.__class__).items(): - if not attr.startswith("__") and not attr.endswith("__"): - setattr(self.__class__, attr, value) - - self.__dict__ = other.__dict__ - - -def test_base_tx_payload() -> None: - """Test BaseTxPayload.""" - - payload = PayloadA(sender="sender") - object.__setattr__(payload, "round_count", 9) - new_payload = payload.with_new_id() - - assert not payload == new_payload - payload_data, new_payload_data = payload.json, new_payload.json - assert not payload_data.pop("id_") == new_payload_data.pop("id_") - assert payload_data == new_payload_data - with pytest.raises(dataclasses.FrozenInstanceError): - payload.round_count = 1 # type: ignore - object.__setattr__(payload, "round_count", 1) - assert payload.round_count == 1 - assert type(hash(payload)) == int - - -def test_meta_round_abstract_round_when_instance_not_subclass_of_abstract_round() -> ( - None -): - """Test instantiation of meta class when instance not a subclass of abstract round.""" - - class MyAbstractRound(metaclass=_MetaAbstractRound): - pass - - -def test_abstract_round_instantiation_without_attributes_raises_error() -> None: - """Test that definition of concrete subclass of AbstractRound without attributes raises error.""" - with pytest.raises(AbstractRoundInternalError): - - class MyRoundBehaviour(AbstractRound): - pass - - with pytest.raises(AbstractRoundInternalError): - - class MyRoundBehaviourB(AbstractRound): - synchronized_data_class = MagicMock() - - -class TestTransactions: - """Test Transactions class.""" - - def setup(self) -> None: - """Set up the test.""" - self.old_value = copy(_MetaPayload.registry) - - def test_encode_decode(self) -> None: - """Test encoding and decoding of payloads.""" - sender = "sender" - - expected_payload = PayloadA(sender=sender) - actual_payload = PayloadA.decode(expected_payload.encode()) - assert expected_payload == actual_payload - - expected_payload_ = PayloadB(sender=sender) - actual_payload_ = PayloadB.decode(expected_payload_.encode()) - assert expected_payload_ == actual_payload_ - - expected_payload__ = PayloadC(sender=sender) - actual_payload__ = PayloadC.decode(expected_payload__.encode()) - assert expected_payload__ == actual_payload__ - - expected_payload___ = PayloadD(sender=sender) - actual_payload___ = PayloadD.decode(expected_payload___.encode()) - assert expected_payload___ == actual_payload___ - - def test_encode_decode_transaction(self) -> None: - """Test encode/decode of a transaction.""" - sender = "sender" - signature = "signature" - payload = PayloadA(sender) - expected = Transaction(payload, signature) - actual = expected.decode(expected.encode()) - assert expected == actual - - def test_encode_too_big_payload(self) -> None: - """Test encode of a too big payload.""" - sender = "sender" - payload = TooBigPayload(sender) - with pytest.raises( - ValueError, - match=f"{type(payload)} must be smaller than {MAX_READ_IN_BYTES} bytes", - ): - payload.encode() - - def test_encode_too_big_transaction(self) -> None: - """Test encode of a too big transaction.""" - sender = "sender" - signature = "signature" - payload = TooBigPayload(sender) - tx = Transaction(payload, signature) - with pytest.raises( - ValueError, - match=f"Transaction must be smaller than {MAX_READ_IN_BYTES} bytes", - ): - tx.encode() - - def test_sign_verify_transaction(self) -> None: - """Test sign/verify transaction.""" - crypto = EthereumCrypto() - sender = crypto.address - payload = PayloadA(sender) - payload_bytes = payload.encode() - signature = crypto.sign_message(payload_bytes) - transaction = Transaction(payload, signature) - transaction.verify(crypto.identifier) - - def test_payload_not_equal_lookalike(self) -> None: - """Test payload __eq__ reflection via NotImplemented""" - payload = PayloadA(sender="sender") - lookalike = ObjectImitator(payload) - assert not payload == lookalike - - def test_transaction_not_equal_lookalike(self) -> None: - """Test transaction __eq__ reflection via NotImplemented""" - payload = PayloadA(sender="sender") - transaction = Transaction(payload, signature="signature") - lookalike = ObjectImitator(transaction) - assert not transaction == lookalike - - def teardown(self) -> None: - """Tear down the test.""" - _MetaPayload.registry = self.old_value - - -@mock.patch( - "aea.crypto.ledger_apis.LedgerApis.recover_message", return_value={"wrong_sender"} -) -def test_verify_transaction_negative_case(*_mocks: Any) -> None: - """Test verify() of transaction, negative case.""" - transaction = Transaction(MagicMock(sender="right_sender", json={}), "") - with pytest.raises( - SignatureNotValidError, match="Signature not valid on transaction: .*" - ): - transaction.verify("") - - -@dataclass(frozen=True) -class SomeClass(BaseTxPayload): - """Test class.""" - - content: Dict - - -@given( - dictionaries( - keys=text(), - values=one_of(floats(allow_nan=False, allow_infinity=False), booleans()), - ) -) -def test_payload_serializer_is_deterministic(obj: Any) -> None: - """Test that 'DictProtobufStructSerializer' is deterministic.""" - obj_ = SomeClass(sender="", content=obj) - obj_bytes = obj_.encode() - assert obj_ == BaseTxPayload.decode(obj_bytes) - - -def test_initialize_block() -> None: - """Test instantiation of a Block instance.""" - block = Block(MagicMock(), []) - assert block.transactions == tuple() - - -class TestBlockchain: - """Test a blockchain object.""" - - def setup(self) -> None: - """Set up the test.""" - self.blockchain = Blockchain() - - def test_height(self) -> None: - """Test the 'height' property getter.""" - assert self.blockchain.height == 0 - - def test_len(self) -> None: - """Test the 'length' property getter.""" - assert self.blockchain.length == 0 - - def test_add_block_positive(self) -> None: - """Test 'add_block', success.""" - block = Block(MagicMock(height=1), []) - self.blockchain.add_block(block) - assert self.blockchain.length == 1 - assert self.blockchain.height == 1 - - def test_add_block_negative_wrong_height(self) -> None: - """Test 'add_block', wrong height.""" - wrong_height = 42 - block = Block(MagicMock(height=wrong_height), []) - with pytest.raises( - AddBlockError, - match=f"expected height {self.blockchain.height + 1}, got {wrong_height}", - ): - self.blockchain.add_block(block) - - def test_add_block_before_initial_height(self) -> None: - """Test 'add_block', too old height.""" - height_offset = 42 - blockchain = Blockchain(height_offset=height_offset) - block = Block(MagicMock(height=height_offset - 1), []) - blockchain.add_block(block) - - def test_blocks(self) -> None: - """Test 'blocks' property getter.""" - assert self.blockchain.blocks == tuple() - - -class TestBlockBuilder: - """Test block builder.""" - - def setup(self) -> None: - """Set up the method.""" - self.block_builder = BlockBuilder() - - def test_get_header_positive(self) -> None: - """Test header property getter, positive.""" - expected_header = MagicMock() - self.block_builder._current_header = expected_header - actual_header = self.block_builder.header - assert expected_header == actual_header - - def test_get_header_negative(self) -> None: - """Test header property getter, negative.""" - with pytest.raises(ValueError, match="header not set"): - self.block_builder.header - - def test_set_header_positive(self) -> None: - """Test header property setter, positive.""" - expected_header = MagicMock() - self.block_builder.header = expected_header - actual_header = self.block_builder.header - assert expected_header == actual_header - - def test_set_header_negative(self) -> None: - """Test header property getter, negative.""" - self.block_builder.header = MagicMock() - with pytest.raises(ValueError, match="header already set"): - self.block_builder.header = MagicMock() - - def test_transitions_getter(self) -> None: - """Test 'transitions' property getter.""" - assert self.block_builder.transactions == tuple() - - def test_add_transitions(self) -> None: - """Test 'add_transition'.""" - transaction = MagicMock() - self.block_builder.add_transaction(transaction) - assert self.block_builder.transactions == (transaction,) - - def test_get_block_negative_header_not_set_yet(self) -> None: - """Test 'get_block', negative case (header not set yet).""" - with pytest.raises(ValueError, match="header not set"): - self.block_builder.get_block() - - def test_get_block_positive(self) -> None: - """Test 'get_block', positive case.""" - self.block_builder.header = MagicMock() - self.block_builder.get_block() - - -class TestAbciAppDB: - """Test 'AbciAppDB' class.""" - - def setup(self) -> None: - """Set up the tests.""" - self.participants = ("a", "b") - self.db = AbciAppDB( - setup_data=dict(participants=[self.participants]), - ) - - @pytest.mark.parametrize( - "data, setup_data", - ( - ({"participants": ["a", "b"]}, {"participants": ["a", "b"]}), - ({"participants": []}, {}), - ({"participants": None}, None), - ("participants", None), - (1, None), - (object(), None), - (["participants"], None), - ({"participants": [], "other": [1, 2]}, {"other": [1, 2]}), - ), - ) - @pytest.mark.parametrize( - "cross_period_persisted_keys, expected_cross_period_persisted_keys", - ((None, set()), (set(), set()), ({"test"}, {"test"})), - ) - def test_init( - self, - data: Dict, - setup_data: Optional[Dict], - cross_period_persisted_keys: Optional[Set[str]], - expected_cross_period_persisted_keys: Set[str], - ) -> None: - """Test constructor.""" - # keys are a set, but we cast them to a frozenset, so we can still update them and also make `mypy` - # think that the type is correct, to simulate a user incorrectly passing a different type and check if the - # attribute can be altered - cast_keys = cast(Optional[FrozenSet[str]], cross_period_persisted_keys) - # update with the default keys - expected_cross_period_persisted_keys.update(AbciAppDB.default_cross_period_keys) - - if setup_data is None: - # the parametrization of `setup_data` set to `None` is in order to check if the exception is raised - # when we incorrectly set the data in the configuration file with a type that is not allowed - with pytest.raises( - ValueError, - match=re.escape( - f"AbciAppDB data must be `Dict[str, List[Any]]`, found `{type(data)}` instead" - ), - ): - AbciAppDB( - data, - ) - return - - # use copies because otherwise the arguments will be modified and the next test runs will be polluted - data_copy = deepcopy(data) - cross_period_persisted_keys_copy = cast_keys.copy() if cast_keys else cast_keys - db = AbciAppDB(data_copy, cross_period_persisted_keys_copy) - assert db._data == {0: setup_data} - assert db.setup_data == setup_data - assert db.cross_period_persisted_keys == expected_cross_period_persisted_keys - - def data_assertion() -> None: - """Assert that the data are fine.""" - assert db._data == {0: setup_data} and db.setup_data == setup_data, ( - "The database's `setup_data` have been altered indirectly, " - "by updating an item passed via the `__init__`!" - ) - - new_value_attempt = "new_value_attempt" - data_copy.update({"dummy_key": [new_value_attempt]}) - data_assertion() - - data_copy["participants"].append(new_value_attempt) - data_assertion() - - if cross_period_persisted_keys_copy: - # cast back to set - cast(Set[str], cross_period_persisted_keys_copy).add(new_value_attempt) - assert ( - db.cross_period_persisted_keys == expected_cross_period_persisted_keys - ), ( - "The database's `cross_period_persisted_keys` have been altered indirectly, " - "by updating an item passed via the `__init__`!" - ) - - class EnumTest(Enum): - """A test Enum class""" - - test = 10 - - @pytest.mark.parametrize( - "data_in, expected_output", - ( - (0, 0), - ([], []), - ({"test": 2}, {"test": 2}), - (EnumTest.test, 10), - (b"test", b"test".hex()), - ({3, 4}, "[3, 4]"), - (object(), None), - ), - ) - def test_normalize(self, data_in: Any, expected_output: Any) -> None: - """Test `normalize`.""" - if expected_output is None: - with pytest.raises(ValueError): - self.db.normalize(data_in) - return - assert self.db.normalize(data_in) == expected_output - - @pytest.mark.parametrize("data", {0: [{"test": 2}]}) - def test_reset_index(self, data: Dict) -> None: - """Test `reset_index`.""" - assert self.db.reset_index == 0 - self.db.sync(self.db.serialize()) - assert self.db.reset_index == 0 - - def test_round_count_setter(self) -> None: - """Tests the round count setter.""" - expected_value = 1 - - # assume the round count is 0 in the begging - self.db._round_count = 0 - - # update to one via the setter - self.db.round_count = expected_value - - assert self.db.round_count == expected_value - - def test_try_alter_init_data(self) -> None: - """Test trying to alter the init data.""" - data_key = "test" - data_value = [data_key] - expected_data = {data_key: data_value} - passed_data = {data_key: data_value.copy()} - db = AbciAppDB(passed_data) - assert db.setup_data == expected_data - - mutability_error_message = ( - "The database's `setup_data` have been altered indirectly, " - "by updating an item retrieved via the `setup_data` property!" - ) - - db.setup_data.update({data_key: ["altered"]}) - assert db.setup_data == expected_data, mutability_error_message - - db.setup_data[data_key].append("altered") - assert db.setup_data == expected_data, mutability_error_message - - def test_cross_period_persisted_keys(self) -> None: - """Test `cross_period_persisted_keys` property""" - setup_data: Dict[str, List] = {} - cross_period_persisted_keys = frozenset({"test"}) - db = AbciAppDB(setup_data, cross_period_persisted_keys.copy()) - - assert isinstance(db.cross_period_persisted_keys, frozenset), ( - "The database's `cross_period_persisted_keys` can be altered indirectly. " - "The `cross_period_persisted_keys` was expected to be a `frozenset`!" - ) - - def test_get(self) -> None: - """Test getters.""" - assert self.db.get("participants", default="default") == self.participants - assert self.db.get("inexistent", default="default") == "default" - assert self.db.get_latest_from_reset_index(0) == { - "participants": self.participants - } - assert self.db.get_latest() == {"participants": self.participants} - - mutable_key = "mutable" - mutable_value = ["test"] - self.db.update(**{mutable_key: mutable_value.copy()}) - mutable_getters = set() - for getter, kwargs in ( - ("get", {"key": mutable_key}), - ("get_strict", {"key": mutable_key}), - ("get_latest_from_reset_index", {"reset_index": 0}), - ("get_latest", {}), - ): - retrieved = getattr(self.db, getter)(**kwargs) - if getter.startswith("get_latest"): - retrieved = retrieved[mutable_key] - retrieved.append("new_value_attempt") - - if self.db.get(mutable_key) != mutable_value: - mutable_getters.add(getter) - - assert not mutable_getters, ( - "The database has been altered indirectly, " - f"by updating the item(s) retrieved via the `{mutable_getters}` method(s)!" - ) - - def test_increment_round_count(self) -> None: - """Test increment_round_count.""" - assert self.db.round_count == -1 - self.db.increment_round_count() - assert self.db.round_count == 0 - - @mock.patch.object( - abci_base, - "is_json_serializable", - return_value=False, - ) - def test_validate(self, _: mock._patch) -> None: - """Test `validate` method.""" - data = "does not matter" - - with pytest.raises( - ABCIAppInternalError, - match=re.escape( - "internal error: `AbciAppDB` data must be json-serializable. Please convert non-serializable data in " - f"`{data}`. You may use `AbciAppDB.validate(your_data)` to validate your data for the `AbciAppDB`." - ), - ): - AbciAppDB.validate(data) - - @pytest.mark.parametrize( - "setup_data, update_data, expected_data", - ( - (dict(), {"dummy_key": "dummy_value"}, {0: {"dummy_key": ["dummy_value"]}}), - ( - dict(), - {"dummy_key": ["dummy_value1", "dummy_value2"]}, - {0: {"dummy_key": [["dummy_value1", "dummy_value2"]]}}, - ), - ( - {"test": ["test"]}, - {"dummy_key": "dummy_value"}, - {0: {"dummy_key": ["dummy_value"], "test": ["test"]}}, - ), - ( - {"test": ["test"]}, - {"test": "dummy_value"}, - {0: {"test": ["test", "dummy_value"]}}, - ), - ( - {"test": [["test"]]}, - {"test": ["dummy_value1", "dummy_value2"]}, - {0: {"test": [["test"], ["dummy_value1", "dummy_value2"]]}}, - ), - ( - {"test": ["test"]}, - {"test": ["dummy_value1", "dummy_value2"]}, - {0: {"test": ["test", ["dummy_value1", "dummy_value2"]]}}, - ), - ), - ) - def test_update( - self, setup_data: Dict, update_data: Dict, expected_data: Dict[int, Dict] - ) -> None: - """Test update db.""" - db = AbciAppDB(setup_data) - db.update(**update_data) - assert db._data == expected_data - - mutable_key = "mutable" - mutable_value = ["test"] - update_data = {mutable_key: mutable_value.copy()} - db.update(**update_data) - - update_data[mutable_key].append("new_value_attempt") - assert ( - db.get(mutable_key) == mutable_value - ), "The database has been altered indirectly, by updating the item passed via the `update` method!" - - @pytest.mark.parametrize( - "replacement_value, expected_replacement", - ( - (132, 132), - ("test", "test"), - (set("132"), ("1", "2", "3")), - ({"132"}, ("132",)), - (frozenset("231"), ("1", "2", "3")), - (frozenset({"231"}), ("231",)), - (("1", "3", "2"), ("1", "3", "2")), - (["1", "5", "3"], ["1", "5", "3"]), - ), - ) - @pytest.mark.parametrize( - "setup_data, cross_period_persisted_keys", - ( - (dict(), frozenset()), - ({"test": [["test"]]}, frozenset()), - ({"test": [["test"]]}, frozenset({"test"})), - ({"test": ["test"]}, frozenset({"test"})), - ), - ) - def test_create( - self, - replacement_value: Any, - expected_replacement: Any, - setup_data: Dict, - cross_period_persisted_keys: FrozenSet[str], - ) -> None: - """Test `create` db.""" - db = AbciAppDB(setup_data) - db._cross_period_persisted_keys = cross_period_persisted_keys - db.create() - assert db._data == { - 0: setup_data, - 1: setup_data if cross_period_persisted_keys else {}, - }, "`create` did not produce the expected result!" - - mutable_key = "mutable" - mutable_value = ["test"] - existing_key = "test" - create_data = { - mutable_key: mutable_value.copy(), - existing_key: replacement_value, - } - db.create(**create_data) - - assert db._data == { - 0: setup_data, - 1: setup_data if cross_period_persisted_keys else {}, - 2: db.data_to_lists( - { - mutable_key: mutable_value.copy(), - existing_key: expected_replacement, - } - ), - }, "`create` did not produce the expected result!" - - create_data[mutable_key].append("new_value_attempt") - assert ( - db.get(mutable_key) == mutable_value - ), "The database has been altered indirectly, by updating the item passed via the `create` method!" - - def test_create_key_not_in_db(self) -> None: - """Test the `create` method when a given or a cross-period key does not exist in the db.""" - existing_key = "existing_key" - non_existing_key = "non_existing_key" - - db = AbciAppDB({existing_key: ["test_value"]}) - db._cross_period_persisted_keys = frozenset({non_existing_key}) - with pytest.raises( - ABCIAppInternalError, - match=f"Cross period persisted key `{non_existing_key}` " - "was not found in the db but was required for the next period.", - ): - db.create() - - db._cross_period_persisted_keys = frozenset({existing_key}) - db.create(**{non_existing_key: "test_value"}) - - @pytest.mark.parametrize( - "existing_data, cleanup_history_depth, cleanup_history_depth_current, expected", - ( - ( - {1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}}, - 0, - None, - {1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}}, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": [0]}, - }, - 0, - None, - {2: {"test": [0]}}, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": [0, 1, 2]}, - }, - 0, - 0, - {2: {"test": [0, 1, 2]}}, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": [0, 1, 2]}, - }, - 0, - 1, - {2: {"test": [2]}}, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": list(range(5))}, - 3: {"test": list(range(5, 10))}, - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15, 20))}, - }, - 3, - 0, - { - 3: {"test": list(range(5, 10))}, - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15, 20))}, - }, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": list(range(5))}, - 3: {"test": list(range(5, 10))}, - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15, 20))}, - }, - 5, - 3, - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": list(range(5))}, - 3: {"test": list(range(5, 10))}, - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15 + 2, 20))}, - }, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": list(range(5))}, - 3: {"test": list(range(5, 10))}, - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15, 20))}, - }, - 2, - 3, - { - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15 + 2, 20))}, - }, - ), - ( - { - 1: {"test": ["test", ["dummy_value1", "dummy_value2"]]}, - 2: {"test": list(range(5))}, - 3: {"test": list(range(5, 10))}, - 4: {"test": list(range(10, 15))}, - 5: {"test": list(range(15, 20))}, - }, - 0, - 1, - { - 5: {"test": [19]}, - }, - ), - ), - ) - def test_cleanup( - self, - existing_data: Dict[int, Dict[str, List[Any]]], - cleanup_history_depth: int, - cleanup_history_depth_current: Optional[int], - expected: Dict[int, Dict[str, List[Any]]], - ) -> None: - """Test cleanup db.""" - db = AbciAppDB({}) - db._cross_period_persisted_keys = frozenset() - for _, _data in existing_data.items(): - db._create_from_keys(**_data) - - db.cleanup(cleanup_history_depth, cleanup_history_depth_current) - assert db._data == expected - - def test_serialize(self) -> None: - """Test `serialize` method.""" - assert ( - self.db.serialize() - == '{"db_data": {"0": {"participants": [["a", "b"]]}}, "slashing_config": ""}' - ) - - @pytest.mark.parametrize( - "_data", - ({"db_data": {0: {"test": [0]}}, "slashing_config": "serialized_config"},), - ) - def test_sync(self, _data: Dict[str, Dict[int, Dict[str, List[Any]]]]) -> None: - """Test `sync` method.""" - try: - serialized_data = json.dumps(_data) - except TypeError as exc: - raise AssertionError( - "Incorrectly parametrized test. Data must be json serializable." - ) from exc - - self.db.sync(serialized_data) - assert self.db._data == _data["db_data"] - assert self.db.slashing_config == _data["slashing_config"] - - @pytest.mark.parametrize( - "serialized_data, match", - ( - (b"", "Could not decode data using "), - ( - json.dumps({"both_mandatory_keys_missing": {}}), - "internal error: Mandatory keys `db_data`, `slashing_config` are missing from the deserialized data: " - "{'both_mandatory_keys_missing': {}}\nThe following serialized data were given: " - '{"both_mandatory_keys_missing": {}}', - ), - ( - json.dumps({"db_data": {}}), - "internal error: Mandatory keys `db_data`, `slashing_config` are missing from the deserialized data: " - "{'db_data': {}}\nThe following serialized data were given: {\"db_data\": {}}", - ), - ( - json.dumps({"slashing_config": {}}), - "internal error: Mandatory keys `db_data`, `slashing_config` are missing from the deserialized data: " - "{'slashing_config': {}}\nThe following serialized data were given: {\"slashing_config\": {}}", - ), - ( - json.dumps( - {"db_data": {"invalid_index": {}}, "slashing_config": "anything"} - ), - "An invalid index was found while trying to sync the db using data: ", - ), - ( - json.dumps({"db_data": "invalid", "slashing_config": "anything"}), - "Could not decode db data with an invalid format: ", - ), - ), - ) - def test_sync_incorrect_data(self, serialized_data: Any, match: str) -> None: - """Test `sync` method with incorrect data.""" - with pytest.raises( - ABCIAppInternalError, - match=match, - ): - self.db.sync(serialized_data) - - def test_hash(self) -> None: - """Test `hash` method.""" - expected_hash = ( - b"\xd0^\xb0\x85\xf1\xf5\xd2\xe8\xe8\x85\xda\x1a\x99k" - b"\x1c\xde\xfa1\x8a\x87\xcc\xd7q?\xdf\xbbofz\xfb\x7fI" - ) - assert self.db.hash() == expected_hash - - -class TestBaseSynchronizedData: - """Test 'BaseSynchronizedData' class.""" - - def setup(self) -> None: - """Set up the tests.""" - self.participants = ("a", "b") - self.base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB(setup_data=dict(participants=[self.participants])) - ) - - @given(text()) - def test_slashing_config(self, slashing_config: str) -> None: - """Test the `slashing_config` property.""" - self.base_synchronized_data.slashing_config = slashing_config - assert ( - self.base_synchronized_data.slashing_config - == self.base_synchronized_data.db.slashing_config - == slashing_config - ) - - def test_participants_getter_positive(self) -> None: - """Test 'participants' property getter.""" - assert frozenset(self.participants) == self.base_synchronized_data.participants - - def test_nb_participants_getter(self) -> None: - """Test 'participants' property getter.""" - assert len(self.participants) == self.base_synchronized_data.nb_participants - - def test_participants_getter_negative(self) -> None: - """Test 'participants' property getter, negative case.""" - base_synchronized_data = BaseSynchronizedData(db=AbciAppDB(setup_data={})) - # with pytest.raises(ValueError, match="Value of key=participants is None"): - with pytest.raises( - ValueError, - match=re.escape( - "'participants' field is not set for this period [0] and no default value was provided." - ), - ): - base_synchronized_data.participants - - def test_update(self) -> None: - """Test the 'update' method.""" - participants = ("a",) - expected = BaseSynchronizedData( - db=AbciAppDB(setup_data=dict(participants=[participants])) - ) - actual = self.base_synchronized_data.update(participants=participants) - assert expected.participants == actual.participants - assert actual.db._data == {0: {"participants": [("a", "b"), ("a",)]}} - - def test_create(self) -> None: - """Test the 'create' method.""" - self.base_synchronized_data.db._cross_period_persisted_keys = frozenset( - {"participants"} - ) - assert self.base_synchronized_data.db._data == { - 0: {"participants": [("a", "b")]} - } - actual = self.base_synchronized_data.create() - assert actual.db._data == { - 0: {"participants": [("a", "b")]}, - 1: {"participants": [("a", "b")]}, - } - - def test_repr(self) -> None: - """Test the '__repr__' magic method.""" - actual_repr = repr(self.base_synchronized_data) - expected_repr_regex = r"BaseSynchronizedData\(db=AbciAppDB\({(.*)}\)\)" - assert re.match(expected_repr_regex, actual_repr) is not None - - def test_participants_list_is_empty( - self, - ) -> None: - """Tets when participants list is set to zero.""" - base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB(setup_data=dict(participants=[tuple()])) - ) - with pytest.raises(ValueError, match="List participants cannot be empty."): - _ = base_synchronized_data.participants - - def test_all_participants_list_is_empty( - self, - ) -> None: - """Tets when participants list is set to zero.""" - base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB(setup_data=dict(all_participants=[tuple()])) - ) - with pytest.raises(ValueError, match="List participants cannot be empty."): - _ = base_synchronized_data.all_participants - - @pytest.mark.parametrize( - "n_participants, given_threshold, expected_threshold", - ( - (1, None, 1), - (5, None, 4), - (10, None, 7), - (345, None, 231), - (246236, None, 164158), - (1, 1, 1), - (5, 5, 5), - (10, 7, 7), - (10, 8, 8), - (10, 9, 9), - (10, 10, 10), - (345, 300, 300), - (246236, 194158, 194158), - ), - ) - def test_consensus_threshold( - self, n_participants: int, given_threshold: int, expected_threshold: int - ) -> None: - """Test the `consensus_threshold` property.""" - base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB( - setup_data=dict( - all_participants=[tuple(range(n_participants))], - consensus_threshold=[given_threshold], - ) - ) - ) - - assert base_synchronized_data.consensus_threshold == expected_threshold - - @pytest.mark.parametrize( - "n_participants, given_threshold", - ( - (1, 2), - (5, 2), - (10, 4), - (10, 11), - (10, 18), - (345, 200), - (246236, 164157), - (246236, 246237), - ), - ) - def test_consensus_threshold_incorrect( - self, - n_participants: int, - given_threshold: int, - ) -> None: - """Test the `consensus_threshold` property when an incorrect threshold value has been inserted to the db.""" - base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB( - setup_data=dict( - all_participants=[tuple(range(n_participants))], - consensus_threshold=[given_threshold], - ) - ) - ) - - with pytest.raises(ValueError, match="Consensus threshold "): - _ = base_synchronized_data.consensus_threshold - - def test_properties(self) -> None: - """Test several properties""" - participants = ["b", "a"] - randomness_str = ( - "3439d92d58e47d342131d446a3abe264396dd264717897af30525c98408c834f" - ) - randomness_value = 0.20400769574270503 - most_voted_keeper_address = "most_voted_keeper_address" - blacklisted_keepers = "blacklisted_keepers" - participant_to_selection = participant_to_randomness = participant_to_votes = { - "sender": DummyPayload(sender="sender", dummy_attribute=0) - } - safe_contract_address = "0x0" - - base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - participants=participants, - all_participants=participants, - most_voted_randomness=randomness_str, - most_voted_keeper_address=most_voted_keeper_address, - blacklisted_keepers=blacklisted_keepers, - participant_to_selection=CollectionRound.serialize_collection( - participant_to_selection - ), - participant_to_randomness=CollectionRound.serialize_collection( - participant_to_randomness - ), - participant_to_votes=CollectionRound.serialize_collection( - participant_to_votes - ), - safe_contract_address=safe_contract_address, - ) - ) - ) - ) - assert self.base_synchronized_data.period_count == 0 - assert base_synchronized_data.all_participants == frozenset(participants) - assert base_synchronized_data.sorted_participants == ["a", "b"] - assert base_synchronized_data.max_participants == len(participants) - assert abs(base_synchronized_data.keeper_randomness - randomness_value) < 1e-10 - assert base_synchronized_data.most_voted_randomness == randomness_str - assert ( - base_synchronized_data.most_voted_keeper_address - == most_voted_keeper_address - ) - assert base_synchronized_data.is_keeper_set - assert base_synchronized_data.blacklisted_keepers == {blacklisted_keepers} - assert ( - base_synchronized_data.participant_to_selection == participant_to_selection - ) - assert ( - base_synchronized_data.participant_to_randomness - == participant_to_randomness - ) - assert base_synchronized_data.participant_to_votes == participant_to_votes - assert base_synchronized_data.safe_contract_address == safe_contract_address - - -class DummyConcreteRound(AbstractRound): - """A dummy concrete round's implementation.""" - - payload_class: Optional[Type[BaseTxPayload]] = None - synchronized_data_class = MagicMock() - payload_attribute = MagicMock() - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, EventType]]: - """A dummy `end_block` implementation.""" - - def check_payload(self, payload: BaseTxPayload) -> None: - """A dummy `check_payload` implementation.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """A dummy `process_payload` implementation.""" - - -class TestAbstractRound: - """Test the 'AbstractRound' class.""" - - def setup(self) -> None: - """Set up the tests.""" - self.known_payload_type = ConcreteRoundA.payload_class - self.participants = ("a", "b") - self.base_synchronized_data = BaseSynchronizedData( - db=AbciAppDB( - setup_data=dict( - all_participants=[self.participants], - participants=[self.participants], - consensus_threshold=[2], - ) - ) - ) - self.round = ConcreteRoundA(self.base_synchronized_data, MagicMock()) - - def test_auto_round_id(self) -> None: - """Test that the 'auto_round_id()' method works as expected.""" - - assert DummyConcreteRound.auto_round_id() == "dummy_concrete_round" - - def test_must_not_set_round_id(self) -> None: - """Test that the 'round_id' must be set in concrete classes.""" - - # no exception as round id is auto-assigned - my_concrete_round = DummyConcreteRound(MagicMock(), MagicMock()) - assert my_concrete_round.round_id == "dummy_concrete_round" - - def test_must_set_payload_class_type(self) -> None: - """Test that the 'payload_class' must be set in concrete classes.""" - - with pytest.raises( - AbstractRoundInternalError, match="'payload_class' not set on .*" - ): - - class MyConcreteRound(AbstractRound): - synchronized_data_class = MagicMock() - payload_attribute = MagicMock() - # here payload_class is missing - - def test_check_payload_type_with_previous_round_transaction(self) -> None: - """Test check 'check_payload_type'.""" - - class MyConcreteRound(DummyConcreteRound): - """A concrete round with the payload class defined.""" - - payload_class = BaseTxPayload - - with pytest.raises(LateArrivingTransaction): - MyConcreteRound(MagicMock(), MagicMock(), BaseTxPayload).check_payload_type( - MagicMock(payload=BaseTxPayload("dummy")) - ) - - def test_check_payload_type(self) -> None: - """Test check 'check_payload_type'.""" - - with pytest.raises( - TransactionTypeNotRecognizedError, - match="current round does not allow transactions", - ): - DummyConcreteRound(MagicMock(), MagicMock()).check_payload_type(MagicMock()) - - def test_synchronized_data_getter(self) -> None: - """Test 'synchronized_data' property getter.""" - state = self.round.synchronized_data - assert state.participants == frozenset(self.participants) - - def test_check_transaction_unknown_payload(self) -> None: - """Test 'check_transaction' method, with unknown payload type.""" - tx_type = "unknown_payload" - tx_mock = MagicMock() - tx_mock.payload_class = tx_type - with pytest.raises( - TransactionTypeNotRecognizedError, - match="request '.*' not recognized", - ): - self.round.check_transaction(tx_mock) - - def test_check_transaction_known_payload(self) -> None: - """Test 'check_transaction' method, with known payload type.""" - tx_mock = MagicMock() - tx_mock.payload = self.known_payload_type(sender="dummy") - self.round.check_transaction(tx_mock) - - def test_process_transaction_negative_unknown_payload(self) -> None: - """Test 'process_transaction' method, with unknown payload type.""" - tx_mock = MagicMock() - tx_mock.payload = object - with pytest.raises( - TransactionTypeNotRecognizedError, - match="request '.*' not recognized", - ): - self.round.process_transaction(tx_mock) - - def test_process_transaction_negative_check_transaction_fails(self) -> None: - """Test 'process_transaction' method, with 'check_transaction' failing.""" - tx_mock = MagicMock() - tx_mock.payload = object - error_message = "transaction not valid" - with mock.patch.object( - self.round, "check_payload_type", side_effect=ValueError(error_message) - ): - with pytest.raises(ValueError, match=error_message): - self.round.process_transaction(tx_mock) - - def test_process_transaction_positive(self) -> None: - """Test 'process_transaction' method, positive case.""" - tx_mock = MagicMock() - tx_mock.payload = BaseTxPayload(sender="dummy") - self.round.process_transaction(tx_mock) - - def test_check_majority_possible_raises_error_when_nb_participants_is_0( - self, - ) -> None: - """Check that 'check_majority_possible' raises error when nb_participants=0.""" - with pytest.raises( - ABCIAppInternalError, - match="nb_participants not consistent with votes_by_participants", - ): - DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).check_majority_possible({}, 0) - - def test_check_majority_possible_passes_when_vote_set_is_empty(self) -> None: - """Check that 'check_majority_possible' passes when the set of votes is empty.""" - DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).check_majority_possible({}, 1) - - def test_check_majority_possible_passes_when_vote_set_nonempty_and_check_passes( - self, - ) -> None: - """ - Check that 'check_majority_possible' passes when set of votes is non-empty. - - The check passes because: - - the threshold is 2 - - the other voter can vote for the same item of the first voter - """ - DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).check_majority_possible({"alice": DummyPayload("alice", True)}, 2) - - def test_check_majority_possible_passes_when_payload_attributes_majority_match( - self, - ) -> None: - """ - Test 'check_majority_possible' when set of votes is non-empty and the majority of the attribute values match. - - The check passes because: - - the threshold is 3 (participants are 4) - - 3 voters have the same attribute value in their payload - """ - DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).check_majority_possible( - { - "voter_1": DummyPayload("voter_1", 0), - "voter_2": DummyPayload("voter_2", 0), - "voter_3": DummyPayload("voter_3", 0), - }, - 4, - ) - - def test_check_majority_possible_passes_when_vote_set_nonempty_and_check_doesnt_pass( - self, - ) -> None: - """ - Check that 'check_majority_possible' doesn't pass when set of votes is non-empty. - - the check does not pass because: - - the threshold is 2 - - both voters have already voted for different items - """ - with pytest.raises( - ABCIAppException, - match="cannot reach quorum=2, number of remaining votes=0, number of most voted item's votes=1", - ): - DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).check_majority_possible( - { - "alice": DummyPayload("alice", False), - "bob": DummyPayload("bob", True), - }, - 2, - ) - - def test_is_majority_possible_positive_case(self) -> None: - """Test 'is_majority_possible', positive case.""" - assert DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).is_majority_possible({"alice": DummyPayload("alice", False)}, 2) - - def test_is_majority_possible_negative_case(self) -> None: - """Test 'is_majority_possible', negative case.""" - assert not DummyConcreteRound( - self.base_synchronized_data, MagicMock() - ).is_majority_possible( - { - "alice": DummyPayload("alice", False), - "bob": DummyPayload("bob", True), - }, - 2, - ) - - def test_check_majority_possible_raises_error_when_new_voter_already_voted( - self, - ) -> None: - """Test 'check_majority_possible_with_new_vote' raises when new voter already voted.""" - with pytest.raises(ABCIAppInternalError, match="voter has already voted"): - DummyConcreteRound( - self.base_synchronized_data, - MagicMock(), - ).check_majority_possible_with_new_voter( - {"alice": DummyPayload("alice", False)}, - "alice", - DummyPayload("alice", True), - 2, - ) - - def test_check_majority_possible_raises_error_when_nb_participants_inconsistent( - self, - ) -> None: - """Test 'check_majority_possible_with_new_vote' raises when 'nb_participants' inconsistent with other args.""" - with pytest.raises( - ABCIAppInternalError, - match="nb_participants not consistent with votes_by_participants", - ): - DummyConcreteRound( - self.base_synchronized_data, - MagicMock(), - ).check_majority_possible_with_new_voter( - {"alice": DummyPayload("alice", True)}, - "bob", - DummyPayload("bob", True), - 1, - ) - - def test_check_majority_possible_when_check_passes( - self, - ) -> None: - """ - Test 'check_majority_possible_with_new_vote' when the check passes. - - The test passes because: - - the number of participants is 2, and so the threshold is 2 - - the new voter votes for the same item already voted by voter 1. - """ - DummyConcreteRound( - self.base_synchronized_data, - MagicMock(), - ).check_majority_possible_with_new_voter( - {"alice": DummyPayload("alice", True)}, "bob", DummyPayload("bob", True), 2 - ) - - -class TestTimeouts: - """Test the 'Timeouts' class.""" - - def setup(self) -> None: - """Set up the test.""" - self.timeouts: Timeouts = Timeouts() - - def test_size(self) -> None: - """Test the 'size' property.""" - assert self.timeouts.size == 0 - self.timeouts._heap.append(MagicMock()) - assert self.timeouts.size == 1 - - def test_add_timeout(self) -> None: - """Test the 'add_timeout' method.""" - # the first time, entry_count = 0 - entry_count = self.timeouts.add_timeout(datetime.datetime.now(), MagicMock()) - assert entry_count == 0 - - # the second time, entry_count is incremented - entry_count = self.timeouts.add_timeout(datetime.datetime.now(), MagicMock()) - assert entry_count == 1 - - def test_cancel_timeout(self) -> None: - """Test the 'cancel_timeout' method.""" - entry_count = self.timeouts.add_timeout(datetime.datetime.now(), MagicMock()) - assert self.timeouts.size == 1 - - self.timeouts.cancel_timeout(entry_count) - - # cancelling timeouts does not remove them from the heap - assert self.timeouts.size == 1 - - def test_pop_earliest_cancelled_timeouts(self) -> None: - """Test the 'pop_earliest_cancelled_timeouts' method.""" - entry_count_1 = self.timeouts.add_timeout(datetime.datetime.now(), MagicMock()) - entry_count_2 = self.timeouts.add_timeout(datetime.datetime.now(), MagicMock()) - self.timeouts.cancel_timeout(entry_count_1) - self.timeouts.cancel_timeout(entry_count_2) - self.timeouts.pop_earliest_cancelled_timeouts() - assert self.timeouts.size == 0 - - def test_get_earliest_timeout_a(self) -> None: - """Test the 'get_earliest_timeout' method.""" - deadline_1 = datetime.datetime.now() - event_1 = MagicMock() - - sleep(0.5) - - deadline_2 = datetime.datetime.now() - event_2 = MagicMock() - assert deadline_1 < deadline_2 - - self.timeouts.add_timeout(deadline_2, event_2) - self.timeouts.add_timeout(deadline_1, event_1) - - assert self.timeouts.size == 2 - # test that we get the event with the earliest deadline - timeout, event = self.timeouts.get_earliest_timeout() - assert timeout == deadline_1 - assert event == event_1 - - # test that get_earliest_timeout does not remove elements - assert self.timeouts.size == 2 - - popped_timeout, popped_event = self.timeouts.pop_timeout() - assert popped_timeout == timeout - assert popped_event == event - - def test_get_earliest_timeout_b(self) -> None: - """Test the 'get_earliest_timeout' method.""" - - deadline_1 = datetime.datetime.now() - event_1 = MagicMock() - - sleep(0.5) - - deadline_2 = datetime.datetime.now() - event_2 = MagicMock() - assert deadline_1 < deadline_2 - - self.timeouts.add_timeout(deadline_1, event_1) - self.timeouts.add_timeout(deadline_2, event_2) - - assert self.timeouts.size == 2 - # test that we get the event with the earliest deadline - timeout, event = self.timeouts.get_earliest_timeout() - assert timeout == deadline_1 - assert event == event_1 - - # test that get_earliest_timeout does not remove elements - assert self.timeouts.size == 2 - - def test_pop_timeout(self) -> None: - """Test the 'pop_timeout' method.""" - deadline_1 = datetime.datetime.now() - event_1 = MagicMock() - - sleep(0.5) - - deadline_2 = datetime.datetime.now() - event_2 = MagicMock() - assert deadline_1 < deadline_2 - - self.timeouts.add_timeout(deadline_2, event_2) - self.timeouts.add_timeout(deadline_1, event_1) - - assert self.timeouts.size == 2 - # test that we get the event with the earliest deadline - timeout, event = self.timeouts.pop_timeout() - assert timeout == deadline_1 - assert event == event_1 - - # test that pop_timeout removes elements - assert self.timeouts.size == 1 - - -STUB_TERMINATION_CONFIG = abci_base.BackgroundAppConfig( - round_cls=ConcreteBackgroundRound, - start_event=ConcreteEvents.TERMINATE, - abci_app=TerminationAppTest, -) - -STUB_SLASH_CONFIG = abci_base.BackgroundAppConfig( - round_cls=ConcreteBackgroundSlashingRound, - start_event=ConcreteEvents.SLASH_START, - end_event=ConcreteEvents.SLASH_END, - abci_app=SlashingAppTest, -) - - -class TestAbciApp: - """Test the 'AbciApp' class.""" - - def setup(self) -> None: - """Set up the test.""" - self.abci_app = AbciAppTest(MagicMock(), MagicMock(), MagicMock()) - self.abci_app.add_background_app(STUB_TERMINATION_CONFIG) - - def teardown(self) -> None: - """Teardown the test.""" - self.abci_app.background_apps.clear() - - @pytest.mark.parametrize("flag", (True, False)) - def test_is_abstract(self, flag: bool) -> None: - """Test `is_abstract` property.""" - - class CopyOfAbciApp(AbciAppTest): - """Copy to avoid side effects due to state change""" - - CopyOfAbciApp._is_abstract = flag - assert CopyOfAbciApp.is_abstract() is flag - - def test_initial_round_cls_not_set(self) -> None: - """Test when 'initial_round_cls' is not set.""" - - with pytest.raises( - ABCIAppInternalError, match="'initial_round_cls' field not set" - ): - - class MyAbciApp(AbciApp): - # here 'initial_round_cls' should be defined. - # ... - transition_function: AbciAppTransitionFunction = {} - - def test_transition_function_not_set(self) -> None: - """Test when 'transition_function' is not set.""" - with pytest.raises( - ABCIAppInternalError, match="'transition_function' field not set" - ): - - class MyAbciApp(AbciApp): - initial_round_cls = ConcreteRoundA - # here 'transition_function' should be defined. - # ... - - def test_last_timestamp_negative(self) -> None: - """Test the 'last_timestamp' property, negative case.""" - with pytest.raises(ABCIAppInternalError, match="last timestamp is None"): - self.abci_app.last_timestamp - - def test_last_timestamp_positive(self) -> None: - """Test the 'last_timestamp' property, positive case.""" - expected = MagicMock() - self.abci_app._last_timestamp = expected - assert expected == self.abci_app.last_timestamp - - @pytest.mark.parametrize( - "db_key, sync_classes, default, property_found", - ( - ("", set(), "default", False), - ("non_existing_key", {BaseSynchronizedData}, True, False), - ("participants", {BaseSynchronizedData}, {}, False), - ("is_keeper_set", {BaseSynchronizedData}, True, True), - ), - ) - def test_get_synced_value( - self, - db_key: str, - sync_classes: Set[Type[BaseSynchronizedData]], - default: Any, - property_found: bool, - ) -> None: - """Test the `_get_synced_value` method.""" - res = self.abci_app._get_synced_value(db_key, sync_classes, default) - if property_found: - assert res == getattr(self.abci_app.synchronized_data, db_key) - return - assert res == self.abci_app.synchronized_data.db.get(db_key, default) - - def test_process_event(self) -> None: - """Test the 'process_event' method, positive case, with timeout events.""" - self.abci_app.add_background_app(STUB_SLASH_CONFIG) - self.abci_app.setup() - self.abci_app._last_timestamp = MagicMock() - assert self.abci_app._transition_backup.transition_function is None - assert isinstance(self.abci_app.current_round, ConcreteRoundA) - self.abci_app.process_event(ConcreteEvents.B) - assert isinstance(self.abci_app.current_round, ConcreteRoundB) - self.abci_app.process_event(ConcreteEvents.TIMEOUT) - assert isinstance(self.abci_app.current_round, ConcreteRoundA) - self.abci_app.process_event(ConcreteEvents.TERMINATE) - assert isinstance(self.abci_app.current_round, ConcreteTerminationRoundA) - expected_backup = deepcopy(self.abci_app.transition_function) - assert ( - self.abci_app._transition_backup.transition_function - == AbciAppTest.transition_function - ) - self.abci_app.process_event(ConcreteEvents.SLASH_START) - assert isinstance(self.abci_app.current_round, ConcreteSlashingRoundA) - assert ( - self.abci_app._transition_backup.transition_function - == expected_backup - == TerminationAppTest.transition_function - ) - assert self.abci_app.transition_function == SlashingAppTest.transition_function - self.abci_app.process_event(ConcreteEvents.SLASH_END) - # should return back to the round that was running before the slashing started - assert isinstance(self.abci_app.current_round, ConcreteTerminationRoundA) - assert self.abci_app.transition_function == expected_backup - assert self.abci_app._transition_backup.transition_function is None - assert self.abci_app._transition_backup.round is None - - def test_process_event_negative_case(self) -> None: - """Test the 'process_event' method, negative case.""" - with mock.patch.object(self.abci_app.logger, "warning") as mock_warning: - self.abci_app.process_event(ConcreteEvents.A) - mock_warning.assert_called_with( - "Cannot process event 'a' as current state is not set" - ) - - def test_update_time(self) -> None: - """Test the 'update_time' method.""" - # schedule round_a - current_time = datetime.datetime.now() - self.abci_app.setup() - self.abci_app._last_timestamp = current_time - - # move to round_b that schedules timeout events - self.abci_app.process_event(ConcreteEvents.B) - assert self.abci_app.current_round_id == "concrete_round_b" - - # simulate most recent timestamp beyond earliest deadline - # after pop, len(timeouts) == 0, because round_a does not schedule new timeout events - current_time = current_time + datetime.timedelta(0, AbciAppTest.TIMEOUT) - self.abci_app.update_time(current_time) - - # now we are back to round_a - assert self.abci_app.current_round_id == "concrete_round_a" - - # move to round_c that schedules timeout events to itself - self.abci_app.process_event(ConcreteEvents.C) - assert self.abci_app.current_round_id == "concrete_round_c" - - # simulate most recent timestamp beyond earliest deadline - # after pop, len(timeouts) == 0, because round_c schedules timeout events - current_time = current_time + datetime.timedelta(0, AbciAppTest.TIMEOUT) - self.abci_app.update_time(current_time) - - assert self.abci_app.current_round_id == "concrete_round_c" - - # further update changes nothing - height = self.abci_app.current_round_height - self.abci_app.update_time(current_time) - assert height == self.abci_app.current_round_height - - def test_get_all_events(self) -> None: - """Test the all events getter.""" - assert { - ConcreteEvents.A, - ConcreteEvents.B, - ConcreteEvents.C, - ConcreteEvents.TIMEOUT, - } == self.abci_app.get_all_events() - - @pytest.mark.parametrize("include_background_rounds", (True, False)) - def test_get_all_rounds_classes( - self, - include_background_rounds: bool, - ) -> None: - """Test the get all rounds getter.""" - expected_rounds = {ConcreteRoundA, ConcreteRoundB, ConcreteRoundC} - - if include_background_rounds: - expected_rounds.update( - { - ConcreteBackgroundRound, - ConcreteTerminationRoundA, - ConcreteTerminationRoundB, - ConcreteTerminationRoundC, - } - ) - - actual_rounds = self.abci_app.get_all_round_classes( - {ConcreteBackgroundRound}, include_background_rounds - ) - - assert actual_rounds == expected_rounds - - def test_get_all_rounds_classes_bg_ever_running( - self, - ) -> None: - """Test the get all rounds when the background round is of an ever running type.""" - # we clear the pre-existing bg apps and add an ever running - self.abci_app.background_apps.clear() - self.abci_app.add_background_app( - abci_base.BackgroundAppConfig(ConcreteBackgroundRound) - ) - include_background_rounds = True - expected_rounds = { - ConcreteRoundA, - ConcreteRoundB, - ConcreteRoundC, - } - assert expected_rounds == self.abci_app.get_all_round_classes( - {ConcreteBackgroundRound}, include_background_rounds - ) - - def test_add_background_app(self) -> None: - """Tests the add method for the background apps.""" - # remove the terminating bg round added in `setup()` and the pending offences bg app added in the metaclass - self.abci_app.background_apps.clear() - - class EmptyAbciApp(AbciAppTest): - """An AbciApp without background apps' attributes set.""" - - cross_period_persisted_keys = frozenset({"1", "2"}) - - class BackgroundAbciApp(AbciAppTest): - """A mock background AbciApp.""" - - cross_period_persisted_keys = frozenset({"2", "3"}) - - assert len(EmptyAbciApp.background_apps) == 0 - assert EmptyAbciApp.cross_period_persisted_keys == {"1", "2"} - # add the background app - bg_app_config = abci_base.BackgroundAppConfig( - round_cls=ConcreteBackgroundRound, - start_event=ConcreteEvents.TERMINATE, - abci_app=BackgroundAbciApp, - ) - EmptyAbciApp.add_background_app(bg_app_config) - assert len(EmptyAbciApp.background_apps) == 1 - assert EmptyAbciApp.cross_period_persisted_keys == {"1", "2", "3"} - - def test_cleanup(self) -> None: - """Test the cleanup method.""" - self.abci_app.setup() - - # Dummy parameters, synchronized data and round - cleanup_history_depth = 1 - start_history_depth = 5 - max_participants = 4 - dummy_synchronized_data = BaseSynchronizedData( - db=AbciAppDB(setup_data=dict(participants=[max_participants])) - ) - dummy_round = ConcreteRoundA(dummy_synchronized_data, MagicMock()) - - # Add dummy data - self.abci_app._previous_rounds = [dummy_round] * start_history_depth - self.abci_app._round_results = [dummy_synchronized_data] * start_history_depth - self.abci_app.synchronized_data.db._data = { - i: {"dummy_key": ["dummy_value"]} for i in range(start_history_depth) - } - - round_height = self.abci_app.current_round_height - # Verify that cleanup reduces the data amount - assert len(self.abci_app._previous_rounds) == start_history_depth - assert len(self.abci_app._round_results) == start_history_depth - assert len(self.abci_app.synchronized_data.db._data) == start_history_depth - assert list(self.abci_app.synchronized_data.db._data.keys()) == list( - range(start_history_depth) - ) - previous_reset_index = self.abci_app.synchronized_data.db.reset_index - - self.abci_app.cleanup(cleanup_history_depth) - - assert len(self.abci_app._previous_rounds) == cleanup_history_depth - assert len(self.abci_app._round_results) == cleanup_history_depth - assert len(self.abci_app.synchronized_data.db._data) == cleanup_history_depth - assert list(self.abci_app.synchronized_data.db._data.keys()) == list( - range(start_history_depth - cleanup_history_depth, start_history_depth) - ) - # reset_index must not change after a cleanup - assert self.abci_app.synchronized_data.db.reset_index == previous_reset_index - - # Verify round height stays unaffected - assert self.abci_app.current_round_height == round_height - - # Add more values to the history - reset_index = self.abci_app.synchronized_data.db.reset_index - cleanup_history_depth_current = 3 - for _ in range(10): - self.abci_app.synchronized_data.db.update(dummy_key="dummy_value") - - # Check that the history cleanup keeps the desired history length - self.abci_app.cleanup_current_histories(cleanup_history_depth_current) - history_len = len( - self.abci_app.synchronized_data.db._data[reset_index]["dummy_key"] - ) - assert history_len == cleanup_history_depth_current - - @mock.patch.object(ConcreteBackgroundRound, "check_transaction") - @pytest.mark.parametrize( - "transaction", - [mock.MagicMock(payload=DUMMY_CONCRETE_BACKGROUND_PAYLOAD)], - ) - def test_check_transaction_for_termination_round( - self, - check_transaction_mock: mock.Mock, - transaction: Transaction, - ) -> None: - """Tests process_transaction when it's a transaction meant for the termination app.""" - self.abci_app.setup() - self.abci_app.check_transaction(transaction) - check_transaction_mock.assert_called_with(transaction) - - @mock.patch.object(ConcreteBackgroundRound, "process_transaction") - @pytest.mark.parametrize( - "transaction", - [mock.MagicMock(payload=DUMMY_CONCRETE_BACKGROUND_PAYLOAD)], - ) - def test_process_transaction_for_termination_round( - self, - process_transaction_mock: mock.Mock, - transaction: Transaction, - ) -> None: - """Tests process_transaction when it's a transaction meant for the termination app.""" - self.abci_app.setup() - self.abci_app.process_transaction(transaction) - process_transaction_mock.assert_called_with(transaction) - - -class TestOffenceTypeFns: - """Test `OffenceType`-related functions.""" - - @staticmethod - def test_light_offences() -> None: - """Test `light_offences` function.""" - assert list(light_offences()) == [ - OffenseType.VALIDATOR_DOWNTIME, - OffenseType.INVALID_PAYLOAD, - OffenseType.BLACKLISTED, - OffenseType.SUSPECTED, - ] - - @staticmethod - def test_serious_offences() -> None: - """Test `serious_offences` function.""" - assert list(serious_offences()) == [ - OffenseType.UNKNOWN, - OffenseType.DOUBLE_SIGNING, - OffenseType.LIGHT_CLIENT_ATTACK, - ] - - -@composite -def availability_window_data(draw: DrawFn) -> Dict[str, int]: - """A strategy for building valid availability window data.""" - max_length = draw(integers(min_value=1, max_value=12_000)) - array = draw(integers(min_value=0, max_value=(2**max_length) - 1)) - num_positive = draw(integers(min_value=0, max_value=1_000_000)) - num_negative = draw(integers(min_value=0, max_value=1_000_000)) - - return { - "max_length": max_length, - "array": array, - "num_positive": num_positive, - "num_negative": num_negative, - } - - -class TestAvailabilityWindow: - """Test `AvailabilityWindow`.""" - - @staticmethod - @given(integers(min_value=1, max_value=100)) - def test_not_equal(max_length: int) -> None: - """Test the `add` method.""" - availability_window_1 = AvailabilityWindow(max_length) - availability_window_2 = AvailabilityWindow(max_length) - assert availability_window_1 == availability_window_2 - availability_window_2.add(False) - assert availability_window_1 != availability_window_2 - # test with a different type - assert availability_window_1 != MagicMock() - - @staticmethod - @given(integers(min_value=0, max_value=100), data()) - def test_add(max_length: int, hypothesis_data: Any) -> None: - """Test the `add` method.""" - if max_length < 1: - with pytest.raises( - ValueError, - match=f"An `AvailabilityWindow` with a `max_length` {max_length} < 1 is not valid.", - ): - AvailabilityWindow(max_length) - return - - availability_window = AvailabilityWindow(max_length) - - expected_positives = expected_negatives = 0 - for i in range(max_length): - value = hypothesis_data.draw(booleans()) - availability_window.add(value) - items_in = i + 1 - assert len(availability_window._window) == items_in - assert availability_window._window[-1] is value - expected_positives += 1 if value else 0 - assert availability_window._num_positive == expected_positives - expected_negatives = items_in - expected_positives - assert availability_window._num_negative == expected_negatives - - # max length is reached and window starts cycling - assert len(availability_window._window) == max_length - for _ in range(10): - value = hypothesis_data.draw(booleans()) - expected_popped_value = ( - None if max_length == 0 else availability_window._window[0] - ) - availability_window.add(value) - assert len(availability_window._window) == max_length - if expected_popped_value is not None: - expected_positives -= bool(expected_popped_value) - expected_negatives -= bool(not expected_popped_value) - expected_positives += bool(value) - expected_negatives += bool(not value) - assert availability_window._num_positive == expected_positives - assert availability_window._num_negative == expected_negatives - - @staticmethod - @given( - max_length=integers(min_value=1, max_value=30_000), - num_positive=integers(min_value=0), - num_negative=integers(min_value=0), - ) - @pytest.mark.parametrize( - "window, expected_serialization", - ( - (deque(()), 0), - (deque((False, False, False)), 0), - (deque((True, False, True)), 5), - (deque((True for _ in range(3))), 7), - ( - deque((True for _ in range(1000))), - int( - "10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958" - "58127594672917553146825187145285692314043598457757469857480393456777482423098542107460506237114187" - "79541821530464749835819412673987675591655439460770629145711964776865421676604298316526243868372056" - "68069375" - ), - ), - ), - ) - def test_to_dict( - max_length: int, - num_positive: int, - num_negative: int, - window: Deque, - expected_serialization: int, - ) -> None: - """Test `to_dict` method.""" - availability_window = AvailabilityWindow(max_length) - availability_window._num_positive = num_positive - availability_window._num_negative = num_negative - availability_window._window = window - assert availability_window.to_dict() == { - "max_length": max_length, - "array": expected_serialization, - "num_positive": num_positive, - "num_negative": num_negative, - } - - @staticmethod - @pytest.mark.parametrize( - "data_, key, validator, expected_error", - ( - ({"a": 1, "b": 2, "c": 3}, "a", lambda x: x > 0, None), - ( - {"a": 1, "b": 2, "c": 3}, - "d", - lambda x: x > 0, - r"Missing required key: d\.", - ), - ( - {"a": "1", "b": 2, "c": 3}, - "a", - lambda x: x > 0, - r"a must be of type int\.", - ), - ( - {"a": -1, "b": 2, "c": 3}, - "a", - lambda x: x > 0, - r"a has invalid value -1\.", - ), - ), - ) - def test_validate_key( - data_: dict, key: str, validator: Callable, expected_error: Optional[str] - ) -> None: - """Test the `_validate_key` method.""" - if expected_error: - with pytest.raises(ValueError, match=expected_error): - AvailabilityWindow._validate_key(data_, key, validator) - else: - AvailabilityWindow._validate_key(data_, key, validator) - - @staticmethod - @pytest.mark.parametrize( - "data_, error_regex", - ( - ("not a dict", r"Expected dict, got"), - ( - {"max_length": -1, "array": 42, "num_positive": 10, "num_negative": 0}, - r"max_length", - ), - ( - {"max_length": 2, "array": 4, "num_positive": 10, "num_negative": 0}, - r"array", - ), - ( - {"max_length": 8, "array": 42, "num_positive": -1, "num_negative": 0}, - r"num_positive", - ), - ( - {"max_length": 8, "array": 42, "num_positive": 10, "num_negative": -1}, - r"num_negative", - ), - ), - ) - def test_validate_negative(data_: dict, error_regex: str) -> None: - """Negative tests for the `_validate` method.""" - with pytest.raises((TypeError, ValueError), match=error_regex): - AvailabilityWindow._validate(data_) - - @staticmethod - @given(availability_window_data()) - def test_validate_positive(data_: Dict[str, int]) -> None: - """Positive tests for the `_validate` method.""" - AvailabilityWindow._validate(data_) - - @staticmethod - @given(availability_window_data()) - def test_from_dict(data_: Dict[str, int]) -> None: - """Test `from_dict` method.""" - availability_window = AvailabilityWindow.from_dict(data_) - - # convert the serialized array to a binary string - binary_number = bin(data_["array"])[2:] - # convert each character in the binary string to a flag - flags = [bool(int(digit)) for digit in binary_number] - expected_window = deque(flags, maxlen=data_["max_length"]) - - assert availability_window._max_length == data_["max_length"] - assert availability_window._window == expected_window - assert availability_window._num_positive == data_["num_positive"] - assert availability_window._num_negative == data_["num_negative"] - - @staticmethod - @given(availability_window_data()) - def test_to_dict_and_back(data_: Dict[str, int]) -> None: - """Test that the `from_dict` produces an object that generates the input data again when calling `to_dict`.""" - availability_window = AvailabilityWindow.from_dict(data_) - assert availability_window.to_dict() == data_ - - -class TestOffenceStatus: - """Test the `OffenceStatus` dataclass.""" - - @staticmethod - @pytest.mark.parametrize("custom_amount", (0, 5)) - @pytest.mark.parametrize("light_unit_amount, serious_unit_amount", ((1, 2),)) - @pytest.mark.parametrize( - "validator_downtime, invalid_payload, blacklisted, suspected, " - "num_unknown_offenses, num_double_signed, num_light_client_attack, expected", - ( - (False, False, False, False, 0, 0, 0, 0), - (True, False, False, False, 0, 0, 0, 1), - (False, True, False, False, 0, 0, 0, 1), - (False, False, True, False, 0, 0, 0, 1), - (False, False, False, True, 0, 0, 0, 1), - (False, False, False, False, 1, 0, 0, 2), - (False, False, False, False, 0, 1, 0, 2), - (False, False, False, False, 0, 0, 1, 2), - (False, False, False, False, 0, 2, 1, 6), - (False, True, False, True, 5, 2, 1, 18), - (True, True, True, True, 5, 2, 1, 20), - ), - ) - def test_slash_amount( - custom_amount: int, - light_unit_amount: int, - serious_unit_amount: int, - validator_downtime: bool, - invalid_payload: bool, - blacklisted: bool, - suspected: bool, - num_unknown_offenses: int, - num_double_signed: int, - num_light_client_attack: int, - expected: int, - ) -> None: - """Test the `slash_amount` method.""" - status = OffenceStatus() - - if validator_downtime: - for _ in range(abci_base.NUMBER_OF_BLOCKS_TRACKED): - status.validator_downtime.add(True) - - for _ in range(abci_base.NUMBER_OF_ROUNDS_TRACKED): - if invalid_payload: - status.invalid_payload.add(True) - if blacklisted: - status.blacklisted.add(True) - if suspected: - status.suspected.add(True) - - status.num_unknown_offenses = num_unknown_offenses - status.num_double_signed = num_double_signed - status.num_light_client_attack = num_light_client_attack - status.custom_offences_amount = custom_amount - - actual = status.slash_amount(light_unit_amount, serious_unit_amount) - assert actual == expected + status.custom_offences_amount - - -@composite -def offence_tracking(draw: DrawFn) -> Tuple[Evidences, LastCommitInfo]: - """A strategy for building offences reported by Tendermint.""" - n_validators = draw(integers(min_value=1, max_value=10)) - - validators = [ - draw( - builds( - Validator, - address=just(bytes(i)), - power=integers(min_value=0), - ) - ) - for i in range(n_validators) - ] - - evidences = builds( - Evidences, - byzantine_validators=lists( - builds( - Evidence, - evidence_type=sampled_from(EvidenceType), - validator=sampled_from(validators), - height=integers(min_value=0), - time=builds( - Timestamp, - seconds=integers(min_value=0), - nanos=integers(min_value=0, max_value=999_999_999), - ), - total_voting_power=integers(min_value=0), - ), - min_size=n_validators, - max_size=n_validators, - unique_by=lambda v: v.validator.address, - ), - ) - - last_commit_info = builds( - LastCommitInfo, - round_=integers(min_value=0), - votes=lists( - builds( - VoteInfo, - validator=sampled_from(validators), - signed_last_block=booleans(), - ), - min_size=n_validators, - max_size=n_validators, - unique_by=lambda v: v.validator.address, - ), - ) - - ev_example, commit_example = draw(evidences), draw(last_commit_info) - - # this assertion proves that all the validators are unique - unique_commit_addresses = set( - v.validator.address.decode() for v in commit_example.votes - ) - assert len(unique_commit_addresses) == n_validators - - # this assertion proves that the same validators are used for evidences and votes - assert unique_commit_addresses == set( - e.validator.address.decode() for e in ev_example.byzantine_validators - ) - - return ev_example, commit_example - - -@composite -def offence_status(draw: DrawFn) -> OffenceStatus: - """Build an offence status instance.""" - validator_downtime = just( - AvailabilityWindow.from_dict(draw(availability_window_data())) - ) - invalid_payload = just( - AvailabilityWindow.from_dict(draw(availability_window_data())) - ) - blacklisted = just(AvailabilityWindow.from_dict(draw(availability_window_data()))) - suspected = just(AvailabilityWindow.from_dict(draw(availability_window_data()))) - - status = builds( - OffenceStatus, - validator_downtime=validator_downtime, - invalid_payload=invalid_payload, - blacklisted=blacklisted, - suspected=suspected, - num_unknown_offenses=integers(min_value=0), - num_double_signed=integers(min_value=0), - num_light_client_attack=integers(min_value=0), - ) - - return draw(status) - - -class TestOffenseStatusEncoderDecoder: - """Test the `OffenseStatusEncoder` and the `OffenseStatusDecoder`.""" - - @staticmethod - @given(dictionaries(keys=text(), values=offence_status(), min_size=1)) - def test_encode_decode_offense_status(offense_status: str) -> None: - """Test encoding an offense status mapping and then decoding it by using the custom encoder/decoder.""" - encoded = json.dumps(offense_status, cls=OffenseStatusEncoder) - decoded = json.loads(encoded, cls=OffenseStatusDecoder) - - assert decoded == offense_status - - def test_encode_unknown(self) -> None: - """Test the encoder with an unknown input.""" - - class Unknown: - """A dummy class that the encoder is not aware of.""" - - unknown = "?" - - with pytest.raises( - TypeError, match="Object of type Unknown is not JSON serializable" - ): - json.dumps(Unknown(), cls=OffenseStatusEncoder) - - -class TestRoundSequence: - """Test the RoundSequence class.""" - - def setup(self) -> None: - """Set up the test.""" - self.round_sequence = RoundSequence( - context=MagicMock(), abci_app_cls=AbciAppTest - ) - self.round_sequence.setup(MagicMock(), logging.getLogger()) - self.round_sequence.tm_height = 1 - - @pytest.mark.parametrize( - "property_name, set_twice_exc, config_exc", - ( - ( - "validator_to_agent", - "The mapping of the validators' addresses to their agent addresses can only be set once. " - "Attempted to set with {new_content_attempt} but it has content already: {value}.", - "The mapping of the validators' addresses to their agent addresses has not been set.", - ), - ), - ) - @given(data()) - def test_slashing_properties( - self, property_name: str, set_twice_exc: str, config_exc: str, _data: Any - ) -> None: - """Test `validator_to_agent` getter and setter.""" - if property_name == "validator_to_agent": - data_generator = dictionaries(text(), text()) - else: - data_generator = dictionaries(text(), just(OffenceStatus())) - - value = _data.draw(data_generator) - round_sequence = RoundSequence(context=MagicMock(), abci_app_cls=AbciAppTest) - - if value: - setattr(round_sequence, property_name, value) - assert getattr(round_sequence, property_name) == value - new_content_attempt = _data.draw(data_generator) - with pytest.raises( - ValueError, - match=re.escape( - set_twice_exc.format( - new_content_attempt=new_content_attempt, value=value - ) - ), - ): - setattr(round_sequence, property_name, new_content_attempt) - return - - with pytest.raises(SlashingNotConfiguredError, match=config_exc): - getattr(round_sequence, property_name) - - @mock.patch("json.loads", return_value="json_serializable") - @pytest.mark.parametrize("slashing_config", (None, "", "test")) - def test_sync_db_and_slashing( - self, mock_loads: mock.MagicMock, slashing_config: str - ) -> None: - """Test the `sync_db_and_slashing` method.""" - self.round_sequence.latest_synchronized_data.slashing_config = slashing_config - serialized_db_state = "dummy_db_state" - self.round_sequence.sync_db_and_slashing(serialized_db_state) - - # Check that `sync()` was called with the correct arguments - mock_sync = cast( - mock.Mock, self.round_sequence.abci_app.synchronized_data.db.sync - ) - mock_sync.assert_called_once_with(serialized_db_state) - - if slashing_config: - mock_loads.assert_called_once_with( - slashing_config, cls=OffenseStatusDecoder - ) - else: - mock_loads.assert_not_called() - - @mock.patch("json.dumps") - @pytest.mark.parametrize("slashing_enabled", (True, False)) - def test_store_offence_status( - self, mock_dumps: mock.MagicMock, slashing_enabled: bool - ) -> None: - """Test the `store_offence_status` method.""" - # Set up mock objects and return values - self.round_sequence._offence_status = {"not_encoded": OffenceStatus()} - mock_encoded_status = "encoded_status" - mock_dumps.return_value = mock_encoded_status - - self.round_sequence._slashing_enabled = slashing_enabled - - # Call the method to be tested - self.round_sequence.store_offence_status() - - if slashing_enabled: - # Check that `json.dumps()` was called with the correct arguments, only if slashing is enabled - mock_dumps.assert_called_once_with( - self.round_sequence.offence_status, - cls=OffenseStatusEncoder, - sort_keys=True, - ) - assert ( - self.round_sequence.abci_app.synchronized_data.db.slashing_config - == mock_encoded_status - ) - return - - # otherwise check that it was not called - mock_dumps.assert_not_called() - - @given( - validator=builds(Validator, address=binary(), power=integers()), - agent_address=text(), - ) - def test_get_agent_address(self, validator: Validator, agent_address: str) -> None: - """Test `get_agent_address` method.""" - round_sequence = RoundSequence(context=MagicMock(), abci_app_cls=AbciAppTest) - round_sequence.validator_to_agent = { - validator.address.hex().upper(): agent_address - } - assert round_sequence.get_agent_address(validator) == agent_address - - unknown = deepcopy(validator) - unknown.address += b"unknown" - with pytest.raises( - ValueError, - match=re.escape( - f"Requested agent address for an unknown validator address {unknown.address.hex().upper()}. " - f"Available validators are: {round_sequence.validator_to_agent.keys()}" - ), - ): - round_sequence.get_agent_address(unknown) - - @pytest.mark.parametrize("offset", tuple(range(5))) - @pytest.mark.parametrize("n_blocks", (0, 1, 10)) - def test_height(self, n_blocks: int, offset: int) -> None: - """Test 'height' property.""" - self.round_sequence._blockchain._blocks = [MagicMock() for _ in range(n_blocks)] - self.round_sequence._blockchain._height_offset = offset - assert self.round_sequence._blockchain.length == n_blocks - assert self.round_sequence.height == n_blocks + offset - - def test_is_finished(self) -> None: - """Test 'is_finished' property.""" - assert not self.round_sequence.is_finished - self.round_sequence.abci_app._current_round = None - assert self.round_sequence.is_finished - - def test_last_round(self) -> None: - """Test 'last_round' property.""" - assert self.round_sequence.last_round_id is None - - def test_last_timestamp_none(self) -> None: - """ - Test 'last_timestamp' property. - - The property is None because there are no blocks. - """ - with pytest.raises(ABCIAppInternalError, match="last timestamp is None"): - self.round_sequence.last_timestamp - - def test_last_timestamp(self) -> None: - """Test 'last_timestamp' property, positive case.""" - seconds = 1 - nanoseconds = 1000 - expected_timestamp = datetime.datetime.fromtimestamp( - seconds + nanoseconds / 10**9 - ) - self.round_sequence._blockchain.add_block( - Block(MagicMock(height=1, timestamp=expected_timestamp), []) - ) - assert self.round_sequence.last_timestamp == expected_timestamp - - def test_abci_app_negative(self) -> None: - """Test 'abci_app' property, negative case.""" - self.round_sequence._abci_app = None - with pytest.raises(ABCIAppInternalError, match="AbciApp not set"): - self.round_sequence.abci_app - - def test_check_is_finished_negative(self) -> None: - """Test 'check_is_finished', negative case.""" - self.round_sequence.abci_app._current_round = None - with pytest.raises( - ValueError, - match="round sequence is finished, cannot accept new transactions", - ): - self.round_sequence.check_is_finished() - - def test_current_round_positive(self) -> None: - """Test 'current_round' property getter, positive case.""" - assert isinstance(self.round_sequence.current_round, ConcreteRoundA) - - def test_current_round_negative_current_round_not_set(self) -> None: - """Test 'current_round' property getter, negative case (current round not set).""" - self.round_sequence.abci_app._current_round = None - with pytest.raises(ValueError, match="current_round not set!"): - self.round_sequence.current_round - - def test_current_round_id(self) -> None: - """Test 'current_round_id' property getter""" - assert self.round_sequence.current_round_id == ConcreteRoundA.auto_round_id() - - def test_latest_result(self) -> None: - """Test 'latest_result' property getter.""" - assert self.round_sequence.latest_synchronized_data - - @pytest.mark.parametrize("committed", (True, False)) - def test_last_round_transition_timestamp(self, committed: bool) -> None: - """Test 'last_round_transition_timestamp' method.""" - if committed: - self.round_sequence.begin_block( - MagicMock(height=1), MagicMock(), MagicMock() - ) - self.round_sequence.end_block() - self.round_sequence.commit() - assert ( - self.round_sequence.last_round_transition_timestamp - == self.round_sequence._blockchain.last_block.timestamp - ) - else: - assert self.round_sequence._blockchain.height == 0 - with pytest.raises( - ValueError, - match="Trying to access `last_round_transition_timestamp` while no transition has been completed yet.", - ): - _ = self.round_sequence.last_round_transition_timestamp - - @pytest.mark.parametrize("committed", (True, False)) - def test_last_round_transition_height(self, committed: bool) -> None: - """Test 'last_round_transition_height' method.""" - if committed: - self.round_sequence.begin_block( - MagicMock(height=1), MagicMock(), MagicMock() - ) - self.round_sequence.end_block() - self.round_sequence.commit() - assert ( - self.round_sequence.last_round_transition_height - == self.round_sequence._blockchain.height - == 1 - ) - else: - assert self.round_sequence._blockchain.height == 0 - with pytest.raises( - ValueError, - match="Trying to access `last_round_transition_height` while no transition has been completed yet.", - ): - _ = self.round_sequence.last_round_transition_height - - def test_block_before_blockchain_is_init(self, caplog: LogCaptureFixture) -> None: - """Test block received before blockchain initialized.""" - - self.round_sequence.begin_block(MagicMock(height=1), MagicMock(), MagicMock()) - self.round_sequence.end_block() - blockchain = self.round_sequence.blockchain - blockchain._is_init = False - self.round_sequence.blockchain = blockchain - with caplog.at_level(logging.INFO): - self.round_sequence.commit() - expected = "Received block with height 1 before the blockchain was initialized." - assert expected in caplog.text - - @pytest.mark.parametrize("last_round_transition_root_hash", (b"", b"test")) - def test_last_round_transition_root_hash( - self, - last_round_transition_root_hash: bytes, - ) -> None: - """Test 'last_round_transition_root_hash' method.""" - self.round_sequence._last_round_transition_root_hash = ( - last_round_transition_root_hash - ) - - if last_round_transition_root_hash == b"": - with mock.patch.object( - RoundSequence, - "root_hash", - new_callable=mock.PropertyMock, - return_value="test", - ): - assert self.round_sequence.last_round_transition_root_hash == "test" - else: - assert ( - self.round_sequence.last_round_transition_root_hash - == last_round_transition_root_hash - ) - - @pytest.mark.parametrize("tm_height", (None, 1, 5)) - def test_last_round_transition_tm_height(self, tm_height: Optional[int]) -> None: - """Test 'last_round_transition_tm_height' method.""" - if tm_height is None: - with pytest.raises( - ValueError, - match="Trying to access Tendermint's last round transition height before any `end_block` calls.", - ): - _ = self.round_sequence.last_round_transition_tm_height - else: - self.round_sequence.tm_height = tm_height - self.round_sequence.begin_block( - MagicMock(height=1), MagicMock(), MagicMock() - ) - self.round_sequence.end_block() - self.round_sequence.commit() - assert self.round_sequence.last_round_transition_tm_height == tm_height - - @given(one_of(none(), integers())) - def test_tm_height(self, tm_height: int) -> None: - """Test `tm_height` getter and setter.""" - - self.round_sequence.tm_height = tm_height - - if tm_height is None: - with pytest.raises( - ValueError, - match="Trying to access Tendermint's current height before any `end_block` calls.", - ): - _ = self.round_sequence.tm_height - else: - assert ( - self.round_sequence.tm_height - == self.round_sequence._tm_height - == tm_height - ) - - @given(one_of(none(), datetimes())) - def test_block_stall_deadline_expired( - self, block_stall_deadline: datetime.datetime - ) -> None: - """Test 'block_stall_deadline_expired' method.""" - - self.round_sequence._block_stall_deadline = block_stall_deadline - actual = self.round_sequence.block_stall_deadline_expired - - if block_stall_deadline is None: - assert actual is False - else: - expected = datetime.datetime.now() > block_stall_deadline - assert actual is expected - - @pytest.mark.parametrize("begin_height", tuple(range(0, 50, 10))) - @pytest.mark.parametrize("initial_height", tuple(range(0, 11, 5))) - def test_init_chain(self, begin_height: int, initial_height: int) -> None: - """Test 'init_chain' method.""" - for i in range(begin_height): - self.round_sequence._blockchain.add_block( - MagicMock(header=MagicMock(height=i + 1)) - ) - assert self.round_sequence._blockchain.height == begin_height - self.round_sequence.init_chain(initial_height) - assert self.round_sequence._blockchain.height == initial_height - 1 - - @given(offence_tracking()) - @settings(suppress_health_check=[HealthCheck.too_slow]) - def test_track_tm_offences( - self, offences: Tuple[Evidences, LastCommitInfo] - ) -> None: - """Test `_track_tm_offences` method.""" - evidences, last_commit_info = offences - dummy_addr_template = "agent_{i}" - round_sequence = RoundSequence(context=MagicMock(), abci_app_cls=AbciAppTest) - synchronized_data_mock = MagicMock() - round_sequence.setup(synchronized_data_mock, MagicMock()) - round_sequence.enable_slashing() - - expected_offence_status = { - dummy_addr_template.format(i=i): OffenceStatus() - for i in range(len(last_commit_info.votes)) - } - for i, vote_info in enumerate(last_commit_info.votes): - agent_address = dummy_addr_template.format(i=i) - # initialize dummy round sequence's offence status and validator to agent address mapping - round_sequence._offence_status[agent_address] = OffenceStatus() - validator_address = vote_info.validator.address.hex() - round_sequence._validator_to_agent[validator_address] = agent_address - # set expected result - expected_was_down = not vote_info.signed_last_block - expected_offence_status[agent_address].validator_downtime.add( - expected_was_down - ) - - for byzantine_validator in evidences.byzantine_validators: - agent_address = round_sequence._validator_to_agent[ - byzantine_validator.validator.address.hex() - ] - evidence_type = byzantine_validator.evidence_type - expected_offence_status[agent_address].num_unknown_offenses += bool( - evidence_type == EvidenceType.UNKNOWN - ) - expected_offence_status[agent_address].num_double_signed += bool( - evidence_type == EvidenceType.DUPLICATE_VOTE - ) - expected_offence_status[agent_address].num_light_client_attack += bool( - evidence_type == EvidenceType.LIGHT_CLIENT_ATTACK - ) - - round_sequence._track_tm_offences(evidences, last_commit_info) - assert round_sequence._offence_status == expected_offence_status - - @mock.patch.object(abci_base, "ADDRESS_LENGTH", len("agent_i")) - def test_track_app_offences(self) -> None: - """Test `_track_app_offences` method.""" - dummy_addr_template = "agent_{i}" - stub_offending_keepers = [dummy_addr_template.format(i=i) for i in range(2)] - self.round_sequence.enable_slashing() - self.round_sequence._offence_status = { - dummy_addr_template.format(i=i): OffenceStatus() for i in range(4) - } - expected_offence_status = deepcopy(self.round_sequence._offence_status) - - for i in (dummy_addr_template.format(i=i) for i in range(4)): - offended = i in stub_offending_keepers - expected_offence_status[i].blacklisted.add(offended) - expected_offence_status[i].suspected.add(offended) - - with mock.patch.object( - self.round_sequence.latest_synchronized_data.db, - "get", - return_value="".join(stub_offending_keepers), - ): - self.round_sequence._track_app_offences() - assert self.round_sequence._offence_status == expected_offence_status - - @given(builds(SlashingNotConfiguredError, text())) - def test_handle_slashing_not_configured( - self, exc: SlashingNotConfiguredError - ) -> None: - """Test `_handle_slashing_not_configured` method.""" - logging.disable(logging.CRITICAL) - - round_sequence = RoundSequence(context=MagicMock(), abci_app_cls=AbciAppTest) - round_sequence.setup(MagicMock(), MagicMock()) - - assert not round_sequence._slashing_enabled - assert round_sequence.latest_synchronized_data.nb_participants == 0 - round_sequence._handle_slashing_not_configured(exc) - assert not round_sequence._slashing_enabled - - with mock.patch.object( - round_sequence.latest_synchronized_data.db, - "get", - return_value=[i for i in range(4)], - ): - assert round_sequence.latest_synchronized_data.nb_participants == 4 - round_sequence._handle_slashing_not_configured(exc) - assert not round_sequence._slashing_enabled - - logging.disable(logging.NOTSET) - - @pytest.mark.parametrize("_track_offences_raises", (True, False)) - def test_try_track_offences(self, _track_offences_raises: bool) -> None: - """Test `_try_track_offences` method.""" - evidences, last_commit_info = MagicMock(), MagicMock() - self.round_sequence.enable_slashing() - with mock.patch.object( - self.round_sequence, - "_track_app_offences", - ), mock.patch.object( - self.round_sequence, - "_track_tm_offences", - side_effect=SlashingNotConfiguredError if _track_offences_raises else None, - ) as _track_offences_mock, mock.patch.object( - self.round_sequence, "_handle_slashing_not_configured" - ) as _handle_slashing_not_configured_mock: - self.round_sequence._try_track_offences(evidences, last_commit_info) - if _track_offences_raises: - _handle_slashing_not_configured_mock.assert_called_once() - else: - _track_offences_mock.assert_called_once_with( - evidences, last_commit_info - ) - - def test_begin_block_negative_is_finished(self) -> None: - """Test 'begin_block' method, negative case (round sequence is finished).""" - self.round_sequence.abci_app._current_round = None - with pytest.raises( - ABCIAppInternalError, - match="internal error: round sequence is finished, cannot accept new blocks", - ): - self.round_sequence.begin_block(MagicMock(), MagicMock(), MagicMock()) - - def test_begin_block_negative_wrong_phase(self) -> None: - """Test 'begin_block' method, negative case (wrong phase).""" - self.round_sequence._block_construction_phase = MagicMock() - with pytest.raises( - ABCIAppInternalError, - match="internal error: cannot accept a 'begin_block' request.", - ): - self.round_sequence.begin_block(MagicMock(), MagicMock(), MagicMock()) - - def test_begin_block_positive(self) -> None: - """Test 'begin_block' method, positive case.""" - self.round_sequence.begin_block(MagicMock(), MagicMock(), MagicMock()) - - def test_deliver_tx_negative_wrong_phase(self) -> None: - """Test 'begin_block' method, negative (wrong phase).""" - with pytest.raises( - ABCIAppInternalError, - match="internal error: cannot accept a 'deliver_tx' request", - ): - self.round_sequence.deliver_tx(MagicMock()) - - def test_deliver_tx_positive_not_valid(self) -> None: - """Test 'begin_block' method, positive (not valid).""" - self.round_sequence.begin_block(MagicMock(), MagicMock(), MagicMock()) - with mock.patch.object( - self.round_sequence.current_round, "check_transaction", return_value=True - ): - with mock.patch.object( - self.round_sequence.current_round, "process_transaction" - ): - self.round_sequence.deliver_tx(MagicMock()) - - def test_end_block_negative_wrong_phase(self) -> None: - """Test 'end_block' method, negative case (wrong phase).""" - with pytest.raises( - ABCIAppInternalError, - match="internal error: cannot accept a 'end_block' request.", - ): - self.round_sequence.end_block() - - def test_end_block_positive(self) -> None: - """Test 'end_block' method, positive case.""" - self.round_sequence.begin_block(MagicMock(), MagicMock(), MagicMock()) - self.round_sequence.end_block() - - def test_commit_negative_wrong_phase(self) -> None: - """Test 'end_block' method, negative case (wrong phase).""" - with pytest.raises( - ABCIAppInternalError, - match="internal error: cannot accept a 'commit' request.", - ): - self.round_sequence.commit() - - def test_commit_negative_exception(self) -> None: - """Test 'end_block' method, negative case (raise exception).""" - self.round_sequence.begin_block(MagicMock(height=1), MagicMock(), MagicMock()) - self.round_sequence.end_block() - with mock.patch.object( - self.round_sequence._blockchain, "add_block", side_effect=AddBlockError - ): - with pytest.raises(AddBlockError): - self.round_sequence.commit() - - def test_commit_positive_no_change_round(self) -> None: - """Test 'end_block' method, positive (no change round).""" - self.round_sequence.begin_block(MagicMock(height=1), MagicMock(), MagicMock()) - self.round_sequence.end_block() - with mock.patch.object( - self.round_sequence.current_round, - "end_block", - return_value=None, - ): - assert isinstance(self.round_sequence.current_round, ConcreteRoundA) - - def test_commit_positive_with_change_round(self) -> None: - """Test 'end_block' method, positive (with change round).""" - self.round_sequence.begin_block(MagicMock(height=1), MagicMock(), MagicMock()) - self.round_sequence.end_block() - round_result, next_round = MagicMock(), MagicMock() - with mock.patch.object( - self.round_sequence.current_round, - "end_block", - return_value=(round_result, next_round), - ): - self.round_sequence.commit() - assert not isinstance( - self.round_sequence.abci_app._current_round, ConcreteRoundA - ) - assert self.round_sequence.latest_synchronized_data == round_result - - @pytest.mark.parametrize("is_replay", (True, False)) - def test_reset_blockchain(self, is_replay: bool) -> None: - """Test `reset_blockchain` method.""" - self.round_sequence.reset_blockchain(is_replay) - if is_replay: - assert ( - self.round_sequence._block_construction_phase - == RoundSequence._BlockConstructionState.WAITING_FOR_BEGIN_BLOCK - ) - assert self.round_sequence._blockchain.height == 0 - - def last_round_values_updated(self, any_: bool = True) -> bool: - """Check if the values for the last round-related attributes have been updated.""" - seq = self.round_sequence - - current_last_pairs = ( - ( - seq._blockchain.last_block.timestamp, - seq._last_round_transition_timestamp, - ), - (seq._blockchain.height, seq._last_round_transition_height), - (seq.root_hash, seq._last_round_transition_root_hash), - (seq.tm_height, seq._last_round_transition_tm_height), - ) - - if any_: - return any(current == last for current, last in current_last_pairs) - - return all(current == last for current, last in current_last_pairs) - - @mock.patch.object(AbciApp, "process_event") - @mock.patch.object(RoundSequence, "serialized_offence_status") - @pytest.mark.parametrize("end_block_res", (None, (MagicMock(), MagicMock()))) - @pytest.mark.parametrize( - "slashing_enabled, offence_status_", - ( - ( - False, - False, - ), - ( - False, - True, - ), - ( - False, - False, - ), - ( - True, - True, - ), - ), - ) - def test_update_round( - self, - serialized_offence_status_mock: mock.Mock, - process_event_mock: mock.Mock, - end_block_res: Optional[Tuple[BaseSynchronizedData, Any]], - slashing_enabled: bool, - offence_status_: dict, - ) -> None: - """Test '_update_round' method.""" - self.round_sequence.begin_block(MagicMock(height=1), MagicMock(), MagicMock()) - block = self.round_sequence._block_builder.get_block() - self.round_sequence._blockchain.add_block(block) - self.round_sequence._slashing_enabled = slashing_enabled - self.round_sequence._offence_status = offence_status_ - - with mock.patch.object( - self.round_sequence.current_round, "end_block", return_value=end_block_res - ): - self.round_sequence._update_round() - - if end_block_res is None: - assert not self.last_round_values_updated() - process_event_mock.assert_not_called() - return - - assert self.last_round_values_updated(any_=False) - process_event_mock.assert_called_with( - end_block_res[-1], result=end_block_res[0] - ) - - if slashing_enabled: - serialized_offence_status_mock.assert_called_once() - else: - serialized_offence_status_mock.assert_not_called() - - @mock.patch.object(AbciApp, "process_event") - @pytest.mark.parametrize( - "termination_round_result, current_round_result", - [ - (None, None), - (None, (MagicMock(), MagicMock())), - ((MagicMock(), MagicMock()), None), - ((MagicMock(), MagicMock()), (MagicMock(), MagicMock())), - ], - ) - def test_update_round_when_termination_returns( - self, - process_event_mock: mock.Mock, - termination_round_result: Optional[Tuple[BaseSynchronizedData, Any]], - current_round_result: Optional[Tuple[BaseSynchronizedData, Any]], - ) -> None: - """Test '_update_round' method.""" - self.round_sequence.begin_block(MagicMock(height=1), MagicMock(), MagicMock()) - block = self.round_sequence._block_builder.get_block() - self.round_sequence._blockchain.add_block(block) - self.round_sequence.abci_app.add_background_app(STUB_TERMINATION_CONFIG) - self.round_sequence.abci_app.setup() - - with mock.patch.object( - self.round_sequence.current_round, - "end_block", - return_value=current_round_result, - ), mock.patch.object( - ConcreteBackgroundRound, - "end_block", - return_value=termination_round_result, - ): - self.round_sequence._update_round() - - if termination_round_result is None and current_round_result is None: - assert ( - self.round_sequence._last_round_transition_timestamp - != self.round_sequence._blockchain.last_block.timestamp - ) - assert ( - self.round_sequence._last_round_transition_height - != self.round_sequence._blockchain.height - ) - assert ( - self.round_sequence._last_round_transition_root_hash - != self.round_sequence.root_hash - ) - assert ( - self.round_sequence._last_round_transition_tm_height - != self.round_sequence.tm_height - ) - process_event_mock.assert_not_called() - elif termination_round_result is None and current_round_result is not None: - assert ( - self.round_sequence._last_round_transition_timestamp - == self.round_sequence._blockchain.last_block.timestamp - ) - assert ( - self.round_sequence._last_round_transition_height - == self.round_sequence._blockchain.height - ) - assert ( - self.round_sequence._last_round_transition_root_hash - == self.round_sequence.root_hash - ) - assert ( - self.round_sequence._last_round_transition_tm_height - == self.round_sequence.tm_height - ) - process_event_mock.assert_called_with( - current_round_result[-1], - result=current_round_result[0], - ) - elif termination_round_result is not None: - assert ( - self.round_sequence._last_round_transition_timestamp - == self.round_sequence._blockchain.last_block.timestamp - ) - assert ( - self.round_sequence._last_round_transition_height - == self.round_sequence._blockchain.height - ) - assert ( - self.round_sequence._last_round_transition_root_hash - == self.round_sequence.root_hash - ) - assert ( - self.round_sequence._last_round_transition_tm_height - == self.round_sequence.tm_height - ) - process_event_mock.assert_called_with( - termination_round_result[-1], - result=termination_round_result[0], - ) - - self.round_sequence.abci_app.background_apps.clear() - - @pytest.mark.parametrize("restart_from_round", (ConcreteRoundA, MagicMock())) - @pytest.mark.parametrize("serialized_db_state", (None, "serialized state")) - @given(integers()) - def test_reset_state( - self, - restart_from_round: AbstractRound, - serialized_db_state: str, - round_count: int, - ) -> None: - """Tests reset_state""" - with mock.patch.object( - self.round_sequence, - "_reset_to_default_params", - ) as mock_reset, mock.patch.object( - self.round_sequence, "sync_db_and_slashing" - ) as mock_sync_db_and_slashing: - transition_fn = self.round_sequence.abci_app.transition_function - round_id = restart_from_round.auto_round_id() - if restart_from_round in transition_fn: - self.round_sequence.reset_state( - round_id, round_count, serialized_db_state - ) - mock_reset.assert_called() - - if serialized_db_state is None: - mock_sync_db_and_slashing.assert_not_called() - - else: - mock_sync_db_and_slashing.assert_called_once_with( - serialized_db_state - ) - assert ( - self.round_sequence._last_round_transition_root_hash - == self.round_sequence.root_hash - ) - - else: - round_ids = {cls.auto_round_id() for cls in transition_fn} - with pytest.raises( - ABCIAppInternalError, - match=re.escape( - "internal error: Cannot reset state. The Tendermint recovery parameters are incorrect. " - "Did you update the `restart_from_round` with an incorrect round id? " - f"Found {round_id}, but the app's transition function has the following round ids: " - f"{round_ids}.", - ), - ): - self.round_sequence.reset_state( - restart_from_round.auto_round_id(), - round_count, - serialized_db_state, - ) - - def test_reset_to_default_params(self) -> None: - """Tests _reset_to_default_params.""" - # we set some values to the parameters, to make sure that they are not "empty" - self.round_sequence._last_round_transition_timestamp = MagicMock() - self.round_sequence._last_round_transition_height = MagicMock() - self.round_sequence._last_round_transition_root_hash = MagicMock() - self.round_sequence._last_round_transition_tm_height = MagicMock() - self.round_sequence._tm_height = MagicMock() - self._pending_offences = MagicMock() - self._slashing_enabled = MagicMock() - - # we reset them - self.round_sequence._reset_to_default_params() - - # we check whether they have been reset - assert self.round_sequence._last_round_transition_timestamp is None - assert self.round_sequence._last_round_transition_height == 0 - assert self.round_sequence._last_round_transition_root_hash == b"" - assert self.round_sequence._last_round_transition_tm_height is None - assert self.round_sequence._tm_height is None - assert self.round_sequence.pending_offences == set() - assert not self.round_sequence._slashing_enabled - - def test_add_pending_offence(self) -> None: - """Tests add_pending_offence.""" - assert self.round_sequence.pending_offences == set() - mock_offence = MagicMock() - self.round_sequence.add_pending_offence(mock_offence) - assert self.round_sequence.pending_offences == {mock_offence} - - -def test_meta_abci_app_when_instance_not_subclass_of_abstract_round() -> None: - """ - Test instantiation of meta-class when instance not a subclass of AbciApp. - - Since the class is not a subclass of AbciApp, the checks performed by - the meta-class should not apply. - """ - - class MyAbciApp(metaclass=_MetaAbciApp): - pass - - -def test_meta_abci_app_when_final_round_not_subclass_of_degenerate_round() -> None: - """Test instantiation of meta-class when a final round is not a subclass of DegenerateRound.""" - - class FinalRound(AbstractRound, ABC): - """A round class for testing.""" - - payload_class = MagicMock() - synchronized_data_class = MagicMock() - payload_attribute = MagicMock() - round_id = "final_round" - - with pytest.raises( - AEAEnforceError, - match="non-final state.*must have at least one non-timeout transition", - ): - - class MyAbciApp(AbciApp, metaclass=_MetaAbciApp): - initial_round_cls: Type[AbstractRound] = ConcreteRoundA - transition_function: Dict[ - Type[AbstractRound], Dict[str, Type[AbstractRound]] - ] = { - ConcreteRoundA: {"event": FinalRound, "timeout": ConcreteRoundA}, - FinalRound: {}, - } - event_to_timeout = {"timeout": 1.0} - final_states: Set[AppState] = set() - - -def test_synchronized_data_type_on_abci_app_init(caplog: LogCaptureFixture) -> None: - """Test synchronized data access""" - - # NOTE: the synchronized data of a particular AbciApp is only - # updated at the end of a round. However, we want to make sure - # that the instance during the first round of any AbciApp is - # in fact and instance of the locally defined SynchronizedData - - sentinel = object() - - class SynchronizedData(BaseSynchronizedData): - """SynchronizedData""" - - @property - def dummy_attr(self) -> object: - return sentinel - - # this is how it's setup in SharedState.setup, using BaseSynchronizedData - synchronized_data = BaseSynchronizedData(db=AbciAppDB(setup_data={})) - - with mock.patch.object(AbciAppTest, "initial_round_cls") as m: - m.synchronized_data_class = SynchronizedData - abci_app = AbciAppTest(synchronized_data, logging.getLogger(), MagicMock()) - abci_app.setup() - assert isinstance(abci_app.synchronized_data, SynchronizedData) - assert abci_app.synchronized_data.dummy_attr == sentinel - - -def test_get_name() -> None: - """Test the get_name method.""" - - class SomeObject: - @property - def some_property(self) -> Any: - """Some getter.""" - return object() - - assert get_name(SomeObject.some_property) == "some_property" - with pytest.raises(ValueError, match="1 is not a property"): - get_name(1) - - -@pytest.mark.parametrize( - "sender, accused_agent_address, offense_round, offense_type_value, last_transition_timestamp, time_to_live, custom_amount", - ( - ( - "sender", - "test_address", - 90, - 3, - 10, - 2, - 10, - ), - ), -) -def test_pending_offences_payload( - sender: str, - accused_agent_address: str, - offense_round: int, - offense_type_value: int, - last_transition_timestamp: int, - time_to_live: int, - custom_amount: int, -) -> None: - """Test `PendingOffencesPayload`""" - - payload = abci_base.PendingOffencesPayload( - sender, - accused_agent_address, - offense_round, - offense_type_value, - last_transition_timestamp, - time_to_live, - custom_amount, - ) - - assert payload.id_ - assert payload.round_count == abci_base.ROUND_COUNT_DEFAULT - assert payload.sender == sender - assert payload.accused_agent_address == accused_agent_address - assert payload.offense_round == offense_round - assert payload.offense_type_value == offense_type_value - assert payload.last_transition_timestamp == last_transition_timestamp - assert payload.time_to_live == time_to_live - assert payload.custom_amount == custom_amount - assert payload.data == { - "accused_agent_address": accused_agent_address, - "offense_round": offense_round, - "offense_type_value": offense_type_value, - "last_transition_timestamp": last_transition_timestamp, - "time_to_live": time_to_live, - "custom_amount": custom_amount, - } - - -class TestPendingOffencesRound(BaseRoundTestClass): - """Tests for `PendingOffencesRound`.""" - - _synchronized_data_class = BaseSynchronizedData - - @given( - accused_agent_address=sampled_from(list(get_participants())), - offense_round=integers(min_value=0), - offense_type_value=sampled_from( - [value.value for value in OffenseType.__members__.values()] - ), - last_transition_timestamp=floats( - min_value=timegm(datetime.datetime(1971, 1, 1).utctimetuple()), - max_value=timegm(datetime.datetime(8000, 1, 1).utctimetuple()) - 2000, - ), - time_to_live=floats(min_value=1, max_value=2000), - custom_amount=integers(min_value=0), - ) - def test_run( - self, - accused_agent_address: str, - offense_round: int, - offense_type_value: int, - last_transition_timestamp: float, - time_to_live: float, - custom_amount: int, - ) -> None: - """Run tests.""" - - test_round = abci_base.PendingOffencesRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - # initialize the offence status - status_initialization = dict.fromkeys(self.participants, OffenceStatus()) - test_round.context.state.round_sequence.offence_status = status_initialization - - # create the actual and expected value - actual = test_round.context.state.round_sequence.offence_status - expected_invalid = offense_type_value == OffenseType.INVALID_PAYLOAD.value - expected_custom_amount = offense_type_value == OffenseType.CUSTOM.value - expected = deepcopy(status_initialization) - - first_payload, *payloads = [ - abci_base.PendingOffencesPayload( - sender, - accused_agent_address, - offense_round, - offense_type_value, - last_transition_timestamp, - time_to_live, - custom_amount, - ) - for sender in self.participants - ] - - test_round.process_payload(first_payload) - assert test_round.collection == {first_payload.sender: first_payload} - test_round.end_block() - assert actual == expected - - for payload in payloads: - test_round.process_payload(payload) - test_round.end_block() - - expected[accused_agent_address].invalid_payload.add(expected_invalid) - if expected_custom_amount: - expected[accused_agent_address].custom_offences_amount += custom_amount - - assert actual == expected diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_base_rounds.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_base_rounds.py deleted file mode 100644 index 06da2581f..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_base_rounds.py +++ /dev/null @@ -1,668 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the base round classes.""" - -# pylint: skip-file - -import re -from enum import Enum -from typing import FrozenSet, List, Optional, Tuple, Union, cast -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - BaseSynchronizedData, - BaseTxPayload, - TransactionNotValidError, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseOnlyKeeperSendsRoundTest, - DummyCollectDifferentUntilAllRound, - DummyCollectDifferentUntilThresholdRound, - DummyCollectNonEmptyUntilThresholdRound, - DummyCollectSameUntilAllRound, - DummyCollectSameUntilThresholdRound, - DummyCollectionRound, - DummyEvent, - DummyOnlyKeeperSendsRound, - DummyTxPayload, - DummyVotingRound, - MAX_PARTICIPANTS, - _BaseRoundTestClass, - get_dummy_tx_payloads, -) - - -class TestCollectionRound(_BaseRoundTestClass): - """Test class for CollectionRound.""" - - def setup( - self, - ) -> None: - """Setup test.""" - super().setup() - - self.test_round = DummyCollectionRound( - synchronized_data=self.synchronized_data, context=MagicMock() - ) - - def test_serialized_collection(self) -> None: - """Test `serialized_collection` property.""" - assert self.test_round.serialized_collection == {} - - for payload in self.tx_payloads: - self.test_round.process_payload(payload) - - mcs_key = "packages.valory.skills.abstract_round_abci.test_tools.rounds.DummyTxPayload" - expected = { - f"agent_{i}": { - "_metaclass_registry_key": mcs_key, - "id_": self.tx_payloads[i].id_, - "round_count": self.tx_payloads[i].round_count, - "sender": self.tx_payloads[i].sender, - "value": self.tx_payloads[i].value, - "vote": self.tx_payloads[i].vote, - } - for i in range(4) - } - - assert self.test_round.serialized_collection == expected - - def test_run( - self, - ) -> None: - """Run tests.""" - - round_id = DummyCollectionRound.auto_round_id() - - # collection round may set a flag to allow payments from inactive agents (rejoin) - assert self.test_round._allow_rejoin_payloads is False # default - assert ( - self.test_round.accepting_payloads_from - == self.synchronized_data.participants - ) - self.test_round._allow_rejoin_payloads = True - assert ( - self.test_round.accepting_payloads_from - == self.synchronized_data.all_participants - ) - - first_payload, *_ = self.tx_payloads - self.test_round.process_payload(first_payload) - assert self.test_round.collection[first_payload.sender] == first_payload - - with pytest.raises( - ABCIAppInternalError, - match=f"internal error: sender agent_0 has already sent value for round: {round_id}", - ): - self.test_round.process_payload(first_payload) - - with pytest.raises( - ABCIAppInternalError, - match=re.escape( - "internal error: sender not in list of participants: ['agent_0', 'agent_1', 'agent_2', 'agent_3']" - ), - ): - self.test_round.process_payload(DummyTxPayload("sender", "value")) - - with pytest.raises( - TransactionNotValidError, - match=f"sender agent_0 has already sent value for round: {round_id}", - ): - self.test_round.check_payload(first_payload) - - with pytest.raises( - TransactionNotValidError, - match=re.escape( - "sender not in list of participants: ['agent_0', 'agent_1', 'agent_2', 'agent_3']" - ), - ): - self.test_round.check_payload(DummyTxPayload("sender", "value")) - - self._test_payload_with_wrong_round_count(self.test_round) - - -class TestCollectDifferentUntilAllRound(_BaseRoundTestClass): - """Test class for CollectDifferentUntilAllRound.""" - - def test_run( - self, - ) -> None: - """Run Tests.""" - - test_round = DummyCollectDifferentUntilAllRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - round_id = DummyCollectDifferentUntilAllRound.auto_round_id() - - first_payload, *payloads = self.tx_payloads - test_round.process_payload(first_payload) - assert not test_round.collection_threshold_reached - - with pytest.raises( - ABCIAppInternalError, - match=f"internal error: sender agent_0 has already sent value for round: {round_id}", - ): - test_round.process_payload(first_payload) - - with pytest.raises( - TransactionNotValidError, - match=f"sender agent_0 has already sent value for round: {round_id}", - ): - test_round.check_payload(first_payload) - - with pytest.raises( - ABCIAppInternalError, - match="internal error: `CollectDifferentUntilAllRound` encountered a value '.*' that already exists.", - ): - object.__setattr__(first_payload, "sender", "other") - test_round.process_payload(first_payload) - - with pytest.raises( - TransactionNotValidError, - match="`CollectDifferentUntilAllRound` encountered a value '.*' that already exists.", - ): - test_round.check_payload(first_payload) - - for payload in payloads: - assert not test_round.collection_threshold_reached - test_round.process_payload(payload) - - assert test_round.collection_threshold_reached - self._test_payload_with_wrong_round_count(test_round) - - -class TestCollectSameUntilAllRound(_BaseRoundTestClass): - """Test class for CollectSameUntilAllRound.""" - - def test_run( - self, - ) -> None: - """Run Tests.""" - - test_round = DummyCollectSameUntilAllRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - round_id = DummyCollectSameUntilAllRound.auto_round_id() - - first_payload, *payloads = [ - DummyTxPayload( - sender=agent, - value="test", - ) - for agent in sorted(self.participants) - ] - test_round.process_payload(first_payload) - assert not test_round.collection_threshold_reached - - with pytest.raises( - ABCIAppInternalError, - match="1 votes are not enough for `CollectSameUntilAllRound`", - ): - assert test_round.common_payload - - with pytest.raises( - ABCIAppInternalError, - match=f"internal error: sender agent_0 has already sent value for round: {round_id}", - ): - test_round.process_payload(first_payload) - - with pytest.raises( - TransactionNotValidError, - match=f"sender agent_0 has already sent value for round: {round_id}", - ): - test_round.check_payload(first_payload) - - with pytest.raises( - ABCIAppInternalError, - match="internal error: `CollectSameUntilAllRound` encountered a value '.*' " - "which is not the same as the already existing one: '.*'", - ): - bad_payload = DummyTxPayload( - sender="other", - value="other", - ) - test_round.process_payload(bad_payload) - - with pytest.raises( - TransactionNotValidError, - match="`CollectSameUntilAllRound` encountered a value '.*' " - "which is not the same as the already existing one: '.*'", - ): - test_round.check_payload(bad_payload) - - for payload in payloads: - assert not test_round.collection_threshold_reached - test_round.process_payload(payload) - - assert test_round.collection_threshold_reached - assert test_round.common_payload - self._test_payload_with_wrong_round_count(test_round, "test") - - -class TestCollectSameUntilThresholdRound(_BaseRoundTestClass): - """Test CollectSameUntilThresholdRound.""" - - @pytest.mark.parametrize( - "selection_key", - ("dummy_selection_key", tuple(f"dummy_selection_key_{i}" for i in range(2))), - ) - def test_run( - self, - selection_key: Union[str, Tuple[str, ...]], - ) -> None: - """Run tests.""" - - test_round = DummyCollectSameUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - test_round.collection_key = "dummy_collection_key" - test_round.selection_key = selection_key - assert test_round.end_block() is None - - first_payload, *payloads = get_dummy_tx_payloads( - self.participants, value="vote" - ) - test_round.process_payload(first_payload) - - assert not test_round.threshold_reached - with pytest.raises(ABCIAppInternalError, match="not enough votes"): - _ = test_round.most_voted_payload - - for payload in payloads: - test_round.process_payload(payload) - - assert test_round.threshold_reached - assert test_round.most_voted_payload == "vote" - - self._test_payload_with_wrong_round_count(test_round) - - test_round.done_event = DummyEvent.DONE - return_value = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert return_value[-1] == test_round.done_event - - test_round.none_event = DummyEvent.NONE - test_round.collection.clear() - payloads = get_dummy_tx_payloads( - self.participants, value=None, is_value_none=True, is_vote_none=True - ) - for payload in payloads: - test_round.process_payload(payload) - assert test_round.most_voted_payload is None - return_value = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert return_value[-1] == test_round.none_event - - test_round.no_majority_event = DummyEvent.NO_MAJORITY - test_round.collection.clear() - for participant in self.participants: - payload = DummyTxPayload(participant, value=participant) - test_round.process_payload(payload) - return_value = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert return_value[-1] == test_round.no_majority_event - - def test_run_with_none( - self, - ) -> None: - """Run tests.""" - - test_round = DummyCollectSameUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - first_payload, *payloads = get_dummy_tx_payloads( - self.participants, - value=None, - is_value_none=True, - ) - test_round.process_payload(first_payload) - - assert not test_round.threshold_reached - with pytest.raises(ABCIAppInternalError, match="not enough votes"): - _ = test_round.most_voted_payload - - for payload in payloads: - test_round.process_payload(payload) - - assert test_round.threshold_reached - assert test_round.most_voted_payload is None - - -class TestOnlyKeeperSendsRound(_BaseRoundTestClass, BaseOnlyKeeperSendsRoundTest): - """Test OnlyKeeperSendsRound.""" - - @pytest.mark.parametrize( - "payload_key", ("dummy_key", tuple(f"dummy_key_{i}" for i in range(2))) - ) - def test_run( - self, - payload_key: Union[str, Tuple[str, ...]], - ) -> None: - """Run tests.""" - - test_round = DummyOnlyKeeperSendsRound( - synchronized_data=self.synchronized_data.update( - most_voted_keeper_address="agent_0" - ), - context=MagicMock(), - ) - - assert test_round.keeper_payload is None - first_payload, *_ = self.tx_payloads - test_round.process_payload(first_payload) - assert test_round.keeper_payload is not None - - with pytest.raises( - ABCIAppInternalError, - match="internal error: keeper already set the payload.", - ): - test_round.process_payload(first_payload) - - with pytest.raises( - ABCIAppInternalError, - match=re.escape( - "internal error: sender not in list of participants: ['agent_0', 'agent_1', 'agent_2', 'agent_3']" - ), - ): - test_round.process_payload(DummyTxPayload(sender="sender", value="sender")) - - with pytest.raises( - ABCIAppInternalError, match="internal error: agent_1 not elected as keeper." - ): - test_round.process_payload(DummyTxPayload(sender="agent_1", value="sender")) - - with pytest.raises( - TransactionNotValidError, match="keeper payload value already set." - ): - test_round.check_payload(first_payload) - - with pytest.raises( - TransactionNotValidError, - match=re.escape( - "sender not in list of participants: ['agent_0', 'agent_1', 'agent_2', 'agent_3']" - ), - ): - test_round.check_payload(DummyTxPayload(sender="sender", value="sender")) - - with pytest.raises( - TransactionNotValidError, match="agent_1 not elected as keeper." - ): - test_round.check_payload(DummyTxPayload(sender="agent_1", value="sender")) - - self._test_payload_with_wrong_round_count(test_round) - - test_round.done_event = DummyEvent.DONE - test_round.payload_key = payload_key - assert test_round.end_block() - - def test_keeper_payload_is_none( - self, - ) -> None: - """Test keeper payload valur set to none.""" - - keeper = "agent_0" - self._complete_run( - self._test_round( - test_round=DummyOnlyKeeperSendsRound( - synchronized_data=self.synchronized_data.update( - most_voted_keeper_address=keeper, - ), - context=MagicMock(), - ), - keeper_payloads=DummyTxPayload(keeper, None), - synchronized_data_update_fn=lambda _synchronized_data, _test_round: _synchronized_data, - synchronized_data_attr_checks=[], - exit_event="FAIL_EVENT", - ) - ) - - -class TestVotingRound(_BaseRoundTestClass): - """Test VotingRound.""" - - def setup_test_voting_round(self) -> DummyVotingRound: - """Setup test voting round""" - return DummyVotingRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - def test_vote_count(self) -> None: - """Testing agent vote count""" - test_round = self.setup_test_voting_round() - a, b, c, d = self.participants - for agents, vote in [((a, d), True), ((c,), False), ((b,), None)]: - for payload in get_dummy_tx_payloads(frozenset(agents), vote=vote): - test_round.process_payload(payload) - assert dict(test_round.vote_count) == {True: 2, False: 1, None: 1} - - self._test_payload_with_wrong_round_count(test_round) - - @pytest.mark.parametrize("vote", [True, False, None]) - def test_threshold(self, vote: Optional[bool]) -> None: - """Runs threshold test.""" - - test_round = self.setup_test_voting_round() - test_round.collection_key = "dummy_collection_key" - test_round.done_event = DummyEvent.DONE - test_round.negative_event = DummyEvent.NEGATIVE - test_round.none_event = DummyEvent.NONE - - expected_threshold = { - True: lambda: test_round.positive_vote_threshold_reached, - False: lambda: test_round.negative_vote_threshold_reached, - None: lambda: test_round.none_vote_threshold_reached, - }[vote] - - expected_event = { - True: test_round.done_event, - False: test_round.negative_event, - None: test_round.none_event, - }[vote] - - first_payload, *payloads = get_dummy_tx_payloads(self.participants, vote=vote) - test_round.process_payload(first_payload) - assert test_round.end_block() is None - assert not expected_threshold() - for payload in payloads: - test_round.process_payload(payload) - assert expected_threshold() - return_value = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert return_value[-1] == expected_event - - def test_end_round_no_majority(self) -> None: - """Test end round""" - - test_round = self.setup_test_voting_round() - test_round.no_majority_event = DummyEvent.NO_MAJORITY - for i, participant in enumerate(self.participants): - payload = DummyTxPayload(participant, value=participant, vote=bool(i % 2)) - test_round.process_payload(payload) - return_value = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert return_value[-1] == test_round.no_majority_event - - def test_invalid_vote_payload_count(self) -> None: - """Testing agent vote count with invalid payload.""" - test_round = self.setup_test_voting_round() - a, b, c, d = self.participants - - class InvalidPayload(BaseTxPayload): - """InvalidPayload""" - - def get_dummy_tx_payloads_( - participants: FrozenSet[str], - ) -> List[BaseTxPayload]: - """Returns a list of DummyTxPayload objects.""" - return [InvalidPayload(sender=agent) for agent in sorted(participants)] - - for agents in [(a, d), (c,), (b,)]: - for payload in get_dummy_tx_payloads_(frozenset(agents)): - test_round.process_payload(payload) - - with pytest.raises(ValueError): - test_round.vote_count - - -class TestCollectDifferentUntilThresholdRound(_BaseRoundTestClass): - """Test CollectDifferentUntilThresholdRound.""" - - @pytest.mark.parametrize( - "required_confirmations", (MAX_PARTICIPANTS, MAX_PARTICIPANTS + 1) - ) - def test_run( - self, - required_confirmations: int, - ) -> None: - """Run tests.""" - - test_round = DummyCollectDifferentUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - test_round.block_confirmations = 0 - test_round.required_block_confirmations = required_confirmations - test_round.collection_key = "collection_key" - test_round.done_event = 0 - assert ( - test_round.synchronized_data.consensus_threshold <= required_confirmations - ), "Incorrect test parametrization: required confirmations cannot be set with a smalled value than the consensus threshold" - - first_payload, *payloads = get_dummy_tx_payloads(self.participants, vote=False) - test_round.process_payload(first_payload) - - assert not test_round.collection_threshold_reached - for payload in payloads: - test_round.process_payload(payload) - res = test_round.end_block() - assert test_round.block_confirmations <= required_confirmations - assert res is None - assert test_round.collection_threshold_reached - payloads_since_consensus = 2 - confirmations_remaining = required_confirmations - payloads_since_consensus - for _ in range(confirmations_remaining): - res = test_round.end_block() - assert test_round.block_confirmations <= required_confirmations - assert res is None - - res = test_round.end_block() - assert test_round.block_confirmations > required_confirmations - assert res is not None - assert res[1] == test_round.done_event - - assert test_round.collection_threshold_reached - self._test_payload_with_wrong_round_count(test_round) - - def test_end_round(self) -> None: - """Test end round""" - - test_round = DummyCollectDifferentUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - test_round.collection_key = "dummy_collection_key" - test_round.done_event = DummyEvent.DONE - - assert test_round.end_block() is None - for participant in self.participants: - payload = DummyTxPayload(participant, value=participant) - test_round.process_payload(payload) - return_value = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert return_value[-1] == test_round.done_event - - -class TestCollectNonEmptyUntilThresholdRound(_BaseRoundTestClass): - """Test `CollectNonEmptyUntilThresholdRound`.""" - - def test_get_non_empty_values(self) -> None: - """Test `_get_non_empty_values`.""" - test_round = DummyCollectNonEmptyUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - payloads = get_dummy_tx_payloads(self.participants) - none_payload_idx = 3 - object.__setattr__(payloads[none_payload_idx], "value", None) - for payload in payloads: - test_round.process_payload(payload) - - non_empty_values = test_round._get_non_empty_values() - assert non_empty_values == { - tuple(sorted(self.participants))[i]: (f"agent_{i}", False) - if i != none_payload_idx - else (False,) - for i in range(4) - } - - self._test_payload_with_wrong_round_count(test_round) - - def test_process_payload(self) -> None: - """Test `process_payload`.""" - test_round = DummyCollectNonEmptyUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - first_payload, *payloads = get_dummy_tx_payloads(self.participants) - test_round.process_payload(first_payload) - - assert not test_round.collection_threshold_reached - for payload in payloads: - test_round.process_payload(payload) - - assert test_round.collection_threshold_reached - - @pytest.mark.parametrize( - "selection_key", - ("dummy_selection_key", tuple(f"dummy_selection_key_{i}" for i in range(2))), - ) - @pytest.mark.parametrize( - "is_value_none, expected_event", - ((True, DummyEvent.NONE), (False, DummyEvent.DONE)), - ) - def test_end_block( - self, - selection_key: Union[str, Tuple[str, ...]], - is_value_none: bool, - expected_event: str, - ) -> None: - """Test `end_block` when collection threshold is reached.""" - test_round = DummyCollectNonEmptyUntilThresholdRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - test_round.selection_key = selection_key - payloads = get_dummy_tx_payloads( - self.participants, is_value_none=is_value_none, is_vote_none=True - ) - for payload in payloads: - test_round.process_payload(payload) - - test_round.collection = {f"test_{i}": payloads[i] for i in range(len(payloads))} - test_round.collection_key = "test" - test_round.done_event = DummyEvent.DONE - test_round.none_event = DummyEvent.NONE - - res = cast(Tuple[BaseSynchronizedData, Enum], test_round.end_block()) - assert res[0].db == self.synchronized_data.db - assert res[1] == expected_event diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_behaviours.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_behaviours.py deleted file mode 100644 index 1065189c4..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_behaviours.py +++ /dev/null @@ -1,951 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the behaviours.py module of the skill.""" -# pylint: skip-file - -import platform -from abc import ABC -from calendar import timegm -from datetime import datetime -from pathlib import Path -from typing import Any, Dict, Generator, Optional, Tuple -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from hypothesis import given, settings -from hypothesis import strategies as st - -from packages.valory.skills.abstract_round_abci import PUBLIC_ID -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciApp, - AbstractRound, - BaseSynchronizedData, - BaseTxPayload, - DegenerateRound, - EventType, - OffenseType, - PendingOffense, - RoundSequence, -) -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - BaseBehaviour, - DegenerateBehaviour, - TmManager, -) -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - PendingOffencesBehaviour, - _MetaRoundBehaviour, -) -from packages.valory.skills.abstract_round_abci.models import TendermintRecoveryParams -from packages.valory.skills.abstract_round_abci.tests.conftest import profile_name - - -BEHAVIOUR_A_ID = "behaviour_a" -BEHAVIOUR_B_ID = "behaviour_b" -BEHAVIOUR_C_ID = "behaviour_c" -CONCRETE_BACKGROUND_BEHAVIOUR_ID = "background_behaviour" -ROUND_A_ID = "round_a" -ROUND_B_ID = "round_b" -CONCRETE_BACKGROUND_ROUND_ID = "background_round" - - -settings.load_profile(profile_name) - - -def test_skill_public_id() -> None: - """Test skill module public ID""" - - assert PUBLIC_ID.name == Path(__file__).parents[1].name - assert PUBLIC_ID.author == Path(__file__).parents[3].name - - -class RoundA(AbstractRound): - """Round A.""" - - round_id = ROUND_A_ID - payload_class = BaseTxPayload - payload_attribute = "" - synchronized_data_class = BaseSynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, EventType]]: - """End block.""" - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - - -class RoundB(AbstractRound): - """Round B.""" - - round_id = ROUND_B_ID - payload_class = BaseTxPayload - payload_attribute = "" - synchronized_data_class = BaseSynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, EventType]]: - """End block.""" - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - - -class ConcreteBackgroundRound(AbstractRound): - """Concrete Background Round.""" - - round_id = ROUND_B_ID - payload_class = BaseTxPayload - payload_attribute = "" - synchronized_data_class = BaseSynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, EventType]]: - """End block.""" - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - - -class BehaviourA(BaseBehaviour): - """Dummy behaviour.""" - - behaviour_id = BEHAVIOUR_A_ID - matching_round = RoundA - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize behaviour.""" - super().__init__(*args, **kwargs) - self.count = 0 - - def setup(self) -> None: - """Setup behaviour.""" - self.count += 1 - - def async_act(self) -> Generator: - """Dummy act method.""" - yield - - -class BehaviourB(BaseBehaviour): - """Dummy behaviour.""" - - behaviour_id = BEHAVIOUR_B_ID - matching_round = RoundB - - def async_act(self) -> Generator: - """Dummy act method.""" - yield - - -class BehaviourC(BaseBehaviour, ABC): - """Dummy behaviour.""" - - matching_round = MagicMock() - - -def test_auto_behaviour_id() -> None: - """Test that the 'auto_behaviour_id()' method works as expected.""" - - assert BehaviourB.auto_behaviour_id() == BEHAVIOUR_B_ID - assert BehaviourB.behaviour_id == BEHAVIOUR_B_ID - assert BehaviourC.auto_behaviour_id() == "behaviour_c" - assert isinstance(BehaviourC.behaviour_id, property) - - -class ConcreteBackgroundBehaviour(BaseBehaviour): - """Dummy behaviour.""" - - behaviour_id = CONCRETE_BACKGROUND_BEHAVIOUR_ID - matching_round = ConcreteBackgroundRound - - def async_act(self) -> Generator: - """Dummy act method.""" - yield - - -class ConcreteAbciApp(AbciApp): - """Concrete ABCI App.""" - - initial_round_cls = RoundA - transition_function = {RoundA: {MagicMock(): RoundB}} - event_to_timeout: Dict = {} - - -class ConcreteRoundBehaviour(AbstractRoundBehaviour): - """Concrete round behaviour.""" - - abci_app_cls = ConcreteAbciApp - behaviours = {BehaviourA, BehaviourB} # type: ignore - initial_behaviour_cls = BehaviourA - background_behaviours_cls = {ConcreteBackgroundBehaviour} # type: ignore - - -class TestAbstractRoundBehaviour: - """Test 'AbstractRoundBehaviour' class.""" - - def setup(self) -> None: - """Set up the tests.""" - self.round_sequence_mock = MagicMock() - context_mock = MagicMock(params=MagicMock()) - context_mock.state.round_sequence = self.round_sequence_mock - context_mock.state.round_sequence.syncing_up = False - self.round_sequence_mock.block_stall_deadline_expired = False - self.behaviour = ConcreteRoundBehaviour(name="", skill_context=context_mock) - - @pytest.mark.parametrize("use_termination", (True, False)) - def test_setup(self, use_termination: bool) -> None: - """Test 'setup' method.""" - assert self.behaviour.background_behaviours == set() - self.behaviour.context.params.use_termination = use_termination - self.behaviour.setup() - assert self.behaviour.background_behaviours_cls == {ConcreteBackgroundBehaviour} - assert ( - isinstance( - self.behaviour.background_behaviours.pop(), ConcreteBackgroundBehaviour - ) - if use_termination - else self.behaviour.background_behaviours == set() - ) - - def test_teardown(self) -> None: - """Test 'teardown' method.""" - self.behaviour.teardown() - - def test_current_behaviour_return_none(self) -> None: - """Test 'current_behaviour' property return None.""" - assert self.behaviour.current_behaviour is None - - def test_act_current_behaviour_name_is_none(self) -> None: - """Test 'act' with current behaviour None.""" - self.behaviour.tm_manager = self.behaviour.instantiate_behaviour_cls(TmManager) # type: ignore - self.behaviour.current_behaviour = None - with mock.patch.object(self.behaviour, "_process_current_round"): - self.behaviour.act() - - @pytest.mark.parametrize( - "no_round, error", - ( - ( - True, - "Behaviour 'behaviour_without_round' specifies unknown 'unknown' as a matching round. " - "Please make sure that the round is implemented and belongs to the FSM. " - "If 'behaviour_without_round' is a background behaviour, please make sure that it is set correctly, " - "by overriding the corresponding attribute of the chained skill's behaviour.", - ), - (False, "round round_1 is not a matching round of any behaviour"), - ), - ) - def test_check_matching_round_consistency_no_behaviour( - self, no_round: bool, error: str - ) -> None: - """Test classmethod '_check_matching_round_consistency', when no behaviour or round is specified.""" - rounds = [ - MagicMock(**{"auto_round_id.return_value": f"round_{i}"}) for i in range(3) - ] - mock_behaviours = [ - MagicMock(matching_round=round, behaviour_id=f"behaviour_{i}") - for i, round in enumerate(rounds[2:]) - ] - if no_round: - mock_behaviours.append( - MagicMock( - matching_round="unknown", behaviour_id="behaviour_without_round" - ) - ) - - with mock.patch.object( - _MetaRoundBehaviour, "_check_all_required_classattributes_are_set" - ), mock.patch.object( - _MetaRoundBehaviour, "_check_behaviour_id_uniqueness" - ), mock.patch.object( - _MetaRoundBehaviour, "_check_initial_behaviour_in_set_of_behaviours" - ), pytest.raises( - ABCIAppInternalError, - match=error, - ): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = MagicMock( - get_all_round_classes=lambda _, include_background_rounds: rounds, - final_states={ - rounds[0], - }, - ) - behaviours = mock_behaviours # type: ignore - initial_behaviour_cls = MagicMock() - - def test_check_matching_round_consistency(self) -> None: - """Test classmethod '_check_matching_round_consistency', negative case.""" - rounds = [ - MagicMock(**{"auto_round_id.return_value": f"round_{i}"}) for i in range(3) - ] - mock_behaviours = [ - MagicMock(matching_round=round, behaviour_id=f"behaviour_{i}") - for i, round in enumerate(rounds) - ] - - with mock.patch.object( - _MetaRoundBehaviour, "_check_all_required_classattributes_are_set" - ), mock.patch.object( - _MetaRoundBehaviour, "_check_behaviour_id_uniqueness" - ), mock.patch.object( - _MetaRoundBehaviour, "_check_initial_behaviour_in_set_of_behaviours" - ), pytest.raises( - ABCIAppInternalError, - match="internal error: round round_0 is a final round it shouldn't have any matching behaviours", - ): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = MagicMock( - get_all_round_classes=lambda _, include_background_rounds: rounds, - final_states={ - rounds[0], - }, - ) - behaviours = mock_behaviours # type: ignore - initial_behaviour_cls = MagicMock() - - @pytest.mark.parametrize("behaviour_cls", (set(), {MagicMock()})) - def test_check_matching_round_consistency_with_bg_rounds( - self, behaviour_cls: set - ) -> None: - """Test classmethod '_check_matching_round_consistency' when a background behaviour class is set.""" - rounds = [ - MagicMock(**{"auto_round_id.return_value": f"round_{i}"}) for i in range(3) - ] - mock_behaviours = ( - [ - MagicMock(matching_round=round_, behaviour_id=f"behaviour_{i}") - for i, round_ in enumerate(rounds[1:]) - ] - if behaviour_cls - else [] - ) - - with mock.patch.object( - _MetaRoundBehaviour, "_check_all_required_classattributes_are_set" - ), mock.patch.object( - _MetaRoundBehaviour, "_check_behaviour_id_uniqueness" - ), mock.patch.object( - _MetaRoundBehaviour, "_check_initial_behaviour_in_set_of_behaviours" - ): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = MagicMock( - get_all_round_classes=lambda _, include_background_rounds: rounds - if include_background_rounds - else [], - final_states={ - rounds[0], - } - if behaviour_cls - else {}, - ) - behaviours = mock_behaviours # type: ignore - initial_behaviour_cls = MagicMock() - background_behaviours_cls = behaviour_cls - - def test_get_behaviour_id_to_behaviour_mapping_negative(self) -> None: - """Test classmethod '_get_behaviour_id_to_behaviour_mapping', negative case.""" - behaviour_id = "behaviour_id" - behaviour_1 = MagicMock(**{"auto_behaviour_id.return_value": behaviour_id}) - behaviour_2 = MagicMock(**{"auto_behaviour_id.return_value": behaviour_id}) - - with pytest.raises( - ValueError, - match=f"cannot have two behaviours with the same id; got {behaviour_2} and {behaviour_1} both with id '{behaviour_id}'", - ): - with mock.patch.object(_MetaRoundBehaviour, "_check_consistency"): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = MagicMock - behaviours = [behaviour_1, behaviour_2] # type: ignore - initial_behaviour_cls = MagicMock() - - MyRoundBehaviour(name=MagicMock(), skill_context=MagicMock()) - - def test_get_round_to_behaviour_mapping_two_behaviours_same_round(self) -> None: - """Test classmethod '_get_round_to_behaviour_mapping' when two different behaviours point to the same round.""" - behaviour_id_1 = "behaviour_id_1" - behaviour_id_2 = "behaviour_id_2" - round_cls = RoundA - round_id = round_cls.auto_round_id() - behaviour_1 = MagicMock( - matching_round=round_cls, - **{"auto_behaviour_id.return_value": behaviour_id_1}, - ) - behaviour_2 = MagicMock( - matching_round=round_cls, - **{"auto_behaviour_id.return_value": behaviour_id_2}, - ) - - with pytest.raises( - ValueError, - match=f"the behaviours '{behaviour_2.auto_behaviour_id()}' and '{behaviour_1.auto_behaviour_id()}' point to the same matching round '{round_id}'", - ): - with mock.patch.object(_MetaRoundBehaviour, "_check_consistency"): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = ConcreteAbciApp - behaviours = [behaviour_1, behaviour_2] # type: ignore - initial_behaviour_cls = behaviour_1 - - MyRoundBehaviour(name=MagicMock(), skill_context=MagicMock()) - - def test_get_round_to_behaviour_mapping_with_final_rounds(self) -> None: - """Test classmethod '_get_round_to_behaviour_mapping' with final rounds.""" - - class FinalRound(DegenerateRound, ABC): - """A final round for testing.""" - - behaviour_id_1 = "behaviour_id_1" - behaviour_1 = MagicMock(behaviour_id=behaviour_id_1, matching_round=RoundA) - - class AbciAppTest(AbciApp): - """Abci App for testing.""" - - initial_round_cls = RoundA - transition_function = {RoundA: {MagicMock(): FinalRound}, FinalRound: {}} - event_to_timeout: Dict = {} - final_states = {FinalRound} - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = AbciAppTest - behaviours = {behaviour_1} - initial_behaviour_cls = behaviour_1 - matching_round = FinalRound - - behaviour = MyRoundBehaviour(name=MagicMock(), skill_context=MagicMock()) - final_behaviour = behaviour._round_to_behaviour[FinalRound] - assert issubclass(final_behaviour, DegenerateBehaviour) - assert ( - final_behaviour.auto_behaviour_id() - == f"degenerate_behaviour_{FinalRound.auto_round_id()}" - ) - - def test_check_behaviour_id_uniqueness_negative(self) -> None: - """Test metaclass method '_check_consistency', negative case.""" - behaviour_id = "behaviour_id" - behaviour_1_cls_name = "Behaviour1" - behaviour_2_cls_name = "Behaviour2" - behaviour_1 = MagicMock( - __name__=behaviour_1_cls_name, - **{"auto_behaviour_id.return_value": behaviour_id}, - ) - behaviour_2 = MagicMock( - __name__=behaviour_2_cls_name, - **{"auto_behaviour_id.return_value": behaviour_id}, - ) - - with pytest.raises( - ABCIAppInternalError, - match=rf"behaviours \['{behaviour_1_cls_name}', '{behaviour_2_cls_name}'\] have the same behaviour id '{behaviour_id}'", - ): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = MagicMock - behaviours = [behaviour_1, behaviour_2] # type: ignore - initial_behaviour_cls = MagicMock() - - def test_check_consistency_two_behaviours_same_round(self) -> None: - """Test metaclass method '_check_consistency' when two different behaviours point to the same round.""" - behaviour_id_1 = "behaviour_id_1" - behaviour_id_2 = "behaviour_id_2" - round_cls = RoundA - round_id = round_cls.auto_round_id() - behaviour_1 = MagicMock( - matching_round=round_cls, - **{"auto_behaviour_id.return_value": "behaviour_id_1"}, - ) - behaviour_2 = MagicMock( - matching_round=round_cls, - **{"auto_behaviour_id.return_value": "behaviour_id_2"}, - ) - - with pytest.raises( - ABCIAppInternalError, - match=rf"internal error: behaviours \['{behaviour_id_1}', '{behaviour_id_2}'\] have the same matching round '{round_id}'", - ): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = ConcreteAbciApp - behaviours = [behaviour_1, behaviour_2] # type: ignore - initial_behaviour_cls = behaviour_1 - - def test_check_initial_behaviour_in_set_of_behaviours_negative_case(self) -> None: - """Test classmethod '_check_initial_behaviour_in_set_of_behaviours' when initial behaviour is NOT in the set.""" - behaviour_1 = MagicMock( - matching_round=MagicMock(), - **{"auto_behaviour_id.return_value": "behaviour_id_1"}, - ) - behaviour_2 = MagicMock( - matching_round=MagicMock(), - **{"auto_behaviour_id.return_value": "behaviour_id_2"}, - ) - - with pytest.raises( - ABCIAppInternalError, - match=f"initial behaviour {behaviour_2.auto_behaviour_id()} is not in the set of behaviours", - ): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = ConcreteAbciApp - behaviours = {behaviour_1} - initial_behaviour_cls = behaviour_2 - - def test_act_no_round_change(self) -> None: - """Test the 'act' method of the behaviour, with no round change.""" - self.round_sequence_mock.current_round = RoundA(MagicMock(), MagicMock()) - self.round_sequence_mock.current_round_height = 0 - - # check that after setup(), current behaviour is initial behaviour - self.behaviour.setup() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - - with mock.patch.object( - self.behaviour.current_behaviour, "clean_up" - ) as clean_up_mock: - # check that after act(), current behaviour is initial behaviour and `clean_up()` has not been called - self.behaviour.act() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - clean_up_mock.assert_not_called() - - # check that once the flag done is set, the `clean_up()` has been called - # and `current_behaviour` is set to `None`. - self.behaviour.current_behaviour.set_done() - self.behaviour.act() - assert self.behaviour.current_behaviour is None - clean_up_mock.assert_called_once() - - def test_act_behaviour_setup(self) -> None: - """Test the 'act' method of the FSM behaviour triggers setup() of the behaviour.""" - self.round_sequence_mock.current_round = RoundA(MagicMock(), MagicMock()) - self.round_sequence_mock.current_round_height = 0 - - # check that after setup(), current behaviour is initial behaviour - self.behaviour.setup() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - - assert self.behaviour.current_behaviour.count == 0 - - with mock.patch.object( - self.behaviour.current_behaviour, "clean_up" - ) as clean_up_mock: - # check that after act() first time, a call to setup has been made - self.behaviour.act() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - assert self.behaviour.current_behaviour.count == 1 - - # check that after act() second time, no further call to setup - self.behaviour.act() - assert self.behaviour.current_behaviour.count == 1 - - # check that the `clean_up()` has not been called - clean_up_mock.assert_not_called() - - def test_act_with_round_change(self) -> None: - """Test the 'act' method of the behaviour, with round change.""" - self.round_sequence_mock.current_round = RoundA(MagicMock(), MagicMock()) - self.round_sequence_mock.current_round_height = 0 - - # check that after setup(), current behaviour is initial behaviour - self.behaviour.setup() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - - # check that after act(), current behaviour is initial behaviour - with mock.patch.object( - self.behaviour.current_behaviour, "clean_up" - ) as clean_up_mock: - self.behaviour.act() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - clean_up_mock.assert_not_called() - - # change the round - self.round_sequence_mock.current_round = RoundB(MagicMock(), MagicMock()) - self.round_sequence_mock.current_round_height = ( - self.round_sequence_mock.current_round_height + 1 - ) - - # check that if the round is changed, the behaviour transition is performed and the clean-up is called - self.behaviour.act() - assert isinstance(self.behaviour.current_behaviour, BehaviourB) - clean_up_mock.assert_called_once() - - def test_act_with_round_change_after_current_behaviour_is_none(self) -> None: - """Test the 'act' method of the behaviour, with round change, after cur behaviour is none.""" - self.behaviour.tm_manager = self.behaviour.instantiate_behaviour_cls(TmManager) # type: ignore - self.round_sequence_mock.current_round = RoundA(MagicMock(), MagicMock()) - self.round_sequence_mock.current_round_height = 0 - - # instantiate behaviour - self.behaviour.current_behaviour = self.behaviour.instantiate_behaviour_cls( - BehaviourA - ) - - with mock.patch.object( - self.behaviour.current_behaviour, "clean_up" - ) as clean_up_mock: - # check that after act(), current behaviour is same behaviour - self.behaviour.act() - assert isinstance(self.behaviour.current_behaviour, BehaviourA) - clean_up_mock.assert_not_called() - - # check that after the behaviour is done, current behaviour is None - self.behaviour.current_behaviour.set_done() - self.behaviour.act() - assert self.behaviour.current_behaviour is None - clean_up_mock.assert_called_once() - - # change the round - self.round_sequence_mock.current_round = RoundB(MagicMock(), MagicMock()) - self.round_sequence_mock.current_round_height = ( - self.round_sequence_mock.current_round_height + 1 - ) - - # check that if the round is changed, the behaviour transition is taken - self.behaviour.act() - assert isinstance(self.behaviour.current_behaviour, BehaviourB) - clean_up_mock.assert_called_once() - - @mock.patch.object( - AbstractRoundBehaviour, - "_process_current_round", - ) - @mock.patch.object( - TmManager, - "tm_communication_unhealthy", - new_callable=mock.PropertyMock, - return_value=False, - ) - @mock.patch.object( - TmManager, - "is_acting", - new_callable=mock.PropertyMock, - return_value=False, - ) - @pytest.mark.parametrize("expected_termination_acting", (True, False)) - def test_termination_behaviour_acting( - self, - _: mock._patch, - __: mock._patch, - ___: mock._patch, - expected_termination_acting: bool, - ) -> None: - """Test if the termination background behaviour is acting only when it should.""" - self.behaviour.context.params.use_termination = expected_termination_acting - self.behaviour.setup() - if expected_termination_acting: - with mock.patch.object( - ConcreteBackgroundBehaviour, - "act_wrapper", - ) as mock_background_act: - self.behaviour.act() - mock_background_act.assert_called() - else: - assert self.behaviour.background_behaviours == set() - - @mock.patch.object( - AbstractRoundBehaviour, - "_process_current_round", - ) - @pytest.mark.parametrize( - ("mock_tm_communication_unhealthy", "mock_is_acting", "expected_fix"), - [ - (True, True, True), - (False, True, True), - (True, False, True), - (False, False, False), - ], - ) - def test_try_fix_call( - self, - _: mock._patch, - mock_tm_communication_unhealthy: bool, - mock_is_acting: bool, - expected_fix: bool, - ) -> None: - """Test that `try_fix` is called when necessary.""" - self.behaviour.tm_manager = self.behaviour.instantiate_behaviour_cls(TmManager) # type: ignore - with mock.patch.object( - TmManager, - "tm_communication_unhealthy", - new_callable=mock.PropertyMock, - return_value=mock_tm_communication_unhealthy, - ), mock.patch.object( - TmManager, - "is_acting", - new_callable=mock.PropertyMock, - return_value=mock_is_acting, - ), mock.patch.object( - TmManager, - "try_fix", - ) as mock_try_fix: - self.behaviour.act() - if expected_fix: - mock_try_fix.assert_called() - else: - mock_try_fix.assert_not_called() - - -def test_meta_round_behaviour_when_instance_not_subclass_of_abstract_round_behaviour() -> ( - None -): - """Test instantiation of meta class when instance not a subclass of abstract round behaviour.""" - - class MyRoundBehaviour(metaclass=_MetaRoundBehaviour): - pass - - -def test_abstract_round_behaviour_instantiation_without_attributes_raises_error() -> ( - None -): - """Test that definition of concrete subclass of AbstractRoundBehavior without attributes raises error.""" - with pytest.raises(ABCIAppInternalError): - - class MyRoundBehaviour(AbstractRoundBehaviour): - pass - - -def test_abstract_round_behaviour_matching_rounds_not_covered() -> None: - """Test that definition of concrete subclass of AbstractRoundBehavior when matching round not covered.""" - with pytest.raises(ABCIAppInternalError): - - class MyRoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = ConcreteAbciApp - behaviours = {BehaviourA} - initial_behaviour_cls = BehaviourA - - -@mock.patch.object( - BaseBehaviour, - "tm_communication_unhealthy", - new_callable=mock.PropertyMock, - return_value=False, -) -def test_self_loops_in_abci_app_reinstantiate_behaviour(_: mock._patch) -> None: - """Test that a self-loop transition in the AbciApp will trigger a transition in the round behaviour.""" - event = MagicMock() - - class AbciAppTest(AbciApp): - initial_round_cls = RoundA - transition_function = {RoundA: {event: RoundA}} - - class RoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = AbciAppTest - behaviours = {BehaviourA} - initial_behaviour_cls = BehaviourA - - round_sequence = RoundSequence(MagicMock(), AbciAppTest) - round_sequence.end_sync() - round_sequence.setup(MagicMock(), MagicMock()) - context_mock = MagicMock() - context_mock.state.round_sequence = round_sequence - behaviour = RoundBehaviour(name="", skill_context=context_mock) - behaviour.setup() - - behaviour_1 = behaviour.current_behaviour - assert isinstance(behaviour_1, BehaviourA) - - round_sequence.abci_app.process_event(event) - - behaviour.act() - behaviour_2 = behaviour.current_behaviour - assert isinstance(behaviour_2, BehaviourA) - assert id(behaviour_1) != id(behaviour_2) - assert behaviour_1 != behaviour_2 - - -class LongRunningBehaviour(BaseBehaviour): - """A behaviour that runs forevever.""" - - behaviour_id = "long_running_behaviour" - matching_round = RoundA - - def async_act(self) -> Generator: - """An act method that simply cycles forever.""" - while True: - # cycle forever - yield - - -def test_reset_should_be_performed_when_tm_unhealthy() -> None: - """Test that hard reset is performed while a behaviour is running, and tendermint communication is unhealthy.""" - event = MagicMock() - - class AbciAppTest(AbciApp): - initial_round_cls = RoundA - transition_function = {RoundA: {event: RoundA}} - - class RoundBehaviour(AbstractRoundBehaviour): - abci_app_cls = AbciAppTest - behaviours = {LongRunningBehaviour} # type: ignore - initial_behaviour_cls = LongRunningBehaviour - - round_sequence = RoundSequence(MagicMock(), AbciAppTest) - round_sequence.end_sync() - round_sequence.setup(MagicMock(), MagicMock()) - context_mock = MagicMock() - context_mock.state.round_sequence = round_sequence - tm_recovery_params = TendermintRecoveryParams( - reset_from_round=RoundA.auto_round_id() - ) - context_mock.state.get_acn_result = MagicMock(return_value=tm_recovery_params) - context_mock.params.ipfs_domain_name = None - behaviour = RoundBehaviour(name="", skill_context=context_mock) - behaviour.setup() - - current_behaviour = behaviour.current_behaviour - assert isinstance(current_behaviour, LongRunningBehaviour) - - # upon entering the behaviour, the tendermint node communication is working well - with mock.patch.object( - RoundSequence, - "block_stall_deadline_expired", - new_callable=mock.PropertyMock, - return_value=False, - ): - behaviour.act() - - def dummy_num_peers( - timeout: Optional[float] = None, - ) -> Generator[None, None, Optional[int]]: - """A dummy method for num_active_peers.""" - # a None response is acceptable here, because tendermint is not healthy - return None - yield - - def dummy_reset_tendermint_with_wait( - on_startup: bool = False, - is_recovery: bool = False, - ) -> Generator[None, None, bool]: - """A dummy method for reset_tendermint_with_wait.""" - # we assume the reset goes through successfully - return True - yield - - # at this point LongRunningBehaviour is running - # while the behaviour is running, the tendermint node - # becomes unhealthy, we expect the node to be reset - with mock.patch.object( - RoundSequence, - "block_stall_deadline_expired", - new_callable=mock.PropertyMock, - return_value=True, - ), mock.patch.object( - BaseBehaviour, - "num_active_peers", - side_effect=dummy_num_peers, - ), mock.patch.object( - BaseBehaviour, - "reset_tendermint_with_wait", - side_effect=dummy_reset_tendermint_with_wait, - ) as mock_reset_tendermint: - behaviour.tm_manager.synchronized_data.max_participants = 3 # type: ignore - assert behaviour.tm_manager is not None - behaviour.tm_manager.gentle_reset_attempted = True - behaviour.act() - mock_reset_tendermint.assert_called() - - -class TestPendingOffencesBehaviour: - """Tests for `PendingOffencesBehaviour`.""" - - behaviour: PendingOffencesBehaviour - - @classmethod - def setup_class(cls) -> None: - """Setup the test class.""" - cls.behaviour = PendingOffencesBehaviour( - name="test", - skill_context=MagicMock(), - ) - - @pytest.mark.skipif( - platform.system() == "Windows", - reason="`timegm` behaves differently on Windows. " - "As a result, the generation of `last_transition_timestamp` is invalid.", - ) - @given( - offence=st.builds( - PendingOffense, - accused_agent_address=st.text(), - round_count=st.integers(min_value=0), - offense_type=st.sampled_from(OffenseType), - last_transition_timestamp=st.floats( - min_value=timegm(datetime(1971, 1, 1).utctimetuple()), - max_value=timegm(datetime(8000, 1, 1).utctimetuple()) - 2000, - ), - time_to_live=st.floats(min_value=1, max_value=2000), - ), - wait_ticks=st.integers(min_value=0, max_value=1000), - expired=st.booleans(), - ) - def test_pending_offences_act( - self, - offence: PendingOffense, - wait_ticks: int, - expired: bool, - ) -> None: - """Test `PendingOffencesBehaviour`.""" - offence_expiration = offence.last_transition_timestamp + offence.time_to_live - offence_expiration += 1 if expired else -1 - self.behaviour.round_sequence.last_round_transition_timestamp = datetime.fromtimestamp( # type: ignore - offence_expiration - ) - - gen = self.behaviour.async_act() - - with mock.patch.object( - self.behaviour, - "send_a2a_transaction", - ) as mock_send_a2a_transaction, mock.patch.object( - self.behaviour, - "wait_until_round_end", - ) as mock_wait_until_round_end, mock.patch.object( - self.behaviour, - "set_done", - ) as mock_set_done: - # while pending offences are empty, the behaviour simply waits - for _ in range(wait_ticks): - next(gen) - - self.behaviour.round_sequence.pending_offences = {offence} - - with pytest.raises(StopIteration): - next(gen) - - check = "assert_not_called" if expired else "assert_called_once" - - for mocked in ( - mock_send_a2a_transaction, - mock_wait_until_round_end, - mock_set_done, - ): - getattr(mocked, check)() diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_behaviours_utils.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_behaviours_utils.py deleted file mode 100644 index 1991586ac..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_behaviours_utils.py +++ /dev/null @@ -1,2681 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the behaviours_utils.py module of the skill.""" - -import json -import logging -import platform -import time -from abc import ABC -from datetime import datetime -from enum import Enum -from pathlib import Path -from typing import ( - Any, - Callable, - Dict, - Generator, - List, - Optional, - Tuple, - Type, - Union, - cast, -) -from unittest import mock -from unittest.mock import MagicMock - -import pytest -import pytz # pylint: disable=import-error -from _pytest.logging import LogCaptureFixture - -# pylint: skip-file -from aea.common import JSONLike -from aea.protocols.base import Message -from aea.test_tools.utils import as_context -from aea_test_autonomy.helpers.base import try_send -from hypothesis import given, settings -from hypothesis import strategies as st - -from packages.open_aea.protocols.signing import SigningMessage -from packages.valory.connections.http_client.connection import HttpDialogues -from packages.valory.connections.ipfs.connection import IpfsDialogues -from packages.valory.connections.ipfs.connection import PUBLIC_ID as IPFS_CONNECTION_ID -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.protocols.ipfs.dialogues import IpfsDialogue -from packages.valory.protocols.ledger_api.custom_types import ( - SignedTransaction, - SignedTransactions, - TransactionDigest, - TransactionDigests, -) -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.protocols.tendermint import TendermintMessage -from packages.valory.skills.abstract_round_abci import behaviour_utils -from packages.valory.skills.abstract_round_abci.base import ( - AbstractRound, - BaseSynchronizedData, - BaseTxPayload, - DegenerateRound, - LEDGER_API_ADDRESS, - OK_CODE, - Transaction, -) -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - AsyncBehaviour, - BaseBehaviour, - BaseBehaviourInternalError, - DegenerateBehaviour, - GENESIS_TIME_FMT, - INITIAL_HEIGHT, - IPFSBehaviour, - NON_200_RETURN_CODE_DURING_RESET_THRESHOLD, - RPCResponseStatus, - SendException, - TimeoutException, - TmManager, - _MetaBaseBehaviour, - make_degenerate_behaviour, -) -from packages.valory.skills.abstract_round_abci.io_.ipfs import ( - IPFSInteract, - IPFSInteractionError, -) -from packages.valory.skills.abstract_round_abci.models import ( - SharedState, - TendermintRecoveryParams, -) -from packages.valory.skills.abstract_round_abci.tests.conftest import profile_name - - -_DEFAULT_REQUEST_TIMEOUT = 10.0 -_DEFAULT_REQUEST_RETRY_DELAY = 1.0 -_DEFAULT_TX_MAX_ATTEMPTS = 10 -_DEFAULT_TX_TIMEOUT = 10.0 - -settings.load_profile(profile_name) - - -PACKAGE_DIR = Path(__file__).parent.parent - -# https://github.com/python/cpython/issues/94414 -# https://stackoverflow.com/questions/46133223/maximum-value-of-timestamp -# NOTE: timezone in behaviour_utils._get_reset_params set to UTC -# but hypothesis does not allow passing of the `tzinfo` argument -# hence we add and subtract a day from the actual min / max datetime -MIN_DATETIME_WINDOWS = datetime(1970, 1, 3, 1, 0, 0) -MAX_DATETIME_WINDOWS = datetime(3000, 12, 30, 23, 59, 59) - - -def mock_yield_and_return( - return_value: Any, -) -> Callable[[], Generator[None, None, Any]]: - """Wrapper for a Dummy generator that returns a `bool`.""" - - def yield_and_return(*_: Any, **__: Any) -> Generator[None, None, Any]: - """Dummy generator that returns a `bool`.""" - yield - return return_value - - return yield_and_return - - -def yield_and_return_bool_wrapper( - flag_value: bool, -) -> Callable[[], Generator[None, None, Optional[bool]]]: - """Wrapper for a Dummy generator that returns a `bool`.""" - - def yield_and_return_bool( - **_: bool, - ) -> Generator[None, None, Optional[bool]]: - """Dummy generator that returns a `bool`.""" - yield - return flag_value - - return yield_and_return_bool - - -def yield_and_return_int_wrapper( - value: Optional[int], -) -> Callable[[], Generator[None, None, Optional[int]]]: - """Wrapper for a Dummy generator that returns an `int`.""" - - def yield_and_return_int( - **_: int, - ) -> Generator[None, None, Optional[int]]: - """Dummy generator that returns an `int`.""" - yield - return value - - return yield_and_return_int - - -class AsyncBehaviourTest(AsyncBehaviour, ABC): - """Concrete AsyncBehaviour class for testing purposes.""" - - def async_act_wrapper(self) -> Generator: - """Do async act wrapper. Forwards to 'async_act'.""" - yield from self.async_act() - - def async_act(self) -> Generator: - """Do 'async_act'.""" - yield None - - -def test_async_behaviour_ticks() -> None: - """Test "AsyncBehaviour", only ticks.""" - - class MyAsyncBehaviour(AsyncBehaviourTest): - counter = 0 - - def async_act(self) -> Generator: - self.counter += 1 - yield - self.counter += 1 - yield - self.counter += 1 - - behaviour = MyAsyncBehaviour() - assert behaviour.counter == 0 - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - behaviour.act() - assert behaviour.counter == 2 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - behaviour.act() - assert behaviour.counter == 3 - assert behaviour.state == AsyncBehaviour.AsyncState.READY - - -def test_async_behaviour_wait_for_message() -> None: - """Test 'wait_for_message'.""" - - expected_message = "message" - - class MyAsyncBehaviour(AsyncBehaviourTest): - counter = 0 - message = None - - def async_act(self) -> Generator: - self.counter += 1 - self.message = yield from self.wait_for_message( - lambda message: message == expected_message - ) - self.counter += 1 - - behaviour = MyAsyncBehaviour() - assert behaviour.counter == 0 - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.WAITING_MESSAGE - - # another call to act doesn't change the state (still waiting for message) - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.WAITING_MESSAGE - - # sending a message that does not satisfy the condition won't change state - behaviour.try_send("wrong_message") - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.WAITING_MESSAGE - - # sending a message before it is processed raises an exception - behaviour.try_send("wrong_message") - with pytest.raises(SendException, match="cannot send message"): - behaviour.try_send("wrong_message") - behaviour.act() - - # sending the right message will transition to the next state, - # but only when calling act() - behaviour.try_send(expected_message) - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.WAITING_MESSAGE - behaviour.act() - assert behaviour.counter == 2 - assert behaviour.message == expected_message - assert behaviour.state == AsyncBehaviour.AsyncState.READY - - -def test_async_behaviour_wait_for_message_raises_timeout_exception() -> None: - """Test 'wait_for_message' when it raises TimeoutException.""" - - with pytest.raises(TimeoutException): - behaviour = AsyncBehaviourTest() - gen = behaviour.wait_for_message(lambda _: False, timeout=0.01) - # trigger function - try_send(gen) - # sleep so to run out the timeout - time.sleep(0.02) - # trigger function and make the exception to raise - try_send(gen) - - -def test_async_behaviour_wait_for_condition() -> None: - """Test 'wait_for_condition' method.""" - - condition = False - - class MyAsyncBehaviour(AsyncBehaviourTest): - counter = 0 - - def async_act(self) -> Generator: - self.counter += 1 - yield from self.wait_for_condition(lambda: condition) - self.counter += 1 - - behaviour = MyAsyncBehaviour() - assert behaviour.counter == 0 - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - - # if condition is false, execution remains at the same point - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - - # if condition is true, execution continues - condition = True - behaviour.act() - assert behaviour.counter == 2 - assert behaviour.state == AsyncBehaviour.AsyncState.READY - - -def test_async_behaviour_wait_for_condition_with_timeout() -> None: - """Test 'wait_for_condition' method with timeout expired.""" - - class MyAsyncBehaviour(AsyncBehaviourTest): - counter = 0 - - def async_act(self) -> Generator: - self.counter += 1 - yield from self.wait_for_condition(lambda: False, timeout=0.05) - - behaviour = MyAsyncBehaviour() - assert behaviour.counter == 0 - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - - # sleep so the timeout expires - time.sleep(0.1) - - # the next call to act raises TimeoutException - with pytest.raises(TimeoutException): - behaviour.act() - - -def test_async_behaviour_sleep() -> None: - """Test 'sleep' method.""" - - timedelta = 0.5 - - class MyAsyncBehaviour(AsyncBehaviourTest): - counter = 0 - first_datetime = None - last_datetime = None - - def async_act_wrapper(self) -> Generator: - yield from self.async_act() - - def async_act(self) -> Generator: - self.first_datetime = datetime.now() - self.counter += 1 - yield from self.sleep(timedelta) - self.counter += 1 - self.last_datetime = datetime.now() - - behaviour = MyAsyncBehaviour() - assert behaviour.counter == 0 - - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - - # calling 'act()' before the sleep interval will keep the behaviour in the same state - behaviour.act() - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - - # wait the sleep timeout, we give twice the amount of time it takes the behaviour - time.sleep(timedelta * 2) - - assert behaviour.counter == 1 - assert behaviour.state == AsyncBehaviour.AsyncState.RUNNING - behaviour.act() - assert behaviour.counter == 2 - assert behaviour.state == AsyncBehaviour.AsyncState.READY - assert behaviour.last_datetime is not None and behaviour.first_datetime is not None - assert ( - behaviour.last_datetime - behaviour.first_datetime - ).total_seconds() > timedelta - - -def test_async_behaviour_without_yield() -> None: - """Test AsyncBehaviour, async_act without yield/yield from.""" - - class MyAsyncBehaviour(AsyncBehaviourTest): - def async_act_wrapper(self) -> Generator: - return None # type: ignore # need to check design, not sure it's proper case with return None - - behaviour = MyAsyncBehaviour() - behaviour.act() - assert behaviour.state == AsyncBehaviour.AsyncState.READY - - -def test_async_behaviour_raise_stopiteration() -> None: - """Test AsyncBehaviour, async_act raising 'StopIteration'.""" - - class MyAsyncBehaviour(AsyncBehaviourTest): - def async_act_wrapper(self) -> Generator: - raise StopIteration - - behaviour = MyAsyncBehaviour() - behaviour.act() - assert behaviour.state == AsyncBehaviour.AsyncState.READY - - -def test_async_behaviour_stop() -> None: - """Test AsyncBehaviour.stop method.""" - - class MyAsyncBehaviour(AsyncBehaviourTest): - def async_act(self) -> Generator: - yield - - behaviour = MyAsyncBehaviour() - assert behaviour.is_stopped - behaviour.act() - assert not behaviour.is_stopped - behaviour.stop() - assert behaviour.is_stopped - behaviour.stop() - assert behaviour.is_stopped - - -class RoundA(AbstractRound): - """Concrete ABCI round.""" - - round_id = "round_a" - synchronized_data_class = BaseSynchronizedData - payload_class = MagicMock() - payload_attribute = MagicMock() - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Handle end block.""" - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check payload.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - - -class BehaviourATest(BaseBehaviour): - """Concrete BaseBehaviour class.""" - - matching_round: Type[RoundA] = RoundA - - def async_act(self) -> Generator: - """Do the 'async_act'.""" - yield None - - -def _get_status_patch_wrapper( - latest_block_height: int, - app_hash: str, -) -> Callable[[Any, Any], Generator[None, None, MagicMock]]: - """Wrapper for `_get_status` method patch.""" - - def _get_status_patch(*_: Any, **__: Any) -> Generator[None, None, MagicMock]: - """Patch `_get_status` method""" - yield - return MagicMock( - body=json.dumps( - { - "result": { - "sync_info": { - "latest_block_height": latest_block_height, - "latest_app_hash": app_hash, - } - } - } - ).encode() - ) - - return _get_status_patch - - -def _get_status_wrong_patch( - *args: Any, **kwargs: Any -) -> Generator[None, None, MagicMock]: - """Patch `_get_status` method""" - return MagicMock( - body=json.dumps({"result": {"sync_info": {"latest_block_height": -1}}}).encode() - ) - yield - - -def _wait_until_transaction_delivered_patch( - *args: Any, **kwargs: Any -) -> Generator[None, None, Tuple]: - """Patch `_wait_until_transaction_delivered` method""" - return False, HttpMessage( - performative=HttpMessage.Performative.RESPONSE, # type: ignore - body=json.dumps({"tx_result": {"info": "TransactionNotValidError"}}), - ) - yield - - -def dummy_generator_wrapper(return_value: Any = None) -> Callable[[Any], Generator]: - """A wrapper around a dummy generator that yields nothing and returns the given return value.""" - - def dummy_generator(*_: Any, **__: Any) -> Generator[None, None, Any]: - """A dummy generator that yields nothing and returns the given return value.""" - yield - return return_value - - return dummy_generator - - -class TestBaseBehaviour: - """Tests for the 'BaseBehaviour' class.""" - - _DUMMY_CONSENSUS_THRESHOLD = 3 - - def setup(self) -> None: - """Set up the tests.""" - self.context_mock = MagicMock() - self.context_params_mock = MagicMock( - request_timeout=_DEFAULT_REQUEST_TIMEOUT, - request_retry_delay=_DEFAULT_REQUEST_RETRY_DELAY, - tx_timeout=_DEFAULT_TX_TIMEOUT, - max_attempts=_DEFAULT_TX_MAX_ATTEMPTS, - ) - self.context_mock.shared_state = {} - self.context_state_synchronized_data_mock = MagicMock() - self.context_mock.params = self.context_params_mock - self.context_mock.state.synchronized_data = ( - self.context_state_synchronized_data_mock - ) - self.current_round_count = 10 - self.current_reset_index = 10 - self.context_mock.state.synchronized_data.db = MagicMock( - round_count=self.current_round_count, reset_index=self.current_reset_index - ) - self.context_mock.state.round_sequence.current_round_id = "round_a" - self.context_mock.state.round_sequence.syncing_up = False - self.context_mock.state.round_sequence.block_stall_deadline_expired = False - self.context_mock.http_dialogues = HttpDialogues() - self.context_mock.ipfs_dialogues = IpfsDialogues( - connection_id=str(IPFS_CONNECTION_ID) - ) - self.context_mock.outbox = MagicMock(put_message=self.dummy_put_message) - self.context_mock.requests = MagicMock(request_id_to_callback={}) - self.context_mock.handlers.__dict__ = {"http": MagicMock()} - self.behaviour = BehaviourATest(name="", skill_context=self.context_mock) - self.behaviour.context.logger = logging # type: ignore - self.behaviour.params.sleep_time = 0.01 # type: ignore - - def dummy_put_message(self, *args: Any, **kwargs: Any) -> None: - """A dummy implementation of Outbox.put_message""" - return - - def test_behaviour_id(self) -> None: - """Test behaviour_id on instance.""" - assert self.behaviour.behaviour_id == BehaviourATest.auto_behaviour_id() - - @pytest.mark.parametrize( - "ipfs_response, expected_log", - [ - ( - MagicMock( - ipfs_hash="test", performative=IpfsMessage.Performative.IPFS_HASH - ), - "Successfully stored dummy_filename to IPFS with hash: test", - ), - ( - MagicMock( - ipfs_hash="test", performative=IpfsMessage.Performative.ERROR - ), - f"Expected performative {IpfsMessage.Performative.IPFS_HASH} but got {IpfsMessage.Performative.ERROR}.", - ), - ], - ) - def test_send_to_ipfs( - self, - caplog: LogCaptureFixture, - ipfs_response: IpfsMessage, - expected_log: str, - ) -> None: - """Test send_to_ipfs""" - - def dummy_do_ipfs_req( - *args: Any, **kwargs: Any - ) -> Generator[None, None, Optional[IpfsMessage]]: - """A dummy method to be used in mocks.""" - return ipfs_response - yield - - with mock.patch.object( - IPFSBehaviour, - "_build_ipfs_store_file_req", - return_value=(MagicMock(), MagicMock()), - ) as build_req, mock.patch.object( - BaseBehaviour, "_do_ipfs_request", side_effect=dummy_do_ipfs_req - ) as do_req: - generator = self.behaviour.send_to_ipfs("dummy_filename", {}) - try_send(generator) - build_req.assert_called() - do_req.assert_called() - assert expected_log in caplog.text - - def test_ipfs_store_fails(self, caplog: LogCaptureFixture) -> None: - """Test for failure during building store_file_req.""" - expected_logs = "An error occurred while trying to send a file to IPFS:" - with mock.patch.object( - IPFSBehaviour, - "_build_ipfs_store_file_req", - side_effect=IPFSInteractionError, - ), caplog.at_level(logging.ERROR): - generator = self.behaviour.send_to_ipfs("dummy_filename", {}) - try_send(generator) - assert expected_logs in caplog.text - - def test_do_ipfs_request(self) -> None: - """Test _do_ipfs_request""" - message, dialogue = cast( - IpfsDialogues, self.context_mock.ipfs_dialogues - ).create(str(IPFS_CONNECTION_ID), IpfsMessage.Performative.GET_FILES) - message = cast(IpfsMessage, message) - dialogue = cast(IpfsDialogue, dialogue) - - def dummy_wait_for_message( - *args: Any, **kwargs: Any - ) -> Generator[None, None, Message]: - """A dummy implementation of AsyncBehaviour.wait_for_message to be used for mocks.""" - return MagicMock() - yield - - with mock.patch.object( - AsyncBehaviour, "wait_for_message", side_effect=dummy_wait_for_message - ): - gen = self.behaviour._do_ipfs_request( - dialogue, - message, - ) - try_send(gen) - - @pytest.mark.parametrize( - "ipfs_response, expected_log", - [ - ( - MagicMock( - files={"dummy_file_name": "test"}, - performative=IpfsMessage.Performative.FILES, - ), - "Retrieved 1 objects from ipfs.", - ), - ( - MagicMock( - ipfs_hash="test", performative=IpfsMessage.Performative.ERROR - ), - f"Expected performative {IpfsMessage.Performative.FILES} but got {IpfsMessage.Performative.ERROR}.", - ), - ], - ) - def test_get_from_ipfs( - self, - caplog: LogCaptureFixture, - ipfs_response: IpfsMessage, - expected_log: str, - ) -> None: - """Test get_from_ipfs""" - - def dummy_do_ipfs_req( - *args: Any, **kwargs: Any - ) -> Generator[None, None, Optional[IpfsMessage]]: - """A dummy method to be used in mocks.""" - return ipfs_response - yield - - with mock.patch.object( - IPFSBehaviour, - "_build_ipfs_get_file_req", - return_value=(MagicMock(), MagicMock()), - ) as build_req, mock.patch.object( - IPFSBehaviour, - "_deserialize_ipfs_objects", - return_value=MagicMock(), - ), mock.patch.object( - BaseBehaviour, "_do_ipfs_request", side_effect=dummy_do_ipfs_req - ) as do_req: - generator = self.behaviour.get_from_ipfs("dummy_ipfs_hash") - try_send(generator) - build_req.assert_called() - do_req.assert_called() - assert expected_log in caplog.text - - def test_ipfs_get_fails(self, caplog: LogCaptureFixture) -> None: - """Test for failure during building get_files req.""" - expected_logs = "An error occurred while trying to fetch a file from IPFS:" - with mock.patch.object( - IPFSBehaviour, "_build_ipfs_get_file_req", side_effect=IPFSInteractionError - ), caplog.at_level(logging.ERROR): - generator = self.behaviour.get_from_ipfs("dummy_ipfs_hash") - try_send(generator) - assert expected_logs in caplog.text - - def test_params_property(self) -> None: - """Test the 'params' property.""" - assert self.behaviour.params == self.context_params_mock - - def test_synchronized_data_property(self) -> None: - """Test the 'synchronized_data' property.""" - assert ( - self.behaviour.synchronized_data - == self.context_state_synchronized_data_mock - ) - - def test_check_in_round(self) -> None: - """Test 'BaseBehaviour' initialization.""" - expected_round_id = "round" - self.context_mock.state.round_sequence.current_round_id = expected_round_id - assert self.behaviour.check_in_round(expected_round_id) - assert not self.behaviour.check_in_round("wrong round") - - assert not self.behaviour.check_not_in_round(expected_round_id) - assert self.behaviour.check_not_in_round("wrong round") - - func = self.behaviour.is_round_ended(expected_round_id) - assert not func() - - def test_check_in_last_round(self) -> None: - """Test 'BaseBehaviour' initialization.""" - expected_round_id = "round" - self.context_mock.state.round_sequence.last_round_id = expected_round_id - assert self.behaviour.check_in_last_round(expected_round_id) - assert not self.behaviour.check_in_last_round("wrong round") - - assert not self.behaviour.check_not_in_last_round(expected_round_id) - assert self.behaviour.check_not_in_last_round("wrong round") - - assert self.behaviour.check_round_has_finished(expected_round_id) - - def test_check_round_height_has_changed(self) -> None: - """Test 'check_round_height_has_changed'.""" - current_height = 0 - self.context_mock.state.round_sequence.current_round_height = current_height - assert not self.behaviour.check_round_height_has_changed(current_height) - new_height = current_height + 1 - self.context_mock.state.round_sequence.current_round_height = new_height - assert self.behaviour.check_round_height_has_changed(current_height) - assert not self.behaviour.check_round_height_has_changed(new_height) - - def test_wait_until_round_end_negative_last_round_or_matching_round(self) -> None: - """Test 'wait_until_round_end' method, negative case (not in matching nor last round).""" - self.behaviour.context.state.round_sequence.current_round_id = ( - "current_round_id" - ) - self.behaviour.context.state.round_sequence.last_round_id = "last_round_id" - self.behaviour.matching_round.round_id = "matching_round" - generator = self.behaviour.wait_until_round_end() - with pytest.raises( - ValueError, - match=r"Should be in matching round \(matching_round\) or last round \(last_round_id\), actual round current_round_id!", - ): - generator.send(None) - - @mock.patch.object(BaseBehaviour, "wait_for_condition") - @mock.patch.object(BaseBehaviour, "check_not_in_round", return_value=False) - @mock.patch.object(BaseBehaviour, "check_not_in_last_round", return_value=False) - def test_wait_until_round_end_positive(self, *_: Any) -> None: - """Test 'wait_until_round_end' method, positive case.""" - gen = self.behaviour.wait_until_round_end() - try_send(gen) - - def test_wait_from_last_timestamp(self) -> None: - """Test 'wait_from_last_timestamp'.""" - timeout = 1.0 - last_timestamp = datetime.now() - self.behaviour.context.state.round_sequence.abci_app.last_timestamp = ( - last_timestamp - ) - gen = self.behaviour.wait_from_last_timestamp(timeout) - # trigger first execution - try_send(gen) - # at the time this line is executed, the generator is not empty - # as the timeout has not run out yet - try_send(gen) - # sleep enough time to make the timeout to run out - time.sleep(timeout) - # the next iteration of the generator raises StopIteration - # because its execution terminates - with pytest.raises(StopIteration): - gen.send(MagicMock()) - - def test_wait_from_last_timestamp_negative(self) -> None: - """Test 'wait_from_last_timestamp'.""" - timeout = -1.0 - last_timestamp = datetime.now() - self.behaviour.context.state.round_sequence.abci_app.last_timestamp = ( - last_timestamp - ) - with pytest.raises(ValueError): - gen = self.behaviour.wait_from_last_timestamp(timeout) - # trigger first execution - try_send(gen) - - def test_set_done(self) -> None: - """Test 'set_done' method.""" - assert not self.behaviour.is_done() - self.behaviour.set_done() - assert self.behaviour.is_done() - - @mock.patch.object(BaseBehaviour, "_send_transaction") - def test_send_a2a_transaction_positive(self, *_: Any) -> None: - """Test 'send_a2a_transaction' method, positive case.""" - gen = self.behaviour.send_a2a_transaction(MagicMock()) - try_send(gen) - - def test_async_act_wrapper_agent_sync_mode( - self, - ) -> None: - """Test 'async_act_wrapper' in sync mode.""" - self.behaviour.context.state.round_sequence.syncing_up = True - self.behaviour.context.state.round_sequence.height = 0 - self.behaviour.matching_round = MagicMock() - - with mock.patch.object(logging, "info") as log_mock, mock.patch.object( - BaseBehaviour, - "_get_status", - _get_status_patch_wrapper(0, "test"), - ): - gen = self.behaviour.async_act_wrapper() - for __ in range(3): - try_send(gen) - log_mock.assert_called_with( - "local height == remote == 0; Synchronization complete." - ) - - @mock.patch.object(BaseBehaviour, "_get_status", _get_status_wrong_patch) - def test_async_act_wrapper_agent_sync_mode_where_height_dont_match(self) -> None: - """Test 'async_act_wrapper' in sync mode.""" - self.behaviour.context.state.round_sequence.syncing_up = True - self.behaviour.context.state.round_sequence.height = 0 - self.behaviour.context.params.tendermint_check_sleep_delay = 3 - self.behaviour.matching_round = MagicMock() - - gen = self.behaviour.async_act_wrapper() - try_send(gen) - - @pytest.mark.parametrize("exception_cls", [StopIteration]) - def test_async_act_wrapper_exception(self, exception_cls: Exception) -> None: - """Test 'async_act_wrapper'.""" - with mock.patch.object(self.behaviour, "async_act", side_effect=exception_cls): - with mock.patch.object(self.behaviour, "clean_up") as clean_up_mock: - gen = self.behaviour.async_act_wrapper() - try_send(gen) - try_send(gen) - clean_up_mock.assert_called() - - def test_get_request_nonce_from_dialogue(self) -> None: - """Test '_get_request_nonce_from_dialogue' helper method.""" - dialogue_mock = MagicMock() - expected_value = "dialogue_reference" - dialogue_mock.dialogue_label.dialogue_reference = (expected_value, None) - result = BaseBehaviour._get_request_nonce_from_dialogue(dialogue_mock) - assert result == expected_value - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=False) - def test_send_transaction_stop_condition(self, *_: Any) -> None: - """Test '_send_transaction' method's `stop_condition` as provided by `send_a2a_transaction`.""" - request_retry_delay = 0.01 - # set the current round's id so that it does not meet the requirements for a `stop_condition` - self.behaviour.context.state.round_sequence.current_round_id = ( - self.behaviour.matching_round.round_id - ) = "round_a" - # assert that everything is pre-set correctly - assert ( - self.behaviour.context.state.round_sequence.current_round_id - == self.behaviour.matching_round.auto_round_id() - == "round_a" - ) - - # create the exact same stop condition that we create in the `send_a2a_transaction` method - stop_condition = self.behaviour.is_round_ended( - self.behaviour.matching_round.auto_round_id() - ) - gen = self.behaviour._send_transaction( - MagicMock(), - request_retry_delay=request_retry_delay, - stop_condition=stop_condition, - ) - # assert that the stop condition does not apply yet - assert not stop_condition() - # trigger the generator function so that we enter the `stop_condition` loop - try_send(gen) - - # set the current round's id so that it meets the requirements for a `stop_condition` - self.behaviour.context.state.round_sequence.current_round_id = "test" - - # assert that everything was set as expected - assert ( - self.behaviour.context.state.round_sequence.current_round_id - != self.behaviour.matching_round.auto_round_id() - and self.behaviour.context.state.round_sequence.current_round_id == "test" - ) - # assert that the stop condition now applies - assert stop_condition() - - # test with a non-200 response in order to cause the execution to re-enter the while `stop_condition` - # we expect that the second time we will not enter, since we have caused the `stop_condition` to be `True` - with mock.patch.object( - self.behaviour.context.logger, "debug" - ) as mock_debug, mock.patch.object( - self.behaviour.context.logger, "error" - ) as mock_error: - # send message to 'wait_for_message' - try_send(gen, obj=MagicMock(status_code=200)) - # send message to '_submit_tx' - response = MagicMock(body='{"result": {"hash": "", "code": 0}}') - try_send(gen, obj=response) - mock_error.assert_called_with( - f"Received return code != 200 with response {response} with body {str(response.body)}. " - f"Retrying in {request_retry_delay} seconds..." - ) - time.sleep(request_retry_delay) - try_send(gen) - # assert that the stop condition is now `True` and we reach at the end of the method - mock_debug.assert_called_with( - "Stop condition is true, no more attempts to send the transaction." - ) - - def test_send_transaction_positive_false_condition(self) -> None: - """Test '_send_transaction', positive case (false condition)""" - with mock.patch.object(self.behaviour.context.logger, "debug") as mock_debug: - try_send( - self.behaviour._send_transaction( - MagicMock(), stop_condition=lambda: True - ) - ) - mock_debug.assert_called_with( - "Stop condition is true, no more attempts to send the transaction." - ) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - def test_send_transaction_positive(self, *_: Any) -> None: - """Test '_send_transaction', positive case.""" - m = MagicMock(status_code=200) - gen = self.behaviour._send_transaction(m) - # trigger generator function - try_send(gen, obj=None) - # send message to 'wait_for_message' - try_send(gen, obj=m) - # send message to '_submit_tx' - try_send(gen, obj=MagicMock(body='{"result": {"hash": "", "code": 0}}')) - # send message to '_wait_until_transaction_delivered' - success_response = MagicMock( - status_code=200, body='{"result": {"tx_result": {"code": 0}}}' - ) - try_send(gen, obj=success_response) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - @mock.patch.object( - BaseBehaviour, - "_wait_until_transaction_delivered", - new=_wait_until_transaction_delivered_patch, - ) - def test_send_transaction_invalid_transaction(self, *_: Any) -> None: - """Test '_send_transaction', positive case.""" - m = MagicMock(status_code=200) - gen = self.behaviour._send_transaction(m) - try_send(gen, obj=None) - try_send(gen, obj=m) - try_send(gen, obj=MagicMock(body='{"result": {"hash": "", "code": 0}}')) - success_response = MagicMock( - status_code=200, body='{"result": {"tx_result": {"code": 0}}}' - ) - try_send(gen, obj=success_response) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(BaseBehaviour, "_is_invalid_transaction", return_value=False) - @mock.patch.object(BaseBehaviour, "_tx_not_found", return_value=True) - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - @mock.patch.object( - BaseBehaviour, - "_wait_until_transaction_delivered", - new=_wait_until_transaction_delivered_patch, - ) - def test_send_transaction_valid_transaction(self, *_: Any) -> None: - """Test '_send_transaction', positive case.""" - m = MagicMock(status_code=200) - gen = self.behaviour._send_transaction(m) - try_send(gen, obj=None) - try_send(gen, obj=m) - try_send(gen, obj=MagicMock(body='{"result": {"hash": "", "code": 0}}')) - success_response = MagicMock( - status_code=200, body='{"result": {"tx_result": {"code": 0}}}' - ) - try_send(gen, obj=success_response) - - def test_tx_not_found(self, *_: Any) -> None: - """Test _tx_not_found""" - res = MagicMock( - body='{"error": {"code": "dummy_code", "message": "dummy_message", "data": "dummy_data"}}' - ) - self.behaviour._tx_not_found(tx_hash="tx_hash", res=res) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - def test_send_transaction_signing_error(self, *_: Any) -> None: - """Test '_send_transaction', signing error.""" - m = MagicMock(performative=SigningMessage.Performative.ERROR) - gen = self.behaviour._send_transaction(m) - # trigger generator function - try_send(gen, obj=None) - with pytest.raises(RuntimeError): - try_send(gen, obj=m) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - def test_send_transaction_timeout_exception_submit_tx(self, *_: Any) -> None: - """Test '_send_transaction', timeout exception.""" - timeout = 0.05 - delay = 0.1 - m = MagicMock() - with mock.patch.object( - self.behaviour.context.logger, "warning" - ) as mock_warning: - gen = self.behaviour._send_transaction( - m, request_timeout=timeout, request_retry_delay=delay - ) - # trigger generator function - try_send(gen, obj=None) - try_send(gen, obj=m) - time.sleep(timeout) - try_send(gen, obj=m) - time.sleep(delay) - mock_warning.assert_called_with( - f"Timeout expired for submit tx. Retrying in {delay} seconds..." - ) - try_send(gen, obj=None) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - def test_send_transaction_timeout_exception_wait_until_transaction_delivered( - self, *_: Any - ) -> None: - """Test '_send_transaction', timeout exception.""" - timeout = 0.05 - delay = 0.1 - m = MagicMock() - with mock.patch.object( - self.behaviour.context.logger, "warning" - ) as mock_warning: - gen = self.behaviour._send_transaction( - m, request_retry_delay=delay, tx_timeout=timeout - ) - # trigger generator function - try_send(gen, obj=None) - # send message to 'wait_for_message' - try_send(gen, obj=m) - # send message to '_submit_tx' - try_send(gen, obj=MagicMock(body='{"result": {"hash": "", "code": 0}}')) - # send message to '_wait_until_transaction_delivered' - time.sleep(timeout) - try_send(gen, obj=m) - - mock_warning.assert_called_with( - f"Timeout expired for wait until transaction delivered. Retrying in {delay} seconds..." - ) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - def test_send_transaction_transaction_not_delivered(self, *_: Any) -> None: - """Test '_send_transaction', timeout exception.""" - timeout = 0.05 - delay = 0.1 - m = MagicMock() - with mock.patch.object( - self.behaviour.context.logger, "warning" - ) as mock_warning: - gen = self.behaviour._send_transaction( - m, request_retry_delay=delay, tx_timeout=timeout, max_attempts=0 - ) - # trigger generator function - try_send(gen, obj=None) - # send message to 'wait_for_message' - try_send(gen, obj=m) - # send message to '_submit_tx' - try_send(gen, obj=MagicMock(body='{"result": {"hash": "", "code": 0}}')) - # send message to '_wait_until_transaction_delivered' - time.sleep(timeout) - try_send(gen, obj=m) - - mock_warning.assert_called_with( - "Tx sent but not delivered. Response = None" - ) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - def test_send_transaction_wrong_ok_code(self, *_: Any) -> None: - """Test '_send_transaction', positive case.""" - m = MagicMock(status_code=200) - gen = self.behaviour._send_transaction(m) - - with mock.patch.object(self.behaviour.context.logger, "error") as mock_error: - # trigger generator function - try_send(gen, obj=None) - # send message to 'wait_for_message' - try_send(gen, obj=m) - # send message to '_submit_tx' - try_send(gen, obj=MagicMock(body='{"result": {"hash": "", "code": -1}}')) - # send message to '_wait_until_transaction_delivered' - success_response = MagicMock( - status_code=200, body='{"result": {"tx_result": {"code": 0}}}' - ) - try_send(gen, obj=success_response) - - mock_error.assert_called_with( - "Received tendermint code != 0. Retrying in 1.0 seconds..." - ) - - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object( - BaseBehaviour, - "_check_http_return_code_200", - return_value=True, - ) - @mock.patch("json.loads", return_value={"result": {"hash": "", "code": OK_CODE}}) - def test_send_transaction_wait_delivery_timeout_exception(self, *_: Any) -> None: - """Test '_send_transaction', timeout exception on tx delivery.""" - timeout = 0.05 - delay = 0.1 - m = MagicMock() - with mock.patch.object( - self.behaviour.context.logger, "warning" - ) as mock_warning: - gen = self.behaviour._send_transaction( - m, - request_timeout=timeout, - request_retry_delay=delay, - tx_timeout=timeout, - ) - # trigger generator function - try_send(gen, obj=None) - try_send(gen, obj=m) - try_send(gen, obj=m) - time.sleep(timeout) - try_send(gen, obj=m) - mock_warning.assert_called_with( - f"Timeout expired for wait until transaction delivered. Retrying in {delay} seconds..." - ) - time.sleep(delay) - try_send(gen, obj=m) - - @pytest.mark.parametrize("resetting", (True, False)) - @pytest.mark.parametrize( - "non_200_count", - ( - 0, - NON_200_RETURN_CODE_DURING_RESET_THRESHOLD, - NON_200_RETURN_CODE_DURING_RESET_THRESHOLD + 1, - ), - ) - @mock.patch.object(BaseBehaviour, "_send_signing_request") - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch("json.loads") - def test_send_transaction_error_status_code( - self, _: Any, __: Any, ___: Any, ____: Any, resetting: bool, non_200_count: int - ) -> None: - """Test '_send_transaction', error status code.""" - delay = 0.1 - self.behaviour._non_200_return_code_count = non_200_count - m = MagicMock() - with mock.patch.object(self.behaviour.context.logger, "error") as mock_error: - gen = self.behaviour._send_transaction( - m, resetting, request_retry_delay=delay - ) - # trigger generator function - try_send(gen, obj=None) - try_send(gen, obj=m) - # send message to '_submit_tx' - res = MagicMock(body="{'test': 'test'}") - try_send(gen, obj=res) - if ( - resetting - and non_200_count <= NON_200_RETURN_CODE_DURING_RESET_THRESHOLD - ): - mock_error.assert_not_called() - else: - mock_error.assert_called_with( - f"Received return code != 200 with response {res} with body {str(res.body)}. " - f"Retrying in {delay} seconds..." - ) - time.sleep(delay) - try_send(gen, obj=None) - - @mock.patch.object(BaseBehaviour, "_get_request_nonce_from_dialogue") - @mock.patch.object(behaviour_utils, "RawMessage") - @mock.patch.object(behaviour_utils, "Terms") - def test_send_signing_request(self, *_: Any) -> None: - """Test '_send_signing_request'.""" - with mock.patch.object( - self.behaviour.context.signing_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ): - self.behaviour._send_signing_request(b"") - - @given(st.binary()) - def test_fuzz_send_signing_request(self, input_bytes: bytes) -> None: - """Fuzz '_send_signing_request'. - - Mock context manager decorators don't work here. - - :param input_bytes: fuzz input - """ - with mock.patch.object( - self.behaviour.context.signing_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ): - with mock.patch.object(behaviour_utils, "RawMessage"): - with mock.patch.object(behaviour_utils, "Terms"): - self.behaviour._send_signing_request(input_bytes) - - @mock.patch.object(BaseBehaviour, "_get_request_nonce_from_dialogue") - @mock.patch.object(behaviour_utils, "RawMessage") - @mock.patch.object(behaviour_utils, "Terms") - def test_send_transaction_signing_request(self, *_: Any) -> None: - """Test '_send_signing_request'.""" - with mock.patch.object( - self.behaviour.context.signing_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ): - self.behaviour._send_transaction_signing_request(MagicMock(), MagicMock()) - - @pytest.mark.parametrize( - "use_flashbots, target_block_numbers, expected_kwargs", - ( - ( - True, - None, - dict( - counterparty=LEDGER_API_ADDRESS, - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS, - signed_transactions=SignedTransactions( - ledger_id="ethereum_flashbots", - signed_transactions=[{"test_tx": "test_tx"}], - ), - kwargs=LedgerApiMessage.Kwargs( - { - "chain_id": None, - "raise_on_failed_simulation": False, - "use_all_builders": True, - } - ), - ), - ), - ( - True, - [1, 2, 3], - dict( - counterparty=LEDGER_API_ADDRESS, - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTIONS, - signed_transactions=SignedTransactions( - ledger_id="ethereum_flashbots", - signed_transactions=[{"test_tx": "test_tx"}], - ), - kwargs=LedgerApiMessage.Kwargs( - { - "chain_id": None, - "raise_on_failed_simulation": False, - "use_all_builders": True, - "target_block_numbers": [1, 2, 3], - } - ), - ), - ), - ( - False, - None, - dict( - counterparty=LEDGER_API_ADDRESS, - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION, - signed_transaction=SignedTransaction( - ledger_id="ethereum", body={"test_tx": "test_tx"} - ), - ), - ), - ), - ) - def test_send_transaction_request( - self, - use_flashbots: bool, - target_block_numbers: Optional[List[int]], - expected_kwargs: Any, - ) -> None: - """Test '_send_transaction_request'.""" - with mock.patch.object( - self.behaviour.context.ledger_api_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ) as create_mock: - self.behaviour._send_transaction_request( - MagicMock( - signed_transaction=SignedTransaction( - ledger_id="ethereum", body={"test_tx": "test_tx"} - ) - ), - use_flashbots, - target_block_numbers, - ) - create_mock.assert_called_once() - # not using `create_mock.call_args.kwargs` because it is not compatible with Python 3.7 - actual_kwargs = create_mock.call_args[1] - assert actual_kwargs == expected_kwargs - - def test_send_transaction_receipt_request(self) -> None: - """Test '_send_transaction_receipt_request'.""" - with mock.patch.object( - self.behaviour.context.ledger_api_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ): - self.behaviour.context.default_ledger_id = "default_ledger_id" - self.behaviour._send_transaction_receipt_request("digest") - - def test_build_http_request_message(self, *_: Any) -> None: - """Test '_build_http_request_message'.""" - with mock.patch.object( - self.behaviour.context.http_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ): - self.behaviour._build_http_request_message( - "", - "", - parameters={"foo": "bar"}, - headers={"foo": "foo_val", "bar": "bar_val"}, - ) - - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - @mock.patch.object(BaseBehaviour, "sleep") - @mock.patch("json.loads") - def test_wait_until_transaction_delivered(self, *_: Any) -> None: - """Test '_wait_until_transaction_delivered' method.""" - gen = self.behaviour._wait_until_transaction_delivered(MagicMock()) - # trigger generator function - try_send(gen, obj=None) - - # first check attempt fails - failure_response = MagicMock(status_code=500) - try_send(gen, failure_response) - - # second check attempt succeeds - success_response = MagicMock( - status_code=200, body='{"result": {"tx_result": {"code": 0}}}' - ) - try_send(gen, success_response) - - @mock.patch.object(Transaction, "encode", return_value=MagicMock()) - @mock.patch.object( - BaseBehaviour, - "_build_http_request_message", - return_value=(MagicMock(), MagicMock()), - ) - @mock.patch.object(BaseBehaviour, "_check_http_return_code_200", return_value=True) - @mock.patch.object(BaseBehaviour, "sleep") - @mock.patch("json.loads") - def test_wait_until_transaction_delivered_failed(self, *_: Any) -> None: - """Test '_wait_until_transaction_delivered' method.""" - gen = self.behaviour._wait_until_transaction_delivered( - MagicMock(), max_attempts=0 - ) - # trigger generator function - try_send(gen, obj=None) - - # first check attempt fails - failure_response = MagicMock(status_code=500) - try_send(gen, failure_response) - - # second check attempt succeeds - success_response = MagicMock( - status_code=200, body='{"result": {"tx_result": {"code": -1}}}' - ) - try_send(gen, success_response) - - @pytest.mark.skipif( - platform.system() == "Windows", - reason="https://github.com/valory-xyz/open-autonomy/issues/1477", - ) - def test_wait_until_transaction_delivered_raises_timeout(self, *_: Any) -> None: - """Test '_wait_until_transaction_delivered' method.""" - gen = self.behaviour._wait_until_transaction_delivered(MagicMock(), timeout=0.0) - with pytest.raises(TimeoutException): - # trigger generator function - try_send(gen, obj=None) - - @mock.patch.object(behaviour_utils, "Terms") - def test_get_default_terms(self, *_: Any) -> None: - """Test '_get_default_terms'.""" - self.behaviour._get_default_terms() - - @mock.patch.object(BaseBehaviour, "_send_transaction_signing_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_receipt_request") - @mock.patch.object(behaviour_utils, "Terms") - @pytest.mark.parametrize( - "ledger_message, expected_hash, expected_response_status", - ( - ( - LedgerApiMessage( - cast( - LedgerApiMessage.Performative, - LedgerApiMessage.Performative.TRANSACTION_DIGEST, - ), - ("", ""), - transaction_digest=TransactionDigest("ledger_id", body="test"), - ), - "test", - RPCResponseStatus.SUCCESS, - ), - ( - LedgerApiMessage( - cast( - LedgerApiMessage.Performative, - LedgerApiMessage.Performative.TRANSACTION_DIGESTS, - ), - ("", ""), - # Only the first hash will be considered - # because we do not support sending multiple messages and receiving multiple tx hashes yet - transaction_digests=TransactionDigests( - "ledger_id", - transaction_digests=["test", "will_not_be_considered"], - ), - ), - "test", - RPCResponseStatus.SUCCESS, - ), - ), - ) - def test_send_raw_transaction( - self, - _send_transaction_signing_request: Any, - _send_transaction_request: Any, - _send_transaction_receipt_request: Any, - _terms: Any, - ledger_message: LedgerApiMessage, - expected_hash: str, - expected_response_status: RPCResponseStatus, - ) -> None: - """Test 'send_raw_transaction'.""" - m = MagicMock() - gen = self.behaviour.send_raw_transaction(m) - # trigger generator function - gen.send(None) - gen.send( - SigningMessage( - cast( - SigningMessage.Performative, - SigningMessage.Performative.SIGNED_TRANSACTION, - ), - ("", ""), - signed_transaction=SignedTransaction( - "ledger_id", body={"hash": expected_hash} - ), - ) - ) - try: - gen.send(ledger_message) - raise ValueError("Generator was expected to have reached its end!") - except StopIteration as e: - tx_hash, status = e.value - - assert tx_hash == expected_hash - assert status == expected_response_status - - @mock.patch.object(BaseBehaviour, "_send_transaction_signing_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_receipt_request") - @mock.patch.object(behaviour_utils, "Terms") - def test_send_raw_transaction_with_wrong_signing_performative( - self, *_: Any - ) -> None: - """Test 'send_raw_transaction'.""" - m = MagicMock() - gen = self.behaviour.send_raw_transaction(m) - # trigger generator function - gen.send(None) - try: - gen.send(MagicMock(performative=SigningMessage.Performative.ERROR)) - raise ValueError("Generator was expected to have reached its end!") - except StopIteration as e: - tx_hash, status = e.value - - assert tx_hash is None - assert status == RPCResponseStatus.UNCLASSIFIED_ERROR - - @pytest.mark.parametrize( - "message, expected_rpc_status", - ( - ("Simulation failed for bundle", RPCResponseStatus.SIMULATION_FAILED), - ("replacement transaction underpriced", RPCResponseStatus.UNDERPRICED), - ("nonce too low", RPCResponseStatus.INCORRECT_NONCE), - ("insufficient funds", RPCResponseStatus.INSUFFICIENT_FUNDS), - ("already known", RPCResponseStatus.ALREADY_KNOWN), - ("test", RPCResponseStatus.UNCLASSIFIED_ERROR), - ), - ) - @mock.patch.object(BaseBehaviour, "_send_transaction_signing_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_receipt_request") - @mock.patch.object(behaviour_utils, "Terms") - def test_send_raw_transaction_errors( - self, - _: Any, - __: Any, - ___: Any, - ____: Any, - message: str, - expected_rpc_status: RPCResponseStatus, - ) -> None: - """Test 'send_raw_transaction'.""" - m = MagicMock() - gen = self.behaviour.send_raw_transaction(m) - # trigger generator function - gen.send(None) - gen.send( - SigningMessage( - cast( - SigningMessage.Performative, - SigningMessage.Performative.SIGNED_TRANSACTION, - ), - ("", ""), - signed_transaction=SignedTransaction( - "ledger_id", body={"hash": "test"} - ), - ) - ) - try: - gen.send( - LedgerApiMessage( - cast( - LedgerApiMessage.Performative, - LedgerApiMessage.Performative.ERROR, - ), - ("", ""), - message=message, - ) - ) - raise ValueError("Generator was expected to have reached its end!") - except StopIteration as e: - tx_hash, status = e.value - - assert tx_hash == "test" - assert status == expected_rpc_status - - @mock.patch.object(BaseBehaviour, "_send_transaction_signing_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_request") - @mock.patch.object(BaseBehaviour, "_send_transaction_receipt_request") - @mock.patch.object(behaviour_utils, "Terms") - def test_send_raw_transaction_hashes_mismatch(self, *_: Any) -> None: - """Test 'send_raw_transaction' when signature and tx responses' hashes mismatch.""" - m = MagicMock() - gen = self.behaviour.send_raw_transaction(m) - # trigger generator function - gen.send(None) - gen.send( - SigningMessage( - cast( - SigningMessage.Performative, - SigningMessage.Performative.SIGNED_TRANSACTION, - ), - ("", ""), - signed_transaction=SignedTransaction( - "ledger_id", body={"hash": "signed"} - ), - ) - ) - try: - gen.send( - LedgerApiMessage( - cast( - LedgerApiMessage.Performative, - LedgerApiMessage.Performative.TRANSACTION_DIGEST, - ), - ("", ""), - transaction_digest=TransactionDigest("ledger_id", body="tx"), - ) - ) - raise ValueError("Generator was expected to have reached its end!") - except StopIteration as e: - tx_hash, status = e.value - - assert tx_hash is None - assert status == RPCResponseStatus.UNCLASSIFIED_ERROR - - def test_get_transaction_receipt(self, caplog: LogCaptureFixture) -> None: - """Test get_transaction_receipt.""" - - expected: JSONLike = {"dummy": "tx_receipt"} - transaction_receipt = LedgerApiMessage.TransactionReceipt("", expected, {}) - tx_receipt_message = LedgerApiMessage( - LedgerApiMessage.Performative.TRANSACTION_RECEIPT, # type: ignore - transaction_receipt=transaction_receipt, - ) - side_effect = mock_yield_and_return(tx_receipt_message) - with as_context( - mock.patch.object(self.behaviour, "_send_transaction_receipt_request"), - mock.patch.object( - self.behaviour, "wait_for_message", side_effect=side_effect - ), - ): - gen = self.behaviour.get_transaction_receipt("tx_digest") - try: - while True: - next(gen) - except StopIteration as e: - assert e.value == expected - - def test_get_transaction_receipt_error(self, caplog: LogCaptureFixture) -> None: - """Test get_transaction_receipt with error performative.""" - - error_message = LedgerApiMessage(LedgerApiMessage.Performative.ERROR, code=0) # type: ignore - side_effect = mock_yield_and_return(error_message) - with as_context( - mock.patch.object(self.behaviour, "_send_transaction_receipt_request"), - mock.patch.object( - self.behaviour, "wait_for_message", side_effect=side_effect - ), - ): - gen = self.behaviour.get_transaction_receipt("tx_digest") - try_send(gen) - try_send(gen) - assert "Error when requesting transaction receipt" in caplog.text - - @pytest.mark.parametrize("contract_address", [None, "contract_address"]) - def test_get_contract_api_response(self, contract_address: Optional[str]) -> None: - """Test 'get_contract_api_response'.""" - with mock.patch.object( - self.behaviour.context.contract_api_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ), mock.patch.object(behaviour_utils, "Terms"), mock.patch.object( - BaseBehaviour, "_send_transaction_signing_request" - ), mock.patch.object( - BaseBehaviour, "_send_transaction_request" - ): - gen = self.behaviour.get_contract_api_response( - MagicMock(), contract_address, "contract_id", "contract_callable" - ) - # first trigger - try_send(gen, obj=None) - # wait for message - try_send(gen, obj=MagicMock()) - - @mock.patch.object( - BaseBehaviour, "_build_http_request_message", return_value=(None, None) - ) - def test_get_status(self, _: mock.Mock) -> None: - """Test '_get_status'.""" - expected_result = json.dumps("Test result.").encode() - - def dummy_do_request(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_do_request` method.""" - yield - return mock.MagicMock(body=expected_result) - - with mock.patch.object( - BaseBehaviour, "_do_request", side_effect=dummy_do_request - ): - get_status_generator = self.behaviour._get_status() - next(get_status_generator) - with pytest.raises(StopIteration) as e: - next(get_status_generator) - res = e.value.args[0] - assert isinstance(res, MagicMock) - assert res.body == expected_result - - def test_get_netinfo(self) -> None: - """Test _get_netinfo method""" - dummy_res = { - "result": { - "n_peers": "1", - } - } - expected_result = json.dumps(dummy_res).encode() - - def dummy_do_request(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_do_request` method.""" - yield - return mock.MagicMock(body=expected_result) - - with mock.patch.object( - BaseBehaviour, "_do_request", side_effect=dummy_do_request - ): - get_netinfo_generator = self.behaviour._get_netinfo() - next(get_netinfo_generator) - with pytest.raises(StopIteration) as e: - next(get_netinfo_generator) - res = e.value.args[0] - assert isinstance(res, MagicMock) - assert res.body == expected_result - - @pytest.mark.parametrize( - ("num_peers", "expected_num_peers", "netinfo_status_code"), - [ - ("0", 1, 200), - ("0", None, 500), - ("0", None, None), - (None, None, 200), - ], - ) - def test_num_active_peers( - self, - num_peers: Optional[str], - expected_num_peers: Optional[int], - netinfo_status_code: Optional[int], - ) -> None: - """Test num_active_peers.""" - dummy_res = { - "result": { - "n_peers": num_peers, - } - } - - def dummy_get_netinfo(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_get_netinfo` method.""" - yield - - if netinfo_status_code is None: - raise TimeoutException() - - return mock.MagicMock( - status_code=netinfo_status_code, - body=json.dumps(dummy_res).encode(), - ) - - with mock.patch.object( - BaseBehaviour, - "_get_netinfo", - side_effect=dummy_get_netinfo, - ): - num_active_peers_generator = self.behaviour.num_active_peers() - next(num_active_peers_generator) - with pytest.raises(StopIteration) as e: - next(num_active_peers_generator) - actual_num_peers = e.value.value - assert actual_num_peers == expected_num_peers - - def test_default_callback_request_stopped(self) -> None: - """Test 'default_callback_request' when stopped.""" - message = MagicMock() - current_behaviour = self.behaviour - with mock.patch.object(self.behaviour.context.logger, "debug") as debug_mock: - self.behaviour.get_callback_request()(message, current_behaviour) - debug_mock.assert_called_with( - "Dropping message as behaviour has stopped: %s", message - ) - - def test_default_callback_late_arriving_message(self, *_: Any) -> None: - """Test 'default_callback_request' when a message arrives late.""" - self.behaviour._AsyncBehaviour__stopped = False - message = MagicMock() - current_behaviour = MagicMock() - with mock.patch.object(self.behaviour.context.logger, "warning") as info_mock: - self.behaviour.get_callback_request()(message, current_behaviour) - info_mock.assert_called_with( - "No callback defined for request with nonce: " - f"{message.dialogue_reference.__getitem__()}, " - f"arriving for behaviour: {self.behaviour.behaviour_id}" - ) - - def test_default_callback_request_waiting_message(self, *_: Any) -> None: - """Test 'default_callback_request' when waiting message.""" - self.behaviour._AsyncBehaviour__stopped = False # type: ignore - self.behaviour._AsyncBehaviour__state = ( # type: ignore - AsyncBehaviour.AsyncState.WAITING_MESSAGE - ) - message = MagicMock() - current_behaviour = self.behaviour - self.behaviour.get_callback_request()(message, current_behaviour) - - def test_default_callback_request_else(self, *_: Any) -> None: - """Test 'default_callback_request' else branch.""" - self.behaviour._AsyncBehaviour__stopped = False # type: ignore - message = MagicMock() - current_behaviour = self.behaviour - with mock.patch.object( - self.behaviour.context.logger, "warning" - ) as warning_mock: - self.behaviour.get_callback_request()(message, current_behaviour) - warning_mock.assert_called_with( - "Could not send message to FSMBehaviour: %s", message - ) - - def test_stop(self) -> None: - """Test the stop method.""" - self.behaviour.stop() - - @pytest.mark.parametrize( - "performative", - ( - TendermintMessage.Performative.GET_GENESIS_INFO, - TendermintMessage.Performative.GET_RECOVERY_PARAMS, - ), - ) - @pytest.mark.parametrize( - "address_to_acn_deliverable, n_pending", - ( - ({}, 0), - ({i: None for i in range(3)}, 3), - ({0: "test", 1: None, 2: None}, 2), - ({i: "test" for i in range(3)}, 0), - ), - ) - def test_acn_request_from_pending( - self, - performative: TendermintMessage.Performative, - address_to_acn_deliverable: Dict[str, Any], - n_pending: int, - ) -> None: - """Test the `_acn_request_from_pending` method.""" - self.behaviour.context.state.address_to_acn_deliverable = ( - address_to_acn_deliverable - ) - gen = self.behaviour._acn_request_from_pending(performative) - - if n_pending == 0: - with pytest.raises(StopIteration): - next(gen) - return - - with mock.patch.object( - self.behaviour.context.tendermint_dialogues, - "create", - return_value=(MagicMock(), MagicMock()), - ) as dialogues_mock: - dialogues_mock.assert_not_called() - self.behaviour.context.outbox.put_message = MagicMock() - self.behaviour.context.outbox.put_message.assert_not_called() - - next(gen) - - dialogues_expected_calls = tuple( - mock.call(counterparty=address, performative=performative) - for address, deliverable in address_to_acn_deliverable.items() - if deliverable is None - ) - dialogues_mock.assert_has_calls(dialogues_expected_calls) - assert self.behaviour.context.outbox.put_message.call_count == len( - dialogues_expected_calls - ) - - time.sleep(self.behaviour.params.sleep_time) - with pytest.raises(StopIteration): - next(gen) - - @pytest.mark.parametrize( - "performative", - ( - TendermintMessage.Performative.GET_GENESIS_INFO, - TendermintMessage.Performative.GET_RECOVERY_PARAMS, - ), - ) - @pytest.mark.parametrize( - "address_to_acn_deliverable_per_attempt, expected_result", - ( - ( - tuple({"address": None} for _ in range(10)), - None, - ), # an example in which no agent responds - ( - ( - {f"address{i}": None for i in range(3)}, - {"address1": None, "address2": "test", "address3": None}, - ) - + tuple( - {"address1": None, "address2": "test", "address3": "malicious"} - for _ in range(8) - ), - None, - ), # an example in which no majority is reached - ( - tuple({f"address{i}": None for i in range(3)} for _ in range(3)) - + ({"address1": "test", "address2": "test", "address3": None},), - "test", - ), # an example in which majority is reached during the 4th ACN attempt - ), - ) - def test_perform_acn_request( - self, - performative: TendermintMessage.Performative, - address_to_acn_deliverable_per_attempt: Tuple[Dict[str, Any], ...], - expected_result: Any, - ) -> None: - """Test the `_perform_acn_request` method.""" - final_attempt_idx = len(address_to_acn_deliverable_per_attempt) - 1 - gen = self.behaviour._perform_acn_request(performative) - - with mock.patch.object( - self.behaviour, - "_acn_request_from_pending", - side_effect=dummy_generator_wrapper(), - ) as _acn_request_from_pending_mock: - for i in range(self.behaviour.params.max_attempts): - acn_result = expected_result if i == final_attempt_idx + 1 else None - with mock.patch.object( - self.behaviour.context.state, - "get_acn_result", - return_value=acn_result, - ): - if i != final_attempt_idx + 1: - self.behaviour.context.state.address_to_acn_deliverable = ( - address_to_acn_deliverable_per_attempt[i] - ) - next(gen) - continue - - try: - next(gen) - except StopIteration as exc: - assert exc.value == expected_result - else: - raise AssertionError( - "The `_perform_acn_request` was expected to yield for the last time." - ) - - break - - n_expected_calls = final_attempt_idx + 1 - expected_calls = tuple( - mock.call(performative) for _ in range(n_expected_calls) - ) - assert _acn_request_from_pending_mock.call_count == n_expected_calls - _acn_request_from_pending_mock.assert_has_calls(expected_calls) - - @pytest.mark.parametrize("expected_result", (True, False)) - def test_request_recovery_params(self, expected_result: bool) -> None: - """Test `request_recovery_params`.""" - acn_result = "not None ACN result" if expected_result else None - request_recovery_params = self.behaviour.request_recovery_params(False) - - with mock.patch.object( - self.behaviour, - "_perform_acn_request", - side_effect=dummy_generator_wrapper(acn_result), - ) as perform_acn_request_mock: - next(request_recovery_params) - - try: - next(request_recovery_params) - except StopIteration as exc: - assert exc.value is expected_result - else: - raise AssertionError( - "The `request_recovery_params` was expected to yield for the last time." - ) - - perform_acn_request_mock.assert_called_once_with( - TendermintMessage.Performative.GET_RECOVERY_PARAMS - ) - - def test_start_reset(self) -> None: - """Test the `_start_reset` method.""" - with mock.patch.object( - BaseBehaviour, - "wait_from_last_timestamp", - new_callable=lambda *_: dummy_generator_wrapper(), - ): - res = self.behaviour._start_reset() - for _ in range(2): - next(res) - assert self.behaviour._check_started is not None - assert self.behaviour._check_started <= datetime.now() - assert self.behaviour._timeout == self.behaviour.params.max_healthcheck - assert not self.behaviour._is_healthy - - def test_end_reset(self) -> None: - """Test the `_end_reset` method.""" - self.behaviour._end_reset() - assert self.behaviour._check_started is None - assert self.behaviour._timeout == -1.0 - assert self.behaviour._is_healthy - - @pytest.mark.parametrize( - "check_started, is_healthy, timeout, expiration_expected", - ( - (None, True, 0, False), - (None, False, 0, False), - (datetime(1, 1, 1), True, 0, False), - (datetime.now(), False, 3000, False), - (datetime(1, 1, 1), False, 0, True), - ), - ) - def test_is_timeout_expired( - self, - check_started: Optional[datetime], - is_healthy: bool, - timeout: float, - expiration_expected: bool, - ) -> None: - """Test the `_is_timeout_expired` method.""" - self.behaviour._check_started = check_started - self.behaviour._is_healthy = is_healthy - self.behaviour._timeout = timeout - assert self.behaviour._is_timeout_expired() == expiration_expected - - @pytest.mark.parametrize("default", (True, False)) - @given( - st.datetimes( - min_value=MIN_DATETIME_WINDOWS, - max_value=MAX_DATETIME_WINDOWS, - ), - st.integers(), - st.integers(), - st.integers(), - ) - def test_get_reset_params( - self, - default: bool, - timestamp: datetime, - height: int, - interval: int, - period: int, - ) -> None: - """Test `_get_reset_params` method.""" - self.context_mock.state.round_sequence.last_round_transition_timestamp = ( - timestamp - ) - self.context_mock.state.round_sequence.last_round_transition_tm_height = height - self.behaviour.params.reset_pause_duration = interval - self.context_state_synchronized_data_mock.period_count = period - - actual = self.behaviour._get_reset_params(default) - - if default: - assert actual is None - - else: - initial_height = INITIAL_HEIGHT - genesis_time = timestamp.astimezone(pytz.UTC).strftime(GENESIS_TIME_FMT) - period_count = str(period) - - expected = { - "genesis_time": genesis_time, - "initial_height": initial_height, - "period_count": period_count, - } - - assert actual == expected - - @mock.patch.object(BaseBehaviour, "_start_reset") - @mock.patch.object(BaseBehaviour, "_is_timeout_expired") - def test_reset_tendermint_with_wait_timeout_expired(self, *_: mock.Mock) -> None: - """Test tendermint reset.""" - with pytest.raises(RuntimeError, match="Error resetting tendermint node."): - next(self.behaviour.reset_tendermint_with_wait()) - - @mock.patch.object(BaseBehaviour, "_start_reset") - @mock.patch.object( - BaseBehaviour, "_build_http_request_message", return_value=(None, None) - ) - @pytest.mark.parametrize( - "reset_response, status_response, local_height, on_startup, n_iter, expecting_success", - ( - ( - {"message": "Tendermint reset was successful.", "status": True}, - {"result": {"sync_info": {"latest_block_height": 1}}}, - 1, - False, - 3, - True, - ), - ( - {"message": "Tendermint reset was successful.", "status": True}, - {"result": {"sync_info": {"latest_block_height": 1}}}, - 1, - True, - 2, - True, - ), - ( - { - "message": "Tendermint reset was successful.", - "status": True, - "is_replay": True, - }, - {"result": {"sync_info": {"latest_block_height": 1}}}, - 1, - False, - 3, - True, - ), - ( - {"message": "Tendermint reset was successful.", "status": True}, - {"result": {"sync_info": {"latest_block_height": 1}}}, - 3, - False, - 3, - False, - ), - ( - {"message": "Error resetting tendermint.", "status": False}, - {}, - 0, - False, - 2, - False, - ), - ("wrong_response", {}, 0, False, 2, False), - ( - {"message": "Reset Successful.", "status": True}, - "not_accepting_txs_yet", - 0, - False, - 3, - False, - ), - ), - ) - def test_reset_tendermint_with_wait( - self, - build_http_request_message_mock: mock.Mock, - _start_reset: mock.Mock, - reset_response: Union[Dict[str, Union[bool, str]], str], - status_response: Union[Dict[str, Union[int, str]], str], - local_height: int, - on_startup: bool, - n_iter: int, - expecting_success: bool, - ) -> None: - """Test tendermint reset.""" - - def dummy_do_request(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_do_request` method.""" - yield - if reset_response == "wrong_response": - return mock.MagicMock(body=b"") - return mock.MagicMock(body=json.dumps(reset_response).encode()) - - def dummy_get_status(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_get_status` method.""" - yield - if status_response == "not_accepting_txs_yet": - return mock.MagicMock(body=b"") - return mock.MagicMock(body=json.dumps(status_response).encode()) - - period_count_mock = MagicMock() - self.context_state_synchronized_data_mock.period_count = period_count_mock - self.behaviour.params.reset_pause_duration = 1 - with mock.patch.object( - BaseBehaviour, "_is_timeout_expired", return_value=False - ), mock.patch.object( - BaseBehaviour, - "wait_from_last_timestamp", - new_callable=lambda *_: dummy_generator_wrapper(), - ), mock.patch.object( - BaseBehaviour, "_do_request", new_callable=lambda *_: dummy_do_request - ), mock.patch.object( - BaseBehaviour, "_get_status", new_callable=lambda *_: dummy_get_status - ), mock.patch.object( - BaseBehaviour, "sleep", new_callable=lambda *_: dummy_generator_wrapper() - ): - self.behaviour.context.state.round_sequence.height = local_height - reset = self.behaviour.reset_tendermint_with_wait(on_startup=on_startup) - for _ in range(n_iter): - next(reset) - initial_height = INITIAL_HEIGHT - genesis_time = self.behaviour.context.state.round_sequence.last_round_transition_timestamp.astimezone( - pytz.UTC - ).strftime( - "%Y-%m-%dT%H:%M:%S.%fZ" - ) - - expected_parameters = ( - { - "genesis_time": genesis_time, - "initial_height": initial_height, - "period_count": str(period_count_mock), - } - if not on_startup - else None - ) - - build_http_request_message_mock.assert_called_with( - "GET", - self.behaviour.context.params.tendermint_com_url + "/hard_reset", - parameters=expected_parameters, - ) - - should_be_healthy = isinstance(reset_response, dict) and reset_response.get( - "status", False - ) - assert self.behaviour._is_healthy is should_be_healthy - - # perform the last iteration which also returns the result - try: - next(reset) - except StopIteration as e: - assert e.value == expecting_success - if expecting_success: - # upon having a successful reset we expect the reset params of that - # reset to be stored in the shared state, as they could be used - # later for performing hard reset in cases when the agent <-> tendermint - # communication is broken - shared_state = cast(SharedState, self.behaviour.context.state) - tm_recovery_params = shared_state.tm_recovery_params - assert tm_recovery_params.reset_params == expected_parameters - assert ( - tm_recovery_params.round_count - == shared_state.synchronized_data.db.round_count - 1 - ) - assert ( - tm_recovery_params.reset_from_round - == self.behaviour.matching_round.auto_round_id() - ) - assert not self.behaviour._is_healthy - else: - pytest.fail("`reset_tendermint_with_wait` did not finish!") - - @given(st.binary()) - def test_fuzz_submit_tx(self, input_bytes: bytes) -> None: - """Fuzz '_submit_tx'. - - Mock context manager decorators don't work here. - - :param input_bytes: fuzz input - """ - self.behaviour._submit_tx(input_bytes) - - -def test_degenerate_behaviour_async_act() -> None: - """Test DegenerateBehaviour.async_act.""" - - class ConcreteDegenerateBehaviour(DegenerateBehaviour): - """Concrete DegenerateBehaviour class.""" - - behaviour_id = "concrete_degenerate_behaviour" - matching_round = MagicMock() - sleep_time_before_exit = 0.01 - - context = MagicMock() - # this is needed to trigger execution of async_act - context.state.round_sequence.syncing_up = False - context.state.round_sequence.block_stall_deadline_expired = False - behaviour = ConcreteDegenerateBehaviour( - name=ConcreteDegenerateBehaviour.auto_behaviour_id(), skill_context=context - ) - with pytest.raises( - SystemExit, - ): - behaviour.act() - time.sleep(0.02) - behaviour.act() - - -def test_make_degenerate_behaviour() -> None: - """Test 'make_degenerate_behaviour'.""" - - class FinalRound(DegenerateRound, ABC): - """A final round for testing.""" - - new_cls = make_degenerate_behaviour(FinalRound) - - assert isinstance(new_cls, type) - assert issubclass(new_cls, DegenerateBehaviour) - assert new_cls.matching_round == FinalRound - - assert ( - new_cls.auto_behaviour_id() - == f"degenerate_behaviour_{FinalRound.auto_round_id()}" - ) - - -class TestTmManager: - """Class to test the TmManager behaviour.""" - - _DUMMY_CONSENSUS_THRESHOLD = 3 - - def setup(self) -> None: - """Set up the tests.""" - self.context_mock = MagicMock() - self.context_params_mock = MagicMock( - request_timeout=_DEFAULT_REQUEST_TIMEOUT, - request_retry_delay=_DEFAULT_REQUEST_RETRY_DELAY, - tx_timeout=_DEFAULT_TX_TIMEOUT, - max_attempts=_DEFAULT_TX_MAX_ATTEMPTS, - consensus_params=MagicMock( - consensus_threshold=self._DUMMY_CONSENSUS_THRESHOLD - ), - ) - self.context_state_synchronized_data_mock = MagicMock( - consensus_threshold=self._DUMMY_CONSENSUS_THRESHOLD - ) - self.context_mock.params = self.context_params_mock - self.context_mock.state.synchronized_data = ( - self.context_state_synchronized_data_mock - ) - self.recovery_params = TendermintRecoveryParams(MagicMock()) - self.context_mock.state.tm_recovery_params = self.recovery_params - self.context_mock.state.round_sequence.current_round_id = "round_a" - self.context_mock.state.round_sequence.syncing_up = False - self.context_mock.state.round_sequence.block_stall_deadline_expired = False - self.context_mock.http_dialogues = HttpDialogues() - self.context_mock.handlers.__dict__ = {"http": MagicMock()} - self.tm_manager = TmManager(name="", skill_context=self.context_mock) - self.tm_manager._max_reset_retry = 1 - self.tm_manager.synchronized_data.max_participants = 3 # type: ignore - - def test_async_act(self) -> None: - """Test the async_act method of the TmManager.""" - self.tm_manager.act_wrapper() - with pytest.raises( - SystemExit, - ): - self.tm_manager.act_wrapper() - - @given(latest_block_height=st.integers(min_value=0)) - @pytest.mark.parametrize( - "acn_communication_success", - ( - True, - False, - ), - ) - @pytest.mark.parametrize( - "gentle_reset_attempted", - ( - True, - False, - ), - ) - @pytest.mark.parametrize( - ("tm_reset_success", "num_active_peers"), - [ - (True, 4), - (False, 4), - (True, 2), - (False, None), - ], - ) - def test_handle_unhealthy_tm( - self, - latest_block_height: int, - acn_communication_success: bool, - gentle_reset_attempted: bool, - tm_reset_success: bool, - num_active_peers: Optional[int], - ) -> None: - """Test _handle_unhealthy_tm.""" - - self.tm_manager.gentle_reset_attempted = gentle_reset_attempted - self.tm_manager.context.state.round_sequence.height = latest_block_height - - def mock_sleep(_seconds: int) -> Generator: - """A method that mocks sleep.""" - return - yield - - def dummy_do_request(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_do_request` method.""" - yield - return mock.MagicMock() - - def dummy_get_status(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_get_status` method.""" - yield - return mock.MagicMock( - body=json.dumps( - { - "result": { - "sync_info": {"latest_block_height": latest_block_height} - } - } - ).encode() - ) - - gen = self.tm_manager._handle_unhealthy_tm() - with mock.patch.object( - self.tm_manager, - "reset_tendermint_with_wait", - side_effect=yield_and_return_bool_wrapper(tm_reset_success), - ), mock.patch.object( - self.tm_manager, - "num_active_peers", - side_effect=yield_and_return_int_wrapper(num_active_peers), - ), mock.patch.object( - self.tm_manager, "sleep", side_effect=mock_sleep - ), mock.patch.object( - BaseBehaviour, - "request_recovery_params", - side_effect=dummy_generator_wrapper(acn_communication_success), - ), mock.patch.object( - BaseBehaviour, "_do_request", new_callable=lambda *_: dummy_do_request - ), mock.patch.object( - BaseBehaviour, "_get_status", new_callable=lambda *_: dummy_get_status - ), mock.patch.object( - self.tm_manager.round_sequence, "set_block_stall_deadline" - ) as set_block_stall_deadline_mock: - next(gen) - - if not gentle_reset_attempted: - next(gen) - assert self.tm_manager.gentle_reset_attempted - with pytest.raises(StopIteration): - next(gen) - set_block_stall_deadline_mock.assert_called_once() - assert self.tm_manager.gentle_reset_attempted - return - - if not acn_communication_success: - with pytest.raises(StopIteration): - next(gen) - set_block_stall_deadline_mock.assert_not_called() - return - - next(gen) - with pytest.raises(StopIteration): - next(gen) - - set_block_stall_deadline_mock.assert_not_called() - assert self.tm_manager.informed is True - - @pytest.mark.parametrize( - "n_repetitions", - ( - 1, - 2, - 1000, - ), - ) - def test_handle_unhealthy_tm_logging(self, n_repetitions: int) -> None: - """Verify if unintended logging repetition occurs during the execution of `_handle_unhealthy_tm`.""" - - self.tm_manager.gentle_reset_attempted = False - self.tm_manager.context.state.round_sequence.height = 10 - - def mock_sleep(_seconds: int) -> Generator: - """A method that mocks sleep.""" - return - yield - - def dummy_do_request(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_do_request` method.""" - yield - return mock.MagicMock() - - def dummy_get_status(*_: Any) -> Generator[None, None, MagicMock]: - """Dummy `_get_status` method.""" - yield - return mock.MagicMock( - body=json.dumps( - {"result": {"sync_info": {"latest_block_height": 0}}} - ).encode() - ) - - with mock.patch.object( - self.tm_manager, - "reset_tendermint_with_wait", - side_effect=yield_and_return_bool_wrapper(True), - ), mock.patch.object( - self.tm_manager, - "num_active_peers", - side_effect=yield_and_return_int_wrapper(4), - ), mock.patch.object( - self.tm_manager, "sleep", side_effect=mock_sleep - ), mock.patch.object( - BaseBehaviour, "_do_request", new_callable=lambda *_: dummy_do_request - ), mock.patch.object( - BaseBehaviour, "_get_status", new_callable=lambda *_: dummy_get_status - ): - assert self.tm_manager.informed is False - for _ in range(n_repetitions): - gen = self.tm_manager._handle_unhealthy_tm() - next(gen) - assert self.tm_manager.informed is True - - @pytest.mark.parametrize( - "expected_reset_params", - ( - {"genesis_time": "genesis-time", "initial_height": "1"}, - None, - ), - ) - def test_get_reset_params( - self, expected_reset_params: Optional[Dict[str, str]] - ) -> None: - """Test that reset params returns the correct params.""" - self.context_mock.state.tm_recovery_params = TendermintRecoveryParams( - reset_from_round="does not matter", reset_params=expected_reset_params - ) - actual_reset_params = self.tm_manager._get_reset_params(False) - assert expected_reset_params == actual_reset_params - - # setting the "default" arg to true should have no effect - actual_reset_params = self.tm_manager._get_reset_params(True) - assert expected_reset_params == actual_reset_params - - def test_sleep_after_hard_reset(self) -> None: - """Check that hard_reset_sleep returns the expected amount of time.""" - expected = self.tm_manager._hard_reset_sleep - actual = self.tm_manager.hard_reset_sleep - assert actual == expected - - @pytest.mark.parametrize( - ("state", "notified", "message", "num_iter"), - [ - (AsyncBehaviour.AsyncState.READY, False, None, 1), - (AsyncBehaviour.AsyncState.WAITING_MESSAGE, True, Message(), 2), - (AsyncBehaviour.AsyncState.WAITING_MESSAGE, True, Message(), 1), - ], - ) - def test_try_fix( - self, - state: AsyncBehaviour.AsyncState, - notified: bool, - message: Optional[Message], - num_iter: int, - ) -> None: - """Tests try_fix.""" - - def mock_handle_unhealthy_tm() -> Generator: - """A mock implementation of _handle_unhealthy_tm.""" - for _ in range(num_iter): - msg = yield - if msg is not None: - # if a message is recieved, the state of the behviour should be "RUNNING" - self.tm_manager._AsyncBehaviour__state = ( - AsyncBehaviour.AsyncState.RUNNING - ) - return - - with mock.patch.object( - self.tm_manager, - "_handle_unhealthy_tm", - side_effect=mock_handle_unhealthy_tm, - ): - # there is no active generator in the beginning - assert not self.tm_manager.is_acting - - # a generator should be created, and be active - self.tm_manager.try_fix() - assert self.tm_manager.is_acting - - # a message may (or may not) arrive - self.tm_manager._AsyncBehaviour__notified = notified - self.tm_manager._AsyncBehaviour__state = state - self.tm_manager._AsyncBehaviour__message = message - - # the generator has a single yield statement, - # a second try_fix() call should finish it - for _ in range(num_iter): - self.tm_manager.try_fix() - assert not self.tm_manager.is_acting, num_iter - - @pytest.mark.parametrize( - "state", - [ - AsyncBehaviour.AsyncState.WAITING_MESSAGE, - AsyncBehaviour.AsyncState.READY, - ], - ) - def test_get_callback_request(self, state: AsyncBehaviour.AsyncState) -> None: - """Tests get_callback_request.""" - self.tm_manager._AsyncBehaviour__state = state - dummy_msg, dummy_behaviour = MagicMock(), MagicMock() - callback_req = self.tm_manager.get_callback_request() - with mock.patch.object(self.tm_manager, "try_send"): - callback_req(dummy_msg, dummy_behaviour) - - def test_is_acting(self) -> None: - """Test is_acting.""" - self.tm_manager._active_generator = MagicMock() - assert self.tm_manager.is_acting - - self.tm_manager._active_generator = None - assert not self.tm_manager.is_acting - - -def test_meta_base_behaviour_when_instance_not_subclass_of_base_behaviour() -> None: - """Test instantiation of meta class when instance not a subclass of BaseBehaviour.""" - - class MyBaseBehaviour(metaclass=_MetaBaseBehaviour): - pass - - -def test_base_behaviour_instantiation_without_attributes_raises_error() -> None: - """Test that definition of concrete subclass of BaseBehaviour without attributes raises error.""" - with pytest.raises(BaseBehaviourInternalError): - - class MyBaseBehaviour(BaseBehaviour): - pass - - -class TestIPFSBehaviour: - """Test IPFSBehaviour tests.""" - - def setup(self) -> None: - """Sets up the tests.""" - self.context_mock = MagicMock() - self.context_mock.ipfs_dialogues = IpfsDialogues( - connection_id=str(IPFS_CONNECTION_ID) - ) - self.behaviour = BehaviourATest(name="", skill_context=self.context_mock) - - def test_build_ipfs_message(self) -> None: - """Tests _build_ipfs_message.""" - res = self.behaviour._build_ipfs_message(IpfsMessage.Performative.GET_FILES) # type: ignore - assert res is not None - - def test_build_ipfs_store_file_req(self) -> None: - """Tests _build_ipfs_store_file_req.""" - with mock.patch.object( - IPFSInteract, "store", return_value=MagicMock() - ) as mock_store: - res = self.behaviour._build_ipfs_store_file_req("dummy_filename", {}) - mock_store.assert_called() - assert res is not None - - def test_build_ipfs_get_file_req(self) -> None: - """Tests _build_ipfs_get_file_req.""" - res = self.behaviour._build_ipfs_get_file_req("dummy_ipfs_hash") - assert res is not None - - def test_deserialize_ipfs_objects(self) -> None: - """Tests _deserialize_ipfs_objects""" - with mock.patch.object( - IPFSInteract, "load", return_value=MagicMock() - ) as mock_load: - res = self.behaviour._deserialize_ipfs_objects({}) - mock_load.assert_called() - assert res is not None diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_common.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_common.py deleted file mode 100644 index 427aa81e1..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_common.py +++ /dev/null @@ -1,407 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the common.py module of the skill.""" - -import random -import re -from typing import ( - Any, - Callable, - Dict, - FrozenSet, - Generator, - Optional, - Set, - Type, - TypeVar, - Union, -) -from unittest import mock -from unittest.mock import MagicMock - -import pytest - -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.common import ( - RandomnessBehaviour, - SelectKeeperBehaviour, - random_selection, -) -from packages.valory.skills.abstract_round_abci.models import BaseParams -from packages.valory.skills.abstract_round_abci.tests.conftest import irrelevant_config -from packages.valory.skills.abstract_round_abci.utils import VerifyDrand - - -ReturnValueType = TypeVar("ReturnValueType") - - -def test_random_selection() -> None: - """Test 'random_selection'""" - assert random_selection(elements=[0, 1, 2], randomness=0.25) == 0 - assert random_selection(elements=[0, 1, 2], randomness=0.5) == 1 - assert random_selection(elements=[0, 1, 2], randomness=0.75) == 2 - - with pytest.raises( - ValueError, match=re.escape("Randomness should lie in the [0,1) interval") - ): - random_selection(elements=[0, 1], randomness=-1) - - with pytest.raises( - ValueError, match=re.escape("Randomness should lie in the [0,1) interval") - ): - random_selection(elements=[0, 1], randomness=1) - - with pytest.raises( - ValueError, match=re.escape("Randomness should lie in the [0,1) interval") - ): - random_selection(elements=[0, 1], randomness=2) - - with pytest.raises(ValueError, match="No elements to randomly select among"): - random_selection(elements=[], randomness=0.5) - - -class DummyRandomnessBehaviour(RandomnessBehaviour): - """Dummy randomness behaviour.""" - - behaviour_id = "dummy_randomness" - payload_class = MagicMock() - matching_round = MagicMock() - - -class DummySelectKeeperBehaviour(SelectKeeperBehaviour): - """Dummy select keeper behaviour.""" - - behaviour_id = "dummy_select_keeper" - payload_class = MagicMock() - matching_round = MagicMock() - - -DummyBehaviourType = Union[DummyRandomnessBehaviour, DummySelectKeeperBehaviour] - - -class BaseDummyBehaviour: # pylint: disable=too-few-public-methods - """A Base dummy behaviour class.""" - - behaviour: DummyBehaviourType - dummy_behaviour_cls: Type[DummyBehaviourType] - - @classmethod - def setup_class(cls) -> None: - """Setup the test class.""" - cls.behaviour = cls.dummy_behaviour_cls( - name="test", - skill_context=MagicMock( - params=BaseParams( - name="test", - skill_context=MagicMock(), - service_id="test_id", - consensus=dict(max_participants=1), - **irrelevant_config, - ), - ), - ) - - -def dummy_generator( - return_value: ReturnValueType, -) -> Callable[[Any, Any], Generator[None, None, ReturnValueType]]: - """A method that returns a dummy generator which yields nothing once and then returns the given `return_value`.""" - - def dummy_generator_wrapped( - *_: Any, **__: Any - ) -> Generator[None, None, ReturnValueType]: - """A wrapped method which yields nothing once and then returns the given `return_value`.""" - yield - return return_value - - return dummy_generator_wrapped - - -def last_iteration(gen: Generator) -> None: - """Perform a generator iteration and ensure that it is the last one.""" - with pytest.raises(StopIteration): - next(gen) - - -class TestRandomnessBehaviour(BaseDummyBehaviour): - """Test `RandomnessBehaviour`.""" - - @classmethod - def setup_class(cls) -> None: - """Setup the test class.""" - cls.dummy_behaviour_cls = DummyRandomnessBehaviour - super().setup_class() - - @pytest.mark.parametrize( - "return_value, expected_hash", - ( - (MagicMock(performative=LedgerApiMessage.Performative.ERROR), None), - (MagicMock(state=MagicMock(body={"hash_key_is_not_in_body": ""})), None), - ( - MagicMock(state=MagicMock(body={"hash": "test_randomness"})), - { - "randomness": "d067b86fa5235e7e5225e8328e8faac5c279cbf57131d647e4da0a70df6d3d7b", - "round": 0, - }, - ), - ), - ) - def test_failsafe_randomness( - self, return_value: MagicMock, expected_hash: Optional[str] - ) -> None: - """Test `failsafe_randomness`.""" - gen = self.behaviour.failsafe_randomness() - - with mock.patch.object( - DummyRandomnessBehaviour, - "get_ledger_api_response", - dummy_generator(return_value), - ): - next(gen) - try: - next(gen) - except StopIteration as e: - assert e.value == expected_hash - else: - raise AssertionError( - "`get_ledger_api_response`'s generator should have been exhausted." - ) - - @pytest.mark.parametrize("randomness_response", ("test", None)) - @pytest.mark.parametrize("verified", (True, False)) - def test_get_randomness_from_api( - self, randomness_response: Optional[str], verified: bool - ) -> None: - """Test `get_randomness_from_api`.""" - # create a dummy `process_response` for `MagicMock`ed `randomness_api` - self.behaviour.context.randomness_api.process_response = ( - lambda res: res + "_processed" if res is not None else None - ) - gen = self.behaviour.get_randomness_from_api() - - with mock.patch.object( - DummyRandomnessBehaviour, - "get_http_response", - dummy_generator(randomness_response), - ), mock.patch.object( - VerifyDrand, - "verify", - return_value=(verified, "Error message."), - ): - next(gen) - try: - next(gen) - except StopIteration as e: - if randomness_response is None or not verified: - assert e.value is None - else: - assert e.value == randomness_response + "_processed" - else: - raise AssertionError( - "`get_randomness_from_api`'s generator should have been exhausted." - ) - - @pytest.mark.parametrize( - "retries_exceeded, failsafe_succeeds", - # (False, False) is not tested, because it does not make sense - ((True, False), (True, True), (False, True)), - ) - @pytest.mark.parametrize( - "observation", - ( - None, - {}, - { - "randomness": "d067b86fa5235e7e5225e8328e8faac5c279cbf57131d647e4da0a70df6d3d7b", - "round": 0, - }, - ), - ) - def test_async_act( - self, - retries_exceeded: bool, - failsafe_succeeds: bool, - observation: Optional[Dict[str, Union[str, int]]], - ) -> None: - """Test `async_act`.""" - # create a dummy `is_retries_exceeded` for `MagicMock`ed `randomness_api` - self.behaviour.context.randomness_api.is_retries_exceeded = ( - lambda: retries_exceeded - ) - gen = self.behaviour.async_act() - - with mock.patch.object( - self.behaviour, - "failsafe_randomness", - dummy_generator(observation), - ), mock.patch.object( - self.behaviour, - "get_randomness_from_api", - dummy_generator(observation), - ), mock.patch.object( - self.behaviour, - "send_a2a_transaction", - ) as send_a2a_transaction_mocked, mock.patch.object( - self.behaviour, - "wait_until_round_end", - ) as wait_until_round_end_mocked, mock.patch.object( - self.behaviour, - "set_done", - ) as set_done_mocked, mock.patch.object( - self.behaviour, - "sleep", - ) as sleep_mocked: - next(gen) - last_iteration(gen) - - if not failsafe_succeeds or failsafe_succeeds and observation is None: - return - - # here, the observation is retrieved from either `failsafe_randomness` or `get_randomness_from_api` - # depending on the test's parametrization - if not observation: - sleep_mocked.assert_called_once_with( - self.behaviour.context.randomness_api.retries_info.suggested_sleep_time - ) - self.behaviour.context.randomness_api.increment_retries.assert_called_once() - return - - send_a2a_transaction_mocked.assert_called_once() - wait_until_round_end_mocked.assert_called_once() - set_done_mocked.assert_called_once() - - def test_clean_up(self) -> None: - """Test `clean_up`.""" - self.behaviour.clean_up() - self.behaviour.context.randomness_api.reset_retries.assert_called_once() - - def teardown(self) -> None: - """Teardown run after each test method.""" - self.behaviour.context.randomness_api.increment_retries.reset_mock() - - -class TestSelectKeeperBehaviour(BaseDummyBehaviour): - """Tests for `SelectKeeperBehaviour`.""" - - @classmethod - def setup_class(cls) -> None: - """Setup the test class.""" - cls.dummy_behaviour_cls = DummySelectKeeperBehaviour - super().setup_class() - - @mock.patch.object(random, "shuffle", lambda do_not_shuffle: do_not_shuffle) - @pytest.mark.parametrize( - "participants, blacklisted_keepers, most_voted_keeper_address, expected_keeper", - ( - ( - frozenset((f"test_p{i}" for i in range(4))), - set(), - "test_p0", - "test_p1", - ), - ( - frozenset((f"test_p{i}" for i in range(4))), - set(), - "test_p1", - "test_p2", - ), - ( - frozenset((f"test_p{i}" for i in range(4))), - set(), - "test_p2", - "test_p3", - ), - ( - frozenset((f"test_p{i}" for i in range(4))), - set(), - "test_p3", - "test_p0", - ), - ( - frozenset((f"test_p{i}" for i in range(4))), - {f"test_p{i}" for i in range(1)}, - "test_p1", - "test_p2", - ), - ( - frozenset((f"test_p{i}" for i in range(4))), - {f"test_p{i}" for i in range(4)}, - "", - "", - ), - ), - ) - def test_select_keeper( - self, - participants: FrozenSet[str], - blacklisted_keepers: Set[str], - most_voted_keeper_address: str, # pylint: disable=unused-argument - expected_keeper: str, - ) -> None: - """Test `_select_keeper`.""" - for sync_data_name in ( - "participants", - "blacklisted_keepers", - "most_voted_keeper_address", - ): - setattr( - self.behaviour.context.state.synchronized_data, - sync_data_name, - locals()[sync_data_name], - ) - - select_keeper_method = ( - self.behaviour._select_keeper # pylint: disable=protected-access - ) - - if not participants - blacklisted_keepers: - with pytest.raises( - RuntimeError, - match="Cannot continue if all the keepers have been blacklisted!", - ): - select_keeper_method() - return - - with mock.patch("random.seed"): - actual_keeper = select_keeper_method() - assert actual_keeper == expected_keeper - - def test_async_act(self) -> None: - """Test `async_act`.""" - gen = self.behaviour.async_act() - - with mock.patch.object( - self.behaviour, - "_select_keeper", - return_value="test_keeper", - ), mock.patch.object( - self.behaviour, - "send_a2a_transaction", - ) as send_a2a_transaction_mocked, mock.patch.object( - self.behaviour, - "wait_until_round_end", - ) as wait_until_round_end_mocked, mock.patch.object( - self.behaviour, - "set_done", - ) as set_done_mocked: - last_iteration(gen) - send_a2a_transaction_mocked.assert_called_once() - wait_until_round_end_mocked.assert_called_once() - set_done_mocked.assert_called_once() diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_dialogues.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_dialogues.py deleted file mode 100644 index 12aeeaaa5..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_dialogues.py +++ /dev/null @@ -1,100 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -from enum import Enum -from typing import Type, cast -from unittest.mock import MagicMock - -import pytest -from aea.protocols.dialogue.base import Dialogues -from aea.skills.base import Model - -from packages.valory.connections.ipfs.connection import PUBLIC_ID as IPFS_CONNECTION_ID -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue, - AbciDialogues, - ContractApiDialogue, - ContractApiDialogues, - HttpDialogue, - HttpDialogues, - IpfsDialogues, - LedgerApiDialogue, - LedgerApiDialogues, - SigningDialogue, - SigningDialogues, - TendermintDialogue, - TendermintDialogues, -) - - -@pytest.mark.parametrize( - "dialogues_cls,expected_role_from_first_message", - [ - (AbciDialogues, AbciDialogue.Role.CLIENT), - (HttpDialogues, HttpDialogue.Role.CLIENT), - (SigningDialogues, SigningDialogue.Role.SKILL), - (LedgerApiDialogues, LedgerApiDialogue.Role.AGENT), - (ContractApiDialogues, ContractApiDialogue.Role.AGENT), - (TendermintDialogues, TendermintDialogue.Role.AGENT), - ], -) -def test_dialogues_creation( - dialogues_cls: Type[Model], expected_role_from_first_message: Enum -) -> None: - """Test XDialogues creations.""" - dialogues = cast(Dialogues, dialogues_cls(name="", skill_context=MagicMock())) - assert expected_role_from_first_message == dialogues._role_from_first_message( - MagicMock(), MagicMock() - ) - - -def test_ledger_api_dialogue() -> None: - """Test 'LedgerApiDialogue' creation.""" - dialogue = LedgerApiDialogue(MagicMock(), "", MagicMock()) - with pytest.raises(ValueError, match="Terms not set!"): - dialogue.terms - - expected_terms = MagicMock() - dialogue.terms = expected_terms - assert expected_terms == dialogue.terms - - -def test_contract_api_dialogue() -> None: - """Test 'ContractApiDialogue' creation.""" - dialogue = ContractApiDialogue(MagicMock(), "", MagicMock()) - with pytest.raises(ValueError, match="Terms not set!"): - dialogue.terms - - expected_terms = MagicMock() - dialogue.terms = expected_terms - assert expected_terms == dialogue.terms - - -def test_ipfs_dialogue() -> None: - """Test 'IpfsDialogues' creation.""" - dialogues = IpfsDialogues(name="", skill_context=MagicMock()) - dialogues.create( - counterparty=str(IPFS_CONNECTION_ID), - performative=IpfsMessage.Performative.GET_FILES, - ) diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_handlers.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_handlers.py deleted file mode 100644 index 415f11ced..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_handlers.py +++ /dev/null @@ -1,596 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the handlers.py module of the skill.""" - -# pylint: skip-file - -import json -import logging -from dataclasses import asdict -from datetime import datetime -from typing import Any, Dict, cast -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from _pytest.logging import LogCaptureFixture -from aea.configurations.data_types import PublicId -from aea.protocols.base import Message - -from packages.valory.protocols.abci import AbciMessage -from packages.valory.protocols.abci.custom_types import ( - CheckTxType, - CheckTxTypeEnum, - ConsensusParams, - Evidences, - Header, - LastCommitInfo, - Timestamp, - ValidatorUpdates, -) -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.tendermint import TendermintMessage -from packages.valory.skills.abstract_round_abci import handlers -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AddBlockError, - ERROR_CODE, - OK_CODE, - SignatureNotValidError, - TransactionNotValidError, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue, - AbciDialogues, - TendermintDialogue, - TendermintDialogues, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler, - AbstractResponseHandler, - TendermintHandler, - Transaction, - exception_to_info_msg, -) -from packages.valory.skills.abstract_round_abci.models import TendermintRecoveryParams -from packages.valory.skills.abstract_round_abci.test_tools.rounds import DummyRound - - -def test_exception_to_info_msg() -> None: - """Test 'exception_to_info_msg' helper function.""" - exception = Exception("exception message") - expected_string = f"{exception.__class__.__name__}: {str(exception)}" - actual_string = exception_to_info_msg(exception) - assert expected_string == actual_string - - -class TestABCIRoundHandler: - """Test 'ABCIRoundHandler'.""" - - def setup(self) -> None: - """Set up the tests.""" - self.context = MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")) - self.dialogues = AbciDialogues(name="", skill_context=self.context) - self.handler = ABCIRoundHandler(name="", skill_context=self.context) - self.context.state.round_sequence.height = 0 - self.context.state.round_sequence.root_hash = b"root_hash" - self.context.state.round_sequence.last_round_transition_timestamp = ( - datetime.now() - ) - - def test_info(self) -> None: - """Test the 'info' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_INFO, - version="", - block_version=0, - p2p_version=0, - ) - response = self.handler.info( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_INFO - - @pytest.mark.parametrize("app_hash", (b"", b"test")) - def test_init_chain(self, app_hash: bytes) -> None: - """Test the 'init_chain' handler method.""" - time = Timestamp(0, 0) - consensus_params = ConsensusParams(*(mock.MagicMock() for _ in range(4))) - validators = ValidatorUpdates(mock.MagicMock()) - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_INIT_CHAIN, - time=time, - chain_id="test_chain_id", - consensus_params=consensus_params, - validators=validators, - app_state_bytes=b"", - initial_height=10, - ) - self.context.state.round_sequence.last_round_transition_root_hash = app_hash - response = self.handler.init_chain( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_INIT_CHAIN - assert response.validators == ValidatorUpdates([]) - assert response.app_hash == app_hash - - def test_begin_block(self) -> None: - """Test the 'begin_block' handler method.""" - header = Header(*(MagicMock() for _ in range(14))) - last_commit_info = LastCommitInfo(*(MagicMock() for _ in range(2))) - byzantine_validators = Evidences(MagicMock()) - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_BEGIN_BLOCK, - hash=b"", - header=header, - last_commit_info=last_commit_info, - byzantine_validators=byzantine_validators, - ) - response = self.handler.begin_block( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_BEGIN_BLOCK - - @mock.patch.object(handlers, "Transaction") - def test_check_tx(self, *_: Any) -> None: - """Test the 'check_tx' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_CHECK_TX, - tx=b"", - type=CheckTxType(CheckTxTypeEnum.NEW), - ) - response = self.handler.check_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_CHECK_TX - assert response.code == OK_CODE - - @mock.patch.object( - Transaction, - "decode", - side_effect=SignatureNotValidError, - ) - def test_check_tx_negative(self, *_: Any) -> None: - """Test the 'check_tx' handler method, negative case.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_CHECK_TX, - tx=b"", - type=CheckTxType(CheckTxTypeEnum.NEW), - ) - response = self.handler.check_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_CHECK_TX - assert response.code == ERROR_CODE - - @mock.patch.object(handlers, "Transaction") - def test_deliver_tx(self, *_: Any) -> None: - """Test the 'deliver_tx' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - tx=b"", - ) - with mock.patch.object( - self.context.state.round_sequence, "add_pending_offence" - ) as mock_add_pending_offence: - response = self.handler.deliver_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - mock_add_pending_offence.assert_called_once() - - assert response.performative == AbciMessage.Performative.RESPONSE_DELIVER_TX - assert response.code == OK_CODE - - @mock.patch.object( - Transaction, - "decode", - side_effect=SignatureNotValidError, - ) - def test_deliver_tx_negative(self, *_: Any) -> None: - """Test the 'deliver_tx' handler method, negative case.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - tx=b"", - ) - with mock.patch.object( - self.context.state.round_sequence, "add_pending_offence" - ) as mock_add_pending_offence: - response = self.handler.deliver_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - mock_add_pending_offence.assert_not_called() - - assert response.performative == AbciMessage.Performative.RESPONSE_DELIVER_TX - assert response.code == ERROR_CODE - - @mock.patch.object(handlers, "Transaction") - def test_deliver_bad_tx(self, *_: Any) -> None: - """Test the 'deliver_tx' handler method, when the transaction is not ok.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_DELIVER_TX, - tx=b"", - ) - with mock.patch.object( - self.context.state.round_sequence, - "check_is_finished", - side_effect=TransactionNotValidError, - ), mock.patch.object( - self.context.state.round_sequence, "add_pending_offence" - ) as mock_add_pending_offence: - response = self.handler.deliver_tx( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - mock_add_pending_offence.assert_called_once() - - assert response.performative == AbciMessage.Performative.RESPONSE_DELIVER_TX - assert response.code == ERROR_CODE - - @pytest.mark.parametrize("request_height", tuple(range(3))) - def test_end_block(self, request_height: int) -> None: - """Test the 'end_block' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_END_BLOCK, - height=request_height, - ) - assert isinstance(message, AbciMessage) - assert isinstance(dialogue, AbciDialogue) - assert message.height == request_height - assert self.context.state.round_sequence.tm_height != request_height - response = self.handler.end_block(message, dialogue) - assert response.performative == AbciMessage.Performative.RESPONSE_END_BLOCK - assert self.context.state.round_sequence.tm_height == request_height - - def test_commit(self) -> None: - """Test the 'commit' handler method.""" - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_COMMIT, - ) - response = self.handler.commit( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - assert response.performative == AbciMessage.Performative.RESPONSE_COMMIT - - def test_commit_negative(self) -> None: - """Test the 'commit' handler method, negative case.""" - self.context.state.round_sequence.commit.side_effect = AddBlockError() - message, dialogue = self.dialogues.create( - counterparty="", - performative=AbciMessage.Performative.REQUEST_COMMIT, - ) - with pytest.raises(AddBlockError): - self.handler.commit( - cast(AbciMessage, message), cast(AbciDialogue, dialogue) - ) - - -class ConcreteResponseHandler(AbstractResponseHandler): - """A concrete response handler for testing purposes.""" - - SUPPORTED_PROTOCOL = HttpMessage.protocol_id - allowed_response_performatives = frozenset({HttpMessage.Performative.RESPONSE}) - - -class TestAbstractResponseHandler: - """Test 'AbstractResponseHandler'.""" - - def setup(self) -> None: - """Set up the tests.""" - self.context = MagicMock() - self.handler = ConcreteResponseHandler(name="", skill_context=self.context) - - def test_handle(self) -> None: - """Test the 'handle' method.""" - callback = MagicMock() - request_reference = "reference" - self.context.requests.request_id_to_callback = {} - self.context.requests.request_id_to_callback[request_reference] = callback - with mock.patch.object( - self.handler, "_recover_protocol_dialogues" - ) as mock_dialogues_fn: - mock_dialogue = MagicMock() - mock_dialogue.dialogue_label.dialogue_reference = (request_reference, "") - mock_dialogues = MagicMock() - mock_dialogues.update = MagicMock(return_value=mock_dialogue) - mock_dialogues_fn.return_value = mock_dialogues - mock_message = MagicMock(performative=HttpMessage.Performative.RESPONSE) - self.handler.handle(mock_message) - callback.assert_called() - - @mock.patch.object( - AbstractResponseHandler, "_recover_protocol_dialogues", return_value=None - ) - def test_handle_negative_cannot_recover_dialogues(self, *_: Any) -> None: - """Test the 'handle' method, negative case (cannot recover dialogues).""" - self.handler.handle(MagicMock()) - - @mock.patch.object(AbstractResponseHandler, "_recover_protocol_dialogues") - def test_handle_negative_cannot_update_dialogues( - self, mock_dialogues_fn: Any - ) -> None: - """Test the 'handle' method, negative case (cannot update dialogues).""" - mock_dialogues = MagicMock(update=MagicMock(return_value=None)) - mock_dialogues_fn.return_value = mock_dialogues - self.handler.handle(MagicMock()) - - def test_handle_negative_performative_not_allowed(self) -> None: - """Test the 'handle' method, negative case (performative not allowed).""" - self.handler.handle(MagicMock()) - - def test_handle_negative_cannot_find_callback(self) -> None: - """Test the 'handle' method, negative case (cannot find callback).""" - self.context.requests.request_id_to_callback = {} - with pytest.raises( - ABCIAppInternalError, match="No callback defined for request with nonce: " - ): - self.handler.handle( - MagicMock(performative=HttpMessage.Performative.RESPONSE) - ) - - -class TestTendermintHandler: - """Test Tendermint Handler""" - - def setup(self) -> None: - """Set up the tests.""" - self.agent_name = "Alice" - self.context = MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")) - other_agents = ["Alice", "Bob", "Charlie"] - self.context.state = MagicMock(acn_container=lambda: other_agents) - self.handler = TendermintHandler(name="dummy", skill_context=self.context) - self.handler.context.logger = logging.getLogger() - self.dialogues = TendermintDialogues(name="dummy", skill_context=self.context) - - @property - def dummy_validator_config(self) -> Dict[str, Dict[str, str]]: - """Dummy validator config""" - return { - self.agent_name: { - "hostname": "localhost", - "address": "address", - "pub_key": "pub_key", - "peer_id": "peer_id", - } - } - - @staticmethod - def make_error_message() -> TendermintMessage: - """Make dummy error message""" - performative = TendermintMessage.Performative.ERROR - error_code = TendermintMessage.ErrorCode.INVALID_REQUEST - error_msg, error_data = "", {} # type: ignore - message = TendermintMessage( - performative, # type: ignore - error_code=error_code, - error_msg=error_msg, - error_data=error_data, - ) - message.sender = "Alice" - return message - - # pre-condition checks - def test_handle_unidentified_tendermint_dialogue( - self, caplog: LogCaptureFixture - ) -> None: - """Test unidentified tendermint dialogue""" - message = Message() - with mock.patch.object(self.handler.dialogues, "update", return_value=None): - self.handler.handle(message) - log_message = self.handler.LogMessages.unidentified_dialogue.value - assert log_message in caplog.text - - def test_handle_no_addresses_retrieved_yet(self, caplog: LogCaptureFixture) -> None: - """Test handle request no registered addresses""" - performative = TendermintMessage.Performative.GET_GENESIS_INFO - message = TendermintMessage(performative) # type: ignore - message.sender = "Alice" - self.handler.initial_tm_configs = {} - self.handler.handle(message) - log_message = self.handler.LogMessages.no_addresses_retrieved_yet.value - assert log_message in caplog.text - log_message = self.handler.LogMessages.sending_error_response.value - assert log_message in caplog.text - - def test_handle_not_in_registered_addresses( - self, caplog: LogCaptureFixture - ) -> None: - """Test handle response sender not in registered addresses""" - performative = TendermintMessage.Performative.GENESIS_INFO - message = TendermintMessage(performative, info="info") # type: ignore - message.sender = "NotAlice" - self.handler.handle(message) - log_message = self.handler.LogMessages.not_in_registered_addresses.value - assert log_message in caplog.text - - # request - def test_handle_get_genesis_info(self, caplog: LogCaptureFixture) -> None: - """Test handle request for genesis info""" - performative = TendermintMessage.Performative.GET_GENESIS_INFO - message = TendermintMessage(performative) # type: ignore - self.context.agent_address = message.sender = self.agent_name - self.handler.initial_tm_configs = self.dummy_validator_config - self.handler.handle(message) - log_message = self.handler.LogMessages.sending_request_response.value - assert log_message in caplog.text - - # response - def test_handle_response_invalid_addresses(self, caplog: LogCaptureFixture) -> None: - """Test handle response for genesis info with invalid address.""" - validator_config = self.dummy_validator_config - validator_config[self.agent_name]["hostname"] = "random" - performative = TendermintMessage.Performative.GENESIS_INFO - info = json.dumps(validator_config[self.agent_name]) - message = TendermintMessage(performative, info=info) # type: ignore - self.context.agent_address = message.sender = self.agent_name - self.handler.initial_tm_configs = validator_config - self.handler.handle(message) - log_message = self.handler.LogMessages.failed_to_parse_address.value - assert log_message in caplog.text - - def test_handle_genesis_info(self, caplog: LogCaptureFixture) -> None: - """Test handle response for genesis info with valid address""" - performative = TendermintMessage.Performative.GENESIS_INFO - info = json.dumps(self.dummy_validator_config[self.agent_name]) - message = TendermintMessage(performative, info=info) # type: ignore - self.context.agent_address = message.sender = self.agent_name - self.handler.initial_tm_configs = self.dummy_validator_config - self.handler.handle(message) - log_message = self.handler.LogMessages.collected_config_info.value - assert log_message in caplog.text - - @pytest.mark.parametrize("registered", (True, False)) - @pytest.mark.parametrize( - "performative", - ( - TendermintMessage.Performative.RECOVERY_PARAMS, - TendermintMessage.Performative.GET_RECOVERY_PARAMS, - ), - ) - def test_recovery_params( - self, - registered: bool, - performative: TendermintMessage.Performative, - caplog: LogCaptureFixture, - ) -> None: - """Test handle response for recovery parameters.""" - if not registered: - self.agent_name = "not-registered" - - if performative == TendermintMessage.Performative.GET_RECOVERY_PARAMS: - self.context.state.tm_recovery_params = TendermintRecoveryParams( - "DummyRound" - ) - message = TendermintMessage(performative) # type: ignore - log_message = self.handler.LogMessages.sending_request_response.value - elif performative == TendermintMessage.Performative.RECOVERY_PARAMS: - params = json.dumps( - asdict(TendermintRecoveryParams(DummyRound.auto_round_id())) - ) - message = TendermintMessage(performative, params=params) # type: ignore - log_message = self.handler.LogMessages.collected_params.value - else: - raise AssertionError( - f"Invalid performative {performative} for `test_recovery_params`." - ) - - self.context.agent_address = message.sender = self.agent_name - tm_configs = {self.agent_name: {"dummy": "value"}} if registered else {} - - self.handler.initial_tm_configs = tm_configs - self.handler.handle(message) - - if not registered: - log_message = self.handler.LogMessages.not_in_registered_addresses.value - - assert log_message in caplog.text - - @pytest.mark.parametrize( - "side_effect, expected_exception", - ( - ( - json.decoder.JSONDecodeError("", "", 0), - ": line 1 column 1 (char 0)", - ), - ( - {"not a dict"}, - "argument after ** must be a mapping, not str", - ), - ), - ) - def test_recovery_params_error( - self, - side_effect: Any, - expected_exception: str, - caplog: LogCaptureFixture, - ) -> None: - """Test handle response for recovery parameters.""" - message = TendermintMessage( - TendermintMessage.Performative.RECOVERY_PARAMS, params=MagicMock() # type: ignore - ) - - self.context.agent_address = message.sender = self.agent_name - tm_configs = {self.agent_name: {"dummy": "value"}} - self.handler.initial_tm_configs = tm_configs - with mock.patch.object(json, "loads", side_effect=side_effect): - self.handler.handle(message) - - log_message = self.handler.LogMessages.failed_to_parse_params.value - assert log_message in caplog.text - assert expected_exception in caplog.text - - # error - def test_handle_error(self, caplog: LogCaptureFixture) -> None: - """Test handle error""" - message = self.make_error_message() - self.handler.initial_tm_configs = self.dummy_validator_config - self.handler.handle(message) - log_message = self.handler.LogMessages.received_error_response.value - assert log_message in caplog.text - - def test_handle_error_no_target_message_retrieved( - self, caplog: LogCaptureFixture - ) -> None: - """Test handle error no target message retrieved""" - message, nonce = self.make_error_message(), "0" - dialogue = TendermintDialogue(mock.Mock(), "Bob", mock.Mock()) - dialogue.dialogue_label.dialogue_reference = nonce, "stub" - self.handler.dialogues.update = lambda _: dialogue # type: ignore - callback = lambda *args, **kwargs: None # noqa: E731 - self.context.requests.request_id_to_callback = {nonce: callback} - self.handler.initial_tm_configs = self.dummy_validator_config - self.handler.handle(message) - log_message = ( - self.handler.LogMessages.received_error_without_target_message.value - ) - assert log_message in caplog.text - - # performative - def test_handle_performative_not_recognized( - self, caplog: LogCaptureFixture - ) -> None: - """Test performative no recognized""" - message = self.make_error_message() - message._slots.performative = MagicMock(value="wacky") - self.handler.initial_tm_configs = self.dummy_validator_config - self.handler.handle(message) - log_message = self.handler.LogMessages.performative_not_recognized.value - assert log_message in caplog.text - - def test_sender_not_in_registered_addresses( - self, caplog: LogCaptureFixture - ) -> None: - """Test sender not in registered addresses.""" - - performative = TendermintMessage.Performative.GET_GENESIS_INFO - message = TendermintMessage(performative) # type: ignore - self.context.agent_address = message.sender = "dummy" - self.handler.initial_tm_configs = self.dummy_validator_config - self.handler.handle(message) - log_message = self.handler.LogMessages.not_in_registered_addresses.value - assert log_message in caplog.text diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/__init__.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/__init__.py deleted file mode 100644 index b640bcf74..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Package for `io` testing.""" diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/test_ipfs.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/test_ipfs.py deleted file mode 100644 index ce81b61a7..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/test_ipfs.py +++ /dev/null @@ -1,110 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 tests for the `IPFS` interactions.""" - -# pylint: skip-file - -import os -from pathlib import PosixPath -from typing import Any, Dict, cast -from unittest import mock - -import pytest - -from packages.valory.skills.abstract_round_abci.io_.ipfs import ( - IPFSInteract, - IPFSInteractionError, -) -from packages.valory.skills.abstract_round_abci.io_.load import AbstractLoader -from packages.valory.skills.abstract_round_abci.io_.store import ( - AbstractStorer, - StoredJSONType, - SupportedFiletype, -) - - -use_ipfs_daemon = pytest.mark.usefixtures("ipfs_daemon") - - -class TestIPFSInteract: - """Test `IPFSInteract`.""" - - def setup(self) -> None: - """Setup test class.""" - self.ipfs_interact = IPFSInteract() - - @pytest.mark.parametrize("multiple", (True, False)) - def test_store_and_send_and_back( - self, - multiple: bool, - dummy_obj: StoredJSONType, - dummy_multiple_obj: Dict[str, StoredJSONType], - tmp_path: PosixPath, - ) -> None: - """Test store -> send -> download -> read of objects.""" - obj: StoredJSONType - if multiple: - obj = dummy_multiple_obj - filepath = "dummy_dir" - else: - obj = dummy_obj - filepath = "test_file.json" - - filepath = str(tmp_path / filepath) - serialized_objects = self.ipfs_interact.store( - filepath, obj, multiple, SupportedFiletype.JSON - ) - expected_objects = obj - actual_objects = cast( - Dict[str, Any], - self.ipfs_interact.load( - serialized_objects, - SupportedFiletype.JSON, - ), - ) - if multiple: - # here we manually remove the trailing the dir from the name. - # This is done by the IPFS connection under normal circumstances. - actual_objects = {os.path.basename(k): v for k, v in actual_objects.items()} - - assert actual_objects == expected_objects - - def test_store_fails(self, dummy_multiple_obj: Dict[str, StoredJSONType]) -> None: - """Tests when "store" fails.""" - dummy_filepath = "dummy_dir" - multiple = False - with mock.patch.object( - AbstractStorer, - "store", - side_effect=ValueError, - ), pytest.raises(IPFSInteractionError): - self.ipfs_interact.store( - dummy_filepath, dummy_multiple_obj, multiple, SupportedFiletype.JSON - ) - - def test_load_fails(self, dummy_multiple_obj: Dict[str, StoredJSONType]) -> None: - """Tests when "load" fails.""" - dummy_object = {"test": "test"} - with mock.patch.object( - AbstractLoader, - "load", - side_effect=ValueError, - ), pytest.raises(IPFSInteractionError): - self.ipfs_interact.load(dummy_object) diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/test_load.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/test_load.py deleted file mode 100644 index ae48cefca..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/test_load.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for the loading functionality of abstract round abci.""" - -# pylint: skip-file - -import json -from typing import Optional, cast - -import pytest - -from packages.valory.skills.abstract_round_abci.io_.load import ( - CustomLoaderType, - JSONLoader, - Loader, - SupportedLoaderType, -) -from packages.valory.skills.abstract_round_abci.io_.store import SupportedFiletype - - -class TestLoader: - """Tests for the `Loader`.""" - - def setup(self) -> None: - """Setup the tests.""" - self.json_loader = Loader(SupportedFiletype.JSON, None) - - def __dummy_custom_loader(self) -> None: - """A dummy custom loading function to use for the tests.""" - - @staticmethod - @pytest.mark.parametrize( - "filetype, custom_loader, expected_loader", - ( - (None, None, None), - (SupportedFiletype.JSON, None, JSONLoader.load_single_object), - ( - SupportedFiletype.JSON, - __dummy_custom_loader, - JSONLoader.load_single_object, - ), - (None, __dummy_custom_loader, __dummy_custom_loader), - ), - ) - def test__get_loader_from_filetype( - filetype: Optional[SupportedFiletype], - custom_loader: CustomLoaderType, - expected_loader: Optional[SupportedLoaderType], - ) -> None: - """Test `_get_loader_from_filetype`.""" - if all( - test_arg is None for test_arg in (filetype, custom_loader, expected_loader) - ): - with pytest.raises( - ValueError, - match="Please provide either a supported filetype or a custom loader function.", - ): - Loader(filetype, custom_loader)._get_single_loader_from_filetype() - - else: - expected_loader = cast(SupportedLoaderType, expected_loader) - loader = Loader(filetype, custom_loader) - assert ( - loader._get_single_loader_from_filetype().__code__.co_code - == expected_loader.__code__.co_code - ) - - def test_load(self) -> None: - """Test `load`.""" - expected_object = dummy_object = {"test": "test"} - filename = "test" - serialized_object = json.dumps(dummy_object) - actual_object = self.json_loader.load({filename: serialized_object}) - assert expected_object == actual_object - - def test_no_object(self) -> None: - """Test `load` throws error when no object is provided.""" - with pytest.raises( - ValueError, - match='"serialized_objects" does not contain any objects', - ): - self.json_loader.load({}) - - def test_load_multiple_objects(self) -> None: - """Test `load` when multiple objects are to be deserialized.""" - dummy_object = {"test": "test"} - serialized_object = json.dumps(dummy_object) - serialized_objects = { - "obj1": serialized_object, - "obj2": serialized_object, - } - expected_objects = { - "obj1": dummy_object, - "obj2": dummy_object, - } - actual_objects = self.json_loader.load(serialized_objects) - assert expected_objects == actual_objects diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/test_store.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/test_store.py deleted file mode 100644 index eae3d53b0..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_io/test_store.py +++ /dev/null @@ -1,104 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for the storing functionality of abstract round abci.""" - -# pylint: skip-file - -import json -from pathlib import Path, PosixPath -from typing import Optional, cast - -import pytest - -from packages.valory.skills.abstract_round_abci.io_.store import ( - CustomStorerType, - JSONStorer, - Storer, - SupportedFiletype, - SupportedStorerType, -) - - -class TestStorer: - """Tests for the `Storer`.""" - - def setup(self) -> None: - """Setup the tests.""" - self.path = "tmp" - self.json_storer = Storer(SupportedFiletype.JSON, None, self.path) - - def __dummy_custom_storer(self) -> None: - """A dummy custom storing function to use for the tests.""" - - @staticmethod - @pytest.mark.parametrize( - "filetype, custom_storer, expected_storer", - ( - (None, None, None), - (SupportedFiletype.JSON, None, JSONStorer.serialize_object), - ( - SupportedFiletype.JSON, - __dummy_custom_storer, - JSONStorer.serialize_object, - ), - (None, __dummy_custom_storer, __dummy_custom_storer), - ), - ) - def test__get_single_storer_from_filetype( - filetype: Optional[SupportedFiletype], - custom_storer: Optional[CustomStorerType], - expected_storer: Optional[SupportedStorerType], - tmp_path: PosixPath, - ) -> None: - """Test `_get_single_storer_from_filetype`.""" - if all( - test_arg is None for test_arg in (filetype, custom_storer, expected_storer) - ): - with pytest.raises( - ValueError, - match="Please provide either a supported filetype or a custom storing function.", - ): - Storer( - filetype, custom_storer, str(tmp_path) - )._get_single_storer_from_filetype() - - else: - expected_storer = cast(SupportedStorerType, expected_storer) - storer = Storer(filetype, custom_storer, str(tmp_path)) - assert ( - storer._get_single_storer_from_filetype().__code__.co_code - == expected_storer.__code__.co_code - ) - - def test_store(self) -> None: - """Test `store`.""" - dummy_object = {"test": "test"} - expected_object = {self.path: json.dumps(dummy_object, indent=4)} - actual_object = self.json_storer.store(dummy_object, False) - assert expected_object == actual_object - - def test_store_multiple(self) -> None: - """Test `store` when multiple files are present.""" - dummy_object = {"test": "test"} - dummy_filename = "test" - expected_path = Path(f"{self.path}/{dummy_filename}").__str__() - expected_object = {expected_path: json.dumps(dummy_object, indent=4)} - actual_object = self.json_storer.store({dummy_filename: dummy_object}, True) - assert expected_object == actual_object diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_models.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_models.py deleted file mode 100644 index ee598b722..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_models.py +++ /dev/null @@ -1,901 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the models.py module of the skill.""" - -# pylint: skip-file - -import builtins -import json -import logging -import re -from collections import OrderedDict -from dataclasses import dataclass -from enum import Enum -from pathlib import Path -from tempfile import TemporaryDirectory -from time import sleep -from typing import Any, Dict, List, Optional, Set, Tuple, Type, cast -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from aea.exceptions import AEAEnforceError -from typing_extensions import Literal, TypedDict - -from packages.valory.skills.abstract_round_abci.base import ( - AbstractRound, - BaseSynchronizedData, - OffenceStatus, - OffenseStatusEncoder, - ROUND_COUNT_DEFAULT, -) -from packages.valory.skills.abstract_round_abci.models import ( - ApiSpecs, - BaseParams, - BenchmarkTool, - DEFAULT_BACKOFF_FACTOR, - GenesisBlock, - GenesisConfig, - GenesisConsensusParams, - GenesisEvidence, - GenesisValidator, - MIN_RESET_PAUSE_DURATION, - NUMBER_OF_RETRIES, - Requests, -) -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.abstract_round_abci.models import ( - TendermintRecoveryParams, - _MetaSharedState, - check_type, -) -from packages.valory.skills.abstract_round_abci.test_tools.abci_app import AbciAppTest -from packages.valory.skills.abstract_round_abci.tests.conftest import ( - irrelevant_genesis_config, -) - - -BASE_DUMMY_SPECS_CONFIG = dict( - name="dummy", - skill_context=MagicMock(), - url="http://dummy", - api_id="api_id", - method="GET", - headers=OrderedDict([("Dummy-Header", "dummy_value")]), - parameters=OrderedDict([("Dummy-Param", "dummy_param")]), -) - -BASE_DUMMY_PARAMS = dict( - name="", - skill_context=MagicMock(is_abstract_component=True), - setup={}, - tendermint_url="", - max_healthcheck=1, - round_timeout_seconds=1.0, - sleep_time=1, - retry_timeout=1, - retry_attempts=1, - reset_pause_duration=MIN_RESET_PAUSE_DURATION, - drand_public_key="", - tendermint_com_url="", - reset_tendermint_after=1, - service_id="abstract_round_abci", - service_registry_address="0xa51c1fc2f0d1a1b8494ed1fe312d7c3a78ed91c0", - keeper_timeout=1.0, - tendermint_check_sleep_delay=3, - tendermint_max_retries=5, - cleanup_history_depth=0, - genesis_config=irrelevant_genesis_config, - cleanup_history_depth_current=None, - request_timeout=0.0, - request_retry_delay=0.0, - tx_timeout=0.0, - max_attempts=0, - on_chain_service_id=None, - share_tm_config_on_startup=False, - tendermint_p2p_url="", - use_termination=False, - use_slashing=False, - slash_cooldown_hours=3, - slash_threshold_amount=10_000_000_000_000_000, - light_slash_unit_amount=5_000_000_000_000_000, - serious_slash_unit_amount=8_000_000_000_000_000, -) - - -class TestApiSpecsModel: - """Test ApiSpecsModel.""" - - api_specs: ApiSpecs - - def setup( - self, - ) -> None: - """Setup test.""" - - self.api_specs = ApiSpecs( - **BASE_DUMMY_SPECS_CONFIG, - response_key="value", - response_index=0, - response_type="float", - error_key="error", - error_index=None, - error_type="str", - error_data="error text", - ) - - def test_init( - self, - ) -> None: - """Test initialization.""" - - # test ensure method. - with pytest.raises( - AEAEnforceError, - match="'url' of type '' required, but it is not set in `models.params.args` of `skill.yaml` of", - ): - _ = ApiSpecs( - name="dummy", - skill_context=MagicMock(), - ) - - assert self.api_specs.retries_info.backoff_factor == DEFAULT_BACKOFF_FACTOR - assert self.api_specs.retries_info.retries == NUMBER_OF_RETRIES - assert self.api_specs.retries_info.retries_attempted == 0 - - assert self.api_specs.url == "http://dummy" - assert self.api_specs.api_id == "api_id" - assert self.api_specs.method == "GET" - assert self.api_specs.headers == {"Dummy-Header": "dummy_value"} - assert self.api_specs.parameters == {"Dummy-Param": "dummy_param"} - assert self.api_specs.response_info.response_key == "value" - assert self.api_specs.response_info.response_index == 0 - assert self.api_specs.response_info.response_type == "float" - assert self.api_specs.response_info.error_key == "error" - assert self.api_specs.response_info.error_index is None - assert self.api_specs.response_info.error_type == "str" - assert self.api_specs.response_info.error_data is None - - @pytest.mark.parametrize("retries", range(10)) - def test_suggested_sleep_time(self, retries: int) -> None: - """Test `suggested_sleep_time`""" - self.api_specs.retries_info.retries_attempted = retries - assert ( - self.api_specs.retries_info.suggested_sleep_time - == DEFAULT_BACKOFF_FACTOR**retries - ) - - def test_retries( - self, - ) -> None: - """Tests for retries.""" - - self.api_specs.increment_retries() - assert self.api_specs.retries_info.retries_attempted == 1 - assert not self.api_specs.is_retries_exceeded() - - for _ in range(NUMBER_OF_RETRIES): - self.api_specs.increment_retries() - assert self.api_specs.is_retries_exceeded() - self.api_specs.reset_retries() - assert self.api_specs.retries_info.retries_attempted == 0 - - def test_get_spec( - self, - ) -> None: - """Test get_spec method.""" - - actual_specs = { - "url": "http://dummy", - "method": "GET", - "headers": {"Dummy-Header": "dummy_value"}, - "parameters": {"Dummy-Param": "dummy_param"}, - } - - specs = self.api_specs.get_spec() - assert all([key in specs for key in actual_specs.keys()]) - assert all([specs[key] == actual_specs[key] for key in actual_specs]) - - @pytest.mark.parametrize( - "api_specs_config, message, expected_res, expected_error", - ( - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="value", - response_index=None, - response_type="float", - error_key=None, - error_index=None, - error_data=None, - ), - MagicMock(body=b'{"value": "10.232"}'), - 10.232, - None, - ), - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="test:response:key", - response_index=2, - response_type="dict", - error_key="error:key", - error_index=3, - error_type="str", - error_data=None, - ), - MagicMock( - body=b'{"test": {"response": {"key": ["does_not_matter", "does_not_matter", {"this": "matters"}]}}}' - ), - {"this": "matters"}, - None, - ), - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="test:response:key", - response_index=2, - error_key="error:key", - error_index=3, - error_type="str", - error_data=None, - ), - MagicMock(body=b'{"cannot be parsed'), - None, - None, - ), - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="test:response:key", - response_index=2, - error_key="error:key", - error_index=3, - error_type="str", - error_data=None, - ), - MagicMock( - # the null will raise `TypeError` and we test that it is handled - body=b'{"test": {"response": {"key": ["does_not_matter", "does_not_matter", null]}}}' - ), - "None", - None, - ), - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="test:response:key", - response_index=2, # this will raise `IndexError` and we test that it is handled - error_key="error:key", - error_index=3, - error_type="str", - error_data=None, - ), - MagicMock( - body=b'{"test": {"response": {"key": ["does_not_matter", "does_not_matter"]}}}' - ), - None, - None, - ), - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="test:response:key", # this will raise `KeyError` and we test that it is handled - response_index=2, - error_key="error:key", - error_index=3, - error_type="str", - error_data=None, - ), - MagicMock( - body=b'{"test": {"response": {"key_does_not_match": ["does_not_matter", "does_not_matter"]}}}' - ), - None, - None, - ), - ( - dict( - **BASE_DUMMY_SPECS_CONFIG, - response_key="test:response:key", - response_index=2, - error_key="error:key", - error_index=3, - error_type="str", - error_data=None, - ), - MagicMock( - body=b'{"test": {"response": {"key_does_not_match": ["does_not_matter", "does_not_matter"]}}, ' - b'"error": {"key": [0, 1, 2, "test that the error is being parsed correctly"]}}' - ), - None, - "test that the error is being parsed correctly", - ), - ), - ) - def test_process_response( - self, - api_specs_config: dict, - message: MagicMock, - expected_res: Any, - expected_error: Any, - ) -> None: - """Test `process_response` method.""" - api_specs = ApiSpecs(**api_specs_config) - actual = api_specs.process_response(message) - assert actual == expected_res - response_type = api_specs_config.get("response_type", None) - if response_type is not None: - assert type(actual) == getattr(builtins, response_type) - assert api_specs.response_info.error_data == expected_error - - def test_attribute_manipulation(self) -> None: - """Test manipulating the attributes.""" - with pytest.raises(AttributeError, match="This object is frozen!"): - del self.api_specs.url - - with pytest.raises(AttributeError, match="This object is frozen!"): - self.api_specs.url = "" - - self.api_specs.__dict__["_frozen"] = False - self.api_specs.url = "" - del self.api_specs.url - - -class ConcreteRound(AbstractRound): - """A ConcreteRoundA for testing purposes.""" - - synchronized_data_class = MagicMock() - payload_attribute = MagicMock() - payload_class = MagicMock() - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Handle the end of the block.""" - - -class SharedState(BaseSharedState): - """Shared State for testing purposes.""" - - abci_app_cls = AbciAppTest - - -class TestSharedState: - """Test SharedState(Model) class.""" - - def test_initialization(self, *_: Any) -> None: - """Test the initialization of the shared state.""" - SharedState(name="", skill_context=MagicMock()) - - @staticmethod - def dummy_state_setup(shared_state: SharedState) -> None: - """Setup a shared state instance with dummy params.""" - shared_state.context.params.setup_params = { - "test": [], - "all_participants": list(range(4)), - } - shared_state.setup() - - @pytest.mark.parametrize( - "acn_configured_agents, validator_to_agent, raises", - ( - ( - {i for i in range(4)}, - {f"validator_address_{i}": i for i in range(4)}, - False, - ), - ( - {i for i in range(5)}, - {f"validator_address_{i}": i for i in range(4)}, - True, - ), - ( - {i for i in range(4)}, - {f"validator_address_{i}": i for i in range(5)}, - True, - ), - ), - ) - def test_setup_slashing( - self, - acn_configured_agents: Set[str], - validator_to_agent: Dict[str, str], - raises: bool, - ) -> None: - """Test the `validator_to_agent` properties.""" - shared_state = SharedState(name="", skill_context=MagicMock()) - self.dummy_state_setup(shared_state) - - if not raises: - shared_state.initial_tm_configs = dict.fromkeys(acn_configured_agents) - shared_state.setup_slashing(validator_to_agent) - assert shared_state.round_sequence.validator_to_agent == validator_to_agent - - status = shared_state.round_sequence.offence_status - encoded_status = json.dumps( - status, - cls=OffenseStatusEncoder, - ) - expected_status = { - agent: OffenceStatus() for agent in acn_configured_agents - } - encoded_expected_status = json.dumps( - expected_status, cls=OffenseStatusEncoder - ) - - assert encoded_status == encoded_expected_status - - random_agent = acn_configured_agents.pop() - status[random_agent].num_unknown_offenses = 10 - assert status[random_agent].num_unknown_offenses == 10 - - for other_agent in acn_configured_agents - {random_agent}: - assert status[other_agent].num_unknown_offenses == 0 - - return - - expected_diff = acn_configured_agents.symmetric_difference( - validator_to_agent.values() - ) - with pytest.raises( - ValueError, - match=re.escape( - f"Trying to use the mapping `{validator_to_agent}`, which contains validators for non-configured " - "agents and/or does not contain validators for some configured agents. The agents which have been " - f"configured via ACN are `{acn_configured_agents}` and the diff was for {expected_diff}." - ), - ): - shared_state.initial_tm_configs = dict.fromkeys(acn_configured_agents) - shared_state.setup_slashing(validator_to_agent) - - def test_setup(self, *_: Any) -> None: - """Test setup method.""" - shared_state = SharedState( - name="", skill_context=MagicMock(is_abstract_component=False) - ) - assert shared_state.initial_tm_configs == {} - self.dummy_state_setup(shared_state) - assert shared_state.initial_tm_configs == {i: None for i in range(4)} - - @pytest.mark.parametrize( - "initial_tm_configs, address_input, exception, expected", - ( - ( - {}, - "0x1", - "The validator address of non-participating agent `0x1` was requested.", - None, - ), - ({}, "0x0", "SharedState's setup was not performed successfully.", None), - ( - {"0x0": None}, - "0x0", - "ACN registration has not been successfully performed for agent `0x0`. " - "Have you set the `share_tm_config_on_startup` flag to `true` in the configuration?", - None, - ), - ( - {"0x0": {}}, - "0x0", - "The tendermint configuration for agent `0x0` is invalid: `{}`.", - None, - ), - ( - {"0x0": {"address": None}}, - "0x0", - "The tendermint configuration for agent `0x0` is invalid: `{'address': None}`.", - None, - ), - ( - {"0x0": {"address": "test_validator_address"}}, - "0x0", - None, - "test_validator_address", - ), - ), - ) - def test_get_validator_address( - self, - initial_tm_configs: Dict[str, Optional[Dict[str, Any]]], - address_input: str, - exception: Optional[str], - expected: Optional[str], - ) -> None: - """Test `get_validator_address` method.""" - shared_state = SharedState(name="", skill_context=MagicMock()) - with mock.patch.object(shared_state.context, "params") as mock_params: - mock_params.setup_params = { - "all_participants": ["0x0"], - } - shared_state.setup() - shared_state.initial_tm_configs = initial_tm_configs - if exception is None: - assert shared_state.get_validator_address(address_input) == expected - return - with pytest.raises(ValueError, match=exception): - shared_state.get_validator_address(address_input) - - @pytest.mark.parametrize("self_idx", (range(4))) - def test_acn_container(self, self_idx: int) -> None: - """Test the `acn_container` method.""" - - shared_state = SharedState( - name="", skill_context=MagicMock(agent_address=self_idx) - ) - self.dummy_state_setup(shared_state) - expected = {i: None for i in range(4) if i != self_idx} - assert shared_state.acn_container() == expected - - def test_synchronized_data_negative_not_available(self, *_: Any) -> None: - """Test 'synchronized_data' property getter, negative case (not available).""" - shared_state = SharedState(name="", skill_context=MagicMock()) - with pytest.raises(ValueError, match="round sequence not available"): - shared_state.synchronized_data - - def test_synchronized_data_positive(self, *_: Any) -> None: - """Test 'synchronized_data' property getter, negative case (not available).""" - shared_state = SharedState(name="", skill_context=MagicMock()) - shared_state.context.params.setup_params = { - "test": [], - "all_participants": [["0x0"]], - } - shared_state.setup() - shared_state.round_sequence.abci_app._round_results = [MagicMock()] - shared_state.synchronized_data - - def test_synchronized_data_db(self, *_: Any) -> None: - """Test 'synchronized_data' AbciAppDB.""" - shared_state = SharedState(name="", skill_context=MagicMock()) - with mock.patch.object(shared_state.context, "params") as mock_params: - mock_params.setup_params = { - "safe_contract_address": "0xsafe", - "oracle_contract_address": "0xoracle", - "all_participants": "0x0", - } - shared_state.setup() - for key, value in mock_params.setup_params.items(): - assert shared_state.synchronized_data.db.get_strict(key) == value - - @pytest.mark.parametrize( - "address_to_acn_deliverable, n_participants, expected", - ( - ({}, 4, None), - ({i: "test" for i in range(4)}, 4, "test"), - ( - {i: TendermintRecoveryParams("test") for i in range(4)}, - 4, - TendermintRecoveryParams("test"), - ), - ({1: "test", 2: "non-matching", 3: "test", 4: "test"}, 4, "test"), - ({i: "test" for i in range(4)}, 4, "test"), - ({1: "no", 2: "result", 3: "matches", 4: ""}, 4, None), - ), - ) - def test_get_acn_result( - self, - address_to_acn_deliverable: Dict[str, Any], - n_participants: int, - expected: Optional[str], - ) -> None: - """Test `get_acn_result`.""" - shared_state = SharedState( - abci_app_cls=AbciAppTest, name="", skill_context=MagicMock() - ) - shared_state.context.params.setup_params = { - "test": [], - "all_participants": ["0x0"], - } - shared_state.setup() - shared_state.synchronized_data.update(participants=tuple(range(n_participants))) - shared_state.address_to_acn_deliverable = address_to_acn_deliverable - actual = shared_state.get_acn_result() - - assert actual == expected - - def test_recovery_params_on_init(self) -> None: - """Test that `tm_recovery_params` get initialized correctly.""" - shared_state = SharedState(name="", skill_context=MagicMock()) - assert shared_state.tm_recovery_params is not None - assert shared_state.tm_recovery_params.round_count == ROUND_COUNT_DEFAULT - assert ( - shared_state.tm_recovery_params.reset_from_round - == AbciAppTest.initial_round_cls.auto_round_id() - ) - assert shared_state.tm_recovery_params.reset_params is None - - def test_set_last_reset_params(self) -> None: - """Test that `last_reset_params` get set correctly.""" - shared_state = SharedState(name="", skill_context=MagicMock()) - test_params = [("genesis_time", "some-time"), ("initial_height", "0")] - shared_state.last_reset_params = test_params - assert shared_state.last_reset_params == test_params - - -class TestBenchmarkTool: - """Test BenchmarkTool""" - - @staticmethod - def _check_behaviour_data(data: List, agent_name: str) -> None: - """Check behaviour data.""" - assert len(data) == 1 - - (behaviour_data,) = data - assert behaviour_data["behaviour"] == agent_name - assert all( - [key in behaviour_data["data"] for key in ("local", "consensus", "total")] - ) - - def test_end_2_end(self) -> None: - """Test end 2 end of the tool.""" - - agent_name = "agent" - skill_context = MagicMock( - agent_address=agent_name, logger=MagicMock(info=logging.info) - ) - - with TemporaryDirectory() as temp_dir: - benchmark = BenchmarkTool( - name=agent_name, skill_context=skill_context, log_dir=temp_dir - ) - - with benchmark.measure(agent_name).local(): - sleep(1.0) - - with benchmark.measure(agent_name).consensus(): - sleep(1.0) - - self._check_behaviour_data(benchmark.data, agent_name) - - benchmark.save() - - benchmark_dir = Path(temp_dir, agent_name) - benchmark_file = benchmark_dir / "0.json" - assert (benchmark_file).is_file() - - behaviour_data = json.loads(benchmark_file.read_text()) - self._check_behaviour_data(behaviour_data, agent_name) - - -def test_requests_model_initialization() -> None: - """Test initialization of the 'Requests(Model)' class.""" - Requests(name="", skill_context=MagicMock()) - - -def test_base_params_model_initialization() -> None: - """Test initialization of the 'BaseParams(Model)' class.""" - kwargs = BASE_DUMMY_PARAMS.copy() - bp = BaseParams(**kwargs) - - with pytest.raises(AttributeError, match="This object is frozen!"): - bp.request_timeout = 0.1 - - with pytest.raises(AttributeError, match="This object is frozen!"): - del bp.request_timeout - - bp.__dict__["_frozen"] = False - del bp.request_timeout - - assert getattr(bp, "request_timeout", None) is None - - kwargs["skill_context"] = MagicMock(is_abstract_component=False) - required_setup_params = { - "safe_contract_address": "0x0", - "all_participants": ["0x0"], - "consensus_threshold": 1, - } - kwargs["setup"] = required_setup_params - BaseParams(**kwargs) - - -@pytest.mark.parametrize( - "setup, error_text", - ( - ({}, "`setup` params contain no values!"), - ( - {"a": "b"}, - "Value for `safe_contract_address` missing from the `setup` params.", - ), - ), -) -def test_incorrect_setup(setup: Dict[str, Any], error_text: str) -> None: - """Test BaseParams model initialization with incorrect setup data.""" - kwargs = BASE_DUMMY_PARAMS.copy() - - with pytest.raises( - AEAEnforceError, - match=error_text, - ): - kwargs["skill_context"] = MagicMock(is_abstract_component=False) - kwargs["setup"] = setup - BaseParams(**kwargs) - - with pytest.raises( - AEAEnforceError, - match=f"`reset_pause_duration` must be greater than or equal to {MIN_RESET_PAUSE_DURATION}", - ): - kwargs["reset_pause_duration"] = MIN_RESET_PAUSE_DURATION - 1 - BaseParams(**kwargs) - - -def test_genesis_block() -> None: - """Test genesis block methods.""" - json = {"max_bytes": "a", "max_gas": "b", "time_iota_ms": "c"} - gb = GenesisBlock(**json) - assert gb.to_json() == json - - with pytest.raises(TypeError, match="Error in field 'max_bytes'. Expected type .*"): - json["max_bytes"] = 0 # type: ignore - GenesisBlock(**json) - - -def test_genesis_evidence() -> None: - """Test genesis evidence methods.""" - json = {"max_age_num_blocks": "a", "max_age_duration": "b", "max_bytes": "c"} - ge = GenesisEvidence(**json) - assert ge.to_json() == json - - -def test_genesis_validator() -> None: - """Test genesis validator methods.""" - json = {"pub_key_types": ["a", "b"]} - ge = GenesisValidator(pub_key_types=tuple(json["pub_key_types"])) - assert ge.to_json() == json - - with pytest.raises( - TypeError, match="Error in field 'pub_key_types'. Expected type .*" - ): - GenesisValidator(**json) # type: ignore - - -def test_genesis_consensus_params() -> None: - """Test genesis consensus params methods.""" - consensus_params = cast(Dict, irrelevant_genesis_config["consensus_params"]) - gcp = GenesisConsensusParams.from_json_dict(consensus_params) - assert gcp.to_json() == consensus_params - - -def test_genesis_config() -> None: - """Test genesis config methods.""" - gcp = GenesisConfig.from_json_dict(irrelevant_genesis_config) - assert gcp.to_json() == irrelevant_genesis_config - - -def test_meta_shared_state_when_instance_not_subclass_of_shared_state() -> None: - """Test instantiation of meta class when instance not a subclass of shared state.""" - - class MySharedState(metaclass=_MetaSharedState): - pass - - -def test_shared_state_instantiation_without_attributes_raises_error() -> None: - """Test that definition of concrete subclass of SharedState without attributes raises error.""" - with pytest.raises(AttributeError, match="'abci_app_cls' not set on .*"): - - class MySharedState(BaseSharedState): - pass - - with pytest.raises(AttributeError, match="The object `None` is not a class"): - - class MySharedStateB(BaseSharedState): - abci_app_cls = None # type: ignore - - with pytest.raises( - AttributeError, - match="The class is not an instance of packages.valory.skills.abstract_round_abci.base.AbciApp", - ): - - class MySharedStateC(BaseSharedState): - abci_app_cls = MagicMock - - -@dataclass -class A: - """Class for testing.""" - - value: int - - -@dataclass -class B: - """Class for testing.""" - - value: str - - -class C(TypedDict): - """Class for testing.""" - - name: str - year: int - - -class D(TypedDict, total=False): - """Class for testing.""" - - name: str - year: int - - -testdata_positive = [ - ("test_arg", 1, int), - ("test_arg", "1", str), - ("test_arg", True, bool), - ("test_arg", 1, Optional[int]), - ("test_arg", None, Optional[int]), - ("test_arg", "1", Optional[str]), - ("test_arg", None, Optional[str]), - ("test_arg", None, Optional[bool]), - ("test_arg", None, Optional[List[int]]), - ("test_arg", [], Optional[List[int]]), - ("test_arg", [1], Optional[List[int]]), - ("test_arg", {"str": 1}, Optional[Dict[str, int]]), - ("test_arg", {"str": A(1)}, Dict[str, A]), - ("test_arg", [("1", "2")], List[Tuple[str, str]]), - ("test_arg", [1], List[Optional[int]]), - ("test_arg", [1, None], List[Optional[int]]), - ("test_arg", A, Type[A]), - ("test_arg", A, Optional[Type[A]]), - ("test_arg", None, Optional[Type[A]]), - ("test_arg", MagicMock(), Optional[Type[A]]), # any type allowed - ("test_arg", {"name": "str", "year": 1}, C), - ("test_arg", 42, Literal[42]), - ("test_arg", {"name": "str"}, D), -] - - -@pytest.mark.parametrize("name,value,type_hint", testdata_positive) -def test_type_check_positive(name: str, value: Any, type_hint: Any) -> None: - """Test the type check mixin.""" - - check_type(name, value, type_hint) - - -testdata_negative = [ - ("test_arg", "1", int), - ("test_arg", 1, str), - ("test_arg", None, bool), - ("test_arg", "1", Optional[int]), - ("test_arg", 1, Optional[str]), - ("test_arg", 1, Optional[bool]), - ("test_arg", ["1"], Optional[List[int]]), - ("test_arg", {"str": "1"}, Optional[Dict[str, int]]), - ("test_arg", {1: 1}, Optional[Dict[str, int]]), - ("test_arg", {"str": B("1")}, Dict[str, A]), - ("test_arg", [()], List[Tuple[str, str]]), - ("test_arg", [("1",)], List[Tuple[str, str]]), - ("test_arg", [("1", 1)], List[Tuple[str, str]]), - ("test_arg", [("1", 1, "1")], List[Tuple[str, ...]]), - ("test_arg", ["1"], List[Optional[int]]), - ("test_arg", [1, None, "1"], List[Optional[int]]), - ("test_arg", B, Type[A]), - ("test_arg", B, Optional[Type[A]]), - ("test_arg", {"name": "str", "year": "1"}, C), - ("test_arg", 41, Literal[42]), - ("test_arg", C({"name": "str", "year": 1}), A), - ("test_arg", {"name": "str"}, C), -] - - -@pytest.mark.parametrize("name,value,type_hint", testdata_negative) -def test_type_check_negative(name: str, value: Any, type_hint: Any) -> None: - """Test the type check mixin.""" - - with pytest.raises(TypeError): - check_type(name, value, type_hint) diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/__init__.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/__init__.py deleted file mode 100644 index 261d2d3cb..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Package for `test_tools` testing.""" diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/base.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/base.py deleted file mode 100644 index 859557464..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/base.py +++ /dev/null @@ -1,86 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for abstract_round_abci/test_tools/common.py""" - -from pathlib import Path -from typing import Any, Dict, Type, cast - -from aea.helpers.base import cd -from aea.test_tools.utils import copy_class - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload, _MetaPayload -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci import ( - PATH_TO_SKILL, -) - - -class FSMBehaviourTestToolSetup: - """BaseRandomnessBehaviourTestSetup""" - - test_cls: Type[FSMBehaviourBaseCase] - __test_cls: Type[FSMBehaviourBaseCase] - __old_value: Dict[str, Type[BaseTxPayload]] - - @classmethod - def setup_class(cls) -> None: - """Setup class""" - - if not hasattr(cls, "test_cls"): - raise AttributeError(f"{cls} must set `test_cls`") - - cls.__test_cls = cls.test_cls - cls.__old_value = _MetaPayload.registry.copy() - _MetaPayload.registry.clear() - - @classmethod - def teardown_class(cls) -> None: - """Teardown class""" - _MetaPayload.registry = cls.__old_value - - def setup(self) -> None: - """Setup test""" - test_cls = copy_class(self.__test_cls) - self.test_cls = cast(Type[FSMBehaviourBaseCase], test_cls) - - def teardown(self) -> None: - """Teardown test""" - self.test_cls.teardown_class() - - def set_path_to_skill(self, path_to_skill: Path = PATH_TO_SKILL) -> None: - """Set path_to_skill""" - self.test_cls.path_to_skill = path_to_skill - - def setup_test_cls(self, **kwargs: Any) -> FSMBehaviourBaseCase: - """Helper method to setup test to be tested""" - - # different test tools will require the setting of - # different class attributes (such as path_to_skill). - # One should write a test that sets these, - # and subsequently invoke this method to test the setup. - - with cd(self.test_cls.path_to_skill): - self.test_cls.setup_class(**kwargs) - - test_instance = self.test_cls() - test_instance.setup() - return test_instance diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_base.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_base.py deleted file mode 100644 index 294c84660..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_base.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for abstract_round_abci/test_tools/base.py""" - -from enum import Enum -from typing import Any, Dict, cast - -import pytest -from aea.mail.base import Envelope - -from packages.valory.connections.ledger.connection import ( - PUBLIC_ID as LEDGER_CONNECTION_PUBLIC_ID, -) -from packages.valory.protocols.contract_api.message import ContractApiMessage -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.behaviours import BaseBehaviour -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - DummyContext, - FSMBehaviourBaseCase, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci import PUBLIC_ID -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.behaviours import ( - DummyRoundBehaviour, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.models import ( - SharedState, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.rounds import ( - Event, - SynchronizedData, -) -from packages.valory.skills.abstract_round_abci.tests.test_tools.base import ( - FSMBehaviourTestToolSetup, -) - - -class TestFSMBehaviourBaseCaseSetup(FSMBehaviourTestToolSetup): - """test TestFSMBehaviourBaseCaseSetup setup""" - - test_cls = FSMBehaviourBaseCase - - @pytest.mark.parametrize("kwargs", [{}]) - def test_setup_fails_without_path(self, kwargs: Dict[str, Dict[str, Any]]) -> None: - """Test setup""" - with pytest.raises(ValueError): - self.test_cls.setup_class(**kwargs) - - @pytest.mark.parametrize("kwargs", [{}, {"param_overrides": {"new_p": None}}]) - def test_setup(self, kwargs: Dict[str, Dict[str, Any]]) -> None: - """Test setup""" - - self.set_path_to_skill() - test_instance = self.setup_test_cls(**kwargs) - assert test_instance - assert hasattr(test_instance.behaviour.context.params, "new_p") == bool(kwargs) - - @pytest.mark.parametrize("behaviour", DummyRoundBehaviour.behaviours) - def test_fast_forward_to_behaviour(self, behaviour: BaseBehaviour) -> None: - """Test fast_forward_to_behaviour""" - self.set_path_to_skill() - test_instance = self.setup_test_cls() - - skill = test_instance._skill # pylint: disable=protected-access - round_behaviour = skill.skill_context.behaviours.main - behaviour_id = behaviour.behaviour_id - synchronized_data = SynchronizedData( - AbciAppDB(setup_data=dict(participants=[tuple("abcd")])) - ) - - test_instance.fast_forward_to_behaviour( - behaviour=round_behaviour, - behaviour_id=behaviour_id, - synchronized_data=synchronized_data, - ) - - current_behaviour = test_instance.behaviour.current_behaviour - assert current_behaviour is not None - assert isinstance( - current_behaviour.synchronized_data, - SynchronizedData, - ) - assert current_behaviour.behaviour_id == behaviour.behaviour_id - assert ( # pylint: disable=protected-access - test_instance.skill.skill_context.state.round_sequence.abci_app._current_round_cls - == current_behaviour.matching_round - == behaviour.matching_round - ) - - @pytest.mark.parametrize("event", Event) - @pytest.mark.parametrize("set_none", [False, True]) - def test_end_round(self, event: Enum, set_none: bool) -> None: - """Test end_round""" - - self.set_path_to_skill() - test_instance = self.setup_test_cls() - current_behaviour = cast( - BaseBehaviour, test_instance.behaviour.current_behaviour - ) - abci_app = current_behaviour.context.state.round_sequence.abci_app - if set_none: - test_instance.behaviour.current_behaviour = None - assert abci_app.current_round_height == 0 - test_instance.end_round(event) - assert abci_app.current_round_height == 1 - int(set_none) - - def test_mock_ledger_api_request(self) -> None: - """Test mock_ledger_api_request""" - - self.set_path_to_skill() - test_instance = self.setup_test_cls() - - request_kwargs = dict(performative=LedgerApiMessage.Performative.GET_BALANCE) - response_kwargs = dict(performative=LedgerApiMessage.Performative.BALANCE) - with pytest.raises( - AssertionError, - match="Invalid number of messages in outbox. Expected 1. Found 0.", - ): - test_instance.mock_ledger_api_request(request_kwargs, response_kwargs) - - message = LedgerApiMessage(**request_kwargs, dialogue_reference=("a", "b")) # type: ignore - envelope = Envelope( - to=str(LEDGER_CONNECTION_PUBLIC_ID), - sender=str(PUBLIC_ID), - protocol_specification_id=LedgerApiMessage.protocol_specification_id, - message=message, - ) - multiplexer = test_instance._multiplexer # pylint: disable=protected-access - multiplexer.out_queue.put_nowait(envelope) - test_instance.mock_ledger_api_request(request_kwargs, response_kwargs) - - def test_mock_contract_api_request(self) -> None: - """Test mock_contract_api_request""" - - self.set_path_to_skill() - test_instance = self.setup_test_cls() - - contract_id = "dummy_contract" - request_kwargs = dict(performative=ContractApiMessage.Performative.GET_STATE) - response_kwargs = dict(performative=ContractApiMessage.Performative.STATE) - with pytest.raises( - AssertionError, - match="Invalid number of messages in outbox. Expected 1. Found 0.", - ): - test_instance.mock_contract_api_request( - contract_id, request_kwargs, response_kwargs - ) - - message = ContractApiMessage( - **request_kwargs, # type: ignore - dialogue_reference=("a", "b"), - ledger_id="ethereum", - contract_id=contract_id - ) - envelope = Envelope( - to=str(LEDGER_CONNECTION_PUBLIC_ID), - sender=str(PUBLIC_ID), - protocol_specification_id=ContractApiMessage.protocol_specification_id, - message=message, - ) - multiplexer = test_instance._multiplexer # pylint: disable=protected-access - multiplexer.out_queue.put_nowait(envelope) - test_instance.mock_contract_api_request( - contract_id, request_kwargs, response_kwargs - ) - - -def test_dummy_context_is_abstract_component() -> None: - """Test dummy context is abstract component""" - - shared_state = SharedState(name="dummy_shared_state", skill_context=DummyContext()) - assert shared_state.context.is_abstract_component diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_common.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_common.py deleted file mode 100644 index b5cb5d272..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_common.py +++ /dev/null @@ -1,183 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for abstract_round_abci/test_tools/common.py""" - -from typing import Type, Union, cast - -import pytest - -from packages.valory.skills.abstract_round_abci.test_tools.common import ( - BaseRandomnessBehaviourTest, - BaseSelectKeeperBehaviourTest, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci import ( - PATH_TO_SKILL, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.behaviours import ( - DummyFinalBehaviour, - DummyKeeperSelectionBehaviour, - DummyRandomnessBehaviour, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.rounds import ( - Event, -) -from packages.valory.skills.abstract_round_abci.tests.test_tools.base import ( - FSMBehaviourTestToolSetup, -) - - -class BaseCommonBaseCaseTestSetup(FSMBehaviourTestToolSetup): - """BaseRandomnessBehaviourTestSetup""" - - test_cls: Type[Union[BaseRandomnessBehaviourTest, BaseSelectKeeperBehaviourTest]] - - def set_done_event(self) -> None: - """Set done_event""" - self.test_cls.done_event = Event.DONE - - def set_next_behaviour_class(self, next_behaviour_class: Type) -> None: - """Set next_behaviour_class""" - self.test_cls.next_behaviour_class = next_behaviour_class - - -class TestBaseRandomnessBehaviourTestSetup(BaseCommonBaseCaseTestSetup): - """Test BaseRandomnessBehaviourTest setup.""" - - test_cls: Type[BaseRandomnessBehaviourTest] = BaseRandomnessBehaviourTest - - def set_randomness_behaviour_class(self) -> None: - """Set randomness_behaviour_class""" - self.test_cls.randomness_behaviour_class = DummyRandomnessBehaviour # type: ignore - - def test_setup_randomness_behaviour_class_not_set(self) -> None: - """Test setup randomness_behaviour_class not set.""" - - self.set_path_to_skill() - test_instance = cast(BaseRandomnessBehaviourTest, self.setup_test_cls()) - expected = f"'{self.test_cls.__name__}' object has no attribute 'randomness_behaviour_class'" - with pytest.raises(AttributeError, match=expected): - test_instance.test_randomness_behaviour() - - def test_setup_done_event_not_set(self) -> None: - """Test setup done_event = Event.DONE not set.""" - - self.set_path_to_skill() - self.set_randomness_behaviour_class() - - test_instance = cast(BaseRandomnessBehaviourTest, self.setup_test_cls()) - expected = f"'{self.test_cls.__name__}' object has no attribute 'done_event'" - with pytest.raises(AttributeError, match=expected): - test_instance.test_randomness_behaviour() - - def test_setup_next_behaviour_class_not_set(self) -> None: - """Test setup next_behaviour_class not set.""" - - self.set_path_to_skill() - self.set_randomness_behaviour_class() - self.set_done_event() - - test_instance = cast(BaseRandomnessBehaviourTest, self.setup_test_cls()) - expected = ( - f"'{self.test_cls.__name__}' object has no attribute 'next_behaviour_class'" - ) - with pytest.raises(AttributeError, match=expected): - test_instance.test_randomness_behaviour() - - def test_successful_setup_randomness_behaviour_test(self) -> None: - """Test successful setup of the test class inheriting from BaseRandomnessBehaviourTest.""" - - self.set_path_to_skill() - self.set_randomness_behaviour_class() - self.set_done_event() - self.set_next_behaviour_class(DummyKeeperSelectionBehaviour) - test_instance = cast(BaseRandomnessBehaviourTest, self.setup_test_cls()) - test_instance.test_randomness_behaviour() - - -class TestBaseRandomnessBehaviourTestRunning(BaseRandomnessBehaviourTest): - """Test TestBaseRandomnessBehaviourTestRunning running.""" - - path_to_skill = PATH_TO_SKILL - randomness_behaviour_class = DummyRandomnessBehaviour - next_behaviour_class = DummyKeeperSelectionBehaviour - done_event = Event.DONE - - -class TestBaseSelectKeeperBehaviourTestSetup(BaseCommonBaseCaseTestSetup): - """Test BaseRandomnessBehaviourTest setup.""" - - test_cls: Type[BaseSelectKeeperBehaviourTest] = BaseSelectKeeperBehaviourTest - - def set_select_keeper_behaviour_class(self) -> None: - """Set select_keeper_behaviour_class""" - self.test_cls.select_keeper_behaviour_class = DummyKeeperSelectionBehaviour # type: ignore - - def test_setup_select_keeper_behaviour_class_not_set(self) -> None: - """Test setup select_keeper_behaviour_class not set.""" - - self.set_path_to_skill() - test_instance = cast(BaseSelectKeeperBehaviourTest, self.setup_test_cls()) - expected = f"'{self.test_cls.__name__}' object has no attribute 'select_keeper_behaviour_class'" - with pytest.raises(AttributeError, match=expected): - test_instance.test_select_keeper_preexisting_keeper() - - def test_setup_done_event_not_set(self) -> None: - """Test setup done_event = Event.DONE not set.""" - - self.set_path_to_skill() - self.set_select_keeper_behaviour_class() - - test_instance = cast(BaseSelectKeeperBehaviourTest, self.setup_test_cls()) - expected = f"'{self.test_cls.__name__}' object has no attribute 'done_event'" - with pytest.raises(AttributeError, match=expected): - test_instance.test_select_keeper_preexisting_keeper() - - def test_setup_next_behaviour_class_not_set(self) -> None: - """Test setup next_behaviour_class not set.""" - - self.set_path_to_skill() - self.set_select_keeper_behaviour_class() - self.set_done_event() - - test_instance = cast(BaseSelectKeeperBehaviourTest, self.setup_test_cls()) - expected = ( - f"'{self.test_cls.__name__}' object has no attribute 'next_behaviour_class'" - ) - with pytest.raises(AttributeError, match=expected): - test_instance.test_select_keeper_preexisting_keeper() - - def test_successful_setup_select_keeper_behaviour_test(self) -> None: - """Test successful setup of the test class inheriting from BaseSelectKeeperBehaviourTest.""" - - self.set_path_to_skill() - self.set_select_keeper_behaviour_class() - self.set_done_event() - self.set_next_behaviour_class(DummyFinalBehaviour) - test_instance = cast(BaseSelectKeeperBehaviourTest, self.setup_test_cls()) - test_instance.test_select_keeper_preexisting_keeper() - - -class TestBaseSelectKeeperBehaviourTestRunning(BaseSelectKeeperBehaviourTest): - """Test BaseSelectKeeperBehaviourTest running.""" - - path_to_skill = PATH_TO_SKILL - select_keeper_behaviour_class = DummyKeeperSelectionBehaviour - next_behaviour_class = DummyFinalBehaviour - done_event = Event.DONE diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_integration.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_integration.py deleted file mode 100644 index e71ed9258..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_integration.py +++ /dev/null @@ -1,143 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for abstract_round_abci/test_tools/integration.py""" - -from typing import cast - -import pytest - -from packages.open_aea.protocols.signing import SigningMessage -from packages.open_aea.protocols.signing.custom_types import SignedMessage -from packages.valory.connections.ledger.connection import ( - PUBLIC_ID as LEDGER_CONNECTION_PUBLIC_ID, -) -from packages.valory.connections.ledger.tests.conftest import make_ledger_api_connection -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.protocols.ledger_api.dialogues import LedgerApiDialogue -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.behaviours import BaseBehaviour -from packages.valory.skills.abstract_round_abci.models import Requests -from packages.valory.skills.abstract_round_abci.test_tools.integration import ( - IntegrationBaseCase, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.behaviours import ( - DummyStartingBehaviour, -) -from packages.valory.skills.abstract_round_abci.tests.data.dummy_abci.rounds import ( - SynchronizedData, -) -from packages.valory.skills.abstract_round_abci.tests.test_tools.base import ( - FSMBehaviourTestToolSetup, -) - - -def simulate_ledger_get_balance_request(test_instance: IntegrationBaseCase) -> None: - """Simulate ledger GET_BALANCE request""" - - ledger_api_dialogues = test_instance.skill.skill_context.ledger_api_dialogues - ledger_api_msg, ledger_api_dialogue = ledger_api_dialogues.create( - counterparty=str(LEDGER_CONNECTION_PUBLIC_ID), - performative=LedgerApiMessage.Performative.GET_BALANCE, - ledger_id="ethereum", - address="0x" + "0" * 40, - ) - ledger_api_dialogue = cast(LedgerApiDialogue, ledger_api_dialogue) - current_behaviour = cast(BaseBehaviour, test_instance.behaviour.current_behaviour) - request_nonce = current_behaviour._get_request_nonce_from_dialogue( # pylint: disable=protected-access - ledger_api_dialogue - ) - cast(Requests, current_behaviour.context.requests).request_id_to_callback[ - request_nonce - ] = current_behaviour.get_callback_request() - current_behaviour.context.outbox.put_message(message=ledger_api_msg) - - -class TestIntegrationBaseCase(FSMBehaviourTestToolSetup): - """TestIntegrationBaseCase""" - - test_cls = IntegrationBaseCase - - def test_instantiation(self) -> None: - """Test instantiation""" - - self.set_path_to_skill() - self.test_cls.make_ledger_api_connection_callable = make_ledger_api_connection - test_instance = cast(IntegrationBaseCase, self.setup_test_cls()) - - assert test_instance - assert test_instance.get_message_from_outbox() is None - assert test_instance.get_message_from_decision_maker_inbox() is None - assert test_instance.process_n_messages(ncycles=0) is tuple() - - expected = "Invalid number of messages in outbox. Expected 1. Found 0." - with pytest.raises(AssertionError, match=expected): - assert test_instance.process_message_cycle() - with pytest.raises(AssertionError, match=expected): - assert test_instance.process_n_messages(ncycles=1) - - def test_process_messages_cycle(self) -> None: - """Test process_message_cycle""" - - self.set_path_to_skill() - self.test_cls.make_ledger_api_connection_callable = make_ledger_api_connection - test_instance = cast(IntegrationBaseCase, self.setup_test_cls()) - - simulate_ledger_get_balance_request(test_instance) - message = test_instance.process_message_cycle( - handler=None, - ) - assert message is None - - simulate_ledger_get_balance_request(test_instance) - # connection error - cannot dynamically mix in an autouse fixture - message = test_instance.process_message_cycle( - handler=test_instance.ledger_handler, - expected_content={"performative": LedgerApiMessage.Performative.ERROR}, - ) - assert message - - def test_process_n_messages(self) -> None: - """Test process_n_messages""" - - self.set_path_to_skill() - self.test_cls.make_ledger_api_connection_callable = make_ledger_api_connection - test_instance = cast(IntegrationBaseCase, self.setup_test_cls()) - - behaviour_id = DummyStartingBehaviour.auto_behaviour_id() - synchronized_data = SynchronizedData( - AbciAppDB(setup_data=dict(participants=[tuple("abcd")])) - ) - - handlers = [test_instance.signing_handler] - expected_content = [ - {"performative": SigningMessage.Performative.SIGNED_MESSAGE} - ] - expected_types = [{"signed_message": SignedMessage}] - - messages = test_instance.process_n_messages( - ncycles=1, - behaviour_id=behaviour_id, - synchronized_data=synchronized_data, - handlers=handlers, # type: ignore - expected_content=expected_content, # type: ignore - expected_types=expected_types, # type: ignore - fail_send_a2a=True, - ) - assert len(messages) == 1 diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_rounds.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_rounds.py deleted file mode 100644 index 9fbbde9ac..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_tools/test_rounds.py +++ /dev/null @@ -1,659 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - - -"""Test the `rounds` test tool module of the skill.""" - -import re -from enum import Enum -from typing import Any, FrozenSet, Generator, List, Optional, Tuple, Type, cast -from unittest.mock import MagicMock - -import pytest -from hypothesis import given, settings -from hypothesis import strategies as st - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - BaseSynchronizedData, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectDifferentUntilAllRoundTest, - BaseCollectDifferentUntilThresholdRoundTest, - BaseCollectSameUntilAllRoundTest, - BaseCollectSameUntilThresholdRoundTest, - BaseOnlyKeeperSendsRoundTest, - BaseRoundTestClass, - BaseVotingRoundTest, - DummyCollectDifferentUntilAllRound, - DummyCollectDifferentUntilThresholdRound, - DummyCollectSameUntilAllRound, - DummyCollectSameUntilThresholdRound, - DummyEvent, - DummyOnlyKeeperSendsRound, - DummySynchronizedData, - DummyTxPayload, - DummyVotingRound, - MAX_PARTICIPANTS, - get_dummy_tx_payloads, - get_participants, -) -from packages.valory.skills.abstract_round_abci.tests.conftest import profile_name -from packages.valory.skills.abstract_round_abci.tests.test_common import last_iteration - - -settings.load_profile(profile_name) - -# this is how many times we need to iterate before reaching the last iteration for a base test. -BASE_TEST_GEN_ITERATIONS = 4 - - -def test_get_participants() -> None: - """Test `get_participants`.""" - participants = get_participants() - assert isinstance(participants, frozenset) - assert all(isinstance(p, str) for p in participants) - assert len(participants) == MAX_PARTICIPANTS - - -class DummyTxPayloadMatcher: - """A `DummyTxPayload` matcher for assertion comparisons.""" - - expected: DummyTxPayload - - def __init__(self, expected: DummyTxPayload) -> None: - """Initialize the matcher.""" - self.expected = expected - - def __repr__(self) -> str: - """Needs to be implemented for better assertion messages.""" - return ( - "DummyTxPayload(" - f"id={repr(self.expected.id_)}, " - f"round_count={repr(self.expected.round_count)}, " - f"sender={repr(self.expected.sender)}, " - f"value={repr(self.expected.value)}, " - f"vote={repr(self.expected.vote)}" - ")" - ) - - def __eq__(self, other: Any) -> bool: - """The method that will be used for the assertion comparisons.""" - return ( - self.expected.round_count == other.round_count - and self.expected.sender == other.sender - and self.expected.value == other.value - and self.expected.vote == other.vote - ) - - -@given( - st.frozensets(st.text(max_size=200), max_size=100), - st.text(max_size=500), - st.one_of(st.none(), st.booleans()), - st.booleans(), -) -def test_get_dummy_tx_payloads( - participants: FrozenSet[str], - value: str, - vote: Optional[bool], - is_value_none: bool, -) -> None: - """Test `get_dummy_tx_payloads`.""" - expected = [ - DummyTxPayloadMatcher( - DummyTxPayload( - sender=agent, - value=(value or agent) if not is_value_none else value, - vote=vote, - ) - ) - for agent in sorted(participants) - ] - - actual = get_dummy_tx_payloads(participants, value, vote, is_value_none) - - assert len(actual) == len(expected) == len(participants) - assert actual == expected - - -class TestDummyTxPayload: # pylint: disable=too-few-public-methods - """Test class for `DummyTxPayload`""" - - @staticmethod - @given(st.text(max_size=200), st.text(max_size=500), st.booleans()) - def test_properties( - sender: str, - value: str, - vote: bool, - ) -> None: - """Test all the properties.""" - dummy_tx_payload = DummyTxPayload(sender, value, vote) - assert dummy_tx_payload.value == value - assert dummy_tx_payload.vote == vote - assert dummy_tx_payload.data == {"value": value, "vote": vote} - - -class TestDummySynchronizedData: # pylint: disable=too-few-public-methods - """Test class for `DummySynchronizedData`.""" - - @staticmethod - @given(st.lists(st.text(max_size=200), max_size=100)) - def test_most_voted_keeper_address( - most_voted_keeper_address_data: List[str], - ) -> None: - """Test `most_voted_keeper_address`.""" - most_voted_keeper_address_key = "most_voted_keeper_address" - - dummy_synchronized_data = DummySynchronizedData( - db=AbciAppDB( - setup_data={ - most_voted_keeper_address_key: most_voted_keeper_address_data - } - ) - ) - - if len(most_voted_keeper_address_data) == 0: - with pytest.raises( - ValueError, - match=re.escape( - f"'{most_voted_keeper_address_key}' " - "field is not set for this period [0] and no default value was provided.", - ), - ): - _ = dummy_synchronized_data.most_voted_keeper_address - return - - assert ( - dummy_synchronized_data.most_voted_keeper_address - == most_voted_keeper_address_data[-1] - ) - - -class TestBaseRoundTestClass: - """Test `BaseRoundTestClass`.""" - - @staticmethod - def test_test_no_majority_event() -> None: - """Test `_test_no_majority_event`.""" - base_round_test = BaseRoundTestClass() - base_round_test._event_class = DummyEvent # pylint: disable=protected-access - - base_round_test._test_no_majority_event( # pylint: disable=protected-access - MagicMock( - end_block=lambda: ( - MagicMock(), - DummyEvent.NO_MAJORITY, - ) - ) - ) - - @staticmethod - @given(st.integers(min_value=0, max_value=100), st.integers(min_value=1)) - def test_complete_run(iter_count: int, shift: int) -> None: - """Test `_complete_run`.""" - - def dummy_gen() -> Generator[MagicMock, None, None]: - """A dummy generator.""" - return (MagicMock() for _ in range(iter_count)) - - # test with the same number as the generator's contents - gen = dummy_gen() - BaseRoundTestClass._complete_run( # pylint: disable=protected-access - gen, iter_count - ) - - # assert that the generator has been fully consumed - with pytest.raises(StopIteration): - next(gen) - - # test with a larger count than a generator's - with pytest.raises(StopIteration): - BaseRoundTestClass._complete_run( # pylint: disable=protected-access - dummy_gen(), iter_count + shift - ) - - -class BaseTestBase: - """Base class for the Base tests.""" - - gen: Generator - base_round_test: BaseRoundTestClass - base_round_test_cls: Type[BaseRoundTestClass] - test_method_name = "_test_round" - - def setup(self) -> None: - """Setup that is run before each test.""" - self.base_round_test = self.base_round_test_cls() - self.base_round_test._synchronized_data_class = ( # pylint: disable=protected-access - DummySynchronizedData - ) - self.base_round_test.setup() - self.base_round_test._event_class = ( # pylint: disable=protected-access - DummyEvent - ) - - def create_test_gen(self, **kwargs: Any) -> None: - """Create the base test generator.""" - test_method = getattr(self.base_round_test, self.test_method_name) - self.gen = test_method(**kwargs) - - def exhaust_base_test_gen(self) -> None: - """Exhaust the base test generator.""" - for _ in range(BASE_TEST_GEN_ITERATIONS): - next(self.gen) - last_iteration(self.gen) - - def run_test(self, **kwargs: Any) -> None: - """Run a test for a base test.""" - self.create_test_gen(**kwargs) - self.exhaust_base_test_gen() - - -class DummyCollectDifferentUntilAllRoundWithEndBlock( - DummyCollectDifferentUntilAllRound -): - """A `DummyCollectDifferentUntilAllRound` with `end_block` implemented.""" - - def __init__(self, dummy_exit_event: DummyEvent, *args: Any, **kwargs: Any): - """Initialize the dummy class.""" - super().__init__(*args, **kwargs) - self.dummy_exit_event = dummy_exit_event - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """A dummy `end_block` implementation.""" - if self.collection_threshold_reached and self.dummy_exit_event is not None: - return ( - cast( - DummySynchronizedData, - self.synchronized_data.update( - most_voted_keeper_address=list(self.collection.keys()) - ), - ), - self.dummy_exit_event, - ) - return None - - -class TestBaseCollectDifferentUntilAllRoundTest(BaseTestBase): - """Test `BaseCollectDifferentUntilAllRoundTest`.""" - - base_round_test: BaseCollectDifferentUntilAllRoundTest - base_round_test_cls = BaseCollectDifferentUntilAllRoundTest - - @given( - st.one_of(st.none(), st.sampled_from(DummyEvent)), - ) - def test_test_round(self, exit_event: DummyEvent) -> None: - """Test `_test_round`.""" - test_round = DummyCollectDifferentUntilAllRoundWithEndBlock( - exit_event, - self.base_round_test.synchronized_data, - context=MagicMock(), - ) - round_payloads = [ - DummyTxPayload(f"agent_{i}", str(i)) for i in range(MAX_PARTICIPANTS) - ] - synchronized_data_attr_checks = [ - lambda _synchronized_data: _synchronized_data.most_voted_keeper_address - ] - - self.run_test( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - most_voted_keeper_address=[ - f"agent_{i}" for i in range(MAX_PARTICIPANTS) - ] - ), - synchronized_data_attr_checks=synchronized_data_attr_checks, - exit_event=exit_event, - ) - - -class DummyCollectSameUntilAllRoundWithEndBlock(DummyCollectSameUntilAllRound): - """A `DummyCollectSameUntilAllRound` with `end_block` implemented.""" - - def __init__(self, dummy_exit_event: DummyEvent, *args: Any, **kwargs: Any): - """Initialize the dummy class.""" - super().__init__(*args, **kwargs) - self.dummy_exit_event = dummy_exit_event - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """A dummy `end_block` implementation.""" - if self.collection_threshold_reached: - return ( - cast( - DummySynchronizedData, - self.synchronized_data.update( - most_voted_keeper_address=self.common_payload - ), - ), - self.dummy_exit_event, - ) - return None - - -class TestBaseCollectSameUntilAllRoundTest(BaseTestBase): - """Test `BaseCollectSameUntilAllRoundTest`.""" - - base_round_test: BaseCollectSameUntilAllRoundTest - base_round_test_cls: Type[ - BaseCollectSameUntilAllRoundTest - ] = BaseCollectSameUntilAllRoundTest - - @given( - st.sampled_from(DummyEvent), - st.text(max_size=500), - st.booleans(), - ) - def test_test_round( - self, exit_event: DummyEvent, common_value: str, finished: bool - ) -> None: - """Test `_test_round`.""" - test_round = DummyCollectSameUntilAllRoundWithEndBlock( - exit_event, - self.base_round_test.synchronized_data, - context=MagicMock(), - ) - round_payloads = { - f"test{i}": DummyTxPayload(f"agent_{i}", common_value) - for i in range(MAX_PARTICIPANTS) - } - synchronized_data_attr_checks = [ - lambda _synchronized_data: _synchronized_data.most_voted_keeper_address - ] - - self.run_test( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - most_voted_keeper_address=common_value - ), - synchronized_data_attr_checks=synchronized_data_attr_checks, - most_voted_payload=common_value, - exit_event=exit_event, - finished=finished, - ) - - -class DummyCollectSameUntilThresholdRoundWithEndBlock( - DummyCollectSameUntilThresholdRound -): - """A `DummyCollectSameUntilThresholdRound` with `end_block` overriden.""" - - def __init__(self, dummy_exit_event: DummyEvent, *args: Any, **kwargs: Any): - """Initialize the dummy class.""" - super().__init__(*args, **kwargs) - self.dummy_exit_event = dummy_exit_event - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """A dummy `end_block` override.""" - if self.threshold_reached: - return ( - cast( - DummySynchronizedData, - self.synchronized_data.update( - most_voted_keeper_address=self.most_voted_payload - ), - ), - self.dummy_exit_event, - ) - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, DummyEvent.NO_MAJORITY - return None - - -class TestBaseCollectSameUntilThresholdRoundTest(BaseTestBase): - """Test `BaseCollectSameUntilThresholdRoundTest`.""" - - base_round_test: BaseCollectSameUntilThresholdRoundTest - base_round_test_cls: Type[ - BaseCollectSameUntilThresholdRoundTest - ] = BaseCollectSameUntilThresholdRoundTest - - @given( - st.sampled_from(DummyEvent), - st.text(max_size=500), - ) - def test_test_round(self, exit_event: DummyEvent, most_voted_payload: str) -> None: - """Test `_test_round`.""" - test_round = DummyCollectSameUntilThresholdRoundWithEndBlock( - exit_event, - self.base_round_test.synchronized_data, - context=MagicMock(), - ) - round_payloads = { - f"test{i}": DummyTxPayload(f"agent_{i}", most_voted_payload) - for i in range(MAX_PARTICIPANTS) - } - synchronized_data_attr_checks = [ - lambda _synchronized_data: _synchronized_data.most_voted_keeper_address - ] - - self.run_test( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - most_voted_keeper_address=most_voted_payload - ), - synchronized_data_attr_checks=synchronized_data_attr_checks, - most_voted_payload=most_voted_payload, - exit_event=exit_event, - ) - - -class DummyOnlyKeeperSendsRoundTest(DummyOnlyKeeperSendsRound): - """A `DummyOnlyKeeperSendsRound` with `end_block` implemented.""" - - def __init__(self, dummy_exit_event: DummyEvent, *args: Any, **kwargs: Any): - """Initialize the dummy class.""" - super().__init__(*args, **kwargs) - self.dummy_exit_event = dummy_exit_event - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """A dummy `end_block` implementation.""" - if self.keeper_payload is not None and any( - [val is not None for val in self.keeper_payload.values] - ): - return ( - cast( - DummySynchronizedData, - self.synchronized_data.update( - blacklisted_keepers=self.keeper_payload.values[0] - ), - ), - self.dummy_exit_event, - ) - return None - - -class TestBaseOnlyKeeperSendsRoundTest(BaseTestBase): - """Test `BaseOnlyKeeperSendsRoundTest`.""" - - base_round_test: BaseOnlyKeeperSendsRoundTest - base_round_test_cls: Type[ - BaseOnlyKeeperSendsRoundTest - ] = BaseOnlyKeeperSendsRoundTest - most_voted_keeper_address: str = "agent_0" - - def setup(self) -> None: - """Setup that is run before each test.""" - super().setup() - self.base_round_test.synchronized_data.update( - most_voted_keeper_address=self.most_voted_keeper_address - ) - - @given( - st.sampled_from(DummyEvent), - st.text(), - ) - def test_test_round(self, exit_event: DummyEvent, keeper_value: str) -> None: - """Test `_test_round`.""" - test_round = DummyOnlyKeeperSendsRoundTest( - exit_event, - self.base_round_test.synchronized_data, - context=MagicMock(), - ) - keeper_payload = DummyTxPayload(self.most_voted_keeper_address, keeper_value) - synchronized_data_attr_checks = [ - lambda _synchronized_data: _synchronized_data.blacklisted_keepers - ] - - self.run_test( - test_round=test_round, - keeper_payloads=keeper_payload, - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - blacklisted_keepers=keeper_value - ), - synchronized_data_attr_checks=synchronized_data_attr_checks, - exit_event=exit_event, - ) - - -class DummyBaseVotingRoundTestWithEndBlock(DummyVotingRound): - """A `DummyVotingRound` with `end_block` overriden.""" - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """A dummy `end_block` override.""" - if self.positive_vote_threshold_reached: - synchronized_data = cast( - DummySynchronizedData, - self.synchronized_data.update( - is_keeper_set=bool(self.collection), - ), - ) - return synchronized_data, DummyEvent.DONE - if self.negative_vote_threshold_reached: - return self.synchronized_data, DummyEvent.NEGATIVE - if self.none_vote_threshold_reached: - return self.synchronized_data, DummyEvent.NONE - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, DummyEvent.NO_MAJORITY - return None - - -class TestBaseVotingRoundTest(BaseTestBase): - """Test `BaseVotingRoundTest`.""" - - base_round_test: BaseVotingRoundTest - base_round_test_cls: Type[BaseVotingRoundTest] = BaseVotingRoundTest - - @given( - st.one_of(st.none(), st.booleans()), - ) - def test_test_round(self, is_keeper_set: Optional[bool]) -> None: - """Test `_test_round`.""" - if is_keeper_set is None: - exit_event = DummyEvent.NONE - self.test_method_name = "_test_voting_round_none" - elif is_keeper_set: - exit_event = DummyEvent.DONE - self.test_method_name = "_test_voting_round_positive" - else: - exit_event = DummyEvent.NEGATIVE - self.test_method_name = "_test_voting_round_negative" - - test_round = DummyBaseVotingRoundTestWithEndBlock( - self.base_round_test.synchronized_data, - context=MagicMock(), - ) - round_payloads = { - f"test{i}": DummyTxPayload(f"agent_{i}", value="", vote=is_keeper_set) - for i in range(MAX_PARTICIPANTS) - } - synchronized_data_attr_checks = [ - lambda _synchronized_data: _synchronized_data.is_keeper_set - ] - - self.run_test( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - is_keeper_set=is_keeper_set - ), - synchronized_data_attr_checks=synchronized_data_attr_checks, - exit_event=exit_event, - ) - - -class DummyCollectDifferentUntilThresholdRoundWithEndBlock( - DummyCollectDifferentUntilThresholdRound -): - """A `DummyCollectDifferentUntilThresholdRound` with `end_block` implemented.""" - - def __init__(self, dummy_exit_event: DummyEvent, *args: Any, **kwargs: Any): - """Initialize the dummy class.""" - super().__init__(*args, **kwargs) - self.dummy_exit_event = dummy_exit_event - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """A dummy `end_block` implementation.""" - if self.collection_threshold_reached and self.dummy_exit_event is not None: - return ( - cast( - DummySynchronizedData, - self.synchronized_data.update( - most_voted_keeper_address=list(self.collection.keys()) - ), - ), - self.dummy_exit_event, - ) - return None - - -class TestBaseCollectDifferentUntilThresholdRoundTest(BaseTestBase): - """Test `BaseCollectDifferentUntilThresholdRoundTest`.""" - - base_round_test: BaseCollectDifferentUntilThresholdRoundTest - base_round_test_cls: Type[ - BaseCollectDifferentUntilThresholdRoundTest - ] = BaseCollectDifferentUntilThresholdRoundTest - - @given(st.sampled_from(DummyEvent)) - def test_test_round(self, exit_event: DummyEvent) -> None: - """Test `_test_round`.""" - test_round = DummyCollectDifferentUntilThresholdRoundWithEndBlock( - exit_event, - self.base_round_test.synchronized_data, - context=MagicMock(), - ) - round_payloads = { - f"test{i}": DummyTxPayload(f"agent_{i}", str(i)) - for i in range(MAX_PARTICIPANTS) - } - synchronized_data_attr_checks = [ - lambda _synchronized_data: _synchronized_data.most_voted_keeper_address - ] - - self.run_test( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - most_voted_keeper_address=[ - f"agent_{i}" for i in range(MAX_PARTICIPANTS) - ] - ), - synchronized_data_attr_checks=synchronized_data_attr_checks, - exit_event=exit_event, - ) diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_utils.py b/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_utils.py deleted file mode 100644 index 3f412733e..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/tests/test_utils.py +++ /dev/null @@ -1,307 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the utils.py module of the skill.""" - -from collections import defaultdict -from string import printable -from typing import Any, Dict, List, Tuple, Type -from unittest import mock - -import pytest -from hypothesis import assume, given, settings -from hypothesis import strategies as st - -from packages.valory.skills.abstract_round_abci.tests.conftest import profile_name -from packages.valory.skills.abstract_round_abci.utils import ( - DEFAULT_TENDERMINT_P2P_PORT, - KeyType, - MAX_UINT64, - ValueType, - VerifyDrand, - consensus_threshold, - filter_negative, - get_data_from_nested_dict, - get_value_with_type, - inverse, - is_json_serializable, - is_primitive_or_none, - parse_tendermint_p2p_url, -) - - -settings.load_profile(profile_name) - - -# pylint: skip-file - - -DRAND_PUBLIC_KEY: str = "868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31" - -DRAND_VALUE = { - "round": 1416669, - "randomness": "f6be4bf1fa229f22340c1a5b258f809ac4af558200775a67dacb05f0cb258a11", - "signature": ( - "b44d00516f46da3a503f9559a634869b6dc2e5d839e46ec61a090e3032172954929a5" - "d9bd7197d7739fe55db770543c71182562bd0ad20922eb4fe6b8a1062ed21df3b68de" - "44694eb4f20b35262fa9d63aa80ad3f6172dd4d33a663f21179604" - ), - "previous_signature": ( - "903c60a4b937a804001032499a855025573040cb86017c38e2b1c3725286756ce8f33" - "61188789c17336beaf3f9dbf84b0ad3c86add187987a9a0685bc5a303e37b008fba8c" - "44f02a416480dd117a3ff8b8075b1b7362c58af195573623187463" - ), -} - - -class TestVerifyDrand: - """Test DrandVerify.""" - - drand_check: VerifyDrand - - def setup( - self, - ) -> None: - """Setup test.""" - self.drand_check = VerifyDrand() - - def test_verify( - self, - ) -> None: - """Test verify method.""" - - result, error = self.drand_check.verify(DRAND_VALUE, DRAND_PUBLIC_KEY) - assert result - assert error is None - - def test_verify_fails( - self, - ) -> None: - """Test verify method.""" - - drand_value = DRAND_VALUE.copy() - del drand_value["randomness"] - result, error = self.drand_check.verify(drand_value, DRAND_PUBLIC_KEY) - assert not result - assert error == "DRAND dict is missing value for 'randomness'" - - drand_value = DRAND_VALUE.copy() - drand_value["randomness"] = "".join( - list(drand_value["randomness"])[:-1] + ["0"] # type: ignore - ) - result, error = self.drand_check.verify(drand_value, DRAND_PUBLIC_KEY) - assert not result - assert error == "Failed randomness hash check." - - drand_value = DRAND_VALUE.copy() - with mock.patch.object( - self.drand_check, "_verify_signature", return_value=False - ): - result, error = self.drand_check.verify(drand_value, DRAND_PUBLIC_KEY) - - assert not result - assert error == "Failed bls.Verify check." - - @pytest.mark.parametrize("value", (-1, MAX_UINT64 + 1)) - def test_negative_and_overflow(self, value: int) -> None: - """Test verify method.""" - with pytest.raises(ValueError): - self.drand_check._int_to_bytes_big(value) - - -@given(st.integers(min_value=0, max_value=MAX_UINT64)) -def test_verify_int_to_bytes_big_fuzz(integer: int) -> None: - """Test VerifyDrand.""" - - VerifyDrand._int_to_bytes_big(integer) - - -@pytest.mark.parametrize("integer", [-1, MAX_UINT64 + 1]) -def test_verify_int_to_bytes_big_raises(integer: int) -> None: - """Test VerifyDrand._int_to_bytes_big""" - - expected = "VerifyDrand can only handle positive numbers representable with 8 bytes" - with pytest.raises(ValueError, match=expected): - VerifyDrand._int_to_bytes_big(integer) - - -@given(st.binary()) -def test_verify_randomness_hash_fuzz(input_bytes: bytes) -> None: - """Test VerifyDrand._verify_randomness_hash""" - - VerifyDrand._verify_randomness_hash(input_bytes, input_bytes) - - -@given( - st.lists(st.text(), min_size=1, max_size=50), - st.binary(), - st.characters(), -) -def test_get_data_from_nested_dict( - nested_keys: List[str], final_value: bytes, separator: str -) -> None: - """Test `get_data_from_nested_dict`""" - assume(not any(separator in key for key in nested_keys)) - - def create_nested_dict() -> defaultdict: - """Recursively create a nested dict of arbitrary size.""" - return defaultdict(create_nested_dict) - - nested_dict = create_nested_dict() - key_access = (f"[nested_keys[{i}]]" for i in range(len(nested_keys))) - expression = "nested_dict" + "".join(key_access) - expression += " = final_value" - exec(expression) # nosec - - serialized_keys = separator.join(nested_keys) - actual = get_data_from_nested_dict(nested_dict, serialized_keys, separator) - assert actual == final_value - - -@pytest.mark.parametrize( - "type_name, type_, value", - ( - ("str", str, "1"), - ("int", int, 1), - ("float", float, 1.1), - ("dict", dict, {1: 1}), - ("list", list, [1]), - ("non_existent", None, 1), - ), -) -def test_get_value_with_type(type_name: str, type_: Type, value: Any) -> None: - """Test `get_value_with_type`""" - if type_ is None: - with pytest.raises( - AttributeError, match=f"module 'builtins' has no attribute '{type_name}'" - ): - get_value_with_type(value, type_name) - return - - actual = get_value_with_type(value, type_name) - assert type(actual) == type_ - assert actual == value - - -@pytest.mark.parametrize( - ("url", "expected_output"), - ( - ("localhost", ("localhost", DEFAULT_TENDERMINT_P2P_PORT)), - ("localhost:80", ("localhost", 80)), - ("some.random.host:80", ("some.random.host", 80)), - ("1.1.1.1", ("1.1.1.1", DEFAULT_TENDERMINT_P2P_PORT)), - ("1.1.1.1:80", ("1.1.1.1", 80)), - ), -) -def test_parse_tendermint_p2p_url(url: str, expected_output: Tuple[str, int]) -> None: - """Test `parse_tendermint_p2p_url` method.""" - - assert parse_tendermint_p2p_url(url=url) == expected_output - - -@given( - st.one_of(st.none(), st.integers(), st.floats(), st.text(), st.booleans()), - st.one_of( - st.nothing(), - st.frozensets(st.integers()), - st.sets(st.integers()), - st.lists(st.integers()), - st.dictionaries(st.integers(), st.integers()), - st.dates(), - st.complex_numbers(), - st.just(object()), - ), -) -def test_is_primitive_or_none(valid_obj: Any, invalid_obj: Any) -> None: - """Test `is_primitive_or_none`.""" - assert is_primitive_or_none(valid_obj) - assert not is_primitive_or_none(invalid_obj) - - -@given( - st.recursive( - st.none() | st.booleans() | st.floats() | st.text(printable), - lambda children: st.lists(children) - | st.dictionaries(st.text(printable), children), - ), - st.one_of( - st.nothing(), - st.frozensets(st.integers()), - st.sets(st.integers()), - st.dates(), - st.complex_numbers(), - st.just(object()), - ), -) -def test_is_json_serializable(valid_obj: Any, invalid_obj: Any) -> None: - """Test `is_json_serializable`.""" - assert is_json_serializable(valid_obj) - assert not is_json_serializable(invalid_obj) - - -@given( - positive=st.dictionaries(st.text(), st.integers(min_value=0)), - negative=st.dictionaries(st.text(), st.integers(max_value=-1)), -) -def test_filter_negative(positive: Dict[str, int], negative: Dict[str, int]) -> None: - """Test `filter_negative`.""" - assert len(tuple(filter_negative(positive))) == 0 - assert set(filter_negative(negative)) == set(negative.keys()) - - -@pytest.mark.parametrize( - "nb, threshold", - ((1, 1), (2, 2), (3, 3), (4, 3), (5, 4), (6, 5), (100, 67), (300, 201)), -) -def test_consensus_threshold(nb: int, threshold: int) -> None: - """Test `consensus_threshold`.""" - assert consensus_threshold(nb) == threshold - - -@pytest.mark.parametrize( - "dict_, expected", - ( - ({}, {}), - ( - {"test": "this", "which?": "this"}, - {"this": ["test", "which?"]}, - ), - ( - {"test": "this", "which?": "this", "hm": "ok"}, - {"this": ["test", "which?"], "ok": ["hm"]}, - ), - ( - {"test": "this", "hm": "ok"}, - {"this": ["test"], "ok": ["hm"]}, - ), - ( - {"test": "this", "hm": "ok", "ok": "ok"}, - {"this": ["test"], "ok": ["hm", "ok"]}, - ), - ( - {"test": "this", "which?": "this", "hm": "ok", "ok": "ok"}, - {"this": ["test", "which?"], "ok": ["hm", "ok"]}, - ), - ), -) -def test_inverse( - dict_: Dict[KeyType, ValueType], expected: Dict[ValueType, List[KeyType]] -) -> None: - """Test `inverse`.""" - assert inverse(dict_) == expected diff --git a/trader_old/vendor/valory/skills/abstract_round_abci/utils.py b/trader_old/vendor/valory/skills/abstract_round_abci/utils.py deleted file mode 100644 index 864658c27..000000000 --- a/trader_old/vendor/valory/skills/abstract_round_abci/utils.py +++ /dev/null @@ -1,504 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 utility functions for the 'abstract_round_abci' skill.""" - -import builtins -import collections -import dataclasses -import sys -import types -import typing -from hashlib import sha256 -from math import ceil -from typing import ( - Any, - Dict, - FrozenSet, - Iterator, - List, - Optional, - Set, - Tuple, - Type, - TypeVar, - Union, - cast, -) -from unittest.mock import MagicMock - -import typing_extensions -from eth_typing.bls import BLSPubkey, BLSSignature -from py_ecc.bls import G2Basic as bls -from typing_extensions import Literal, TypeGuard, TypedDict - - -MAX_UINT64 = 2**64 - 1 -DEFAULT_TENDERMINT_P2P_PORT = 26656 - - -class VerifyDrand: # pylint: disable=too-few-public-methods - """ - Tool to verify Randomness retrieved from various external APIs. - - The ciphersuite used is BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_ - - cryptographic-specification section in https://drand.love/docs/specification/ - https://github.com/ethereum/py_ecc - """ - - @classmethod - def _int_to_bytes_big(cls, value: int) -> bytes: - """Convert int to bytes.""" - if value < 0 or value > MAX_UINT64: - raise ValueError( - "VerifyDrand can only handle positive numbers representable with 8 bytes" - ) - return int.to_bytes(value, 8, byteorder="big", signed=False) - - @classmethod - def _verify_randomness_hash(cls, randomness: bytes, signature: bytes) -> bool: - """Verify randomness hash.""" - return sha256(signature).digest() == randomness - - @classmethod - def _verify_signature( - cls, - pubkey: Union[BLSPubkey, bytes], - message: bytes, - signature: Union[BLSSignature, bytes], - ) -> bool: - """Verify randomness signature.""" - return bls.Verify( - cast(BLSPubkey, pubkey), message, cast(BLSSignature, signature) - ) - - def verify(self, data: Dict, pubkey: str) -> Tuple[bool, Optional[str]]: - """ - Verify drand value retried from external APIs. - - :param data: dictionary containing drand parameters. - :param pubkey: league of entropy public key - public-endpoints section in https://drand.love/developer/http-api/ - :returns: bool, error message - """ - - encoded_pubkey = bytes.fromhex(pubkey) - try: - randomness = data["randomness"] - signature = data["signature"] - round_value = int(data["round"]) - except KeyError as e: - return False, f"DRAND dict is missing value for {e}" - - previous_signature = data.pop("previous_signature", "") - encoded_randomness = bytes.fromhex(randomness) - encoded_signature = bytes.fromhex(signature) - int_encoded_round = self._int_to_bytes_big(round_value) - encoded_previous_signature = bytes.fromhex(previous_signature) - - if not self._verify_randomness_hash(encoded_randomness, encoded_signature): - return False, "Failed randomness hash check." - - msg_b = encoded_previous_signature + int_encoded_round - msg_hash_b = sha256(msg_b).digest() - - if not self._verify_signature(encoded_pubkey, msg_hash_b, encoded_signature): - return False, "Failed bls.Verify check." - - return True, None - - -def get_data_from_nested_dict( - nested_dict: Dict, keys: str, separator: str = ":" -) -> Any: - """Gets content from a nested dictionary, using serialized response keys which are split by a given separator. - - :param nested_dict: the nested dictionary to get the content from - :param keys: the keys to use on the nested dictionary in order to get the content - :param separator: the separator to use in order to get the keys list. - Choose the separator carefully, so that it does not conflict with any character of the keys. - - :returns: the content result - """ - parsed_keys = keys.split(separator) - for key in parsed_keys: - nested_dict = nested_dict[key] - return nested_dict - - -def get_value_with_type(value: Any, type_name: str) -> Any: - """Get the given value as the specified type.""" - return getattr(builtins, type_name)(value) - - -def parse_tendermint_p2p_url(url: str) -> Tuple[str, int]: - """Parse tendermint P2P url.""" - hostname, *_port = url.split(":") - if len(_port) > 0: - port_str, *_ = _port - port = int(port_str) - else: - port = DEFAULT_TENDERMINT_P2P_PORT - - return hostname, port - - -## -# Typing utils - to be extracted to open-aea -## - - -try: - # Python >=3.8 should have these functions already - from typing import get_args as _get_args # pylint: disable=ungrouped-imports - from typing import get_origin as _get_origin # pylint: disable=ungrouped-imports -except ImportError: # pragma: nocover - # Python 3.7 - def _get_origin(tp): # type: ignore - """Copied from the Python 3.8 typing module""" - if isinstance(tp, typing._GenericAlias): # pylint: disable=protected-access - return tp.__origin__ - if tp is typing.Generic: - return typing.Generic - return None - - def _get_args(tp): # type: ignore - """Copied from the Python 3.8 typing module""" - if isinstance(tp, typing._GenericAlias): # pylint: disable=protected-access - res = tp.__args__ - if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis: - res = (list(res[:-1]), res[-1]) - return res - return () - - -def get_origin(tp): # type: ignore - """ - Get the unsubscripted version of a type. - - This supports generic types, Callable, Tuple, Union, Literal, Final and - ClassVar. Returns None for unsupported types. - Examples: - get_origin(Literal[42]) is Literal - get_origin(int) is None - get_origin(ClassVar[int]) is ClassVar - get_origin(Generic) is Generic - get_origin(Generic[T]) is Generic - get_origin(Union[T, int]) is Union - get_origin(List[Tuple[T, T]][int]) == list - """ - return _get_origin(tp) - - -def get_args(tp): # type: ignore - """ - Get type arguments with all substitutions performed. - - For unions, basic simplifications used by Union constructor are performed. - Examples: - get_args(Dict[str, int]) == (str, int) - get_args(int) == () - get_args(Union[int, Union[T, int], str][int]) == (int, str) - get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) - get_args(Callable[[], T][int]) == ([], int) - """ - return _get_args(tp) - - -## -# The following is borrowed from https://github.com/tamuhey/dataclass_utils/blob/81580d2c0c285081db06be02b4ecdd125532bef5/dataclass_utils/type_checker.py#L152 -## - - -def is_pep604_union(ty: Type[Any]) -> bool: - """Check if a type is a PEP 604 union.""" - return sys.version_info >= (3, 10) and ty is types.UnionType # type: ignore # noqa: E721 # pylint: disable=no-member - - -def _path_to_str(path: List[str]) -> str: - """Convert a path to a string.""" - return " -> ".join(reversed(path)) - - -class AutonomyTypeError(TypeError): - """Type Error for the Autonomy type check system.""" - - def __init__( - self, - ty: Type[Any], - value: Any, - path: Optional[List[str]] = None, - ): - """Initialize AutonomyTypeError.""" - self.ty = ty - self.value = value - self.path = path or [] - super().__init__() - - def __str__(self) -> str: - """Get string representation of AutonomyTypeError.""" - path = _path_to_str(self.path) - msg = f"Error in field '{path}'. Expected type {self.ty}, got {type(self.value)} (value: {self.value})" - return msg - - -Result = Optional[AutonomyTypeError] # returns error context - - -def check( # pylint: disable=too-many-return-statements - value: Any, ty: Type[Any] -) -> Result: - """ - Check a value against a type. - - # Examples - >>> assert is_error(check(1, str)) - >>> assert not is_error(check(1, int)) - >>> assert is_error(check(1, list)) - >>> assert is_error(check(1.3, int)) - >>> assert is_error(check(1.3, Union[str, int])) - """ - if isinstance(value, MagicMock): - # testing - any magic value is ignored - return None - if not isinstance(value, type) and dataclasses.is_dataclass(ty): - # dataclass - return check_dataclass(value, ty) - if is_typeddict(ty): - # should use `typing.is_typeddict` in future - return check_typeddict(value, ty) - to = get_origin(ty) - if to is not None: - # generics - err = check(value, to) - if is_error(err): - return err - - if to is list or to is set or to is frozenset: - err = check_mono_container(value, ty) - elif to is dict: - err = check_dict(value, ty) # type: ignore - elif to is tuple: - err = check_tuple(value, ty) - elif to is Literal: - err = check_literal(value, ty) - elif to is Union or is_pep604_union(to): - err = check_union(value, ty) - elif to is type: - err = check_class(value, ty) - return err - if isinstance(ty, type): - # concrete type - if is_pep604_union(ty): - pass # pragma: no cover - elif issubclass(ty, bool): - if not isinstance(value, ty): - return AutonomyTypeError(ty=ty, value=value) - elif issubclass(ty, int): # For boolean - return check_int(value, ty) - elif ty is typing.Any: - # `isinstance(value, typing.Any) fails on python 3.11` - # https://stackoverflow.com/questions/68031358/typeerror-typing-any-cannot-be-used-with-isinstance - pass - elif not isinstance(value, ty): - return AutonomyTypeError(ty=ty, value=value) - return None - - -def check_class(value: Any, ty: Type[Any]) -> Result: - """Check class type.""" - if not issubclass(value, get_args(ty)): - return AutonomyTypeError(ty=ty, value=value) - return None - - -def check_int(value: Any, ty: Type[Any]) -> Result: - """Check int type.""" - if isinstance(value, bool) or not isinstance(value, ty): - return AutonomyTypeError(ty=ty, value=value) - return None - - -def check_literal(value: Any, ty: Type[Any]) -> Result: - """Check literal type.""" - if all(value != t for t in get_args(ty)): - return AutonomyTypeError(ty=ty, value=value) - return None - - -def check_tuple(value: Any, ty: Type[Tuple[Any, ...]]) -> Result: - """Check tuple type.""" - types_ = get_args(ty) - if len(types_) == 2 and types_[1] == ...: - # arbitrary length tuple (e.g. Tuple[int, ...]) - for v in value: - err = check(v, types_[0]) - if is_error(err): - return err - return None - - if len(value) != len(types_): - return AutonomyTypeError(ty=ty, value=value) - for v, t in zip(value, types_): - err = check(v, t) - if is_error(err): - return err - return None - - -def check_union(value: Any, ty: Type[Any]) -> Result: - """Check union type.""" - if any(not is_error(check(value, t)) for t in get_args(ty)): - return None - return AutonomyTypeError(ty=ty, value=value) - - -def check_mono_container( - value: Any, ty: Union[Type[List[Any]], Type[Set[Any]], Type[FrozenSet[Any]]] -) -> Result: - """Check mono container type.""" - ty_item = get_args(ty)[0] - for v in value: - err = check(v, ty_item) - if is_error(err): - return err - return None - - -def check_dict(value: Dict[Any, Any], ty: Type[Dict[Any, Any]]) -> Result: - """Check dict type.""" - args = get_args(ty) - ty_key = args[0] - ty_item = args[1] - for k, v in value.items(): - err = check(k, ty_key) - if is_error(err): - return err - err = check(v, ty_item) - if err is not None: - err.path.append(k) - return err - return None - - -def check_dataclass(value: Any, ty: Type[Any]) -> Result: - """Check dataclass type.""" - if not dataclasses.is_dataclass(value): - return AutonomyTypeError(ty, value) - for k, ty_ in typing.get_type_hints(ty).items(): - v = getattr(value, k) - err = check(v, ty_) - if err is not None: - err.path.append(k) - return err - return None - - -def check_typeddict(value: Any, ty: Type[Any]) -> Result: - """Check typeddict type.""" - if not isinstance(value, dict): - return AutonomyTypeError(ty, value) # pragma: no cover - is_total: bool = ty.__total__ # type: ignore - for k, ty_ in typing.get_type_hints(ty).items(): - if k not in value: - if is_total: - return AutonomyTypeError(ty_, value, [k]) - continue - v = value[k] - err = check(v, ty_) - if err is not None: - err.path.append(k) - return err - return None - - -# TODO: incorporate -def is_typevar(ty: Type[Any]) -> TypeGuard[TypeVar]: - """Check typevar.""" - return isinstance(ty, TypeVar) # pragma: no cover - - -def is_error(ret: Result) -> TypeGuard[AutonomyTypeError]: - """Check error.""" - return ret is not None - - -def is_typeddict(ty: Type[Any]) -> TypeGuard[Type[TypedDict]]: # type: ignore - """Check typeddict.""" - # TODO: Should use `typing.is_typeddict` in future - # or, use publich API - T = "_TypedDictMeta" - for mod in [typing, typing_extensions]: - if hasattr(mod, T) and isinstance(ty, getattr(mod, T)): - return True - return False - - -def check_type(name: str, value: Any, type_hint: Any) -> None: - """Check value against type hint recursively""" - err = check(value, type_hint) - if err is not None: - err.path.append(name) - raise err - - -def is_primitive_or_none(obj: Any) -> bool: - """Checks if the given object is a primitive type or `None`.""" - primitives = (bool, int, float, str) - return isinstance(obj, primitives) or obj is None - - -def is_json_serializable(obj: Any) -> bool: - """Checks if the given object is json serializable.""" - if isinstance(obj, (tuple, list)): - return all(is_json_serializable(x) for x in obj) - if isinstance(obj, dict): - return all( - is_primitive_or_none(k) and is_json_serializable(v) for k, v in obj.items() - ) - - return is_primitive_or_none(obj) - - -def filter_negative(mapping: Dict[str, int]) -> Iterator[str]: - """Return the keys of a dictionary for which the values are negative integers.""" - return (key for key, number in mapping.items() if number < 0) - - -def consensus_threshold(nb: int) -> int: - """ - Get consensus threshold. - - :param nb: the number of participants - :return: the consensus threshold - """ - return ceil((2 * nb + 1) / 3) - - -KeyType = TypeVar("KeyType") -ValueType = TypeVar("ValueType") - - -def inverse(dict_: Dict[KeyType, ValueType]) -> Dict[ValueType, List[KeyType]]: - """Get the inverse of a dictionary.""" - inverse_: Dict[ValueType, List[KeyType]] = {val: [] for val in dict_.values()} - for key, value in dict_.items(): - inverse_[value].append(key) - return inverse_ diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/README.md b/trader_old/vendor/valory/skills/check_stop_trading_abci/README.md deleted file mode 100644 index 02ad18706..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Check stop trading abci - -## Description - -This package contains the check stop trading skill for an AEA. diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/__init__.py b/trader_old/vendor/valory/skills/check_stop_trading_abci/__init__.py deleted file mode 100644 index da4d21162..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the check stop trading skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/check_stop_trading_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/behaviours.py b/trader_old/vendor/valory/skills/check_stop_trading_abci/behaviours.py deleted file mode 100644 index f1eac99e8..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/behaviours.py +++ /dev/null @@ -1,185 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the behaviours for the check stop trading skill.""" - -import math -from typing import Any, Generator, Set, Type, cast - -from packages.valory.contracts.mech.contract import Mech as MechContract -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.behaviours import AbstractRoundBehaviour -from packages.valory.skills.check_stop_trading_abci.models import CheckStopTradingParams -from packages.valory.skills.check_stop_trading_abci.payloads import ( - CheckStopTradingPayload, -) -from packages.valory.skills.check_stop_trading_abci.rounds import ( - CheckStopTradingAbciApp, - CheckStopTradingRound, -) -from packages.valory.skills.staking_abci.behaviours import ( - StakingInteractBaseBehaviour, - WaitableConditionType, -) -from packages.valory.skills.staking_abci.rounds import StakingState - - -# Liveness ratio from the staking contract is expressed in calls per 10**18 seconds. -LIVENESS_RATIO_SCALE_FACTOR = 10**18 - -# A safety margin in case there is a delay between the moment the KPI condition is -# satisfied, and the moment where the checkpoint is called. -REQUIRED_MECH_REQUESTS_SAFETY_MARGIN = 1 - - -class CheckStopTradingBehaviour(StakingInteractBaseBehaviour): - """A behaviour that checks stop trading conditions.""" - - matching_round = CheckStopTradingRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize the behaviour.""" - super().__init__(**kwargs) - self._mech_request_count: int = 0 - - @property - def mech_request_count(self) -> int: - """Get the liveness period.""" - return self._mech_request_count - - @mech_request_count.setter - def mech_request_count(self, mech_request_count: int) -> None: - """Set the liveness period.""" - self._mech_request_count = mech_request_count - - def _get_mech_request_count(self) -> WaitableConditionType: - """Get the mech request count.""" - status = yield from self.contract_interact( - contract_address=self.params.mech_contract_address, - contract_public_id=MechContract.contract_id, - contract_callable="get_requests_count", - data_key="requests_count", - placeholder=get_name(CheckStopTradingBehaviour.mech_request_count), - address=self.synchronized_data.safe_contract_address, - ) - return status - - @property - def is_first_period(self) -> bool: - """Return whether it is the first period of the service.""" - return self.synchronized_data.period_count == 0 - - @property - def params(self) -> CheckStopTradingParams: - """Return the params.""" - return cast(CheckStopTradingParams, self.context.params) - - def is_staking_kpi_met(self) -> Generator[None, None, bool]: - """Return whether the staking KPI has been met (only for staked services).""" - yield from self.wait_for_condition_with_sleep(self._check_service_staked) - self.context.logger.debug(f"{self.service_staking_state=}") - if self.service_staking_state != StakingState.STAKED: - return False - - yield from self.wait_for_condition_with_sleep(self._get_mech_request_count) - mech_request_count = self.mech_request_count - self.context.logger.debug(f"{mech_request_count=}") - - yield from self.wait_for_condition_with_sleep(self._get_service_info) - mech_request_count_on_last_checkpoint = self.service_info[2][1] - self.context.logger.debug(f"{mech_request_count_on_last_checkpoint=}") - - yield from self.wait_for_condition_with_sleep(self._get_ts_checkpoint) - last_ts_checkpoint = self.ts_checkpoint - self.context.logger.debug(f"{last_ts_checkpoint=}") - - yield from self.wait_for_condition_with_sleep(self._get_liveness_period) - liveness_period = self.liveness_period - self.context.logger.debug(f"{liveness_period=}") - - yield from self.wait_for_condition_with_sleep(self._get_liveness_ratio) - liveness_ratio = self.liveness_ratio - self.context.logger.debug(f"{liveness_ratio=}") - - mech_requests_since_last_cp = ( - mech_request_count - mech_request_count_on_last_checkpoint - ) - self.context.logger.debug(f"{mech_requests_since_last_cp=}") - - current_timestamp = self.synced_timestamp - self.context.logger.debug(f"{current_timestamp=}") - - required_mech_requests = ( - math.ceil( - max(liveness_period, (current_timestamp - last_ts_checkpoint)) - * liveness_ratio - / LIVENESS_RATIO_SCALE_FACTOR - ) - + REQUIRED_MECH_REQUESTS_SAFETY_MARGIN - ) - self.context.logger.debug(f"{required_mech_requests=}") - - if mech_requests_since_last_cp >= required_mech_requests: - return True - return False - - def _compute_stop_trading(self) -> Generator[None, None, bool]: - # This is a "hacky" way of getting required data initialized on - # the Trader: On first period, the FSM needs to initialize some - # data on the trading branch so that it is available in the - # cross-period persistent keys. - if self.is_first_period: - self.context.logger.debug(f"{self.is_first_period=}") - yield # ensures this is a generator - return False - - self.context.logger.debug(f"{self.params.disable_trading=}") - if self.params.disable_trading: - yield # ensures this is a generator - return True - - self.context.logger.debug(f"{self.params.stop_trading_if_staking_kpi_met=}") - if self.params.stop_trading_if_staking_kpi_met: - staking_kpi_met = yield from self.is_staking_kpi_met() - self.context.logger.debug(f"{staking_kpi_met=}") - return staking_kpi_met - - yield - return False - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - stop_trading = yield from self._compute_stop_trading() - self.context.logger.info(f"Computed {stop_trading=}") - payload = CheckStopTradingPayload(self.context.agent_address, stop_trading) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - self.set_done() - - -class CheckStopTradingRoundBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the check stop trading behaviour.""" - - initial_behaviour_cls = CheckStopTradingBehaviour - abci_app_cls = CheckStopTradingAbciApp - behaviours: Set[Type[BaseBehaviour]] = {CheckStopTradingBehaviour} # type: ignore diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/dialogues.py b/trader_old/vendor/valory/skills/check_stop_trading_abci/dialogues.py deleted file mode 100644 index 74cc46dc5..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/dialogues.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/fsm_specification.yaml b/trader_old/vendor/valory/skills/check_stop_trading_abci/fsm_specification.yaml deleted file mode 100644 index e71d9e9b8..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/fsm_specification.yaml +++ /dev/null @@ -1,23 +0,0 @@ -alphabet_in: -- DONE -- NONE -- NO_MAJORITY -- ROUND_TIMEOUT -- SKIP_TRADING -default_start_state: CheckStopTradingRound -final_states: -- FinishedCheckStopTradingRound -- FinishedWithSkipTradingRound -label: CheckStopTradingAbciApp -start_states: -- CheckStopTradingRound -states: -- CheckStopTradingRound -- FinishedCheckStopTradingRound -- FinishedWithSkipTradingRound -transition_func: - (CheckStopTradingRound, DONE): FinishedCheckStopTradingRound - (CheckStopTradingRound, NONE): CheckStopTradingRound - (CheckStopTradingRound, NO_MAJORITY): CheckStopTradingRound - (CheckStopTradingRound, ROUND_TIMEOUT): CheckStopTradingRound - (CheckStopTradingRound, SKIP_TRADING): FinishedWithSkipTradingRound diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/handlers.py b/trader_old/vendor/valory/skills/check_stop_trading_abci/handlers.py deleted file mode 100644 index 64bac3a39..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/handlers.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the handlers for the check stop trading skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCICheckStopTradingHandler = ABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/models.py b/trader_old/vendor/valory/skills/check_stop_trading_abci/models.py deleted file mode 100644 index 3d4728874..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/models.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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. -# -# ------------------------------------------------------------------------------ - - -"""Models for the check stop trading ABCI application.""" - -from typing import Any - -from aea.exceptions import enforce - -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.check_stop_trading_abci.rounds import ( - CheckStopTradingAbciApp, -) -from packages.valory.skills.staking_abci.models import StakingParams - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -class CheckStopTradingParams(StakingParams): - """CheckStopTrading parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the parameters' object.""" - mech_address = kwargs.get("mech_contract_address", None) - enforce(mech_address is not None, "Mech contract address not specified!") - self.mech_contract_address = mech_address - self.disable_trading: bool = self._ensure("disable_trading", kwargs, bool) - self.stop_trading_if_staking_kpi_met: bool = self._ensure( - "stop_trading_if_staking_kpi_met", kwargs, bool - ) - super().__init__(*args, **kwargs) - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = CheckStopTradingAbciApp diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/payloads.py b/trader_old/vendor/valory/skills/check_stop_trading_abci/payloads.py deleted file mode 100644 index 5831cff87..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/payloads.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the transaction payloads for the check stop trading abci.""" - -from dataclasses import dataclass - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class CheckStopTradingPayload(BaseTxPayload): - """A transaction payload for the check stop trading abci.""" - - vote: bool diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/rounds.py b/trader_old/vendor/valory/skills/check_stop_trading_abci/rounds.py deleted file mode 100644 index 21b93e89b..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/rounds.py +++ /dev/null @@ -1,147 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the rounds for the check stop trading ABCI application.""" - -from abc import ABC -from enum import Enum -from typing import Dict, Optional, Set, Tuple, Type - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AbstractRound, - AppState, - BaseSynchronizedData, - CollectionRound, - DegenerateRound, - DeserializedCollection, - VotingRound, - get_name, -) -from packages.valory.skills.check_stop_trading_abci.payloads import ( - CheckStopTradingPayload, -) - - -class Event(Enum): - """Event enumeration for the check stop trading skill.""" - - DONE = "done" - NONE = "none" - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - SKIP_TRADING = "skip_trading" - - -class SynchronizedData(BaseSynchronizedData): - """Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - def _get_deserialized(self, key: str) -> DeserializedCollection: - """Strictly get a collection and return it deserialized.""" - serialized = self.db.get_strict(key) - return CollectionRound.deserialize_collection(serialized) - - def is_staking_kpi_met(self) -> bool: - """Get the status of the staking kpi.""" - return bool(self.db.get("is_staking_kpi_met", False)) - - -class CheckStopTradingRound(VotingRound): - """A round for checking stop trading conditions.""" - - payload_class = CheckStopTradingPayload - synchronized_data_class = SynchronizedData - done_event = Event.SKIP_TRADING - negative_event = Event.DONE - none_event = Event.NONE - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_votes) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - - if res is None: - return None - - is_staking_kpi_met = self.positive_vote_threshold_reached - self.synchronized_data.update(is_staking_kpi_met=is_staking_kpi_met) - - return res - - -class FinishedCheckStopTradingRound(DegenerateRound, ABC): - """A round that represents check stop trading has finished.""" - - -class FinishedWithSkipTradingRound(DegenerateRound, ABC): - """A round that represents check stop trading has finished with skip trading.""" - - -class CheckStopTradingAbciApp(AbciApp[Event]): # pylint: disable=too-few-public-methods - """CheckStopTradingAbciApp - - Initial round: CheckStopTradingRound - - Initial states: {CheckStopTradingRound} - - Transition states: - 0. CheckStopTradingRound - - done: 1. - - none: 0. - - round timeout: 0. - - no majority: 0. - - skip trading: 2. - 1. FinishedCheckStopTradingRound - 2. FinishedWithSkipTradingRound - - Final states: {FinishedCheckStopTradingRound, FinishedWithSkipTradingRound} - - Timeouts: - round timeout: 30.0 - """ - - initial_round_cls: Type[AbstractRound] = CheckStopTradingRound - transition_function: AbciAppTransitionFunction = { - CheckStopTradingRound: { - Event.DONE: FinishedCheckStopTradingRound, - Event.NONE: CheckStopTradingRound, - Event.ROUND_TIMEOUT: CheckStopTradingRound, - Event.NO_MAJORITY: CheckStopTradingRound, - Event.SKIP_TRADING: FinishedWithSkipTradingRound, - }, - FinishedCheckStopTradingRound: {}, - FinishedWithSkipTradingRound: {}, - } - final_states: Set[AppState] = { - FinishedCheckStopTradingRound, - FinishedWithSkipTradingRound, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = {CheckStopTradingRound: set()} - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedCheckStopTradingRound: set(), - FinishedWithSkipTradingRound: set(), - } diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/skill.yaml b/trader_old/vendor/valory/skills/check_stop_trading_abci/skill.yaml deleted file mode 100644 index d37ff0def..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/skill.yaml +++ /dev/null @@ -1,146 +0,0 @@ -name: check_stop_trading_abci -author: valory -version: 0.1.0 -type: skill -description: This skill implements the check for stop trading for an AEA. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeif2pq7fg5upl6vmfgfzpiwsh4nbk4zaeyz6upyucqi5tasrxgq4ee - __init__.py: bafybeifc23rlw2hzhplp3wfceixnmwq5ztnixhh7jp4dd5av3crwp3x22a - behaviours.py: bafybeie5mkpxsd6z3vjsoacvswin6zz4q4um5gqp6jhwtn65fepx2kma3m - dialogues.py: bafybeictrrnwcijiejczy23dfvbx5kujgef3dulzqhs3etl2juvz5spm2e - fsm_specification.yaml: bafybeihhau35a5xclncjpxh5lg7qiw34xs4d5qlez7dnjpkf45d3gc57ai - handlers.py: bafybeiard64fwxib3rtyp67ymhf222uongcyqhfhdyttpsyqkmyh5ajipu - models.py: bafybeigwdhgianx5rizlb7ebmm6pdtkixh4uehbvu5c24ysvyvojs74dfq - payloads.py: bafybeidh5bqywun4chrbsci2xbcrnnzuys5sswxwbxq3yl2ksawi3xsi5q - rounds.py: bafybeift7b2afck4e5so2cpgyoywa76t6el6d4qwfoitvfdjw6kgf4fwie - tests/__init__.py: bafybeihv2cjk4va5bc5ncqtppqg2xmmxcro34bma36trtvk32gtmhdycxu - tests/test_dialogues.py: bafybeia5ac27w7ijx2nyx5dqyrnv4troo4572gjq7nrcxdncexoxucnqti - tests/test_handlers.py: bafybeigpmtx2hyunzn6nxk2x4bvvybek7jvuhbk34fqlj7fgfsszcoqhxy - tests/test_payloads.py: bafybeih7q7kdfxsf4ejxxqwjumwglfwwcrbqcjnuy42mkhnfwccxuhiviy - tests/test_rounds.py: bafybeidgbc7mi7r2fpk7ak6xceohuoq2zkpkberkokcb3sb2uzwkxoluae -fingerprint_ignore_patterns: [] -connections: [] -contracts: -- valory/mech:0.1.0:bafybeiejfjfoxqggghcme43sx53q5gruefrws3k2jam2opkxl5uzffoarm -protocols: [] -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/staking_abci:0.1.0:bafybeicupccurmrg7qesivonlyt3nryarsmk5qf5yh6auno64wn45bybvq -behaviours: - main: - args: {} - class_name: CheckStopTradingRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCICheckStopTradingHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 350.0 - service_id: check_stop_trading - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - sleep_time: 5 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - termination_sleep: 900 - tx_timeout: 10.0 - use_termination: false - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - disable_trading: false - stop_trading_if_staking_kpi_met: true - class_name: CheckStopTradingParams - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState -dependencies: {} -is_abstract: true diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/__init__.py b/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/__init__.py deleted file mode 100644 index 8b00b9e88..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/check_stop_trading skill.""" diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_dialogues.py b/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_dialogues.py deleted file mode 100644 index be3bcac1f..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.check_stop_trading_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_handlers.py b/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_handlers.py deleted file mode 100644 index bb1d25447..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_handlers.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 tests for the handlers for the check stop trading abci.""" - -from unittest.mock import MagicMock - -import pytest -from aea.configurations.data_types import PublicId -from aea.skills.base import Handler - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.check_stop_trading_abci.handlers import ( - ABCICheckStopTradingHandler, - ContractApiHandler, - HttpHandler, - IpfsHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, -) - - -@pytest.mark.parametrize( - "handler, base_handler", - [ - (ABCICheckStopTradingHandler, ABCIRoundHandler), - (HttpHandler, BaseHttpHandler), - (SigningHandler, BaseSigningHandler), - (LedgerApiHandler, BaseLedgerApiHandler), - (ContractApiHandler, BaseContractApiHandler), - (TendermintHandler, BaseTendermintHandler), - (IpfsHandler, BaseIpfsHandler), - ], -) -def test_handler(handler: Handler, base_handler: Handler) -> None: - """Test that the 'handlers.py' of the CheckStopTradingAbci can be imported.""" - handler = handler( - name="dummy_handler", - skill_context=MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")), - ) - - assert isinstance(handler, base_handler) diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_payloads.py b/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_payloads.py deleted file mode 100644 index de53b3995..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_payloads.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the transaction payloads for the check stop trading abci.""" - -from packages.valory.skills.check_stop_trading_abci.payloads import ( - CheckStopTradingPayload, -) - - -def test_check_stop_trading_payload() -> None: - """Test `CheckStopTradingPayload`.""" - - payload = CheckStopTradingPayload(sender="sender", vote=True) - - assert payload.vote - assert payload.data == {"vote": True} - assert CheckStopTradingPayload.from_json(payload.json) == payload diff --git a/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_rounds.py b/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_rounds.py deleted file mode 100644 index 8967831fa..000000000 --- a/trader_old/vendor/valory/skills/check_stop_trading_abci/tests/test_rounds.py +++ /dev/null @@ -1,285 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 package contains the tests for the CheckStopTradingAbciApp.""" - -import json -from dataclasses import dataclass, field -from typing import ( - Any, - Callable, - Dict, - FrozenSet, - Hashable, - List, - Mapping, - Optional, - Type, -) -from unittest.mock import MagicMock, Mock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - CollectionRound, - VotingRound, - get_name, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseVotingRoundTest, -) -from packages.valory.skills.check_stop_trading_abci.payloads import ( - CheckStopTradingPayload, -) -from packages.valory.skills.check_stop_trading_abci.rounds import ( - CheckStopTradingAbciApp, - CheckStopTradingRound, - Event, - FinishedCheckStopTradingRound, - FinishedWithSkipTradingRound, - SynchronizedData, -) - - -DUMMY_PAYLOAD_DATA = {"example_key": "example_value"} - - -@pytest.fixture -def abci_app() -> CheckStopTradingAbciApp: - """Fixture for CheckStopTradingAbciApp.""" - synchronized_data = Mock() - logger = Mock() - context = Mock() - - return CheckStopTradingAbciApp( - synchronized_data=synchronized_data, logger=logger, context=context - ) - - -def get_participants() -> FrozenSet[str]: - """Participants""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -def get_participant_to_votes( - participants: FrozenSet[str], vote: bool -) -> Dict[str, CheckStopTradingPayload]: - """participant_to_votes""" - - return { - participant: CheckStopTradingPayload(sender=participant, vote=vote) - for participant in participants - } - - -def get_participant_to_votes_serialized( - participants: FrozenSet[str], vote: bool -) -> Dict[str, Dict[str, Any]]: - """participant_to_votes""" - - return CollectionRound.serialize_collection( - get_participant_to_votes(participants, vote) - ) - - -def get_payloads( - payload_cls: Type[CheckStopTradingPayload], - data: Optional[str], -) -> Mapping[str, CheckStopTradingPayload]: - """Get payloads.""" - return { - participant: payload_cls(participant, data is not None) - for participant in get_participants() - } - - -def get_dummy_check_stop_trading_payload_serialized() -> str: - """Dummy payload serialization""" - return json.dumps(DUMMY_PAYLOAD_DATA, sort_keys=True) - - -@dataclass -class RoundTestCase: - """RoundTestCase""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, CheckStopTradingPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -MAX_PARTICIPANTS: int = 4 - - -class BaseCheckStopTradingRoundTest(BaseVotingRoundTest): - """Base Test Class for CheckStopTradingRound""" - - test_class: Type[VotingRound] - test_payload: Type[CheckStopTradingPayload] - - def _test_voting_round( - self, vote: bool, expected_event: Any, threshold_check: Callable - ) -> None: - """Helper method to test voting rounds with positive or negative votes.""" - - test_round = self.test_class( - synchronized_data=self.synchronized_data, context=MagicMock() - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_votes(self.participants, vote=vote), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.update( - participant_to_votes=get_participant_to_votes_serialized( - self.participants, vote=vote - ) - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.participant_to_votes.keys() - ] - if vote - else [], - exit_event=expected_event, - threshold_check=threshold_check, - ) - ) - - def test_positive_votes(self) -> None: - """Test ValidateRound for positive votes.""" - self._test_voting_round( - vote=True, - expected_event=self._event_class.SKIP_TRADING, - threshold_check=lambda x: x.positive_vote_threshold_reached, - ) - - def test_negative_votes(self) -> None: - """Test ValidateRound for negative votes.""" - self._test_voting_round( - vote=False, - expected_event=self._event_class.DONE, - threshold_check=lambda x: x.negative_vote_threshold_reached, - ) - - -class TestCheckStopTradingRound(BaseCheckStopTradingRoundTest): - """Tests for CheckStopTradingRound.""" - - test_class = CheckStopTradingRound - _event_class = Event - _synchronized_data_class = SynchronizedData - - @pytest.mark.parametrize( - "test_case", - ( - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_payloads( - payload_cls=CheckStopTradingPayload, - data=get_dummy_check_stop_trading_payload_serialized(), - ), - final_data={}, - event=Event.SKIP_TRADING, - most_voted_payload=get_dummy_check_stop_trading_payload_serialized(), - synchronized_data_attr_checks=[ - lambda sync_data: sync_data.db.get( - get_name(SynchronizedData.participant_to_votes) - ) - == CollectionRound.deserialize_collection( - json.loads(get_dummy_check_stop_trading_payload_serialized()) - ) - ], - ), - RoundTestCase( - name="No majority", - initial_data={}, - payloads=get_payloads( - payload_cls=CheckStopTradingPayload, - data=get_dummy_check_stop_trading_payload_serialized(), - ), - final_data={}, - event=Event.NO_MAJORITY, - most_voted_payload=get_dummy_check_stop_trading_payload_serialized(), - synchronized_data_attr_checks=[], - ), - ), - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run tests.""" - if test_case.event == Event.SKIP_TRADING: - self.test_positive_votes() - elif test_case.event == Event.NO_MAJORITY: - self.test_negative_votes() - - """Tests for FinishedCheckStopTradingRound.""" - - def test_finished_check_stop_trading_round_initialization(self) -> None: - """Test the initialization of FinishedCheckStopTradingRound.""" - round_ = FinishedCheckStopTradingRound( - synchronized_data=MagicMock(), context=MagicMock() - ) - assert isinstance(round_, FinishedCheckStopTradingRound) - - -class TestFinishedWithSkipTradingRound: - """Tests for FinishedWithSkipTradingRound.""" - - def test_finished_with_skip_trading_round_initialization(self) -> None: - """Test the initialization of FinishedWithSkipTradingRound.""" - round_ = FinishedWithSkipTradingRound( - synchronized_data=MagicMock(), context=MagicMock() - ) - assert isinstance(round_, FinishedWithSkipTradingRound) - - -def test_abci_app_initialization(abci_app: CheckStopTradingAbciApp) -> None: - """Test the initialization of CheckStopTradingAbciApp.""" - assert abci_app.initial_round_cls is CheckStopTradingRound - assert abci_app.final_states == { - FinishedCheckStopTradingRound, - FinishedWithSkipTradingRound, - } - assert abci_app.transition_function == { - CheckStopTradingRound: { - Event.DONE: FinishedCheckStopTradingRound, - Event.NONE: CheckStopTradingRound, - Event.ROUND_TIMEOUT: CheckStopTradingRound, - Event.NO_MAJORITY: CheckStopTradingRound, - Event.SKIP_TRADING: FinishedWithSkipTradingRound, - }, - FinishedCheckStopTradingRound: {}, - FinishedWithSkipTradingRound: {}, - } - assert abci_app.event_to_timeout == {Event.ROUND_TIMEOUT: 30.0} - assert abci_app.db_pre_conditions == {CheckStopTradingRound: set()} - assert abci_app.db_post_conditions == { - FinishedCheckStopTradingRound: set(), - FinishedWithSkipTradingRound: set(), - } - - -def test_synchronized_data_initialization() -> None: - """Test the initialization and attributes of SynchronizedData.""" - data = SynchronizedData(db=AbciAppDB(setup_data={"test": ["test"]})) - assert data.db._data == {0: {"test": ["test"]}} diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/README.md b/trader_old/vendor/valory/skills/decision_maker_abci/README.md deleted file mode 100644 index 93307c4d7..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# DecisionMaker abci - -## Description - -This module contains the ABCI decision-making skill for an AEA. diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/__init__.py b/trader_old/vendor/valory/skills/decision_maker_abci/__init__.py deleted file mode 100644 index 17b61f59d..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- 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 the decision maker skill for the trader.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/decision_maker_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/__init__.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/__init__.py deleted file mode 100644 index c0db5476d..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 package contains the behaviours for the 'decision_maker_abci' skill.""" diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/base.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/base.py deleted file mode 100644 index 15f76fea3..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/base.py +++ /dev/null @@ -1,879 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the base behaviour for the 'decision_maker_abci' skill.""" - -import dataclasses -import json -import os -from abc import ABC -from datetime import datetime, timedelta -from typing import Any, Callable, Dict, Generator, List, Optional, Set, Tuple, cast - -from aea.configurations.data_types import PublicId -from aea.protocols.base import Message -from aea.protocols.dialogue.base import Dialogue -from hexbytes import HexBytes - -from packages.valory.contracts.erc20.contract import ERC20 -from packages.valory.contracts.gnosis_safe.contract import ( - GnosisSafeContract, - SafeOperation, -) -from packages.valory.contracts.mech.contract import Mech -from packages.valory.contracts.multisend.contract import MultiSendContract -from packages.valory.contracts.transfer_nft_condition.contract import ( - TransferNftCondition, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.abstract_round_abci.behaviour_utils import TimeoutException -from packages.valory.skills.decision_maker_abci.io_.loader import ComponentPackageLoader -from packages.valory.skills.decision_maker_abci.models import ( - AccuracyInfoFields, - BenchmarkingMockData, - BenchmarkingMode, - DecisionMakerParams, - L0_END_FIELD, - L0_START_FIELD, - L1_END_FIELD, - L1_START_FIELD, - LiquidityInfo, - MultisendBatch, - SharedState, -) -from packages.valory.skills.decision_maker_abci.policy import EGreedyPolicy -from packages.valory.skills.decision_maker_abci.states.base import SynchronizedData -from packages.valory.skills.decision_maker_abci.utils.nevermined import ( - no_did_prefixed, - zero_x_transformer, -) -from packages.valory.skills.market_manager_abci.behaviours import BetsManagerBehaviour -from packages.valory.skills.market_manager_abci.bets import ( - Bet, - CONFIDENCE_FIELD, - INFO_UTILITY_FIELD, - P_NO_FIELD, - P_YES_FIELD, - PredictionResponse, -) -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - hash_payload_to_hex, -) -from packages.valory.skills.transaction_settlement_abci.rounds import TX_HASH_LENGTH - - -WaitableConditionType = Generator[None, None, bool] - -# setting the safe gas to 0 means that all available gas will be used -# which is what we want in most cases -# more info here: https://safe-docs.dev.gnosisdev.com/safe/docs/contracts_tx_execution/ -SAFE_GAS = 0 -CID_PREFIX = "f01701220" -WXDAI = "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d" -BET_AMOUNT_FIELD = "bet_amount" -SUPPORTED_STRATEGY_LOG_LEVELS = ("info", "warning", "error") -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" -NEW_LINE = "\n" -QUOTE = '"' -TWO_QUOTES = '""' -INIT_LIQUIDITY_INFO = LiquidityInfo() - - -def remove_fraction_wei(amount: int, fraction: float) -> int: - """Removes the given fraction from the given integer amount and returns the value as an integer.""" - if 0 <= fraction <= 1: - keep_percentage = 1 - fraction - return int(amount * keep_percentage) - raise ValueError(f"The given fraction {fraction!r} is not in the range [0, 1].") - - -class DecisionMakerBaseBehaviour(BetsManagerBehaviour, ABC): - """Represents the base class for the decision-making FSM behaviour.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize the bet placement behaviour.""" - super().__init__(**kwargs) - self.token_balance = 0 - self.wallet_balance = 0 - self.multisend_batches: List[MultisendBatch] = [] - self.multisend_data = b"" - self._safe_tx_hash = "" - self._policy: Optional[EGreedyPolicy] = None - self._inflight_strategy_req: Optional[str] = None - - @property - def subscription_params(self) -> Dict[str, Any]: - """Get the subscription params.""" - return self.params.mech_to_subscription_params - - @property - def did(self) -> str: - """Get the did.""" - subscription_params = self.subscription_params - return subscription_params["did"] - - @property - def token_address(self) -> str: - """Get the token address.""" - subscription_params = self.subscription_params - return subscription_params["token_address"] - - def strategy_exec(self, strategy: str) -> Optional[Tuple[str, str]]: - """Get the executable strategy file's content.""" - return self.shared_state.strategies_executables.get(strategy, None) - - def execute_strategy(self, *args: Any, **kwargs: Any) -> Dict[str, Any]: - """Execute the strategy and return the results.""" - trading_strategy = kwargs.pop("trading_strategy", None) - if trading_strategy is None: - self.context.logger.error(f"No trading strategy was given in {kwargs=}!") - return {BET_AMOUNT_FIELD: 0} - - strategy = self.strategy_exec(trading_strategy) - if strategy is None: - self.context.logger.error( - f"No executable was found for {trading_strategy=}!" - ) - return {BET_AMOUNT_FIELD: 0} - - strategy_exec, callable_method = strategy - if callable_method in globals(): - del globals()[callable_method] - - exec(strategy_exec, globals()) # pylint: disable=W0122 # nosec - method = globals().get(callable_method, None) - if method is None: - self.context.logger.error( - f"No {callable_method!r} method was found in {trading_strategy} strategy's executable." - ) - return {BET_AMOUNT_FIELD: 0} - - return method(*args, **kwargs) - - @property - def params(self) -> DecisionMakerParams: - """Return the params.""" - return cast(DecisionMakerParams, self.context.params) - - @property - def benchmarking_mode(self) -> BenchmarkingMode: - """Return the benchmarking mode configurations.""" - return cast(BenchmarkingMode, self.context.benchmarking_mode) - - @property - def mock_data(self) -> BenchmarkingMockData: - """Return the mock data for the benchmarking mode.""" - mock_data = self.shared_state.mock_data - if mock_data is None: - raise ValueError("Attempted to access the mock data while being empty!") - return mock_data - - @property - def acc_info_fields(self) -> AccuracyInfoFields: - """Return the accuracy information fieldnames.""" - return cast(AccuracyInfoFields, self.context.acc_info_fields) - - @property - def shared_state(self) -> SharedState: - """Get the shared state.""" - return cast(SharedState, self.context.state) - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return SynchronizedData(super().synchronized_data.db) - - @property - def synced_timestamp(self) -> int: - """Return the synchronized timestamp across the agents.""" - return int(self.round_sequence.last_round_transition_timestamp.timestamp()) - - @property - def safe_tx_hash(self) -> str: - """Get the safe_tx_hash.""" - return self._safe_tx_hash - - @safe_tx_hash.setter - def safe_tx_hash(self, safe_hash: str) -> None: - """Set the safe_tx_hash.""" - length = len(safe_hash) - if length != TX_HASH_LENGTH: - raise ValueError( - f"Incorrect length {length} != {TX_HASH_LENGTH} detected " - f"when trying to assign a safe transaction hash: {safe_hash}" - ) - self._safe_tx_hash = safe_hash[2:] - - @property - def multi_send_txs(self) -> List[dict]: - """Get the multisend transactions as a list of dictionaries.""" - return [dataclasses.asdict(batch) for batch in self.multisend_batches] - - @property - def txs_value(self) -> int: - """Get the total value of the transactions.""" - return sum(batch.value for batch in self.multisend_batches) - - @property - def tx_hex(self) -> Optional[str]: - """Serialize the safe tx to a hex string.""" - if self.safe_tx_hash == "": - self.context.logger.error( - "Cannot prepare a transaction without a transaction hash." - ) - return None - return hash_payload_to_hex( - self.safe_tx_hash, - self.txs_value, - SAFE_GAS, - self.params.multisend_address, - self.multisend_data, - SafeOperation.DELEGATE_CALL.value, - ) - - @property - def policy(self) -> EGreedyPolicy: - """Get the policy.""" - if self._policy is None: - raise ValueError( - "Attempting to retrieve the policy before it has been established." - ) - return self._policy - - @property - def is_first_period(self) -> bool: - """Return whether it is the first period of the service.""" - return ( - self.synchronized_data.period_count == 0 - and not self.benchmarking_mode.enabled - or self.shared_state.mock_data is None - ) - - @property - def sampled_bet(self) -> Bet: - """Get the sampled bet and reset the bets list.""" - self.read_bets() - bet_index = self.synchronized_data.sampled_bet_index - return self.bets[bet_index] - - @property - def collateral_token(self) -> str: - """Get the contract address of the token that the market maker supports.""" - return self.sampled_bet.collateralToken - - @property - def is_wxdai(self) -> bool: - """Get whether the collateral address is wxDAI.""" - return self.collateral_token.lower() == WXDAI.lower() - - @staticmethod - def wei_to_native(wei: int) -> float: - """Convert WEI to native token.""" - return wei / 10**18 - - def get_active_sampled_bet(self) -> Bet: - """Function to get the selected bet that is active without reseting self.bets.""" - bet_index = self.synchronized_data.sampled_bet_index - if len(self.bets) == 0: - msg = "The length of self.bets is 0" - self.context.logger.info(msg) - self.read_bets() - - return self.bets[bet_index] - - def _collateral_amount_info(self, amount: int) -> str: - """Get a description of the collateral token's amount.""" - is_wxdai = True if self.benchmarking_mode.enabled else self.is_wxdai - - return ( - f"{self.wei_to_native(amount)} wxDAI" - if is_wxdai - else f"{amount} WEI of the collateral token with address {self.collateral_token}" - ) - - def _report_balance(self) -> None: - """Report the balances of the native and the collateral tokens.""" - native = self.wei_to_native(self.wallet_balance) - collateral = self._collateral_amount_info(self.token_balance) - self.context.logger.info(f"The safe has {native} xDAI and {collateral}.") - - def _mock_balance_check(self) -> None: - """Mock the balance of the native and the collateral tokens.""" - self.token_balance = self.benchmarking_mode.collateral_balance - self.wallet_balance = self.benchmarking_mode.native_balance - self._report_balance() - - def check_balance(self) -> WaitableConditionType: - """Check the safe's balance.""" - if self.benchmarking_mode.enabled: - self._mock_balance_check() - return True - - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.collateral_token, - contract_id=str(ERC20.contract_id), - contract_callable="check_balance", - account=self.synchronized_data.safe_contract_address, - ) - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.context.logger.error( - f"Could not calculate the balance of the safe: {response_msg}" - ) - return False - - token = response_msg.raw_transaction.body.get("token", None) - wallet = response_msg.raw_transaction.body.get("wallet", None) - if token is None or wallet is None: - self.context.logger.error( - f"Something went wrong while trying to get the balance of the safe: {response_msg}" - ) - return False - - self.token_balance = int(token) - self.wallet_balance = int(wallet) - self._report_balance() - return True - - def update_bet_transaction_information(self) -> None: - """Get whether the bet's invested amount should be updated.""" - sampled_bet = self.sampled_bet - - # Update the bet's invested amount - updated = sampled_bet.update_investments(self.synchronized_data.bet_amount) - if not updated: - self.context.logger.error("Could not update the investments!") - - # Update bet transaction timestamp - sampled_bet.processed_timestamp = self.synced_timestamp - # Update Queue number for priority logic - sampled_bet.queue_status = sampled_bet.queue_status.next_status() - - # the bets are stored here, but we do not update the hash in the synced db in the redeeming round - # this will need to change if this sovereign agent is ever converted to a multi-agent service - self.store_bets() - - def send_message( - self, msg: Message, dialogue: Dialogue, callback: Callable - ) -> None: - """Send a message.""" - self.context.outbox.put_message(message=msg) - nonce = dialogue.dialogue_label.dialogue_reference[0] - self.shared_state.req_to_callback[nonce] = callback - self.shared_state.in_flight_req = True - - def _handle_get_strategy(self, message: IpfsMessage, _: Dialogue) -> None: - """Handle get strategy response.""" - strategy_req = self._inflight_strategy_req - if strategy_req is None: - self.context.logger.error(f"No strategy request to handle for {message=}.") - return - - # store the executable and remove the hash from the mapping because we have downloaded it - _component_yaml, strategy_exec, callable_method = ComponentPackageLoader.load( - message.files - ) - - self.shared_state.strategies_executables[strategy_req] = ( - strategy_exec, - callable_method, - ) - self.shared_state.strategy_to_filehash.pop(strategy_req) - self._inflight_strategy_req = None - - def download_next_strategy(self) -> None: - """Download the strategies one by one. - - The next strategy in the list is downloaded each time this method is called. - - We download all the strategies, - because in the future we will perform some complicated logic, - where we utilize more than one, e.g., in case the default fails - or is weaker than another depending on the situation. - - :return: None - """ - if self._inflight_strategy_req is not None: - # there already is a req in flight - return - if len(self.shared_state.strategy_to_filehash) == 0: - # no strategies pending to be fetched - return - for strategy, file_hash in self.shared_state.strategy_to_filehash.items(): - self.context.logger.info(f"Fetching {strategy} strategy...") - ipfs_msg, message = self._build_ipfs_get_file_req(file_hash) - self._inflight_strategy_req = strategy - self.send_message(ipfs_msg, message, self._handle_get_strategy) - return - - def download_strategies(self) -> Generator: - """Download all the strategies, if not yet downloaded.""" - while len(self.shared_state.strategy_to_filehash) > 0: - self.download_next_strategy() - yield from self.sleep(self.params.sleep_time) - - def get_bet_amount( - self, - win_probability: float, - confidence: float, - selected_type_tokens_in_pool: int, - other_tokens_in_pool: int, - bet_fee: int, - weighted_accuracy: float, - ) -> Generator[None, None, int]: - """Get the bet amount given a specified trading strategy.""" - yield from self.download_strategies() - yield from self.wait_for_condition_with_sleep(self.check_balance) - - next_strategy = self.params.trading_strategy - tried_strategies: Set[str] = set() - while True: - self.context.logger.info(f"Used trading strategy: {next_strategy}") - # the following are always passed to a strategy script, which may choose to ignore any - kwargs: Dict[str, Any] = self.params.strategies_kwargs - kwargs.update( - { - "trading_strategy": next_strategy, - "bankroll": self.token_balance + self.wallet_balance, - "win_probability": win_probability, - "confidence": confidence, - "selected_type_tokens_in_pool": selected_type_tokens_in_pool, - "other_tokens_in_pool": other_tokens_in_pool, - "bet_fee": bet_fee, - "weighted_accuracy": weighted_accuracy, - } - ) - results = self.execute_strategy(**kwargs) - for level in SUPPORTED_STRATEGY_LOG_LEVELS: - logger = getattr(self.context.logger, level, None) - if logger is not None: - for log in results.get(level, []): - logger(log) - bet_amount = results.get(BET_AMOUNT_FIELD, None) - if bet_amount is None: - self.context.logger.error( - f"Required field {BET_AMOUNT_FIELD!r} was not returned by {next_strategy} strategy." - "Setting bet amount to 0." - ) - bet_amount = 0 - - tried_strategies.update({next_strategy}) - strategies_names = set(self.shared_state.strategies_executables) - remaining_strategies = strategies_names - tried_strategies - if ( - bet_amount > 0 - or len(remaining_strategies) == 0 - or not self.params.use_fallback_strategy - ): - break - - next_strategy = remaining_strategies.pop() - self.context.logger.warning( - f"Using fallback strategy {next_strategy} as the previous one returned {bet_amount}." - ) - - return bet_amount - - def default_error( - self, contract_id: str, contract_callable: str, response_msg: ContractApiMessage - ) -> None: - """Return a default contract interaction error message.""" - self.context.logger.error( - f"Could not successfully interact with the {contract_id} contract " - f"using {contract_callable!r}: {response_msg}" - ) - - def _propagate_contract_messages(self, response_msg: ContractApiMessage) -> bool: - """Propagate the contract's message to the logger, if exists. - - Contracts can only return one message at a time. - - :param response_msg: the response message from the contract method. - :return: whether a message has been propagated. - """ - for level in ("info", "warning", "error"): - msg = response_msg.raw_transaction.body.get(level, None) - if msg is not None: - logger = getattr(self.context.logger, level) - logger(msg) - return True - return False - - def contract_interact( - self, - performative: ContractApiMessage.Performative, - contract_address: str, - contract_public_id: PublicId, - contract_callable: str, - data_key: str, - placeholder: str, - **kwargs: Any, - ) -> WaitableConditionType: - """Interact with a contract.""" - contract_id = str(contract_public_id) - response_msg = yield from self.get_contract_api_response( - performative, - contract_address, - contract_id, - contract_callable, - **kwargs, - ) - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.default_error(contract_id, contract_callable, response_msg) - return False - - propagated = self._propagate_contract_messages(response_msg) - data = response_msg.raw_transaction.body.get(data_key, None) - if data is None: - if not propagated: - self.default_error(contract_id, contract_callable, response_msg) - return False - - setattr(self, placeholder, data) - return True - - def _mech_contract_interact( - self, contract_callable: str, data_key: str, placeholder: str, **kwargs: Any - ) -> WaitableConditionType: - """Interact with the mech contract.""" - status = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.mech_contract_address, - contract_public_id=Mech.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def _build_multisend_data( - self, - ) -> WaitableConditionType: - """Get the multisend tx.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.multisend_address, - contract_id=str(MultiSendContract.contract_id), - contract_callable="get_tx_data", - multi_send_txs=self.multi_send_txs, - ) - expected_performative = ContractApiMessage.Performative.RAW_TRANSACTION - if response_msg.performative != expected_performative: - self.context.logger.error( - "Couldn't compile the multisend tx. " # type: ignore - f"Expected response performative {expected_performative.value}, " # type: ignore - f"received {response_msg.performative.value}: {response_msg}" - ) - return False - - multisend_data_str = response_msg.raw_transaction.body.get("data", None) - if multisend_data_str is None: - self.context.logger.error( - f"Something went wrong while trying to prepare the multisend data: {response_msg}" - ) - return False - - # strip "0x" from the response - multisend_data_str = str(response_msg.raw_transaction.body["data"])[2:] - self.multisend_data = bytes.fromhex(multisend_data_str) - return True - - def _build_multisend_safe_tx_hash(self) -> WaitableConditionType: - """Prepares and returns the safe tx hash for a multisend tx.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_raw_safe_transaction_hash", - to_address=self.params.multisend_address, - value=self.txs_value, - data=self.multisend_data, - safe_tx_gas=SAFE_GAS, - operation=SafeOperation.DELEGATE_CALL.value, - ) - - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - "Couldn't get safe tx hash. Expected response performative " # type: ignore - f"{ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response_msg.performative.value}: {response_msg}." - ) - return False - - tx_hash = response_msg.state.body.get("tx_hash", None) - if tx_hash is None or len(tx_hash) != TX_HASH_LENGTH: - self.context.logger.error( - "Something went wrong while trying to get the buy transaction's hash. " - f"Invalid hash {tx_hash!r} was returned." - ) - return False - - # strip "0x" from the response hash - self.safe_tx_hash = tx_hash - return True - - def wait_for_condition_with_sleep( - self, - condition_gen: Callable[[], WaitableConditionType], - timeout: Optional[float] = None, - sleep_time_override: Optional[int] = None, - ) -> Generator[None, None, None]: - """Wait for a condition to happen and sleep in-between checks. - - This is a modified version of the base `wait_for_condition` method which: - 1. accepts a generator that creates the condition instead of a callable - 2. sleeps in-between checks - - :param condition_gen: a generator of the condition to wait for - :param timeout: the maximum amount of time to wait - :param sleep_time_override: override for the sleep time. - If None is given, the default value is used, which is the RPC timeout set in the configuration. - :yield: None - """ - - deadline = ( - datetime.now() + timedelta(0, timeout) - if timeout is not None - else datetime.max - ) - - sleep_time = sleep_time_override or self.params.rpc_sleep_time - while True: - condition_satisfied = yield from condition_gen() - if condition_satisfied: - break - if timeout is not None and datetime.now() > deadline: - raise TimeoutException() - self.context.logger.info(f"Retrying in {sleep_time} seconds.") - yield from self.sleep(sleep_time) - - def _write_benchmark_results( - self, - prediction_response: PredictionResponse, - bet_amount: Optional[float] = None, - liquidity_info: LiquidityInfo = INIT_LIQUIDITY_INFO, - ) -> None: - """Write the results to the benchmarking file.""" - print("Writing benchmarking results") - add_headers = False - results_path = self.params.store_path / self.benchmarking_mode.results_filename - if not os.path.isfile(results_path): - add_headers = True - - with open(results_path, "a") as results_file: - if add_headers: - headers = ( - self.benchmarking_mode.question_id_field, - self.benchmarking_mode.question_field, - self.benchmarking_mode.answer_field, - P_YES_FIELD, - P_NO_FIELD, - CONFIDENCE_FIELD, - INFO_UTILITY_FIELD, - self.benchmarking_mode.bet_amount_field, - L0_START_FIELD, - L1_START_FIELD, - L0_END_FIELD, - L1_END_FIELD, - ) - row = ",".join(headers) + NEW_LINE - results_file.write(row) - - results = ( - self.mock_data.id, - # reintroduce duplicate quotes and quote the question - # as it may contain commas which are also used as separators - QUOTE + self.mock_data.question.replace(QUOTE, TWO_QUOTES) + QUOTE, - self.mock_data.answer, - prediction_response.p_yes, - prediction_response.p_no, - prediction_response.confidence, - prediction_response.info_utility, - bet_amount, - liquidity_info.l0_start, - liquidity_info.l1_start, - liquidity_info.l0_end, - liquidity_info.l1_end, - ) - results_text = tuple(str(res) for res in results) - row = ",".join(results_text) + NEW_LINE - results_file.write(row) - - def finish_behaviour(self, payload: BaseTxPayload) -> Generator: - """Finish the behaviour.""" - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - def build_approval_tx( - self, amount: int, spender: str, token: str - ) -> WaitableConditionType: - """Build an ERC20 approve transaction.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.collateral_token, - contract_id=str(ERC20.contract_id), - contract_callable="build_approval_tx", - spender=spender, - amount=amount, - ) - - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.info(f"Could not build approval tx: {response_msg}") - return False - - approval_data = response_msg.state.body.get("data") - if approval_data is None: - self.context.logger.info(f"Could not build approval tx: {response_msg}") - return False - - batch = MultisendBatch( - to=token, - data=HexBytes(approval_data), - ) - self.multisend_batches.append(batch) - return True - - -class BaseSubscriptionBehaviour(DecisionMakerBaseBehaviour, ABC): - """Base class for subscription behaviours.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize `BaseSubscriptionBehaviour`.""" - super().__init__(**kwargs) - self.balance: int = 0 - - @property - def escrow_payment_condition_address(self) -> str: - """Get the escrow payment address.""" - subscription_params = self.subscription_params - return subscription_params["escrow_payment_condition_address"] - - @property - def lock_payment_condition_address(self) -> str: - """Get the lock payment address.""" - subscription_params = self.subscription_params - return subscription_params["lock_payment_condition_address"] - - @property - def transfer_nft_condition_address(self) -> str: - """Get the transfer nft condition address.""" - subscription_params = self.subscription_params - return subscription_params["transfer_nft_condition_address"] - - @property - def order_address(self) -> str: - """Get the order address.""" - subscription_params = self.subscription_params - return subscription_params["order_address"] - - @property - def purchase_amount(self) -> int: - """Get the purchase amount.""" - subscription_params = self.subscription_params - return int(subscription_params["nft_amount"]) - - @property - def price(self) -> int: - """Get the price.""" - subscription_params = self.subscription_params - return int(subscription_params["price"]) - - @property - def payment_token(self) -> str: - """Get the payment token.""" - subscription_params = self.subscription_params - return subscription_params["payment_token"] - - @property - def is_xdai(self) -> bool: - """ - Check if the payment token is xDAI. - - When the payment token for the subscription is xdai (the native token of the chain), - nevermined sets the payment address to the zeroAddress. - - :return: True if the payment token is xDAI, False otherwise. - """ - return self.payment_token == ZERO_ADDRESS - - @property - def base_url(self) -> str: - """Get the base url.""" - subscription_params = self.subscription_params - return subscription_params["base_url"] - - def _resolve_did(self) -> Generator[None, None, Optional[Dict[str, Any]]]: - """Resolve and parse the did.""" - did_url = f"{self.base_url}/{self.did}" - response = yield from self.get_http_response( - method="GET", - url=did_url, - headers={"accept": "application/json"}, - ) - if response.status_code != 200: - self.context.logger.error( - f"Could not retrieve data from did url {did_url}. " - f"Received status code {response.status_code}." - ) - return None - try: - data = json.loads(response.body) - except (ValueError, TypeError) as e: - self.context.logger.error( - f"Could not parse response from nervermined api, " - f"the following error was encountered {type(e).__name__}: {e}" - ) - return None - - return data - - def _get_nft_balance( - self, token: str, address: str, did: str - ) -> Generator[None, None, bool]: - """Prepare an approval tx.""" - result = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=token, - contract_public_id=TransferNftCondition.contract_id, - contract_callable="balance_of", - data_key="data", - placeholder="balance", - address=address, - did=did, - ) - return result - - def _has_positive_nft_balance(self) -> Generator[None, None, bool]: - """Check if the agent has a non-zero balance of the NFT.""" - result = yield from self._get_nft_balance( - self.token_address, - self.synchronized_data.safe_contract_address, - zero_x_transformer(no_did_prefixed(self.did)), - ) - if not result: - self.context.logger.warning("Failed to get balance") - return False - - return self.balance > 0 diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/bet_placement.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/bet_placement.py deleted file mode 100644 index bfda67fd3..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/bet_placement.py +++ /dev/null @@ -1,225 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour for sampling a bet.""" - -from typing import Any, Generator, Optional, cast - -from hexbytes import HexBytes - -from packages.valory.contracts.erc20.contract import ERC20 -from packages.valory.contracts.market_maker.contract import ( - FixedProductMarketMakerContract, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, - WXDAI, - WaitableConditionType, - remove_fraction_wei, -) -from packages.valory.skills.decision_maker_abci.models import MultisendBatch -from packages.valory.skills.decision_maker_abci.payloads import BetPlacementPayload -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) - - -class BetPlacementBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents blacklist the sampled bet.""" - - matching_round = BetPlacementRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize the bet placement behaviour.""" - super().__init__(**kwargs) - self.buy_amount = 0 - - @property - def market_maker_contract_address(self) -> str: - """Get the contract address of the market maker on which the service is going to place the bet.""" - return self.sampled_bet.id - - @property - def investment_amount(self) -> int: - """Get the investment amount of the bet.""" - return self.synchronized_data.bet_amount - - @property - def w_xdai_deficit(self) -> int: - """Get the amount of missing wxDAI for placing the bet.""" - return self.investment_amount - self.token_balance - - @property - def outcome_index(self) -> int: - """Get the index of the outcome that the service is going to place a bet on.""" - return cast(int, self.synchronized_data.vote) - - def _build_exchange_tx(self) -> WaitableConditionType: - """Exchange xDAI to wxDAI.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=WXDAI, - contract_id=str(ERC20.contract_id), - contract_callable="build_deposit_tx", - ) - - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.info(f"Could not build deposit tx: {response_msg}") - return False - - approval_data = response_msg.state.body.get("data") - if approval_data is None: - self.context.logger.info(f"Could not build deposit tx: {response_msg}") - return False - - batch = MultisendBatch( - to=self.collateral_token, - data=HexBytes(approval_data), - value=self.w_xdai_deficit, - ) - self.multisend_batches.append(batch) - return True - - def _build_approval_tx(self) -> WaitableConditionType: - """Build an ERC20 approve transaction.""" - status = yield from self.build_approval_tx( - self.investment_amount, - self.market_maker_contract_address, - self.collateral_token, - ) - return status - - def _calc_buy_amount(self) -> WaitableConditionType: - """Calculate the buy amount of the conditional token.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.market_maker_contract_address, - contract_id=str(FixedProductMarketMakerContract.contract_id), - contract_callable="calc_buy_amount", - investment_amount=self.investment_amount, - outcome_index=self.outcome_index, - ) - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.context.logger.error( - f"Could not calculate the buy amount: {response_msg}" - ) - return False - - buy_amount = response_msg.raw_transaction.body.get("amount", None) - if buy_amount is None: - self.context.logger.error( - f"Something went wrong while trying to get the buy amount for the conditional token: {response_msg}" - ) - return False - - self.buy_amount = remove_fraction_wei(buy_amount, self.params.slippage) - return True - - def _build_buy_tx(self) -> WaitableConditionType: - """Get the buy tx data encoded.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.market_maker_contract_address, - contract_id=str(FixedProductMarketMakerContract.contract_id), - contract_callable="get_buy_data", - investment_amount=self.investment_amount, - outcome_index=self.outcome_index, - min_outcome_tokens_to_buy=self.buy_amount, - ) - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Could not get the data for the buy transaction: {response_msg}" - ) - return False - - buy_data = response_msg.state.body.get("data", None) - if buy_data is None: - self.context.logger.error( - f"Something went wrong while trying to encode the buy data: {response_msg}" - ) - return False - - batch = MultisendBatch( - to=self.market_maker_contract_address, - data=HexBytes(buy_data), - ) - self.multisend_batches.append(batch) - return True - - def _prepare_safe_tx(self) -> Generator[None, None, Optional[str]]: - """Prepare the safe transaction for placing a bet and return the hex for the tx settlement skill.""" - for step in ( - self._build_approval_tx, - self._calc_buy_amount, - self._build_buy_tx, - self._build_multisend_data, - self._build_multisend_safe_tx_hash, - ): - yield from self.wait_for_condition_with_sleep(step) - - outcome = self.sampled_bet.get_outcome(self.outcome_index) - investment = self._collateral_amount_info(self.investment_amount) - self.context.logger.info( - f"Preparing a multisig transaction to place a bet for {outcome!r}, with confidence " - f"{self.synchronized_data.confidence!r}, for the amount of {investment}, which is equal to the amount of " - f"{self.buy_amount!r} WEI of the conditional token corresponding to {outcome!r}." - ) - - return self.tx_hex - - def async_act(self) -> Generator: - """Do the action.""" - agent = self.context.agent_address - - if self.benchmarking_mode.enabled: - # simulate the bet placement - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - self.update_bet_transaction_information() - payload = BetPlacementPayload( - agent, None, None, True, self.wallet_balance - ) - yield from self.finish_behaviour(payload) - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - yield from self.wait_for_condition_with_sleep(self.check_balance) - tx_submitter = betting_tx_hex = mocking_mode = wallet_balance = None - - can_exchange = ( - self.is_wxdai - # no need to take fees into consideration because it is the safe's balance and the agents pay the fees - and self.wallet_balance >= self.w_xdai_deficit - ) - if self.token_balance < self.investment_amount and can_exchange: - yield from self.wait_for_condition_with_sleep(self._build_exchange_tx) - - if self.token_balance >= self.investment_amount or can_exchange: - tx_submitter = self.matching_round.auto_round_id() - betting_tx_hex = yield from self._prepare_safe_tx() - wallet_balance = self.wallet_balance - - payload = BetPlacementPayload( - agent, - tx_submitter, - betting_tx_hex, - mocking_mode, - wallet_balance, - ) - - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/blacklisting.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/blacklisting.py deleted file mode 100644 index baf8a8563..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/blacklisting.py +++ /dev/null @@ -1,86 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour for the blacklisting of the sampled bet.""" - -from typing import Generator - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import BlacklistingPayload -from packages.valory.skills.decision_maker_abci.states.blacklisting import ( - BlacklistingRound, -) -from packages.valory.skills.decision_maker_abci.states.handle_failed_tx import ( - HandleFailedTxRound, -) - - -class BlacklistingBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents blacklist the sampled bet.""" - - matching_round = BlacklistingRound - - @property - def synced_time(self) -> float: - """Get the synchronized time among agents.""" - synced_time = self.shared_state.round_sequence.last_round_transition_timestamp - return synced_time.timestamp() - - def _blacklist(self) -> None: - """Blacklist the sampled bet.""" - sampled_bet_index = self.synchronized_data.sampled_bet_index - sampled_bet = self.bets[sampled_bet_index] - - # the question is blacklisted, i.e., we did not place a bet on it, - # therefore, we bump the queue's status to the next one - sampled_bet.queue_status = sampled_bet.queue_status.next_status() - - def setup(self) -> None: - """Setup the behaviour""" - self._policy = self.synchronized_data.policy - - def async_act(self) -> Generator: - """Do the action.""" - # if the tool selection has not been run for the current period, do not do anything - if not self.synchronized_data.has_tool_selection_run: - policy = self.policy.serialize() - payload = BlacklistingPayload(self.context.agent_address, None, policy) - yield from self.finish_behaviour(payload) - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - self.read_bets() - self._blacklist() - self.store_bets() - bets_hash = ( - None if self.benchmarking_mode.enabled else self.hash_stored_bets() - ) - if ( - self.synchronized_data.tx_submitter - != HandleFailedTxRound.auto_round_id() - ): - # if we are here, then the tool has responded with an error - self.policy.tool_responded( - self.synchronized_data.mech_tool, self.synced_timestamp - ) - policy = self.policy.serialize() - payload = BlacklistingPayload(self.context.agent_address, bets_hash, policy) - - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/check_benchmarking.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/check_benchmarking.py deleted file mode 100644 index 4d8157f2c..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/check_benchmarking.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour for checking whether the benchmarking mode is enabled.""" - -from typing import Generator - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import VotingPayload -from packages.valory.skills.decision_maker_abci.states.check_benchmarking import ( - CheckBenchmarkingModeRound, -) - - -class CheckBenchmarkingModeBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents blacklist the sampled bet.""" - - matching_round = CheckBenchmarkingModeRound - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - payload = VotingPayload( - self.context.agent_address, self.benchmarking_mode.enabled - ) - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/claim_subscription.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/claim_subscription.py deleted file mode 100644 index f28a422bf..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/claim_subscription.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the behaviour for the decision-making of the skill.""" -import json -from typing import Any, Generator - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - BaseSubscriptionBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import ClaimPayload -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) -from packages.valory.skills.decision_maker_abci.utils.nevermined import ( - get_claim_endpoint, - get_creator, -) - - -SERVICE_INDEX = -1 -ERC1155 = 1155 - - -class ClaimSubscriptionBehaviour(BaseSubscriptionBehaviour): - """A behaviour in which the agents claim the subscription they purchased.""" - - matching_round = ClaimRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize `RedeemBehaviour`.""" - super().__init__(**kwargs) - self.order_tx: str = "" - self.approval_tx: str = "" - self.balance: int = 0 - - def _claim_subscription(self) -> Generator[None, None, bool]: - """Claim the subscription.""" - did_doc = yield from self._resolve_did() - if did_doc is None: - return False - - creator = get_creator(did_doc) - claim_endpoint = get_claim_endpoint(did_doc) - body = { - "agreementId": self.synchronized_data.agreement_id, - "did": self.did, - "nftHolder": creator, - "nftReceiver": self.synchronized_data.safe_contract_address, - "nftAmount": str(self.purchase_amount), - "nftType": ERC1155, - "serviceIndex": SERVICE_INDEX, - } - self.context.logger.info( - "Claiming subscription with body: %s", json.dumps(body) - ) - res = yield from self.get_http_response( - "POST", - claim_endpoint, - json.dumps(body).encode(), - headers={"Content-Type": "application/json"}, - ) - if res.status_code == 201: - self.context.logger.info( - f"Successfully claimed subscription: {res.status_code!r} - {res.body!r}", - ) - return True - - self.context.logger.warning( - f"Couldn't claim subscription: {res.status_code!r} - {res.body!r}" - f"Checking the balance of the safe on the NFT." - ) - has_balance = yield from self._has_positive_nft_balance() - if not has_balance: - self.context.logger.warning( - "Safe doesn't contain the NFT, claiming failed." - ) - return False - - self.context.logger.info("Safe contains the NFT, claiming succeeded.") - return True - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - claim = yield from self._claim_subscription() - sender = self.context.agent_address - payload = ClaimPayload( - sender, - vote=claim, - ) - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/decision_receive.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/decision_receive.py deleted file mode 100644 index 4bac7b4d2..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/decision_receive.py +++ /dev/null @@ -1,612 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour for the decision-making of the skill.""" - -import csv -import json -from copy import deepcopy -from datetime import datetime -from math import prod -from typing import Any, Dict, Generator, List, Optional, Tuple, Union - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - remove_fraction_wei, -) -from packages.valory.skills.decision_maker_abci.behaviours.storage_manager import ( - StorageManagerBehaviour, -) -from packages.valory.skills.decision_maker_abci.io_.loader import ComponentPackageLoader -from packages.valory.skills.decision_maker_abci.models import ( - BenchmarkingMockData, - LiquidityInfo, -) -from packages.valory.skills.decision_maker_abci.payloads import DecisionReceivePayload -from packages.valory.skills.decision_maker_abci.states.decision_receive import ( - DecisionReceiveRound, -) -from packages.valory.skills.market_manager_abci.bets import ( - BINARY_N_SLOTS, - Bet, - CONFIDENCE_FIELD, - INFO_UTILITY_FIELD, - P_NO_FIELD, - P_YES_FIELD, - PredictionResponse, -) -from packages.valory.skills.mech_interact_abci.states.base import ( - MechInteractionResponse, -) - - -SLIPPAGE = 1.05 -WRITE_TEXT_MODE = "w+t" -COMMA = "," -TOKEN_PRECISION = 10**18 - - -class DecisionReceiveBehaviour(StorageManagerBehaviour): - """A behaviour in which the agents receive the mech response.""" - - matching_round = DecisionReceiveRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize Behaviour.""" - super().__init__(**kwargs, loader_cls=ComponentPackageLoader) - self._request_id: int = 0 - self._mech_response: Optional[MechInteractionResponse] = None - self._rows_exceeded: bool = False - - @property - def request_id(self) -> int: - """Get the request id.""" - return self._request_id - - @request_id.setter - def request_id(self, request_id: Union[str, int]) -> None: - """Set the request id.""" - try: - self._request_id = int(request_id) - except ValueError: - msg = f"Request id {request_id} is not a valid integer!" - self.context.logger.error(msg) - - @property - def mech_response(self) -> MechInteractionResponse: - """Get the mech's response.""" - if self._mech_response is None: - error = "The mech's response has not been set!" - return MechInteractionResponse(error=error) - return self._mech_response - - @property - def is_invalid_response(self) -> bool: - """Check if the response is invalid.""" - if self.mech_response.result is None: - self.context.logger.warning( - "Trying to check whether the mech's response is invalid but no response has been detected! " - "Assuming invalid response." - ) - return True - return self.mech_response.result == self.params.mech_invalid_response - - def _next_dataset_row(self) -> Optional[Dict[str, str]]: - """Read the next row from the input dataset which is used during the benchmarking mode. - - :return: a dictionary with the header fields mapped to the values of the first row. - If no rows are left to process in the file, returns `None`. - """ - sep = self.benchmarking_mode.sep - dataset_filepath = ( - self.params.store_path / self.benchmarking_mode.dataset_filename - ) - active_sampled_bet = self.get_active_sampled_bet() - sampled_bet_id = active_sampled_bet.id - - # we have now one reader pointer per market - available_rows_for_market = self.shared_state.bet_id_row_manager[sampled_bet_id] - if available_rows_for_market: - next_mock_data_row = available_rows_for_market[0] - else: - # no more bets available for this market - msg = f"No more mock responses for the market with id: {sampled_bet_id}" - self.sampled_bet.queue_status = ( - self.sampled_bet.queue_status.mark_benchmarking_done() - ) - self.context.logger.info(msg) - self.shared_state.last_benchmarking_has_run = True - self._rows_exceeded = True - return None - - row_with_headers: Optional[Dict[str, str]] = None - with open(dataset_filepath) as read_dataset: - reader = csv.DictReader(read_dataset, delimiter=sep) - - for _ in range(next_mock_data_row): - row_with_headers = next(reader, {}) - - if not row_with_headers: - # if no rows are in the file, then we finished the benchmarking - self._rows_exceeded = True - return None - - msg = f"Processing question in row with index {next_mock_data_row}: {row_with_headers}" - self.context.logger.info(msg) - return row_with_headers - - def _parse_dataset_row(self, row: Dict[str, str]) -> str: - """Parse a dataset's row to store the mock market data and to mock a prediction response.""" - mode = self.benchmarking_mode - mech_tool = self.synchronized_data.mech_tool - fields = {} - - for prediction_attribute, field_part in { - P_YES_FIELD: mode.p_yes_field_part, - P_NO_FIELD: mode.p_no_field_part, - CONFIDENCE_FIELD: mode.confidence_field_part, - INFO_UTILITY_FIELD: mode.info_utility_field_part, - }.items(): - if mode.part_prefix_mode: - fields[prediction_attribute] = row[field_part + mech_tool] - else: - fields[prediction_attribute] = row[mech_tool + field_part] - - # set the benchmarking mock data - self.shared_state.mock_data = BenchmarkingMockData( - row[mode.question_id_field], - row[mode.question_field], - row[mode.answer_field], - float(fields[P_YES_FIELD]), - ) - print(f"parsed row {fields}") - return json.dumps(fields) - - def _mock_response(self) -> None: - """Mock the response data.""" - dataset_row = self._next_dataset_row() - if dataset_row is None: - return - mech_response = self._parse_dataset_row(dataset_row) - print(f"Mech response = {mech_response}") - self._mech_response = MechInteractionResponse(result=mech_response) - - def _get_response(self) -> None: - """Get the response data.""" - mech_responses = self.synchronized_data.mech_responses - if mech_responses: - self._mech_response = mech_responses[0] - return - error = "No Mech responses in synchronized_data." - self._mech_response = MechInteractionResponse(error=error) - - def _get_decision( - self, - ) -> Optional[PredictionResponse]: - """Get vote, win probability and confidence.""" - if self.benchmarking_mode.enabled: - self._mock_response() - else: - self._get_response() - - if self._mech_response is None: - self.context.logger.info("The mech response is None") - return None - - self.context.logger.info(f"Decision has been received:\n{self.mech_response}") - if self.mech_response.result is None: - self.context.logger.error( - f"There was an error on the mech's response: {self.mech_response.error}" - ) - return None - - try: - return PredictionResponse(**json.loads(self.mech_response.result)) - except (json.JSONDecodeError, ValueError) as exc: - self.context.logger.error(f"Could not parse the mech's response: {exc}") - return None - - @staticmethod - def _get_bet_sample_info(bet: Bet, vote: int) -> Tuple[int, int]: - """Get the bet sample information.""" - token_amounts = bet.outcomeTokenAmounts - selected_type_tokens_in_pool = token_amounts[vote] - opposite_vote = vote ^ 1 - other_tokens_in_pool = token_amounts[opposite_vote] - - return selected_type_tokens_in_pool, other_tokens_in_pool - - def _compute_new_tokens_distribution( - self, - token_amounts: List[int], - prices: List[float], - net_bet_amount: int, - vote: int, - ) -> Tuple[int, int, int, int, int]: - k = prod(token_amounts) - self.context.logger.info(f"k: {k}") - - # the OMEN market trades an equal amount of the investment to each of the tokens in the pool - # here we calculate the bet amount per pool's token - bet_per_token = net_bet_amount / BINARY_N_SLOTS - self.context.logger.info(f"Bet per token: {bet_per_token}") - - tokens_traded = [int(bet_per_token / prices[i]) for i in range(BINARY_N_SLOTS)] - self.context.logger.info(f"Tokens traded: {[x for x in tokens_traded]}") - - # get the shares for the answer that the service has selected - selected_shares = tokens_traded.pop(vote) - self.context.logger.info(f"Selected shares: {selected_shares}") - - # get the shares for the opposite answer - other_shares = tokens_traded.pop() - self.context.logger.info(f"Other shares: {other_shares}") - - # get the number of tokens in the pool for the answer that the service has selected - selected_type_tokens_in_pool = token_amounts.pop(vote) - self.context.logger.info( - f"Selected type tokens in pool: {selected_type_tokens_in_pool}" - ) - - # get the number of tokens in the pool for the opposite answer - other_tokens_in_pool = token_amounts.pop() - self.context.logger.info(f"Other tokens in pool: {other_tokens_in_pool}") - - # the OMEN market then trades the opposite tokens to the tokens of the answer that has been selected, - # preserving the balance of the pool - # here we calculate the number of shares that we get after trading the tokens for the opposite answer - tokens_remaining_in_pool = int(k / (other_tokens_in_pool + other_shares)) - self.context.logger.info( - f"Tokens remaining in pool: {tokens_remaining_in_pool}" - ) - - swapped_shares = selected_type_tokens_in_pool - tokens_remaining_in_pool - self.context.logger.info(f"Swapped shares: {swapped_shares}") - - # calculate the resulting number of shares if the service would take that position - num_shares = selected_shares + swapped_shares - self.context.logger.info(f"Number of shares: {num_shares}") - - # calculate the available number of shares - price = prices[vote] - self.context.logger.info(f"Price: {prices[vote]}") - - available_shares = int(selected_type_tokens_in_pool * price) - self.context.logger.info(f"Available shares: {available_shares}") - - return ( - selected_type_tokens_in_pool, - other_tokens_in_pool, - other_shares, - num_shares, - available_shares, - ) - - def _calc_binary_shares( - self, bet: Bet, net_bet_amount: int, vote: int - ) -> Tuple[int, int]: - """Calculate the claimed shares. This calculation only works for binary markets.""" - # calculate the pool's k (x*y=k) - token_amounts = bet.outcomeTokenAmounts - self.context.logger.info(f"Token amounts: {[x for x in token_amounts]}") - - # calculate the number of the traded tokens - prices = bet.outcomeTokenMarginalPrices - self.context.logger.info(f"Prices: {prices}") - - if prices is None: - return 0, 0 - - _, _, _, num_shares, available_shares = self._compute_new_tokens_distribution( - token_amounts.copy(), prices, net_bet_amount, vote - ) - - return num_shares, available_shares - - def _update_market_liquidity(self) -> None: - """Update the current market's liquidity information.""" - active_sampled_bet = self.get_active_sampled_bet() - question_id = active_sampled_bet.id - # check if share state information is empty and we need to initialize - empty_dict = len(self.shared_state.liquidity_amounts) == 0 - new_market = question_id not in self.shared_state.liquidity_amounts.keys() - if empty_dict or new_market: - self.shared_state.current_liquidity_amounts = ( - active_sampled_bet.outcomeTokenAmounts - ) - self.shared_state.current_liquidity_prices = ( - active_sampled_bet.outcomeTokenMarginalPrices - ) - self.shared_state.liquidity_cache[question_id] = ( - active_sampled_bet.scaledLiquidityMeasure - ) - - def _calculate_new_liquidity(self, net_bet_amount: int, vote: int) -> LiquidityInfo: - """Calculate and return the new liquidity information.""" - token_amounts = self.shared_state.current_liquidity_amounts - k = prod(token_amounts) - prices = self.shared_state.current_liquidity_prices - - ( - selected_type_tokens_in_pool, - other_tokens_in_pool, - other_shares, - _, - _, - ) = self._compute_new_tokens_distribution( - token_amounts.copy(), prices, net_bet_amount, vote - ) - - new_other = other_tokens_in_pool + other_shares - new_selected = int(k / new_other) - if vote == 0: - return LiquidityInfo( - selected_type_tokens_in_pool, - other_tokens_in_pool, - new_selected, - int(new_other), - ) - return LiquidityInfo( - other_tokens_in_pool, - selected_type_tokens_in_pool, - int(new_other), - new_selected, - ) - - def _compute_scaled_liquidity_measure( - self, token_amounts: List[int], token_prices: List[float] - ) -> float: - """Function to compute the scaled liquidity measure from token amounts and prices.""" - return ( - sum(amount * price for amount, price in zip(token_amounts, token_prices)) - / TOKEN_PRECISION - ) - - def _update_liquidity_info(self, net_bet_amount: int, vote: int) -> LiquidityInfo: - """Update the liquidity information at shared state and the prices after placing a bet for a market.""" - liquidity_info = self._calculate_new_liquidity(net_bet_amount, vote) - l0_start, l1_start = liquidity_info.validate_start_information() - - # to compute the new price we need the previous constants - prices = self.shared_state.current_liquidity_prices - - liquidity_constants = [ - l0_start * prices[0], - l1_start * prices[1], - ] - active_sampled_bet = self.get_active_sampled_bet() - market_id = active_sampled_bet.id - self.shared_state.current_liquidity_prices = liquidity_info.get_new_prices( - liquidity_constants - ) - self.shared_state.current_liquidity_amounts = liquidity_info.get_end_liquidity() - log_message = ( - f"New liquidity amounts: {self.shared_state.current_liquidity_amounts}" - ) - self.context.logger.info(log_message) - - # update the scaled liquidity Measure - self.shared_state.liquidity_cache[market_id] = ( - self._compute_scaled_liquidity_measure( - self.shared_state.current_liquidity_amounts, - self.shared_state.current_liquidity_prices, - ) - ) - - return liquidity_info - - def rebet_allowed( - self, prediction_response: PredictionResponse, potential_net_profit: int - ) -> bool: - """Whether a rebet is allowed or not.""" - # WARNING: Every time you call self.sampled_bet a reset in self.bets is done so any changes there will be lost - bet = self.sampled_bet - previous_response = deepcopy(bet.prediction_response) - previous_liquidity = bet.position_liquidity - previous_net_profit = bet.potential_net_profit - bet.prediction_response = prediction_response - vote = bet.prediction_response.vote - bet.position_liquidity = bet.outcomeTokenAmounts[vote] if vote else 0 - bet.potential_net_profit = potential_net_profit - rebet_allowed = bet.rebet_allowed( - previous_response, previous_liquidity, previous_net_profit - ) - if not rebet_allowed: - # reset the in-memory bets so that the updates of the sampled bet above are reverted - self.read_bets() - self.context.logger.info("Conditions for rebetting are not met!") - return rebet_allowed - - def _is_profitable( - self, prediction_response: PredictionResponse - ) -> Generator[None, None, Tuple[bool, int]]: - """Whether the decision is profitable or not.""" - if prediction_response.vote is None: - return False, 0 - - if self.benchmarking_mode.enabled: - bet = self.get_active_sampled_bet() # no reset - self.context.logger.info(f"Bet used for benchmarking: {bet}") - self._update_market_liquidity() - else: - # this call is destroying what it was in self.bets - bet = self.sampled_bet - - selected_type_tokens_in_pool, other_tokens_in_pool = self._get_bet_sample_info( - bet, prediction_response.vote - ) - - bet_amount = yield from self.get_bet_amount( - prediction_response.win_probability, - prediction_response.confidence, - selected_type_tokens_in_pool, - other_tokens_in_pool, - bet.fee, - self.synchronized_data.weighted_accuracy, - ) - bet_threshold = self.params.bet_threshold - bet_amount = max(bet_amount, bet_threshold) - - self.context.logger.info(f"Bet amount: {bet_amount}") - self.context.logger.info(f"Bet fee: {bet.fee}") - net_bet_amount = remove_fraction_wei(bet_amount, self.wei_to_native(bet.fee)) - self.context.logger.info(f"Net bet amount: {net_bet_amount}") - - num_shares, available_shares = self._calc_binary_shares( - bet, net_bet_amount, prediction_response.vote - ) - - self.context.logger.info(f"Adjusted available shares: {available_shares}") - if num_shares > available_shares * SLIPPAGE: - self.context.logger.warning( - "Kindly contemplate reducing your bet amount, as the pool's liquidity is low compared to your bet. " - "Consequently, this situation entails a higher level of risk as the obtained number of shares, " - "and therefore the potential net profit, will be lower than if the pool had higher liquidity!" - ) - if bet_threshold <= 0: - self.context.logger.warning( - f"A non-positive bet threshold was given ({bet_threshold}). The threshold will be disabled, " - f"which means that any non-negative potential profit will be considered profitable!" - ) - bet_threshold = 0 - - potential_net_profit = num_shares - net_bet_amount - bet_threshold - is_profitable = potential_net_profit >= 0 - - self.context.logger.info( - f"The current liquidity of the market is {bet.scaledLiquidityMeasure} xDAI. " - f"The potential net profit is {self.wei_to_native(potential_net_profit)} xDAI " - f"from buying {self.wei_to_native(num_shares)} shares for the option {bet.get_outcome(prediction_response.vote)}.\n" - f"Decision for profitability of this market: {is_profitable}." - ) - if is_profitable: - is_profitable = self.rebet_allowed( - prediction_response, potential_net_profit - ) - - if self.benchmarking_mode.enabled: - if is_profitable: - # update the information at the shared state - liquidity_info = self._update_liquidity_info( - net_bet_amount, prediction_response.vote - ) - bet.outcomeTokenAmounts = self.shared_state.current_liquidity_amounts - bet.outcomeTokenMarginalPrices = ( - self.shared_state.current_liquidity_prices - ) - bet.scaledLiquidityMeasure = self.shared_state.liquidity_cache[bet.id] - self.store_bets() - self._write_benchmark_results( - prediction_response, bet_amount, liquidity_info - ) - else: - self._write_benchmark_results(prediction_response) - - self.context.logger.info("Increasing Mech call count by 1") - self.shared_state.benchmarking_mech_calls += 1 - - return is_profitable, bet_amount - - def _update_selected_bet( - self, prediction_response: Optional[PredictionResponse] - ) -> None: - """Update the selected bet.""" - # update the bet's timestamp of processing and its number of bets for the given id - active_sampled_bet = self.get_active_sampled_bet() - active_sampled_bet.processed_timestamp = ( - self.shared_state.get_simulated_now_timestamp( - self.bets, self.params.safe_voting_range - ) - ) - self.context.logger.info(f"Updating bet id: {active_sampled_bet.id}") - self.context.logger.info( - f"with the timestamp:{datetime.fromtimestamp(active_sampled_bet.processed_timestamp)}" - ) - - self.store_bets() - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - success = yield from self._setup_policy_and_tools() - if not success: - return None - - prediction_response = self._get_decision() - is_profitable = None - bet_amount = None - next_mock_data_row = None - bets_hash = None - decision_received_timestamp = None - policy = None - if prediction_response is not None and prediction_response.vote is not None: - is_profitable, bet_amount = yield from self._is_profitable( - prediction_response - ) - decision_received_timestamp = self.synced_timestamp - if is_profitable: - self.store_bets() - bets_hash = self.hash_stored_bets() - - elif ( - prediction_response is not None - and self.benchmarking_mode.enabled - and not self._rows_exceeded - ): - self._write_benchmark_results( - prediction_response, - bet_amount, - ) - self.context.logger.info("Increasing Mech call count by 1") - self.shared_state.benchmarking_mech_calls += 1 - - if prediction_response is not None: - self.policy.tool_responded( - self.synchronized_data.mech_tool, - self.synced_timestamp, - self.is_invalid_response, - ) - policy = self.policy.serialize() - - # always remove the processed trade from the benchmarking input file - # now there is one reader pointer per market - if self.benchmarking_mode.enabled: - # always remove the processed trade from the benchmarking input file - # now there is one reader pointer per market - bet = self.get_active_sampled_bet() - rows_queue = self.shared_state.bet_id_row_manager[bet.id] - if rows_queue: - rows_queue.pop(0) - - self._update_selected_bet(prediction_response) - - payload = DecisionReceivePayload( - self.context.agent_address, - bets_hash, - is_profitable, - prediction_response.vote if prediction_response else None, - prediction_response.confidence if prediction_response else None, - bet_amount, - next_mock_data_row, - policy, - decision_received_timestamp, - ) - - self._store_all() - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/decision_request.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/decision_request.py deleted file mode 100644 index b887fb660..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/decision_request.py +++ /dev/null @@ -1,110 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour of the skill which is responsible for requesting a decision from the mech.""" - -import csv -import json -from dataclasses import asdict -from typing import Any, Dict, Generator, List, Optional -from uuid import uuid4 - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import DecisionRequestPayload -from packages.valory.skills.decision_maker_abci.states.decision_request import ( - DecisionRequestRound, -) -from packages.valory.skills.market_manager_abci.bets import BINARY_N_SLOTS -from packages.valory.skills.mech_interact_abci.states.base import MechMetadata - - -class DecisionRequestBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents prepare a tx to initiate a request to a mech to determine the answer to a bet.""" - - matching_round = DecisionRequestRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize Behaviour.""" - super().__init__(**kwargs) - self._metadata: Optional[MechMetadata] = None - - @property - def metadata(self) -> Dict[str, str]: - """Get the metadata as a dictionary.""" - return asdict(self._metadata) - - @property - def n_slots_supported(self) -> bool: - """Whether the behaviour supports the current number of slots as it currently only supports binary decisions.""" - return self.params.slot_count == BINARY_N_SLOTS - - def setup(self) -> None: - """Setup behaviour.""" - if not self.n_slots_supported or self.benchmarking_mode.enabled: - return - - sampled_bet = self.sampled_bet - prompt_params = dict( - question=sampled_bet.title, yes=sampled_bet.yes, no=sampled_bet.no - ) - prompt = self.params.prompt_template.substitute(prompt_params) - tool = self.synchronized_data.mech_tool - nonce = str(uuid4()) - self._metadata = MechMetadata(prompt, tool, nonce) - msg = f"Prepared metadata {self.metadata!r} for the request." - self.context.logger.info(msg) - - def initialize_bet_id_row_manager(self) -> Dict[str, List[int]]: - """Initialization of the dictionary used to traverse mocked tool responses.""" - bets_mapping: Dict[str, List[int]] = {} - dataset_filepath = ( - self.params.store_path / self.benchmarking_mode.dataset_filename - ) - - with open(dataset_filepath, mode="r") as file: - reader = csv.DictReader(file) - for row_number, row in enumerate(reader, start=1): - question_id = row[self.benchmarking_mode.question_id_field] - if question_id not in bets_mapping: - bets_mapping[question_id] = [] - bets_mapping[question_id].append(row_number) - return bets_mapping - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - payload_content = None - mocking_mode: Optional[bool] = self.benchmarking_mode.enabled - if self._metadata and self.n_slots_supported: - mech_requests = [self.metadata] - payload_content = json.dumps(mech_requests, sort_keys=True) - if not self.n_slots_supported: - mocking_mode = None - - if self.benchmarking_mode.enabled: - # check if the bet_id_row_manager has been loaded already - if len(self.shared_state.bet_id_row_manager) == 0: - bets_mapping = self.initialize_bet_id_row_manager() - self.shared_state.bet_id_row_manager = bets_mapping - - agent = self.context.agent_address - payload = DecisionRequestPayload(agent, payload_content, mocking_mode) - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/handle_failed_tx.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/handle_failed_tx.py deleted file mode 100644 index 52a93b738..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/handle_failed_tx.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour for handling failed transactions.""" - -from typing import Generator - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import HandleFailedTxPayload -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) -from packages.valory.skills.decision_maker_abci.states.handle_failed_tx import ( - HandleFailedTxRound, -) -from packages.valory.skills.mech_interact_abci.states.request import MechRequestRound - - -class HandleFailedTxBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents handle a failed transaction.""" - - matching_round = HandleFailedTxRound - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - after_bet_attempt = self.synchronized_data.tx_submitter in ( - MechRequestRound.auto_round_id(), - BetPlacementRound.auto_round_id(), - ) - submitter = HandleFailedTxRound.auto_round_id() - payload = HandleFailedTxPayload( - self.context.agent_address, after_bet_attempt, submitter - ) - - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/order_subscription.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/order_subscription.py deleted file mode 100644 index 531485dde..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/order_subscription.py +++ /dev/null @@ -1,381 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the behaviour for the decision-making of the skill.""" -from typing import Any, Dict, Generator, List, Optional, cast - -from hexbytes import HexBytes - -from packages.valory.contracts.erc20.contract import ERC20 -from packages.valory.contracts.transfer_nft_condition.contract import ( - TransferNftCondition, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - BaseSubscriptionBehaviour, - WXDAI, - WaitableConditionType, -) -from packages.valory.skills.decision_maker_abci.models import MultisendBatch -from packages.valory.skills.decision_maker_abci.payloads import SubscriptionPayload -from packages.valory.skills.decision_maker_abci.states.order_subscription import ( - SubscriptionRound, -) -from packages.valory.skills.decision_maker_abci.utils.nevermined import ( - generate_id, - get_agreement_id, - get_escrow_payment_seed, - get_lock_payment_seed, - get_price, - get_timeouts_and_timelocks, - get_transfer_nft_condition_seed, - no_did_prefixed, - zero_x_transformer, -) - - -LOCK_CONDITION_INDEX = 0 - - -class OrderSubscriptionBehaviour(BaseSubscriptionBehaviour): - """A behaviour in which the agents purchase a subscriptions.""" - - matching_round = SubscriptionRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize `RedeemBehaviour`.""" - super().__init__(**kwargs) - self.order_tx: str = "" - self.approval_tx: str = "" - self.balance: int = 0 - self.agreement_id: str = "" - self.credits_per_req: int = 0 - self.pending_reqs: int = 0 - - def _get_condition_ids( - self, agreement_id_seed: str, did_doc: Dict[str, Any] - ) -> List[str]: - """Get the condition ids.""" - self.agreement_id = get_agreement_id( - agreement_id_seed, self.synchronized_data.safe_contract_address - ) - price = get_price(did_doc) - receivers = list(price.keys()) - amounts = list(price.values()) - lock_payment_seed, lock_payment_id = get_lock_payment_seed( - self.agreement_id, - did_doc, - self.lock_payment_condition_address, - self.escrow_payment_condition_address, - self.payment_token, - amounts, - receivers, - ) - ( - transfer_nft_condition_seed, - transfer_nft_condition_id, - ) = get_transfer_nft_condition_seed( - self.agreement_id, - did_doc, - self.synchronized_data.safe_contract_address, - self.purchase_amount, - self.transfer_nft_condition_address, - lock_payment_id, - self.token_address, - ) - escrow_payment_seed, _ = get_escrow_payment_seed( - self.agreement_id, - did_doc, - amounts, - receivers, - self.synchronized_data.safe_contract_address, - self.escrow_payment_condition_address, - self.payment_token, - lock_payment_id, - transfer_nft_condition_id, - ) - condition_ids = [ - lock_payment_seed, - transfer_nft_condition_seed, - escrow_payment_seed, - ] - return condition_ids - - def _get_purchase_params(self) -> Generator[None, None, Optional[Dict[str, Any]]]: - """Get purchase params.""" - agreement_id = zero_x_transformer(generate_id()) - did = zero_x_transformer(no_did_prefixed(self.did)) - did_doc = yield from self._resolve_did() - if did_doc is None: - # something went wrong - return None - condition_ids = self._get_condition_ids(agreement_id, did_doc) - timeouts, timelocks = get_timeouts_and_timelocks(did_doc) - price = get_price(did_doc) - receivers = list(price.keys()) - amounts = list(price.values()) - - return { - "agreement_id": agreement_id, - "did": did, - "condition_ids": condition_ids, - "consumer": self.synchronized_data.safe_contract_address, - "index": LOCK_CONDITION_INDEX, - "time_outs": timeouts, - "time_locks": timelocks, - "reward_address": self.escrow_payment_condition_address, - "receivers": receivers, - "amounts": amounts, - "contract_address": self.order_address, - "token_address": self.payment_token, - } - - def _get_approval_params(self) -> Dict[str, Any]: - """Get approval params.""" - approval_params = {} - approval_params["token"] = self.payment_token - approval_params["spender"] = self.lock_payment_condition_address - approval_params["amount"] = self.price # type: ignore - return approval_params - - def _build_withdraw_wxdai_tx(self, amount: int) -> WaitableConditionType: - """Exchange xDAI to wxDAI.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=WXDAI, - contract_id=str(ERC20.contract_id), - contract_callable="build_withdraw_tx", - amount=amount, - ) - - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.info(f"Could not build deposit tx: {response_msg}") - return False - - approval_data = response_msg.state.body.get("data") - if approval_data is None: - self.context.logger.info(f"Could not build deposit tx: {response_msg}") - return False - - batch = MultisendBatch( - to=WXDAI, - data=HexBytes(approval_data), - ) - self.multisend_batches.append(batch) - return True - - def _prepare_order_tx( - self, - contract_address: str, - agreement_id: str, - did: str, - condition_ids: List[str], - time_locks: List[int], - time_outs: List[int], - consumer: str, - index: int, - reward_address: str, - token_address: str, - amounts: List[int], - receivers: List[str], - ) -> Generator[None, None, bool]: - """Prepare a purchase tx.""" - result = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=contract_address, - contract_public_id=TransferNftCondition.contract_id, - contract_callable="build_order_tx", - data_key="data", - placeholder="order_tx", - agreement_id=agreement_id, - did=did, - condition_ids=condition_ids, - time_locks=time_locks, - time_outs=time_outs, - consumer=consumer, - index=index, - reward_address=reward_address, - token_address=token_address, - amounts=amounts, - receives=receivers, - ) - if not result: - return False - - value = self.price if self.is_xdai else 0 - self.multisend_batches.append( - MultisendBatch( - to=contract_address, - data=HexBytes(self.order_tx), - value=value, - ) - ) - return True - - def _prepare_approval_tx( - self, token: str, spender: str, amount: int - ) -> Generator[None, None, bool]: - """Prepare an approval tx.""" - result = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=token, - contract_public_id=ERC20.contract_id, - contract_callable="build_approval_tx", - data_key="data", - placeholder="approval_tx", - amount=amount, - spender=spender, - ) - if not result: - return False - - self.multisend_batches.append( - MultisendBatch( - to=token, - data=HexBytes(self.approval_tx), - ) - ) - return True - - def _get_pending_requests(self) -> Generator[None, None, bool]: - """Get the required balance for the subscription.""" - result = yield from self._mech_contract_interact( - contract_callable="get_pending_requests", - data_key="pending_requests", - placeholder="pending_reqs", - sender_address=self.synchronized_data.safe_contract_address, - ) - if not result: - self.context.logger.info("Could not get the pending requests.") - return False - - return result - - def _get_nevermined_price(self) -> Generator[None, None, bool]: - """Get the price of the subscription.""" - result = yield from self._mech_contract_interact( - contract_callable="get_price", - data_key="price", - placeholder="credits_per_req", - ) - if not result: - self.context.logger.info("Could not get the price.") - return False - - return result - - def _should_purchase(self) -> Generator[None, None, bool]: - """Check if the subscription should be purchased.""" - if not self.params.use_nevermined: - self.context.logger.info("Nevermined subscriptions are turned off.") - return False - - result = yield from self._get_nevermined_price() - if not result: - return False - - result = yield from self._get_pending_requests() - if not result: - return False - - result = yield from self._get_nft_balance( - self.token_address, - self.synchronized_data.safe_contract_address, - zero_x_transformer(no_did_prefixed(self.did)), - ) - if not result: - self.context.logger.warning("Failed to get balance") - return False - - credits_required = (self.pending_reqs + 1) * self.credits_per_req - - return credits_required > self.balance - - def get_payload_content(self) -> Generator[None, None, str]: - """Get the payload.""" - should_purchase = yield from self._should_purchase() - if not should_purchase: - return SubscriptionRound.NO_TX_PAYLOAD - - result = yield from self.check_balance() - if not result: - return SubscriptionRound.ERROR_PAYLOAD - - if not self.is_xdai: - self.context.logger.warning( - f"Subscription is not using xDAI: {self.is_xdai}" - ) - approval_params = self._get_approval_params() - result = yield from self._prepare_approval_tx(**approval_params) - if not result: - return SubscriptionRound.ERROR_PAYLOAD - - else: - self.context.logger.info( - f"Using wxDAI to purchase subscription: {self.wallet_balance} < {self.price}" - ) - if self.wallet_balance < self.price: - if self.wallet_balance + self.token_balance < self.price: - self.context.logger.info( - f"Insufficient funds to purchase subscription: {self.wallet_balance + self.token_balance} < {self.price}" - ) - return SubscriptionRound.ERROR_PAYLOAD - amount_to_withdraw = self.price - self.wallet_balance - self.context.logger.info(f"Withdrawing {amount_to_withdraw} from WxDAI") - result = yield from self._build_withdraw_wxdai_tx(amount_to_withdraw) - if not result: - return SubscriptionRound.ERROR_PAYLOAD - - purchase_params = yield from self._get_purchase_params() - self.context.logger.info( - f"Purchase params for subscription: {purchase_params}. Agreement ID: {self.agreement_id}" - ) - if purchase_params is None: - return SubscriptionRound.ERROR_PAYLOAD - - result = yield from self._prepare_order_tx(**purchase_params) - if not result: - return SubscriptionRound.ERROR_PAYLOAD - - for build_step in ( - self._build_multisend_data, - self._build_multisend_safe_tx_hash, - ): - yield from self.wait_for_condition_with_sleep(build_step) - - return cast(str, self.tx_hex) - - def async_act(self) -> Generator: - """Do the action.""" - sender = self.context.agent_address - - if self.context.benchmarking_mode.enabled: - payload = SubscriptionPayload(sender) - yield from self.finish_behaviour(payload) - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - payload_data = yield from self.get_payload_content() - payload = SubscriptionPayload( - sender, - tx_submitter=SubscriptionRound.auto_round_id(), - tx_hash=payload_data, - agreement_id=self.agreement_id, - wallet_balance=self.wallet_balance, - ) - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/randomness.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/randomness.py deleted file mode 100644 index bb580dfb7..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/randomness.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the behaviour of the skill which is responsible for gathering randomness.""" - -from packages.valory.skills.abstract_round_abci.common import ( - RandomnessBehaviour as RandomnessBehaviourBase, -) -from packages.valory.skills.decision_maker_abci.states.randomness import ( - BenchmarkingRandomnessRound, - RandomnessRound, -) -from packages.valory.skills.transaction_settlement_abci.payloads import ( - RandomnessPayload, -) - - -class RandomnessBehaviour(RandomnessBehaviourBase): - """Retrieve randomness.""" - - matching_round = RandomnessRound - payload_class = RandomnessPayload - - -class BenchmarkingRandomnessBehaviour(RandomnessBehaviour): - """Retrieve randomness in benchmarking mode.""" - - matching_round = BenchmarkingRandomnessRound diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/reedem.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/reedem.py deleted file mode 100644 index e6019516b..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/reedem.py +++ /dev/null @@ -1,993 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the redeeming state of the decision-making abci app.""" - -import json -import time -from abc import ABC -from sys import maxsize -from typing import Any, Dict, Generator, Iterator, List, Optional, Set, Union - -from hexbytes import HexBytes -from web3.constants import HASH_ZERO - -from packages.valory.contracts.conditional_tokens.contract import ( - ConditionalTokensContract, -) -from packages.valory.contracts.realitio.contract import RealitioContract -from packages.valory.contracts.realitio_proxy.contract import RealitioProxyContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload, get_name -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - WaitableConditionType, -) -from packages.valory.skills.decision_maker_abci.behaviours.storage_manager import ( - StorageManagerBehaviour, -) -from packages.valory.skills.decision_maker_abci.models import ( - MultisendBatch, - RedeemingProgress, -) -from packages.valory.skills.decision_maker_abci.payloads import RedeemPayload -from packages.valory.skills.decision_maker_abci.redeem_info import ( - Condition, - FPMM, - Trade, -) -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) -from packages.valory.skills.decision_maker_abci.states.redeem import RedeemRound -from packages.valory.skills.market_manager_abci.graph_tooling.requests import ( - FetchStatus, - MAX_LOG_SIZE, - QueryingBehaviour, -) -from packages.valory.skills.market_manager_abci.graph_tooling.utils import ( - filter_claimed_conditions, - get_condition_id_to_balances, -) - - -ZERO_HEX = HASH_ZERO[2:] -ZERO_BYTES = bytes.fromhex(ZERO_HEX) -BLOCK_NUMBER_KEY = "number" -DEFAULT_TO_BLOCK = "latest" - - -class RedeemInfoBehaviour(StorageManagerBehaviour, QueryingBehaviour, ABC): - """A behaviour responsible for building and handling the redeeming information.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize a `RedeemInfo` object.""" - super().__init__(**kwargs) - self.utilized_tools: Dict[str, str] = {} - self.redeemed_condition_ids: Set[str] = set() - self.payout_so_far: int = 0 - self.trades: Set[Trade] = set() - self.earliest_block_number: int = 0 - - # this is a mapping from condition id to amount - # the purpose of this attribute is to rectify the claimable amount within a redeeming information object. - # this adjustment is necessary because the redeeming information is generated based on a single trade - # per condition or question. - # consequently, the claimable amount must reflect the cumulative sum of claimable amounts - # from all trades associated with it. - self.claimable_amounts: Dict[HexBytes, int] = {} - - def setup(self) -> None: - """Setup the behaviour""" - super().setup() - self.redeemed_condition_ids = self.synchronized_data.redeemed_condition_ids - self.payout_so_far = self.synchronized_data.payout_so_far - - def _set_block_number(self, trade: Trade) -> Generator: - """Set the block number of the given trade's market.""" - timestamp = trade.fpmm.creationTimestamp - - while True: - block = yield from self._fetch_block_number(timestamp) - if self._fetch_status != FetchStatus.IN_PROGRESS: - break - - if self._fetch_status == FetchStatus.SUCCESS: - block_number = block.get("id", "") - if block_number.isdigit(): - self.earliest_block_number = int(block_number) - - self.context.logger.info( - f"Chose block number {self.earliest_block_number!r} as closest to timestamp {timestamp!r}" - ) - - def _try_update_policy(self, tool: str, winning: bool) -> None: - """Try to update the policy.""" - try: - self.policy.update_accuracy_store(tool, winning) - except KeyError: - self.context.logger.warning( - f"The stored utilized tools seem to be outdated as no {tool=} was found. " - "The policy will not be updated. " - "No action is required as this will be automatically resolved." - ) - - def _update_policy(self, update: Trade) -> None: - """Update the policy.""" - # the mapping might not contain a tool for a bet placement because it might have happened on a previous run - tool = self.utilized_tools.get(update.transactionHash, None) - if tool is None: - return - - # we try to avoid an ever-increasing dictionary of utilized tools by removing a tool when not needed anymore - del self.utilized_tools[update.transactionHash] - self._try_update_policy(tool, update.is_winning) - - def update_redeem_info(self, chunk: list) -> Generator: - """Update the redeeming information using the given chunk.""" - trades_updates: Iterator[Trade] = ( - Trade(**trade) - for trade in chunk - if int(trade.get("fpmm", {}).get("answerFinalizedTimestamp", maxsize)) - <= self.synced_timestamp - ) - - is_first_update = True - for update in trades_updates: - self._update_policy(update) - - # do not use the information if position is not winning - if not update.is_winning: - continue - - if is_first_update: - yield from self._set_block_number(update) - is_first_update = False - - condition_id = update.fpmm.condition.id - # If not in the trades, add it as is, along with its claimable amount - if update not in self.trades: - self.trades.add(update) - self.claimable_amounts[condition_id] = update.claimable_amount - continue - - # Find any matching object and combine them - for unique_obj in self.trades: - if update == unique_obj: - self.claimable_amounts[condition_id] += update.claimable_amount - - self.context.logger.info(self.policy.stats_report()) - - -class RedeemBehaviour(RedeemInfoBehaviour): - """Redeem the winnings.""" - - matching_round = RedeemRound - - UTILIZED_TOOLS_PATH = "utilized_tools.json" - - def __init__(self, **kwargs: Any) -> None: - """Initialize `RedeemBehaviour`.""" - super().__init__(**kwargs) - self._claim_params_batch: list = [] - self._latest_block_number: Optional[int] = None - self._finalized: bool = False - self._already_resolved: bool = False - self._payouts: Dict[str, int] = {} - self._built_data: Optional[HexBytes] = None - self._current_redeem_info: Optional[Trade] = None - self._expected_winnings: int = 0 - self._history_hash: bytes = ZERO_BYTES - self._claim_winnings_simulation_ok: bool = False - - @property - def redeeming_progress(self) -> RedeemingProgress: - """Get the redeeming check progress from the shared state.""" - return self.shared_state.redeeming_progress - - @redeeming_progress.setter - def redeeming_progress(self, progress: RedeemingProgress) -> None: - """Set the redeeming check progress in the shared state.""" - self.shared_state.redeeming_progress = progress - - @property - def latest_block_number(self) -> int: - """Get the latest block number.""" - if self._latest_block_number is None: - error = "Attempting to retrieve the latest block number, but it hasn't been set yet." - raise ValueError(error) - return self._latest_block_number - - @latest_block_number.setter - def latest_block_number(self, latest_block_number: str) -> None: - """Set the latest block number.""" - try: - self._latest_block_number = int(latest_block_number) - except (TypeError, ValueError) as exc: - error = f"{latest_block_number=} cannot be converted to a valid integer." - raise ValueError(error) from exc - - @property - def current_redeem_info(self) -> Trade: - """Get the current redeem info.""" - if self._current_redeem_info is None: - raise ValueError("Current redeem information have not been set.") - return self._current_redeem_info - - @property - def current_fpmm(self) -> FPMM: - """Get the current FPMM.""" - return self.current_redeem_info.fpmm - - @property - def current_condition(self) -> Condition: - """Get the current condition.""" - return self.current_fpmm.condition - - @property - def current_question_id(self) -> bytes: - """Get the current question's id.""" - return self.current_fpmm.question.id - - @property - def current_collateral_token(self) -> str: - """Get the current collateral token.""" - return self.current_fpmm.collateralToken - - @property - def current_condition_id(self) -> HexBytes: - """Get the current condition id.""" - return self.current_condition.id - - @property - def current_index_sets(self) -> List[int]: - """Get the current index sets.""" - return self.current_condition.index_sets - - @property - def current_claimable_amount(self) -> int: - """Return the current claimable amount.""" - return self.claimable_amounts[self.current_condition_id] - - @property - def is_dust(self) -> bool: - """Return whether the claimable amount of the given condition id is dust or not.""" - return self.current_claimable_amount < self.params.dust_threshold - - @property - def payouts_batch(self) -> Dict[str, int]: - """Get the trades' transaction hashes mapped to payouts for the current market.""" - return self._payouts - - @payouts_batch.setter - def payouts_batch(self, payouts: Dict[str, int]) -> None: - """Set the trades' transaction hashes mapped to payouts for the current market.""" - self._payouts = payouts - - @property - def finalized(self) -> bool: - """Get whether the current market has been finalized.""" - return self._finalized - - @finalized.setter - def finalized(self, flag: bool) -> None: - """Set whether the current market has been finalized.""" - self._finalized = flag - - @property - def history_hash(self) -> bytes: - """Get the history hash for the current question.""" - return self._history_hash - - @history_hash.setter - def history_hash(self, history_hash: bytes) -> None: - """Set the history hash for the current question.""" - self._history_hash = history_hash - - @property - def is_history_hash_null(self) -> bool: - """Return whether the current history hash is null.""" - return self.history_hash == b"\x00" * 32 - - @property - def already_resolved(self) -> bool: - """Get whether the current market has already been resolved.""" - return self._already_resolved - - @already_resolved.setter - def already_resolved(self, flag: bool) -> None: - """Set whether the current market has already been resolved.""" - self._already_resolved = flag - - @property - def claim_params_batch(self) -> list: - """Get the current batch of the claim parameters.""" - return self._claim_params_batch - - @claim_params_batch.setter - def claim_params_batch(self, claim_params_batch: list) -> None: - """Set the current batch of the claim parameters.""" - self._claim_params_batch = claim_params_batch - - @property - def built_data(self) -> HexBytes: - """Get the built transaction's data.""" - return self._built_data - - @built_data.setter - def built_data(self, built_data: Union[str, bytes]) -> None: - """Set the built transaction's data.""" - self._built_data = HexBytes(built_data) - - @property - def claim_winnings_simulation_ok(self) -> bool: - """Get whether the claim winnings simulation is ok.""" - return self._claim_winnings_simulation_ok - - @claim_winnings_simulation_ok.setter - def claim_winnings_simulation_ok(self, claim_winnings_simulation_ok: bool) -> None: - """Get whether the claim winnings simulation is ok.""" - self._claim_winnings_simulation_ok = claim_winnings_simulation_ok - - def _store_progress(self) -> None: - """Store the redeeming progress.""" - self.redeeming_progress.trades = self.trades - self.redeeming_progress.utilized_tools = self.utilized_tools - self.redeeming_progress.policy = self.policy - self.redeeming_progress.claimable_amounts = self.claimable_amounts - self.redeeming_progress.earliest_block_number = self.earliest_block_number - - def _load_progress(self) -> None: - """Load the redeeming progress.""" - self.trades = self.redeeming_progress.trades - self.utilized_tools = self.redeeming_progress.utilized_tools - self._policy = self.redeeming_progress.policy - self.claimable_amounts = self.redeeming_progress.claimable_amounts - self.earliest_block_number = self.redeeming_progress.earliest_block_number - - def _get_redeem_info( - self, - ) -> Generator: - """Fetch the trades from all the prediction markets and store them as redeeming information.""" - while True: - can_proceed = self._prepare_fetching() - if not can_proceed: - break - - trades_market_chunk = yield from self._fetch_redeem_info() - if trades_market_chunk is not None: - yield from self.update_redeem_info(trades_market_chunk) - - # truncate the trades, otherwise logs get too big - trades_str = str(self.trades)[:MAX_LOG_SIZE] - self.context.logger.info(f"Fetched redeeming information: {trades_str}") - - def _filter_trades(self) -> None: - """Filter the trades, removing the redeemed condition ids.""" - redeemed_condition_ids = [ - condition_id.lower() for condition_id in self.redeemed_condition_ids - ] - self.trades = { - trade - for trade in self.trades - if trade.fpmm.condition.id.hex().lower() not in redeemed_condition_ids - } - self.redeeming_progress.trades = self.trades - - def _conditional_tokens_interact( - self, contract_callable: str, data_key: str, placeholder: str, **kwargs: Any - ) -> WaitableConditionType: - """Interact with the conditional tokens contract.""" - status = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.conditional_tokens_address, - contract_public_id=ConditionalTokensContract.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def _get_latest_block(self) -> WaitableConditionType: - """Get the latest block's timestamp.""" - ledger_api_response = yield from self.get_ledger_api_response( - performative=LedgerApiMessage.Performative.GET_STATE, # type: ignore - ledger_callable="get_block", - block_identifier=DEFAULT_TO_BLOCK, - ) - if ledger_api_response.performative != LedgerApiMessage.Performative.STATE: - self.context.logger.error(f"Failed to get block: {ledger_api_response}") - return False - self.latest_block_number = ledger_api_response.state.body.get(BLOCK_NUMBER_KEY) - return True - - def _check_already_redeemed_via_events(self) -> WaitableConditionType: - """Check whether the condition ids have already been redeemed via events.""" - if len(self.trades) == 0: - return True - - safe_address_lower = self.synchronized_data.safe_contract_address.lower() - kwargs: Dict[str, Any] = { - key: [] - for key in ( - "collateral_tokens", - "parent_collection_ids", - "condition_ids", - "index_sets", - ) - } - for trade in self.trades: - kwargs["collateral_tokens"].append(trade.fpmm.collateralToken) - kwargs["parent_collection_ids"].append(ZERO_BYTES) - kwargs["condition_ids"].append(trade.fpmm.condition.id) - kwargs["index_sets"].append(trade.fpmm.condition.index_sets) - - if not self.redeeming_progress.check_started: - self.redeeming_progress.check_from_block = self.earliest_block_number - yield from self.wait_for_condition_with_sleep(self._get_latest_block) - self.redeeming_progress.check_to_block = self.latest_block_number - self.redeeming_progress.check_started = True - - n_retries = 0 - from_block = self.redeeming_progress.check_from_block - batch_size = self.redeeming_progress.event_filtering_batch_size - while from_block < self.redeeming_progress.check_to_block: - max_to_block = from_block + batch_size - to_block = min(max_to_block, self.redeeming_progress.check_to_block) - result = yield from self._conditional_tokens_interact( - contract_callable="check_redeemed", - data_key="payouts", - placeholder=get_name(RedeemBehaviour.payouts_batch), - redeemer=safe_address_lower, - from_block=from_block, - to_block=to_block, - timeout=self.params.contract_timeout, - **kwargs, - ) - - if not result and n_retries == self.params.max_filtering_retries: - err = "Skipping the redeeming round as the RPC is misbehaving." - self.context.logger.error(err) - return False - - if not result: - n_retries += 1 - keep_fraction = 1 - self.params.reduce_factor - reduced_batch_size = int(batch_size * keep_fraction) - # ensure that the batch size is at least the minimum batch size - batch_size = max(reduced_batch_size, self.params.minimum_batch_size) - self.redeeming_progress.event_filtering_batch_size = batch_size - self.context.logger.warning( - f"Repeating this call with a decreased batch size of {batch_size}." - ) - - continue - - self.redeeming_progress.payouts.update(self.payouts_batch) - self.redeeming_progress.check_from_block = to_block - from_block += batch_size - - return True - - def _check_already_redeemed_via_subgraph(self) -> WaitableConditionType: - """Check whether the condition ids have already been redeemed via subgraph.""" - safe_address = self.synchronized_data.safe_contract_address.lower() - from_timestamp, to_timestamp = 0.0, time.time() # from beginning to now - - # get the trades - trades = yield from self.fetch_trades( - safe_address, from_timestamp, to_timestamp - ) - if trades is None: - return False - - # get the user's positions - user_positions = yield from self.fetch_user_positions(safe_address) - if user_positions is None: - return False - - # process the positions - payouts, unredeemed_raw = get_condition_id_to_balances(trades, user_positions) - - # filter out positions that are already claimed - unredeemed = filter_claimed_conditions( - unredeemed_raw, self.redeeming_progress.claimed_condition_ids - ) - - self.redeeming_progress.payouts = payouts - self.redeeming_progress.unredeemed_trades = unredeemed - - return True - - def _check_already_redeemed(self) -> WaitableConditionType: - """Check whether we have already redeemed for this bet.""" - if self.params.use_subgraph_for_redeeming: - return self._check_already_redeemed_via_subgraph() - - return self._check_already_redeemed_via_events() - - def _clean_redeem_info(self) -> WaitableConditionType: - """Clean the redeeming information based on whether any positions have already been redeemed.""" - if self.payout_so_far > 0: - # filter the trades to avoid checking positions that we are already aware have been redeemed. - self._filter_trades() - - success = yield from self._check_already_redeemed() - if not success: - return False - - payouts = self.redeeming_progress.payouts - payouts_amount = sum(payouts.values()) - if payouts_amount > 0: - self.redeemed_condition_ids |= set(payouts.keys()) - if self.params.use_subgraph_for_redeeming: - self.payout_so_far = payouts_amount - else: - self.payout_so_far += payouts_amount - - # filter the trades again if new payouts have been found - self._filter_trades() - wxdai_amount = self.wei_to_native(self.payout_so_far) - msg = f"The total payout so far has been {wxdai_amount} wxDAI." - self.context.logger.info(msg) - - return True - - def _realitio_interact( - self, contract_callable: str, data_key: str, placeholder: str, **kwargs: Any - ) -> WaitableConditionType: - """Interact with the realitio contract.""" - status = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.realitio_address, - contract_public_id=RealitioContract.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def _check_finalized(self) -> WaitableConditionType: - """Check whether the question has been finalized.""" - result = yield from self._realitio_interact( - contract_callable="check_finalized", - data_key="finalized", - placeholder=get_name(RedeemBehaviour.finalized), - question_id=self.current_question_id, - ) - return result - - def _get_history_hash(self) -> WaitableConditionType: - """Get the history hash for the current question id.""" - result = yield from self._realitio_interact( - contract_callable="get_history_hash", - data_key="data", - placeholder=get_name(RedeemBehaviour.history_hash), - question_id=self.current_question_id, - ) - return result - - def _check_already_resolved(self) -> WaitableConditionType: - """Check whether someone has already resolved for this market.""" - result = yield from self._conditional_tokens_interact( - contract_callable="check_resolved", - data_key="resolved", - placeholder=get_name(RedeemBehaviour.already_resolved), - condition_id=self.current_condition_id, - ) - return result - - def _build_resolve_data(self) -> WaitableConditionType: - """Prepare the safe tx to resolve the condition.""" - result = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.realitio_proxy_address, - contract_public_id=RealitioProxyContract.contract_id, - contract_callable="build_resolve_tx", - data_key="data", - placeholder=get_name(RedeemBehaviour.built_data), - question_id=self.current_question_id, - template_id=self.current_fpmm.templateId, - question=self.current_fpmm.question.data, - num_outcomes=self.current_condition.outcomeSlotCount, - ) - - if not result: - return False - - batch = MultisendBatch( - to=self.params.realitio_proxy_address, - data=HexBytes(self.built_data), - ) - self.multisend_batches.append(batch) - return True - - def _simulate_claiming(self) -> WaitableConditionType: - """Check whether we have already claimed the winnings.""" - result = yield from self._realitio_interact( - contract_callable="simulate_claim_winnings", - data_key="data", - placeholder=get_name(RedeemBehaviour.claim_winnings_simulation_ok), - question_id=self.current_question_id, - claim_params=self.redeeming_progress.claim_params, - sender_address=self.synchronized_data.safe_contract_address, - ) - return result - - def _build_claim_data(self) -> WaitableConditionType: - """Prepare the safe tx to claim the winnings.""" - claim_params = self.redeeming_progress.claim_params - if claim_params is None: - self.context.logger.error( - f"Cannot parse incorrectly formatted realitio `LogNewAnswer` events: {self.redeeming_progress.answered}" - ) - return False - - result = yield from self._realitio_interact( - contract_callable="build_claim_winnings", - data_key="data", - placeholder=get_name(RedeemBehaviour.built_data), - question_id=self.current_question_id, - claim_params=self.redeeming_progress.claim_params, - ) - - if not result: - return False - - batch = MultisendBatch( - to=self.params.realitio_address, - data=HexBytes(self.built_data), - ) - self.multisend_batches.append(batch) - return True - - def get_claim_params(self) -> WaitableConditionType: - """Get the claim params for the current question id.""" - if self.params.use_subgraph_for_redeeming: - return self._get_claim_params_via_subgraph() - - return self._get_claim_params_via_events() - - def _get_claim_params_via_events(self) -> WaitableConditionType: - """Get claim params using an RPC to get the events.""" - if not self.redeeming_progress.claim_started: - self.redeeming_progress.claim_from_block = self.earliest_block_number - self.redeeming_progress.claim_to_block = ( - self.redeeming_progress.check_to_block - ) - self.redeeming_progress.claim_started = True - - n_retries = 0 - from_block = self.redeeming_progress.claim_from_block - batch_size = self.redeeming_progress.event_filtering_batch_size - while from_block < self.redeeming_progress.claim_to_block: - max_to_block = from_block + batch_size - to_block = min(max_to_block, self.redeeming_progress.claim_to_block) - result = yield from self._realitio_interact( - contract_callable="get_claim_params", - data_key="answered", - placeholder=get_name(RedeemBehaviour.claim_params_batch), - from_block=from_block, - to_block=to_block, - question_id=self.current_question_id, - timeout=self.params.contract_timeout, - ) - - if not result and n_retries == self.params.max_filtering_retries: - err = "Skipping redeeming for the current position as the RPC is misbehaving." - self.context.logger.error(err) - return False - - if not result: - n_retries += 1 - keep_fraction = 1 - self.params.reduce_factor - batch_size = int(batch_size * keep_fraction) - self.redeeming_progress.event_filtering_batch_size = batch_size - self.context.logger.warning( - f"Repeating this call with a decreased batch size of {batch_size}." - ) - continue - - self.redeeming_progress.answered.extend(self.claim_params_batch) - self.redeeming_progress.claim_from_block = to_block - from_block += batch_size - - return True - - def _get_claim_params_via_subgraph(self) -> WaitableConditionType: - """Get claim params using a subgraph.""" - question_id_str = "0x" + self.current_question_id.hex() - result = yield from self.fetch_claim_params(question_id_str) - if not result: - return False - - self.redeeming_progress.answered = result - return True - - def _build_redeem_data(self) -> WaitableConditionType: - """Prepare the safe tx to redeem the position.""" - result = yield from self._conditional_tokens_interact( - contract_callable="build_redeem_positions_tx", - data_key="data", - placeholder=get_name(RedeemBehaviour.built_data), - collateral_token=self.current_collateral_token, - parent_collection_id=ZERO_BYTES, - condition_id=self.current_condition_id, - index_sets=self.current_index_sets, - ) - - if not result: - return False - - batch = MultisendBatch( - to=self.params.conditional_tokens_address, - data=HexBytes(self.built_data), - ) - self.multisend_batches.append(batch) - return True - - def _prepare_single_redeem(self) -> WaitableConditionType: - """Prepare a multisend transaction for a single redeeming action.""" - yield from self.wait_for_condition_with_sleep(self._check_already_resolved) - steps = [] - if not self.already_resolved: - # 1. resolve the question if it hasn't been resolved yet - steps.append(self._build_resolve_data) - - yield from self.wait_for_condition_with_sleep(self._get_history_hash) - if not self.is_history_hash_null: - # 2. claim the winnings if claiming has not been done yet - if not self.redeeming_progress.claim_finished: - success = yield from self.get_claim_params() - if not success: - return False - - # simulate claiming to get the claim params - success = yield from self._simulate_claiming() - if not success: - return False - - if self.claim_winnings_simulation_ok: - steps.append(self._build_claim_data) - - # 3. we always redeem the position - steps.append(self._build_redeem_data) - for build_step in steps: - yield from self.wait_for_condition_with_sleep(build_step) - - return True - - def _process_candidate( - self, redeem_candidate: Trade - ) -> Generator[None, None, bool]: - """Process a redeeming candidate and return whether winnings were found.""" - self._current_redeem_info = redeem_candidate - - msg = f"Processing position with condition id {self.current_condition_id!r}..." - self.context.logger.info(msg) - - # double check whether the market is finalized - yield from self.wait_for_condition_with_sleep(self._check_finalized) - if not self.finalized: - self.context.logger.warning( - f"Conflict found! The current market, with condition id {self.current_condition_id!r}, " - f"is reported as not finalized by the realitio contract. " - f"However, an answer was finalized on {redeem_candidate.fpmm.answerFinalizedTimestamp}, " - f"and the last service transition occurred on {self.synced_timestamp}." - ) - return False - - if self.params.use_subgraph_for_redeeming: - condition_id = redeem_candidate.fpmm.condition.id.hex().lower() - if ( - condition_id not in self.redeeming_progress.unredeemed_trades - or self.redeeming_progress.unredeemed_trades[condition_id] == 0 - ): - return False - - # in case that the claimable amount is dust - if self.is_dust: - self.context.logger.info("Position's redeeming amount is dust.") - return False - - if self.params.use_subgraph_for_redeeming: - condition_id = redeem_candidate.fpmm.condition.id.hex().lower() - if ( - condition_id not in self.redeeming_progress.unredeemed_trades - or self.redeeming_progress.unredeemed_trades[condition_id] == 0 - ): - return False - - success = yield from self._prepare_single_redeem() - if not success: - return False - - self._expected_winnings += self.current_claimable_amount - return True - - def _prepare_safe_tx(self) -> Generator[None, None, Optional[str]]: - """ - Prepare the safe tx to redeem the positions of the trader. - - Steps: - 1. Get all the trades of the trader. - 2. For each trade, check if the trader has not already redeemed a non-dust winning position. - 3. If so, prepare a multisend transaction like this: - TXS: - 1. resolve (optional) - Check if the condition needs to be resolved. If so, add the tx to the multisend. - - 2. claimWinnings - Prepare a claim winnings tx for each winning position. Add it to the multisend. - - 3. redeemPositions - Prepare a redeem positions tx for each winning position. Add it to the multisend. - - We do not convert claimed wxDAI to xDAI, because this is the currency that the service is using to place bets. - - :yields: None - :returns: the safe's transaction hash for the redeeming operation. - """ - if len(self.trades) > 0: - self.context.logger.info("Preparing a multisend tx to redeem payout...") - - winnings_found = 0 - - for redeem_candidate in self.trades: - is_claimable = yield from self._process_candidate(redeem_candidate) - if not is_claimable: - msg = "Not redeeming position. Moving to the next one..." - self.context.logger.info(msg) - continue - - if self.params.redeeming_batch_size > 1: - self.context.logger.info("Adding position to the multisend batch...") - - winnings_found += 1 - # we mark this condition id as being claimed. - # once the transaction gets successfully through, it will be moved to - # self.redeeming_progress.claiming_condition_ids, and will no longer be taken into - # consideration. This is done to avoid cases where the subgraph is not up-to date - # and the same condition id is returned multiple times. - claiming_condition_id = redeem_candidate.fpmm.condition.id.hex() - self.redeeming_progress.claiming_condition_ids.append(claiming_condition_id) - - if winnings_found == self.params.redeeming_batch_size: - break - - if winnings_found == 0: - self.context.logger.info("No winnings to redeem.") - return None - - winnings = self.wei_to_native(self._expected_winnings) - self.context.logger.info( - "Preparing the multisend transaction to redeem winnings of " - f"{winnings} wxDAI for {winnings_found} position(s)." - ) - for build_step in ( - self._build_multisend_data, - self._build_multisend_safe_tx_hash, - ): - yield from self.wait_for_condition_with_sleep(build_step) - - self.context.logger.info("Transaction successfully prepared.") - return self.tx_hex - - def _store_utilized_tools(self) -> None: - """Store the tools utilized by the behaviour.""" - path = self.params.store_path / self.UTILIZED_TOOLS_PATH - with path.open("w") as f: - json.dump(self.utilized_tools, f) - - def finish_behaviour(self, payload: BaseTxPayload) -> Generator: - """Finish the behaviour.""" - self._store_utilized_tools() - yield from super().finish_behaviour(payload) - - def _setup_policy_and_tools(self) -> Generator[None, None, bool]: - """Set up the policy and tools.""" - if self.synchronized_data.is_policy_set: - self._policy = self.synchronized_data.policy - self.mech_tools = self.synchronized_data.available_mech_tools - return True - status = yield from super()._setup_policy_and_tools() - return status - - def _build_payload(self, redeem_tx_hex: Optional[str] = None) -> RedeemPayload: - """Build the redeeming round's payload.""" - agent = self.context.agent_address - tx_submitter = self.matching_round.auto_round_id() - benchmarking_enabled = self.benchmarking_mode.enabled - serialized_tools = json.dumps(self.mech_tools) - policy = self.policy.serialize() - utilized_tools = json.dumps(self.utilized_tools) - condition_ids = json.dumps(list(self.redeemed_condition_ids)) - payout = self.payout_so_far - return RedeemPayload( - agent, - tx_submitter, - redeem_tx_hex, - benchmarking_enabled, - serialized_tools, - policy, - utilized_tools, - condition_ids, - payout, - ) - - def _benchmarking_act(self) -> RedeemPayload: - """The act of the agent while running in benchmarking mode.""" - tool = self.synchronized_data.mech_tool - winning = self.mock_data.is_winning - self._try_update_policy(tool, winning) - return self._build_payload() - - def _normal_act(self) -> Generator[None, None, Optional[RedeemPayload]]: - """The act of the agent while running in normal mode.""" - if not self.redeeming_progress.check_started: - yield from self._get_redeem_info() - self._store_progress() - else: - msg = "Picking up progress from where it was left off before the timeout occurred." - self.context.logger.info(msg) - self._load_progress() - - if not self.redeeming_progress.check_finished: - self.redeeming_progress.cleaned = yield from self._clean_redeem_info() - - serialized_tools = json.dumps(self.mech_tools) - payload = RedeemPayload(self.context.agent_address, mech_tools=serialized_tools) - if self.redeeming_progress.cleaned: - redeem_tx_hex = yield from self._prepare_safe_tx() - if redeem_tx_hex is not None: - payload = self._build_payload(redeem_tx_hex) - - return payload - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - success = yield from self._setup_policy_and_tools() - if not success: - return None - - payload: Optional[RedeemPayload] - if self.benchmarking_mode.enabled: - payload = self._benchmarking_act() - else: - # Checking if the last round that submitted the transaction was the bet placement round - # If so, we need to update the bet transaction information, because the transaction was successful - # tx settlement multiplexer assures transitions from Post transaction to Redeem round - # only if the transaction was successful - if ( - self.synchronized_data.did_transact - and self.synchronized_data.tx_submitter - == BetPlacementRound.auto_round_id() - ): - self.update_bet_transaction_information() - - payload = yield from self._normal_act() - if payload is None: - return - - self._store_all() - - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/round_behaviour.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/round_behaviour.py deleted file mode 100644 index 706b62cf5..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/round_behaviour.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the round behaviour for the 'decision_maker_abci' skill.""" - -from typing import Set, Type - -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.bet_placement import ( - BetPlacementBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.blacklisting import ( - BlacklistingBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.check_benchmarking import ( - CheckBenchmarkingModeBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.claim_subscription import ( - ClaimSubscriptionBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.decision_receive import ( - DecisionReceiveBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.decision_request import ( - DecisionRequestBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.handle_failed_tx import ( - HandleFailedTxBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.order_subscription import ( - OrderSubscriptionBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.randomness import ( - BenchmarkingRandomnessBehaviour, - RandomnessBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.reedem import RedeemBehaviour -from packages.valory.skills.decision_maker_abci.behaviours.sampling import ( - SamplingBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.tool_selection import ( - ToolSelectionBehaviour, -) -from packages.valory.skills.decision_maker_abci.rounds import DecisionMakerAbciApp - - -class AgentDecisionMakerRoundBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the decision-making.""" - - initial_behaviour_cls = SamplingBehaviour - abci_app_cls = DecisionMakerAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - SamplingBehaviour, # type: ignore - DecisionRequestBehaviour, # type: ignore - DecisionReceiveBehaviour, # type: ignore - BlacklistingBehaviour, # type: ignore - BetPlacementBehaviour, # type: ignore - RedeemBehaviour, # type: ignore - HandleFailedTxBehaviour, # type: ignore - ToolSelectionBehaviour, # type: ignore - OrderSubscriptionBehaviour, - ClaimSubscriptionBehaviour, - RandomnessBehaviour, # type: ignore - BenchmarkingRandomnessBehaviour, # type: ignore - CheckBenchmarkingModeBehaviour, # type: ignore - } diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/sampling.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/sampling.py deleted file mode 100644 index 1a51ec72f..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/sampling.py +++ /dev/null @@ -1,258 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2025 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 the behaviour for sampling a bet.""" - -from collections import defaultdict -from datetime import datetime -from typing import Any, Dict, Generator, List, Optional, Tuple - -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import SamplingPayload -from packages.valory.skills.decision_maker_abci.states.sampling import SamplingRound -from packages.valory.skills.market_manager_abci.bets import Bet, QueueStatus - - -WEEKDAYS = 7 -UNIX_DAY = 60 * 60 * 24 -UNIX_WEEK = WEEKDAYS * UNIX_DAY - - -class SamplingBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents blacklist the sampled bet.""" - - matching_round = SamplingRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize Behaviour.""" - super().__init__(**kwargs) - self.should_rebet: bool = False - - def setup(self) -> None: - """Setup the behaviour.""" - self.read_bets() - - def processable_bet(self, bet: Bet, now: int) -> bool: - """Whether we can process the given bet.""" - - within_opening_range = bet.openingTimestamp <= ( - now + self.params.sample_bets_closing_days * UNIX_DAY - ) - within_safe_range = ( - now - < bet.openingTimestamp - - self.params.opening_margin - - self.params.safe_voting_range - ) - - within_ranges = within_opening_range and within_safe_range - - # check if bet queue number is processable - processable_statuses = { - QueueStatus.TO_PROCESS, - QueueStatus.PROCESSED, - QueueStatus.REPROCESSED, - } - bet_queue_processable = bet.queue_status in processable_statuses - - return within_ranges and bet_queue_processable - - @staticmethod - def _sort_by_priority_logic(bets: List[Bet]) -> List[Bet]: - """ - Sort bets based on the priority logic. - - :param bets: the bets to sort. - :return: the sorted list of bets. - """ - return sorted( - bets, - key=lambda bet: ( - bet.invested_amount, - -bet.processed_timestamp, # Increasing order of processed_timestamp - bet.scaledLiquidityMeasure, - bet.openingTimestamp, - ), - reverse=True, - ) - - @staticmethod - def _get_bets_queue_wise(bets: List[Bet]) -> Tuple[List[Bet], List[Bet], List[Bet]]: - """Return a dictionary of bets with queue status as key.""" - - bets_by_status: Dict[QueueStatus, List[Bet]] = defaultdict(list) - - for bet in bets: - bets_by_status[bet.queue_status].append(bet) - - return ( - bets_by_status[QueueStatus.TO_PROCESS], - bets_by_status[QueueStatus.PROCESSED], - bets_by_status[QueueStatus.REPROCESSED], - ) - - def _sampled_bet_idx(self, bets: List[Bet]) -> int: - """ - Sample a bet and return its index. - - The sampling logic follows the specified priority logic: - 1. Filter out all the bets that have a processed_timestamp != 0 to get a list of new bets. - 2. If the list of new bets is not empty: - 2.1 Order the list in decreasing order of liquidity (highest liquidity first). - 2.2 For bets with the same liquidity, order them in decreasing order of market closing time (openingTimestamp). - 3. If the list of new bets is empty: - 3.1 Order the bets in decreasing order of invested_amount. - 3.2 For bets with the same invested_amount, order them in increasing order of processed_timestamp (least recently processed first). - 3.3 For bets with the same invested_amount and processed_timestamp, order them in decreasing order of liquidity. - 3.4 For bets with the same invested_amount, processed_timestamp, and liquidity, order them in decreasing order of market closing time (openingTimestamp). - - :param bets: the bets' values to compare for the sampling. - :return: the index of the sampled bet, out of all the available bets, not only the given ones. - """ - - to_process_bets, processed_bets, reprocessed_bets = self._get_bets_queue_wise( - bets - ) - # pick the first queue status that has bets in it - bets_to_sort: List[Bet] = to_process_bets or processed_bets or reprocessed_bets - - sorted_bets = self._sort_by_priority_logic(bets_to_sort) - - return self.bets.index(sorted_bets[0]) - - def _sampling_benchmarking_bet(self, bets: List[Bet]) -> Optional[int]: - """Sample bet for benchmarking""" - to_process_bets, processed_bets, reprocessed_bets = self._get_bets_queue_wise( - bets - ) - - self.context.logger.info(f"TO_PROCESS_LEN: {len(to_process_bets)}") - self.context.logger.info(f"PROCESSED_LEN: {len(processed_bets)}") - self.context.logger.info(f"REPROCESSED_LEN: {len(reprocessed_bets)}") - - self.context.logger.info( - f"MECH CALLS MADE: {self.shared_state.benchmarking_mech_calls}" - ) - - if ( - self.shared_state.benchmarking_mech_calls - == self.benchmarking_mode.nr_mech_calls - ): - return None - - bets_to_sort: List[Bet] = to_process_bets or processed_bets or reprocessed_bets - sorted_bets = self._sort_by_priority_logic(bets_to_sort) - - return self.bets.index(sorted_bets[0]) - - def _sample(self) -> Optional[int]: - """Sample a bet, mark it as processed, and return its index.""" - # modify time "NOW" in benchmarking mode - if self.benchmarking_mode.enabled: - safe_voting_range = ( - self.params.opening_margin + self.params.safe_voting_range - ) - now = self.shared_state.get_simulated_now_timestamp( - self.bets, safe_voting_range - ) - self.context.logger.info(f"Simulating date: {datetime.fromtimestamp(now)}") - else: - now = self.synced_timestamp - - # filter out only the bets that are processable and have a queue_status that allows them to be sampled - available_bets = list( - filter( - lambda bet: self.processable_bet(bet, now=now), - self.bets, - ) - ) - if len(available_bets) == 0: - msg = "There were no unprocessed bets available to sample from!" - self.context.logger.warning(msg) - return None - - if self.benchmarking_mode.enabled: - idx = self._sampling_benchmarking_bet(available_bets) - if not idx: - return None - - # sample a bet using the priority logic - idx = self._sampled_bet_idx(available_bets) - sampled_bet = self.bets[idx] - - # fetch the liquidity of the sampled bet and cache it - liquidity = sampled_bet.scaledLiquidityMeasure - if liquidity == 0: - msg = "There were no unprocessed bets with non-zero liquidity!" - self.context.logger.warning(msg) - return None - self.shared_state.liquidity_cache[sampled_bet.id] = liquidity - - msg = f"Sampled bet: {sampled_bet}" - self.context.logger.info(msg) - return idx - - def _benchmarking_inc_day(self) -> Tuple[bool, bool]: - """Increase the simulated day in benchmarking mode.""" - self.context.logger.info( - "No more markets to bet in the simulated day. Increasing simulated day." - ) - self.shared_state.increase_one_day_simulation() - benchmarking_finished = self.shared_state.check_benchmarking_finished() - if benchmarking_finished: - self.context.logger.info("No more days to simulate in benchmarking mode.") - - self.shared_state.benchmarking_mech_calls = 0 - - day_increased = True - - return benchmarking_finished, day_increased - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - idx = self._sample() - benchmarking_finished = None - day_increased = None - - # day increase simulation and benchmarking finished check - if idx is None and self.benchmarking_mode.enabled: - benchmarking_finished, day_increased = self._benchmarking_inc_day() - for bet in self.bets: - bet.queue_status = bet.queue_status.move_to_fresh() - bet.queue_status = bet.queue_status.move_to_process() - - self.store_bets() - - if idx is None: - bets_hash = None - else: - bets_hash = self.hash_stored_bets() - - payload = SamplingPayload( - self.context.agent_address, - bets_hash, - idx, - benchmarking_finished, - day_increased, - ) - - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/sell_outcome_token.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/sell_outcome_token.py deleted file mode 100644 index 0bf228d07..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/sell_outcome_token.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the behaviour for selling a token.""" -from typing import Any, Generator, Optional, cast - -from hexbytes import HexBytes - -from packages.valory.contracts.market_maker.contract import ( - FixedProductMarketMakerContract, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - DecisionMakerBaseBehaviour, - WaitableConditionType, -) -from packages.valory.skills.decision_maker_abci.models import MultisendBatch -from packages.valory.skills.decision_maker_abci.payloads import MultisigTxPayload -from packages.valory.skills.decision_maker_abci.states.sell_outcome_token import ( - SellOutcomeTokenRound, -) - - -class SellTokenBehaviour(DecisionMakerBaseBehaviour): - """A behaviour in which the agents sell a token.""" - - matching_round = SellOutcomeTokenRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize the sell token behaviour.""" - super().__init__(**kwargs) - self.sell_amount: float = 0.0 - - @property - def market_maker_contract_address(self) -> str: - """Get the contract address of the market maker on which the service is going to place the bet.""" - return self.sampled_bet.id - - @property - def outcome_index(self) -> int: - """Get the index of the outcome for which the service is going to sell token.""" - return cast(int, self.synchronized_data.previous_vote) - - @property - def return_amount(self) -> int: - """Get the amount expected to be returned after the sell tx is completed.""" - previous_vote = self.synchronized_data.previous_vote - - if previous_vote == 0: - return self.sampled_bet.invested_amount_yes - - else: - return self.sampled_bet.invested_amount_no - - def _build_approval_tx(self) -> WaitableConditionType: - """Build an ERC20 approve transaction.""" - status = yield from self.build_approval_tx( - self.return_amount, - self.market_maker_contract_address, - self.sampled_bet.get_outcome(self.outcome_index), - ) - return status - - def _calc_sell_amount(self) -> WaitableConditionType: - """Calculate the sell amount of the conditional token.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.market_maker_contract_address, - contract_id=str(FixedProductMarketMakerContract.contract_id), - contract_callable="calc_sell_amount", - return_amount=self.return_amount, - outcome_index=self.outcome_index, - ) - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.context.logger.error( - f"Could not calculate the sell amount: {response_msg}" - ) - return False - - sell_amount = response_msg.raw_transaction.body.get( - "outcomeTokenSellAmount", None - ) - if sell_amount is None: - self.context.logger.error( - f"Something went wrong while trying to get the outcomeTokenSellAmount amount for the conditional token: {response_msg}" - ) - return False - - self.sell_amount = sell_amount - return True - - def _build_sell_tx(self) -> WaitableConditionType: - """Get the sell tx data encoded.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.market_maker_contract_address, - contract_id=str(FixedProductMarketMakerContract.contract_id), - contract_callable="get_sell_data", - return_amount=self.return_amount, - outcome_index=self.outcome_index, - max_outcome_tokens_to_sell=self.sell_amount, - ) - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Could not get the data for the buy transaction: {response_msg}" - ) - return False - - sell_data = response_msg.state.body.get("data", None) - if sell_data is None: - self.context.logger.error( - f"Something went wrong while trying to encode the buy data: {response_msg}" - ) - return False - - batch = MultisendBatch( - to=self.market_maker_contract_address, - data=HexBytes(sell_data), - ) - self.multisend_batches.append(batch) - return True - - def _prepare_safe_tx(self) -> Generator[None, None, Optional[str]]: - """Prepare the safe transaction for selling an outcome token and return the hex for the tx settlement skill.""" - for step in ( - self._build_approval_tx, - self._calc_sell_amount, - self._build_sell_tx, - self._build_multisend_data, - self._build_multisend_safe_tx_hash, - ): - yield from self.wait_for_condition_with_sleep(step) - - outcome = self.sampled_bet.get_outcome(self.outcome_index) - investment = self._collateral_amount_info(self.return_amount) - self.context.logger.info( - f"Preparing a multisig transaction to sell the outcome token for {outcome!r}, with confidence " - f"{self.synchronized_data.confidence!r}, for the amount of {investment}, which is equal to the amount of " - f"{self.sell_amount!r} WEI of the conditional token corresponding to {outcome!r}." - ) - - return self.tx_hex - - def async_act(self) -> Generator: - """Do the action.""" - - agent = self.context.agent_address - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - tx_submitter = betting_tx_hex = mocking_mode = None - - # if the vote is the same as the previous vote then there is no change in the supported outcome, so we - # should not sell - if self.synchronized_data.vote == self.synchronized_data.previous_vote: - payload = MultisigTxPayload( - agent, tx_submitter, betting_tx_hex, mocking_mode - ) - - yield from self.finish_behaviour(payload) - - tx_submitter = self.matching_round.auto_round_id() - betting_tx_hex = yield from self._prepare_safe_tx() - - payload = MultisigTxPayload( - agent, tx_submitter, betting_tx_hex, mocking_mode - ) - - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/storage_manager.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/storage_manager.py deleted file mode 100644 index 0fd9a8369..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/storage_manager.py +++ /dev/null @@ -1,471 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 behaviour for managing the storage of the agent.""" - -import csv -import json -from abc import ABC -from datetime import datetime -from io import StringIO -from typing import Any, Dict, Generator, List, Optional, Tuple - -from packages.valory.contracts.agent_registry.contract import AgentRegistryContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - CID_PREFIX, - DecisionMakerBaseBehaviour, - WaitableConditionType, -) -from packages.valory.skills.decision_maker_abci.models import AgentToolsSpecs -from packages.valory.skills.decision_maker_abci.policy import ( - AccuracyInfo, - EGreedyPolicy, -) - - -POLICY_STORE = "policy_store_multi_bet_failure_adjusting.json" -AVAILABLE_TOOLS_STORE = "available_tools_store.json" -UTILIZED_TOOLS_STORE = "utilized_tools.json" -GET = "GET" -OK_CODE = 200 - - -class StorageManagerBehaviour(DecisionMakerBaseBehaviour, ABC): - """Manages the storage of the policy and the tools.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize Behaviour.""" - super().__init__(**kwargs) - self._mech_id: int = 0 - self._mech_hash: str = "" - self._utilized_tools: Dict[str, str] = {} - self._mech_tools: Optional[List[str]] = None - self._remote_accuracy_information: StringIO = StringIO() - - @property - def mech_tools(self) -> List[str]: - """Get the mech agent's tools.""" - if self._mech_tools is None: - raise ValueError("The mech's tools have not been set.") - return self._mech_tools - - @mech_tools.setter - def mech_tools(self, mech_tools: List[str]) -> None: - """Set the mech agent's tools.""" - self._mech_tools = mech_tools - - @property - def remote_accuracy_information(self) -> StringIO: - """Get the accuracy information.""" - return self._remote_accuracy_information - - @remote_accuracy_information.setter - def remote_accuracy_information(self, accuracy_information: StringIO) -> None: - """Set the accuracy information.""" - self._remote_accuracy_information = accuracy_information - - @property - def mech_id(self) -> int: - """Get the mech's id.""" - return self._mech_id - - @mech_id.setter - def mech_id(self, mech_id: int) -> None: - """Set the mech's id.""" - self._mech_id = mech_id - - @property - def mech_hash(self) -> str: - """Get the hash of the mech agent.""" - return self._mech_hash - - @mech_hash.setter - def mech_hash(self, mech_hash: str) -> None: - """Set the hash of the mech agent.""" - self._mech_hash = mech_hash - - @property - def utilized_tools(self) -> Dict[str, str]: - """Get the utilized tools.""" - return self._utilized_tools - - @utilized_tools.setter - def utilized_tools(self, utilized_tools: Dict[str, str]) -> None: - """Get the utilized tools.""" - self._utilized_tools = utilized_tools - - @property - def mech_tools_api(self) -> AgentToolsSpecs: - """Get the mech agent api specs.""" - return self.context.agent_tools - - def setup(self) -> None: - """Set the behaviour up.""" - try: - self.utilized_tools = self.synchronized_data.utilized_tools - except Exception: - self.utilized_tools = self._try_recover_utilized_tools() - else: - if self.utilized_tools is None: - self.utilized_tools = self._try_recover_utilized_tools() - - def set_mech_agent_specs(self) -> None: - """Set the mech's agent specs.""" - full_ipfs_hash = CID_PREFIX + self.mech_hash - ipfs_link = self.params.ipfs_address + full_ipfs_hash - # The url needs to be dynamically generated as it depends on the ipfs hash - self.mech_tools_api.__dict__["_frozen"] = False - self.mech_tools_api.url = ipfs_link - self.mech_tools_api.__dict__["_frozen"] = True - - def _get_tools_from_benchmark_file(self) -> None: - """Get the tools from the benchmark dataset.""" - dataset_filepath = ( - self.params.store_path / self.benchmarking_mode.dataset_filename - ) - with open(dataset_filepath) as read_dataset: - row = read_dataset.readline() - if not row: - # if no headers are in the file, then we finished the benchmarking - self.context.logger.error("No headers in dataset file.") - return - - # parse tools from headers - headers = row.split(self.benchmarking_mode.sep) - p_yes_part = self.benchmarking_mode.p_yes_field_part - self.mech_tools = [ - header.replace(p_yes_part, "") for header in headers if p_yes_part in header - ] - - def _get_mech_id(self) -> WaitableConditionType: - """Get the mech's id.""" - result = yield from self._mech_contract_interact( - contract_callable="get_mech_id", - data_key="id", - placeholder=get_name(StorageManagerBehaviour.mech_id), - ) - - return result - - def _get_mech_hash(self) -> WaitableConditionType: - """Get the mech's hash.""" - result = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.agent_registry_address, - contract_public_id=AgentRegistryContract.contract_id, - contract_callable="get_hash", - data_key="hash", - placeholder=get_name(StorageManagerBehaviour.mech_hash), - agent_id=self.mech_id, - ) - return result - - def _get_mech_tools(self) -> WaitableConditionType: - """Get the mech agent's tools from IPFS.""" - self.set_mech_agent_specs() - specs = self.mech_tools_api.get_spec() - res_raw = yield from self.get_http_response(**specs) - res = self.mech_tools_api.process_response(res_raw) - - if self.mech_tools_api.is_retries_exceeded(): - error = "Retries were exceeded while trying to get the mech agent's data." - self.context.logger.error(error) - self.mech_tools_api.reset_retries() - return True - - if res is None: - url = self.mech_tools_api.url - msg = f"Could not get the mech agent's tools from {url}." - self.context.logger.error(msg) - self.mech_tools_api.increment_retries() - return False - - self.context.logger.info(f"Retrieved the mech agent's tools: {res}.") - # keep only the relevant mech tools, sorted - # we sort the tools to avoid using dictionaries in the policy implementation, - # so that we can easily assess which index corresponds to which tool - res = sorted(set(res) - self.params.irrelevant_tools) - self.context.logger.info(f"Relevant tools to the prediction task: {res}.") - - if len(res) == 0: - self.context.logger.error("The relevant mech agent's tools are empty!") - return False - self.mech_tools = res - self.mech_tools_api.reset_retries() - return True - - def _get_tools( - self, - ) -> Generator[None, None, None]: - """Get the Mech's tools.""" - if self.benchmarking_mode.enabled: - self._get_tools_from_benchmark_file() - return - - for step in ( - self._get_mech_id, - self._get_mech_hash, - self._get_mech_tools, - ): - yield from self.wait_for_condition_with_sleep(step) - - def _try_recover_policy(self) -> Optional[EGreedyPolicy]: - """Try to recover the policy from the policy store.""" - try: - policy_path = self.params.store_path / POLICY_STORE - with open(policy_path, "r") as f: - policy_raw = f.read() - policy = EGreedyPolicy.deserialize(policy_raw) - # overwrite the configurable parameters - policy.eps = self.params.epsilon - policy.consecutive_failures_threshold = self.params.policy_threshold - policy.quarantine_duration = self.params.tool_quarantine_duration - return policy - except Exception as e: - self.context.logger.warning(f"Could not recover the policy: {e}.") - return None - - def _get_init_policy(self) -> EGreedyPolicy: - """Get the initial policy.""" - # try to read the policy from the policy store, and if we cannot recover the policy, we create a new one - return self._try_recover_policy() or EGreedyPolicy( - self.params.epsilon, - self.params.policy_threshold, - self.params.tool_quarantine_duration, - ) - - def _fetch_accuracy_info(self) -> Generator[None, None, bool]: - """Fetch the latest accuracy information available.""" - # get the CSV file from IPFS - self.context.logger.info("Reading accuracy information from IPFS...") - accuracy_link = self.params.ipfs_address + self.params.tools_accuracy_hash - response = yield from self.get_http_response(method=GET, url=accuracy_link) - if response.status_code != OK_CODE: - self.context.logger.error( - f"Could not retrieve data from the url {accuracy_link}. " - f"Received status code {response.status_code}." - ) - return False - - self.context.logger.info("Parsing accuracy information of the tools...") - try: - self.remote_accuracy_information = StringIO(response.body.decode()) - except (ValueError, TypeError) as e: - self.context.logger.error( - f"Could not parse response from ipfs server, " - f"the following error was encountered {type(e).__name__}: {e}" - ) - return False - - return True - - def _remove_irrelevant_tools(self) -> None: - """Remove irrelevant tools from the accuracy store.""" - accuracy_store = self.policy.accuracy_store - for tool in accuracy_store.copy(): - if tool not in self.mech_tools: - accuracy_store.pop(tool, None) - - def _global_info_date_to_unix(self, tool_transaction_date: str) -> Optional[int]: - """Convert the global information date to unix.""" - datetime_format = self.acc_info_fields.datetime_format - try: - tool_transaction_datetime = datetime.strptime( - tool_transaction_date, datetime_format - ) - except (ValueError, TypeError): - self.context.logger.warning( - f"Could not parse the global info date {tool_transaction_date!r} using format {datetime_format!r}!" - ) - return None - - return int(tool_transaction_datetime.timestamp()) - - def _parse_global_info_row( - self, - row: Dict[str, str], - max_transaction_date: int, - tool_to_global_info: Dict[str, Dict[str, str]], - ) -> int: - """Parse a row of the global information.""" - tool = row[self.acc_info_fields.tool] - if tool not in self.mech_tools: - # skip irrelevant tools - return max_transaction_date - - # store the global information - tool_to_global_info[tool] = row - - # find the latest transaction date - tool_transaction_date = row[self.acc_info_fields.max] - tool_transaction_unix = self._global_info_date_to_unix(tool_transaction_date) - if ( - tool_transaction_unix is not None - and tool_transaction_unix > max_transaction_date - ): - return tool_transaction_unix - - return max_transaction_date - - def _parse_global_info(self) -> Tuple[int, Dict[str, Dict[str, str]]]: - """Parse the global information of the tools.""" - sep = self.acc_info_fields.sep - reader: csv.DictReader = csv.DictReader( - self.remote_accuracy_information, delimiter=sep - ) - - max_transaction_date = 0 - tool_to_global_info: Dict[str, Dict[str, str]] = {} - for row in reader: - max_transaction_date = self._parse_global_info_row( - row, max_transaction_date, tool_to_global_info - ) - - return max_transaction_date, tool_to_global_info - - def _should_use_global_info(self, global_update_timestamp: int) -> bool: - """Whether we should use the global information of the tools.""" - local_update_timestamp = self.policy.updated_ts - local_update_offset = self.params.policy_store_update_offset - return global_update_timestamp > local_update_timestamp - local_update_offset - - def _overwrite_local_info( - self, tool_to_global_info: Dict[str, Dict[str, str]] - ) -> None: - """Overwrite the local information with the global information.""" - self.context.logger.info( - "The local policy store will be overwritten with global information." - ) - - accuracy_store = self.policy.accuracy_store - for tool, row in tool_to_global_info.items(): - accuracy_store[tool] = AccuracyInfo( - int(row[self.acc_info_fields.requests]), - # naturally, no global information is available for pending. - # set it using the local policy if this information exists - accuracy_store.get(tool, AccuracyInfo()).pending, - float(row[self.acc_info_fields.accuracy]), - ) - self.policy.updated_ts = int(datetime.now().timestamp()) - - def _update_accuracy_store( - self, - global_update_timestamp: int, - tool_to_global_info: Dict[str, Dict[str, str]], - ) -> None: - """ - Update the accuracy store using the latest accuracy information. - - The current method should only be called at the first period. - - :param global_update_timestamp: the timestamp of the latest global information update - :param tool_to_global_info: the global information of the tools - """ - if self._should_use_global_info(global_update_timestamp): - self._overwrite_local_info(tool_to_global_info) - - # update the accuracy store by adding tools for which we do not have any global information yet - for tool in self.mech_tools: - self.policy.accuracy_store.setdefault(tool, AccuracyInfo()) - - def _update_policy_tools(self) -> None: - """Update the policy's tools and their accuracy with the latest information available if `with_global_info`.""" - self.context.logger.info("Updating information of the policy...") - self._remove_irrelevant_tools() - global_info = self._parse_global_info() - self._update_accuracy_store(*global_info) - self.policy.update_weighted_accuracy() - - def _set_policy(self) -> Generator: - """Set the E Greedy Policy.""" - if self.is_first_period or not self.synchronized_data.is_policy_set: - self.context.logger.debug("Setting initial policy") - self._policy = self._get_init_policy() - else: - self.context.logger.debug( - "Reading policy information from synchronized data" - ) - self._policy = self.synchronized_data.policy - - yield from self.wait_for_condition_with_sleep( - self._fetch_accuracy_info, sleep_time_override=self.params.sleep_time - ) - - if self.is_first_period: - self._update_policy_tools() - - def _try_recover_utilized_tools(self) -> Dict[str, str]: - """Try to recover the utilized tools from the tools store.""" - tools_path = self.params.store_path / UTILIZED_TOOLS_STORE - try: - with open(tools_path, "r") as tools_file: - return json.load(tools_file) - except FileNotFoundError: - msg = "No file with pending rewards for the policy were found in the local storage." - self.context.logger.info(msg) - except Exception as exc: - msg = f"Could not recover the pending rewards for the policy: {exc}." - self.context.logger.warning(msg) - return {} - - def _try_recover_mech_tools(self) -> Optional[List[str]]: - """Try to recover the available tools from the tools store.""" - try: - tools_path = self.params.store_path / AVAILABLE_TOOLS_STORE - with open(tools_path, "r") as f: - tools = json.load(f) - return tools - except Exception as e: - self.context.logger.warning(f"Could not recover the tools: {e}.") - return None - - def _setup_policy_and_tools(self) -> Generator[None, None, bool]: - """Set up the policy and tools.""" - yield from self._get_tools() - if self._mech_tools is None: - return False - - yield from self._set_policy() - return True - - def _store_policy(self) -> None: - """Store the policy""" - policy_path = self.params.store_path / POLICY_STORE - with open(policy_path, "w") as f: - f.write(self.policy.serialize()) - - def _store_available_mech_tools(self) -> None: - """Store the policy""" - policy_path = self.params.store_path / AVAILABLE_TOOLS_STORE - with open(policy_path, "w") as f: - json.dump(self.mech_tools, f) - - def _store_utilized_tools(self) -> None: - """Store the utilized tools.""" - tools_path = self.params.store_path / UTILIZED_TOOLS_STORE - with open(tools_path, "w") as f: - json.dump(self.utilized_tools, f) - - def _store_all(self) -> None: - """Store the policy, the available tools and the utilized tools.""" - self._store_policy() - self._store_available_mech_tools() - self._store_utilized_tools() diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/tool_selection.py b/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/tool_selection.py deleted file mode 100644 index 2fd1bbaa8..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/behaviours/tool_selection.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviour of the skill which is responsible for selecting a mech tool.""" - -import json -from typing import Generator, Optional - -from packages.valory.skills.decision_maker_abci.behaviours.storage_manager import ( - StorageManagerBehaviour, -) -from packages.valory.skills.decision_maker_abci.payloads import ToolSelectionPayload -from packages.valory.skills.decision_maker_abci.states.tool_selection import ( - ToolSelectionRound, -) - - -class ToolSelectionBehaviour(StorageManagerBehaviour): - """A behaviour in which the agents select a mech tool.""" - - matching_round = ToolSelectionRound - - def _select_tool(self) -> Generator[None, None, Optional[str]]: - """Select a Mech tool based on an e-greedy policy and return its index.""" - success = yield from self._setup_policy_and_tools() - if not success: - return None - - randomness = ( - (self.benchmarking_mode.randomness if self.is_first_period else None) - if self.benchmarking_mode.enabled - else self.synchronized_data.most_voted_randomness - ) - selected_tool = self.policy.select_tool(randomness) - self.context.logger.info(f"Selected the mech tool {selected_tool!r}.") - return selected_tool - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - mech_tools = policy = utilized_tools = None - selected_tool = yield from self._select_tool() - if selected_tool is not None: - # the period will increment when the benchmarking finishes - benchmarking_running = self.synchronized_data.period_count == 0 - if ( - self.benchmarking_mode.enabled - and benchmarking_running - and not self.shared_state.last_benchmarking_has_run - ): - self.policy.tool_used(selected_tool) - mech_tools = json.dumps(self.mech_tools) - policy = self.policy.serialize() - utilized_tools = json.dumps(self.utilized_tools, sort_keys=True) - self._store_all() - - payload = ToolSelectionPayload( - self.context.agent_address, - mech_tools, - policy, - utilized_tools, - selected_tool, - ) - - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/dialogues.py b/trader_old/vendor/valory/skills/decision_maker_abci/dialogues.py deleted file mode 100644 index e985dc865..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/dialogues.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- 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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/fsm_specification.yaml b/trader_old/vendor/valory/skills/decision_maker_abci/fsm_specification.yaml deleted file mode 100644 index ac3009546..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/fsm_specification.yaml +++ /dev/null @@ -1,133 +0,0 @@ -alphabet_in: -- BENCHMARKING_DISABLED -- BENCHMARKING_ENABLED -- BENCHMARKING_FINISHED -- BLACKLIST -- DONE -- FETCH_ERROR -- INSUFFICIENT_BALANCE -- MECH_RESPONSE_ERROR -- MOCK_MECH_REQUEST -- MOCK_TX -- NEW_SIMULATED_RESAMPLE -- NONE -- NO_MAJORITY -- NO_OP -- NO_REDEEMING -- NO_SUBSCRIPTION -- REDEEM_ROUND_TIMEOUT -- ROUND_TIMEOUT -- SLOTS_UNSUPPORTED_ERROR -- SUBSCRIPTION_ERROR -- TIE -- UNPROFITABLE -default_start_state: CheckBenchmarkingModeRound -final_states: -- BenchmarkingDoneRound -- BenchmarkingModeDisabledRound -- FinishedDecisionMakerRound -- FinishedDecisionRequestRound -- FinishedSubscriptionRound -- FinishedWithoutDecisionRound -- FinishedWithoutRedeemingRound -- ImpossibleRound -- RefillRequiredRound -label: DecisionMakerAbciApp -start_states: -- CheckBenchmarkingModeRound -- ClaimRound -- DecisionReceiveRound -- HandleFailedTxRound -- RandomnessRound -- RedeemRound -states: -- BenchmarkingDoneRound -- BenchmarkingModeDisabledRound -- BenchmarkingRandomnessRound -- BetPlacementRound -- BlacklistingRound -- CheckBenchmarkingModeRound -- ClaimRound -- DecisionReceiveRound -- DecisionRequestRound -- FinishedDecisionMakerRound -- FinishedDecisionRequestRound -- FinishedSubscriptionRound -- FinishedWithoutDecisionRound -- FinishedWithoutRedeemingRound -- HandleFailedTxRound -- ImpossibleRound -- RandomnessRound -- RedeemRound -- RefillRequiredRound -- SamplingRound -- SubscriptionRound -- ToolSelectionRound -transition_func: - (BenchmarkingRandomnessRound, DONE): SamplingRound - (BenchmarkingRandomnessRound, NO_MAJORITY): BenchmarkingRandomnessRound - (BenchmarkingRandomnessRound, ROUND_TIMEOUT): BenchmarkingRandomnessRound - (BetPlacementRound, DONE): FinishedDecisionMakerRound - (BetPlacementRound, INSUFFICIENT_BALANCE): RefillRequiredRound - (BetPlacementRound, MOCK_TX): RedeemRound - (BetPlacementRound, NONE): ImpossibleRound - (BetPlacementRound, NO_MAJORITY): BetPlacementRound - (BetPlacementRound, ROUND_TIMEOUT): BetPlacementRound - (BlacklistingRound, DONE): FinishedWithoutDecisionRound - (BlacklistingRound, FETCH_ERROR): ImpossibleRound - (BlacklistingRound, MOCK_TX): FinishedWithoutDecisionRound - (BlacklistingRound, NONE): ImpossibleRound - (BlacklistingRound, NO_MAJORITY): BlacklistingRound - (BlacklistingRound, ROUND_TIMEOUT): BlacklistingRound - (CheckBenchmarkingModeRound, BENCHMARKING_DISABLED): BenchmarkingModeDisabledRound - (CheckBenchmarkingModeRound, BENCHMARKING_ENABLED): BenchmarkingRandomnessRound - (CheckBenchmarkingModeRound, DONE): ImpossibleRound - (CheckBenchmarkingModeRound, NO_MAJORITY): CheckBenchmarkingModeRound - (CheckBenchmarkingModeRound, ROUND_TIMEOUT): CheckBenchmarkingModeRound - (CheckBenchmarkingModeRound, SUBSCRIPTION_ERROR): ImpossibleRound - (ClaimRound, DONE): ToolSelectionRound - (ClaimRound, NO_MAJORITY): ClaimRound - (ClaimRound, ROUND_TIMEOUT): ClaimRound - (ClaimRound, SUBSCRIPTION_ERROR): ClaimRound - (DecisionReceiveRound, DONE): BetPlacementRound - (DecisionReceiveRound, MECH_RESPONSE_ERROR): BlacklistingRound - (DecisionReceiveRound, NO_MAJORITY): DecisionReceiveRound - (DecisionReceiveRound, ROUND_TIMEOUT): DecisionReceiveRound - (DecisionReceiveRound, TIE): BlacklistingRound - (DecisionReceiveRound, UNPROFITABLE): BlacklistingRound - (DecisionRequestRound, DONE): FinishedDecisionRequestRound - (DecisionRequestRound, MOCK_MECH_REQUEST): DecisionReceiveRound - (DecisionRequestRound, NO_MAJORITY): DecisionRequestRound - (DecisionRequestRound, ROUND_TIMEOUT): DecisionRequestRound - (DecisionRequestRound, SLOTS_UNSUPPORTED_ERROR): BlacklistingRound - (HandleFailedTxRound, BLACKLIST): BlacklistingRound - (HandleFailedTxRound, NO_MAJORITY): HandleFailedTxRound - (HandleFailedTxRound, NO_OP): RedeemRound - (RandomnessRound, DONE): SamplingRound - (RandomnessRound, NO_MAJORITY): RandomnessRound - (RandomnessRound, ROUND_TIMEOUT): RandomnessRound - (RedeemRound, DONE): FinishedDecisionMakerRound - (RedeemRound, MOCK_TX): SamplingRound - (RedeemRound, NONE): ImpossibleRound - (RedeemRound, NO_MAJORITY): RedeemRound - (RedeemRound, NO_REDEEMING): FinishedWithoutRedeemingRound - (RedeemRound, REDEEM_ROUND_TIMEOUT): FinishedWithoutRedeemingRound - (SamplingRound, BENCHMARKING_ENABLED): ToolSelectionRound - (SamplingRound, BENCHMARKING_FINISHED): BenchmarkingDoneRound - (SamplingRound, DONE): SubscriptionRound - (SamplingRound, FETCH_ERROR): ImpossibleRound - (SamplingRound, NEW_SIMULATED_RESAMPLE): SamplingRound - (SamplingRound, NONE): FinishedWithoutDecisionRound - (SamplingRound, NO_MAJORITY): SamplingRound - (SamplingRound, ROUND_TIMEOUT): SamplingRound - (SubscriptionRound, DONE): FinishedSubscriptionRound - (SubscriptionRound, MOCK_TX): ToolSelectionRound - (SubscriptionRound, NONE): SubscriptionRound - (SubscriptionRound, NO_MAJORITY): SubscriptionRound - (SubscriptionRound, NO_SUBSCRIPTION): ToolSelectionRound - (SubscriptionRound, ROUND_TIMEOUT): SubscriptionRound - (SubscriptionRound, SUBSCRIPTION_ERROR): SubscriptionRound - (ToolSelectionRound, DONE): DecisionRequestRound - (ToolSelectionRound, NONE): ToolSelectionRound - (ToolSelectionRound, NO_MAJORITY): ToolSelectionRound - (ToolSelectionRound, ROUND_TIMEOUT): ToolSelectionRound diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/handlers.py b/trader_old/vendor/valory/skills/decision_maker_abci/handlers.py deleted file mode 100644 index b0f6ad169..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/handlers.py +++ /dev/null @@ -1,366 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the handler for the 'decision_maker_abci' skill.""" - -import json -import re -from datetime import datetime -from enum import Enum -from typing import Callable, Dict, Optional, Tuple, cast -from urllib.parse import urlparse - -from aea.protocols.base import Message - -from packages.valory.connections.http_server.connection import ( - PUBLIC_ID as HTTP_SERVER_PUBLIC_ID, -) -from packages.valory.protocols.http.message import HttpMessage -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import AbstractResponseHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.decision_maker_abci.dialogues import ( - HttpDialogue, - HttpDialogues, -) -from packages.valory.skills.decision_maker_abci.models import SharedState -from packages.valory.skills.decision_maker_abci.rounds import SynchronizedData - - -ABCIHandler = BaseABCIRoundHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler - - -class IpfsHandler(AbstractResponseHandler): - """IPFS message handler.""" - - SUPPORTED_PROTOCOL = IpfsMessage.protocol_id - allowed_response_performatives = frozenset({IpfsMessage.Performative.IPFS_HASH}) - custom_support_performative = IpfsMessage.Performative.FILES - - @property - def shared_state(self) -> SharedState: - """Get the parameters.""" - return cast(SharedState, self.context.state) - - def handle(self, message: IpfsMessage) -> None: - """ - Implement the reaction to an IPFS message. - - :param message: the message - :return: None - """ - self.context.logger.debug(f"Received message: {message}") - self.shared_state.in_flight_req = False - - if message.performative != self.custom_support_performative: - return super().handle(message) - - dialogue = self.context.ipfs_dialogues.update(message) - nonce = dialogue.dialogue_label.dialogue_reference[0] - callback = self.shared_state.req_to_callback.pop(nonce) - callback(message, dialogue) - - -OK_CODE = 200 -NOT_FOUND_CODE = 404 -BAD_REQUEST_CODE = 400 -AVERAGE_PERIOD_SECONDS = 10 - - -class HttpMethod(Enum): - """Http methods""" - - GET = "get" - HEAD = "head" - POST = "post" - - -class HttpHandler(BaseHttpHandler): - """This implements the echo handler.""" - - SUPPORTED_PROTOCOL = HttpMessage.protocol_id - - def setup(self) -> None: - """Implement the setup.""" - config_uri_base_hostname = urlparse( - self.context.params.service_endpoint - ).hostname - - propel_uri_base_hostname = ( - r"https?:\/\/[a-zA-Z0-9]{16}.agent\.propel\.(staging\.)?autonolas\.tech" - ) - - local_ip_regex = r"192\.168(\.\d{1,3}){2}" - - # Route regexes - hostname_regex = rf".*({config_uri_base_hostname}|{propel_uri_base_hostname}|{local_ip_regex}|localhost|127.0.0.1|0.0.0.0)(:\d+)?" - self.handler_url_regex = rf"{hostname_regex}\/.*" - health_url_regex = rf"{hostname_regex}\/healthcheck" - - # Routes - self.routes = { - (HttpMethod.GET.value, HttpMethod.HEAD.value): [ - (health_url_regex, self._handle_get_health), - ], - } - - self.json_content_header = "Content-Type: application/json\n" - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return SynchronizedData( - db=self.context.state.round_sequence.latest_synchronized_data.db - ) - - def _get_handler(self, url: str, method: str) -> Tuple[Optional[Callable], Dict]: - """Check if an url is meant to be handled in this handler - - We expect url to match the pattern {hostname}/.*, - where hostname is allowed to be localhost, 127.0.0.1 or the service_endpoint's hostname. - - :param url: the url to check - :param method: the method - :returns: the handling method if the message is intended to be handled by this handler, None otherwise, and the regex captures - """ - # Check base url - if not re.match(self.handler_url_regex, url): - self.context.logger.info( - f"The url {url} does not match the DynamicNFT HttpHandler's pattern" - ) - return None, {} - - # Check if there is a route for this request - for methods, routes in self.routes.items(): - if method not in methods: - continue - - for route in routes: - # Routes are tuples like (route_regex, handle_method) - m = re.match(route[0], url) - if m: - return route[1], m.groupdict() - - # No route found - self.context.logger.info( - f"The message [{method}] {url} is intended for the DynamicNFT HttpHandler but did not match any valid pattern" - ) - return self._handle_bad_request, {} - - def handle(self, message: Message) -> None: - """ - Implement the reaction to an envelope. - - :param message: the message - """ - http_msg = cast(HttpMessage, message) - - # Check if this is a request sent from the http_server skill - if ( - http_msg.performative != HttpMessage.Performative.REQUEST - or message.sender != str(HTTP_SERVER_PUBLIC_ID.without_hash()) - ): - super().handle(message) - return - - # Check if this message is for this skill. If not, send to super() - handler, kwargs = self._get_handler(http_msg.url, http_msg.method) - if not handler: - super().handle(message) - return - - # Retrieve dialogues - http_dialogues = cast(HttpDialogues, self.context.http_dialogues) - http_dialogue = cast(HttpDialogue, http_dialogues.update(http_msg)) - - # Invalid message - if http_dialogue is None: - self.context.logger.info( - "Received invalid http message={}, unidentified dialogue.".format( - http_msg - ) - ) - return - - # Handle message - self.context.logger.info( - "Received http request with method={}, url={} and body={!r}".format( - http_msg.method, - http_msg.url, - http_msg.body, - ) - ) - handler(http_msg, http_dialogue, **kwargs) - - def _handle_bad_request( - self, http_msg: HttpMessage, http_dialogue: HttpDialogue - ) -> None: - """ - Handle a Http bad request. - - :param http_msg: the http message - :param http_dialogue: the http dialogue - """ - http_response = http_dialogue.reply( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_msg, - version=http_msg.version, - status_code=BAD_REQUEST_CODE, - status_text="Bad request", - headers=http_msg.headers, - body=b"", - ) - - # Send response - self.context.logger.info("Responding with: {}".format(http_response)) - self.context.outbox.put_message(message=http_response) - - def _handle_get_health( - self, http_msg: HttpMessage, http_dialogue: HttpDialogue - ) -> None: - """ - Handle a Http request of verb GET. - - :param http_msg: the http message - :param http_dialogue: the http dialogue - """ - seconds_since_last_transition = None - is_tm_unhealthy = None - is_transitioning_fast = None - current_round = None - rounds = None - has_required_funds = self._check_required_funds() - is_receiving_mech_responses = self._check_is_receiving_mech_responses() - is_staking_kpi_met = self.synchronized_data.is_staking_kpi_met - staking_status = self.synchronized_data.service_staking_state.name.lower() - - round_sequence = cast(SharedState, self.context.state).round_sequence - - if round_sequence._last_round_transition_timestamp: - is_tm_unhealthy = cast( - SharedState, self.context.state - ).round_sequence.block_stall_deadline_expired - - current_time = datetime.now().timestamp() - seconds_since_last_transition = current_time - datetime.timestamp( - round_sequence._last_round_transition_timestamp - ) - - is_transitioning_fast = ( - not is_tm_unhealthy - and seconds_since_last_transition - < 2 * self.context.params.reset_pause_duration - ) - - if round_sequence._abci_app: - current_round = round_sequence._abci_app.current_round.round_id - rounds = [ - r.round_id for r in round_sequence._abci_app._previous_rounds[-25:] - ] - rounds.append(current_round) - - data = { - "seconds_since_last_transition": seconds_since_last_transition, - "is_tm_healthy": not is_tm_unhealthy, - "period": self.synchronized_data.period_count, - "reset_pause_duration": self.context.params.reset_pause_duration, - "rounds": rounds, - "is_transitioning_fast": is_transitioning_fast, - "agent_health": { - "is_making_on_chain_transactions": is_receiving_mech_responses, - "is_staking_kpi_met": is_staking_kpi_met, - "has_required_funds": has_required_funds, - "staking_status": staking_status, - }, - } - - self._send_ok_response(http_msg, http_dialogue, data) - - def _send_ok_response( - self, http_msg: HttpMessage, http_dialogue: HttpDialogue, data: Dict - ) -> None: - """Send an OK response with the provided data""" - http_response = http_dialogue.reply( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_msg, - version=http_msg.version, - status_code=OK_CODE, - status_text="Success", - headers=f"{self.json_content_header}{http_msg.headers}", - body=json.dumps(data).encode("utf-8"), - ) - - # Send response - self.context.logger.info("Responding with: {}".format(http_response)) - self.context.outbox.put_message(message=http_response) - - def _send_not_found_response( - self, http_msg: HttpMessage, http_dialogue: HttpDialogue - ) -> None: - """Send an not found response""" - http_response = http_dialogue.reply( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_msg, - version=http_msg.version, - status_code=NOT_FOUND_CODE, - status_text="Not found", - headers=http_msg.headers, - body=b"", - ) - # Send response - self.context.logger.info("Responding with: {}".format(http_response)) - self.context.outbox.put_message(message=http_response) - - def _check_required_funds(self) -> bool: - """Check the agent has enough funds.""" - return ( - self.synchronized_data.wallet_balance - > self.context.params.agent_balance_threshold - ) - - def _check_is_receiving_mech_responses(self) -> bool: - """Check the agent is making on chain transactions.""" - # Checks the most recent decision receive timestamp, which can only be returned after making a mech call - # (an on chain transaction) - return ( - self.synchronized_data.decision_receive_timestamp - < int(datetime.utcnow().timestamp()) - - self.context.params.expected_mech_response_time - ) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/io_/__init__.py b/trader_old/vendor/valory/skills/decision_maker_abci/io_/__init__.py deleted file mode 100644 index fd05584d0..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/io_/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- 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 helper classes for IPFS interaction.""" diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/io_/loader.py b/trader_old/vendor/valory/skills/decision_maker_abci/io_/loader.py deleted file mode 100644 index ebb501cb4..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/io_/loader.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- 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 helper classes for IPFS interaction.""" -from typing import Dict - -import yaml - -from packages.valory.skills.abstract_round_abci.io_.store import SupportedObjectType - - -class ComponentPackageLoader: - """Component package loader.""" - - @staticmethod - def load(serialized_objects: Dict[str, str]) -> SupportedObjectType: - """ - Load a custom component package. - - :param serialized_objects: the serialized objects. - :return: the component.yaml, entry_point.py and callable as tuple. - """ - # the package MUST contain a component.yaml file - if "component.yaml" not in serialized_objects: - raise ValueError( - "Invalid component package. " - "The package MUST contain a component.yaml." - ) - - # load the component.yaml file - component_yaml = yaml.safe_load(serialized_objects["component.yaml"]) - if "entry_point" not in component_yaml or "callable" not in component_yaml: - raise ValueError( - "Invalid component package. " - "The component.yaml file MUST contain the 'entry_point' and 'callable' keys." - ) - - # the name of the script that needs to be executed - entry_point_name = component_yaml["entry_point"] - - # load the script - if entry_point_name not in serialized_objects: - raise ValueError( - f"Invalid component package. " - f"{entry_point_name} is not present in the component package." - ) - entry_point = serialized_objects[entry_point_name] - - # the method that needs to be called - callable_method = component_yaml["callable"] - - return component_yaml, entry_point, callable_method diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/models.py b/trader_old/vendor/valory/skills/decision_maker_abci/models.py deleted file mode 100644 index 40ea13191..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/models.py +++ /dev/null @@ -1,626 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the models for the skill.""" - -import os -import re -import time -from dataclasses import dataclass, field -from datetime import datetime, timedelta -from pathlib import Path -from string import Template -from typing import ( - Any, - Callable, - Dict, - Iterable, - List, - Optional, - Set, - Tuple, - Type, - Union, -) - -from aea.skills.base import Model, SkillContext -from hexbytes import HexBytes -from web3.constants import HASH_ZERO -from web3.types import BlockIdentifier - -from packages.valory.contracts.multisend.contract import MultiSendOperation -from packages.valory.skills.abstract_round_abci.base import AbciApp -from packages.valory.skills.abstract_round_abci.models import ApiSpecs -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.abstract_round_abci.models import TypeCheckMixin -from packages.valory.skills.decision_maker_abci.policy import EGreedyPolicy -from packages.valory.skills.decision_maker_abci.redeem_info import Trade -from packages.valory.skills.decision_maker_abci.rounds import DecisionMakerAbciApp -from packages.valory.skills.market_manager_abci.bets import Bet -from packages.valory.skills.market_manager_abci.models import ( - MarketManagerParams, - Subgraph, -) -from packages.valory.skills.mech_interact_abci.models import ( - Params as MechInteractParams, -) - - -FromBlockMappingType = Dict[HexBytes, Union[int, str]] -ClaimParamsType = Tuple[List[bytes], List[str], List[int], List[bytes]] - - -RE_CONTENT_IN_BRACKETS = r"\{([^}]*)\}" -REQUIRED_BET_TEMPLATE_KEYS = {"yes", "no", "question"} -DEFAULT_FROM_BLOCK = "earliest" -ZERO_HEX = HASH_ZERO[2:] -ZERO_BYTES = bytes.fromhex(ZERO_HEX) -STRATEGY_KELLY_CRITERION = "kelly_criterion" -L0_START_FIELD = "l0_start" -L1_START_FIELD = "l1_start" -L0_END_FIELD = "l0_end" -L1_END_FIELD = "l1_end" -YES = "yes" -NO = "no" - - -class PromptTemplate(Template): - """A prompt template.""" - - delimiter = "@" - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -@dataclass -class LiquidityInfo: - """The structure to have liquidity information before and after a bet is done""" - - # Liquidity of tokens for option 0, before placing the bet - l0_start: Optional[int] = None - # Liquidity of tokens for option 1, before placing the bet - l1_start: Optional[int] = None - # Liquidity of tokens for option 0, after placing the bet - l0_end: Optional[int] = None - # Liquidity of tokens for option 1, after placing the bet - l1_end: Optional[int] = None - - def validate_start_information(self) -> Tuple[int, int]: - """Check if the start liquidity information is complete, otherwise raise an error.""" - if self.l0_start is None or self.l1_start is None: - raise ValueError("The liquidity information is incomplete!") - # return the values for type checking purposes (`mypy` would complain that they might be `None` otherwise) - return self.l0_start, self.l1_start - - def validate_end_information(self) -> Tuple[int, int]: - """Check if the end liquidity information is complete, otherwise raise an error.""" - if self.l0_end is None or self.l1_end is None: - raise ValueError("The liquidity information is incomplete!") - # return the values for type checking purposes (`mypy` would complain that they might be `None` otherwise) - return self.l0_end, self.l1_end - - def get_new_prices(self, liquidity_constants: List[float]) -> List[float]: - """Calculate and return the new prices based on the end liquidity and the liquidity constants of the market.""" - l0_end, l1_end = self.validate_end_information() - new_p0 = liquidity_constants[0] / l0_end - new_p1 = liquidity_constants[1] / l1_end - return [new_p0, new_p1] - - def get_end_liquidity(self) -> List[int]: - """Return the end liquidity.""" - l0_end, l1_end = self.validate_end_information() - return [l0_end, l1_end] - - -@dataclass -class RedeemingProgress: - """A structure to keep track of the redeeming check progress.""" - - trades: Set[Trade] = field(default_factory=set) - utilized_tools: Dict[str, str] = field(default_factory=dict) - policy: Optional[EGreedyPolicy] = None - claimable_amounts: Dict[HexBytes, int] = field(default_factory=dict) - earliest_block_number: int = 0 - event_filtering_batch_size: int = 0 - check_started: bool = False - check_from_block: BlockIdentifier = "earliest" - check_to_block: BlockIdentifier = "latest" - cleaned: bool = False - payouts: Dict[str, int] = field(default_factory=dict) - unredeemed_trades: Dict[str, int] = field(default_factory=dict) - claim_started: bool = False - claim_from_block: BlockIdentifier = "earliest" - claim_to_block: BlockIdentifier = "latest" - answered: list = field(default_factory=list) - claiming_condition_ids: List[str] = field(default_factory=list) - claimed_condition_ids: List[str] = field(default_factory=list) - - @property - def check_finished(self) -> bool: - """Whether the check has finished.""" - return self.check_started and self.check_from_block == self.check_to_block - - @property - def claim_finished(self) -> bool: - """Whether the claiming has finished.""" - return self.claim_started and self.claim_from_block == self.claim_to_block - - @property - def claim_params(self) -> Optional[ClaimParamsType]: - """The claim parameters, prepared for the `claimWinnings` call.""" - history_hashes = [] - addresses = [] - bonds = [] - answers = [] - try: - for i, answer in enumerate(reversed(self.answered)): - # history_hashes second-last-to-first, the hash of each history entry, calculated as described here: - # https://realitio.github.io/docs/html/contract_explanation.html#answer-history-entries. - if i == len(self.answered) - 1: - history_hashes.append(ZERO_BYTES) - else: - history_hashes.append(self.answered[i + 1]["args"]["history_hash"]) - - # last-to-first, the address of each answerer or commitment sender - addresses.append(answer["args"]["user"]) - # last-to-first, the bond supplied with each answer or commitment - bonds.append(answer["args"]["bond"]) - # last-to-first, each answer supplied, or commitment ID if the answer was supplied with commit->reveal - answers.append(answer["args"]["answer"]) - except KeyError: - return None - - return history_hashes, addresses, bonds, answers - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls: Type[AbciApp] = DecisionMakerAbciApp - - def __init__(self, *args: Any, skill_context: SkillContext, **kwargs: Any) -> None: - """Initialize the state.""" - super().__init__(*args, skill_context=skill_context, **kwargs) - self.redeeming_progress: RedeemingProgress = RedeemingProgress() - self.strategy_to_filehash: Dict[str, str] = {} - self.strategies_executables: Dict[str, Tuple[str, str]] = {} - self.in_flight_req: bool = False - self.req_to_callback: Dict[str, Callable] = {} - self.mock_data: Optional[BenchmarkingMockData] = None - # a mapping from market id to scaled liquidity measure - # also used for the benchmarking mode - self.liquidity_cache: Dict[str, float] = {} - # list with the simulated timestamps for the benchmarking mode - self.simulated_days: List[int] = [] - self.simulated_days_idx: int = 0 - # latest liquidity information (only relevant to the benchmarking mode) - self.liquidity_amounts: Dict[str, List[int]] = {} - self.liquidity_prices: Dict[str, List[float]] = {} - # whether this is the last run of the benchmarking mode - self.last_benchmarking_has_run: bool = False - - # the mapping from bet id to the row number in the dataset - # the key is the market id/question_id - self.bet_id_row_manager: Dict[str, List[int]] = {} - - # mech call counter for benchmarking behaviour - self.benchmarking_mech_calls: int = 0 - - @property - def mock_question_id(self) -> Any: - """Get the mock question id.""" - mock_data = self.mock_data - if mock_data is None: - raise ValueError("The mock data have not been set!") - return mock_data.id - - def _get_liquidity_info( - self, liquidity_data: Union[Dict[str, List[int]], Dict[str, List[float]]] - ) -> Any: - """Get the current liquidity information from the given data.""" - _id = self.mock_question_id - if _id not in liquidity_data: - raise ValueError( - f"There are no liquidity information for benchmarking mock data with question id {_id!r}." - ) - return liquidity_data[_id] - - @property - def current_liquidity_prices(self) -> List[float]: - """Return the current liquidity prices.""" - return self._get_liquidity_info(self.liquidity_prices) - - @current_liquidity_prices.setter - def current_liquidity_prices(self, value: List[float]) -> None: - """Set the current liquidity prices.""" - self.liquidity_prices[self.mock_question_id] = value - - @property - def current_liquidity_amounts(self) -> List[int]: - """Return the current liquidity amounts.""" - return self._get_liquidity_info(self.liquidity_amounts) - - @current_liquidity_amounts.setter - def current_liquidity_amounts(self, value: List[int]) -> None: - """Set the current liquidity amounts.""" - self.liquidity_amounts[self.mock_question_id] = value - - def _initialize_simulated_now_timestamps( - self, bets: List[Bet], safe_voting_range: int - ) -> None: - """Creates the list of simulated days for the benchmarking mode""" - self.simulated_days_idx = 0 - # Find the maximum timestamp from openingTimestamp field - max_timestamp = max(bet.openingTimestamp for bet in bets) - # adding some time range to allow voting - # in the sampling round the within_safe condition is designed to check - # the openingtimestamp of the market strickly less than the safe voting range - # so we need to create a timestamp that passes this condition for the max openingtimestamp - max_timestamp = max_timestamp - safe_voting_range - 1 - - # Get current timestamp - now_timestamp = int(time.time()) - # Convert timestamps to datetime objects - max_date = datetime.fromtimestamp(max_timestamp) - current_date = datetime.fromtimestamp(now_timestamp) - self.context.logger.info( - f"Simulating timestamps between {current_date} and {max_date}" - ) - # Generate list of timestamps with one day intervals - timestamps = [] - while current_date <= max_date: - timestamps.append(int(current_date.timestamp())) - current_date += timedelta(days=1) - self.context.logger.info(f"Simulated timestamps: {timestamps}") - self.simulated_days = timestamps - - def increase_one_day_simulation(self) -> None: - """Increased the index used for the current simulated day.""" - self.simulated_days_idx += 1 - - def check_benchmarking_finished(self) -> bool: - """Checks if we simulated already all days.""" - return self.simulated_days_idx >= len(self.simulated_days) - - def get_simulated_now_timestamp( - self, bets: List[Bet], safe_voting_range: int - ) -> int: - """Gets the current simulated day timestamp.""" - if len(self.simulated_days) == 0: - self._initialize_simulated_now_timestamps(bets, safe_voting_range) - - return self.simulated_days[self.simulated_days_idx] - - def setup(self) -> None: - """Set up the model.""" - super().setup() - params = self.context.params - self.redeeming_progress.event_filtering_batch_size = ( - params.event_filtering_batch_size - ) - self.strategy_to_filehash = { - value: key - for key, values in params.file_hash_to_strategies.items() - for value in values - } - selected_strategy = params.trading_strategy - strategy_exec = self.strategy_to_filehash.keys() - if selected_strategy not in strategy_exec: - raise ValueError( - f"The selected trading strategy {selected_strategy} " - f"is not in the strategies' executables {strategy_exec}." - ) - - -def extract_keys_from_template(delimiter: str, template: str) -> Set[str]: - """Extract the keys from a string template, given the delimiter.""" - # matches the placeholders of the template's keys - pattern = re.escape(delimiter) + RE_CONTENT_IN_BRACKETS - keys = re.findall(pattern, template) - return set(keys) - - -def check_prompt_template(bet_prompt_template: PromptTemplate) -> None: - """Check if the keys required for a bet are given in the provided prompt's template.""" - delimiter = bet_prompt_template.delimiter - template_keys = extract_keys_from_template(delimiter, bet_prompt_template.template) - if template_keys != REQUIRED_BET_TEMPLATE_KEYS: - example_key = (REQUIRED_BET_TEMPLATE_KEYS - template_keys).pop() - n_found = len(template_keys) - found = "no keys" if n_found == 0 else f"keys {template_keys}" - raise ValueError( - f"The bet's template should contain exclusively the following keys: {REQUIRED_BET_TEMPLATE_KEYS}.\n" - f"Found {found} instead in the given template:\n{bet_prompt_template.template!r}\n" - f"Please make sure that you are using the right delimiter {delimiter!r} for the prompt's template.\n" - f"For example, to parametrize {example_key!r} you may use " - f"'{delimiter}{{{example_key}}}'" - ) - - -def _raise_incorrect_config(key: str, values: Any) -> None: - """Raise a `ValueError` for incorrect configuration of a nested_list workaround.""" - raise ValueError( - f"The given configuration for {key!r} is incorrectly formatted: {values}!" - "The value is expected to be a list of lists that can be represented as a dictionary." - ) - - -def nested_list_todict_workaround( - kwargs: Dict, - key: str, -) -> Dict: - """Get a nested list from the kwargs and convert it to a dictionary.""" - values = list(kwargs.get(key, [])) - if len(values) == 0: - raise ValueError(f"No {key!r} specified in agent's configurations: {kwargs}!") - if any(not issubclass(type(nested_values), Iterable) for nested_values in values): - _raise_incorrect_config(key, values) - if any(len(nested_values) % 2 == 1 for nested_values in values): - _raise_incorrect_config(key, values) - return {value[0]: value[1] for value in values} - - -class DecisionMakerParams(MarketManagerParams, MechInteractParams): - """Decision maker's parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the parameters' object.""" - # the number of days to sample bets from - self.sample_bets_closing_days: int = self._ensure( - "sample_bets_closing_days", kwargs, int - ) - if self.sample_bets_closing_days <= 0: - msg = "The number of days to sample bets from must be positive!" - raise ValueError(msg) - - # the trading strategy to use for placing bets - self.trading_strategy: str = self._ensure("trading_strategy", kwargs, str) - self.use_fallback_strategy: bool = self._ensure( - "use_fallback_strategy", kwargs, bool - ) - self.tools_accuracy_hash: str = self._ensure("tools_accuracy_hash", kwargs, str) - # the threshold amount in WEI starting from which we are willing to place a bet - self.bet_threshold: int = self._ensure("bet_threshold", kwargs, int) - self._prompt_template: str = self._ensure("prompt_template", kwargs, str) - check_prompt_template(self.prompt_template) - self.dust_threshold: int = self._ensure("dust_threshold", kwargs, int) - self.conditional_tokens_address: str = self._ensure( - "conditional_tokens_address", kwargs, str - ) - self.realitio_proxy_address: str = self._ensure( - "realitio_proxy_address", kwargs, str - ) - self.realitio_address: str = self._ensure("realitio_address", kwargs, str) - # this is the maximum batch size that will be used when filtering blocks for events. - # increasing this number allows for faster filtering operations, - # but also increases the chances of getting a timeout error from the RPC - self.event_filtering_batch_size: int = self._ensure( - "event_filtering_batch_size", kwargs, int - ) - self.reduce_factor: float = self._ensure("reduce_factor", kwargs, float) - # the minimum batch size for redeeming operations, this is added to avoid the batch size to be too small - self.minimum_batch_size: int = self._ensure("minimum_batch_size", kwargs, int) - self.max_filtering_retries: int = self._ensure( - "max_filtering_retries", kwargs, int - ) - # this is the max number of redeeming operations that will be batched on a single multisend transaction. - # increasing this number equals fewer fees but more chances for the transaction to fail - self.redeeming_batch_size: int = self._ensure( - "redeeming_batch_size", kwargs, int - ) - self.redeem_round_timeout: float = self._ensure( - "redeem_round_timeout", kwargs, float - ) - # a slippage in the range of [0, 1] to apply to the `minOutcomeTokensToBuy` when buying shares on a fpmm - self._slippage: float = 0.0 - self.slippage: float = self._ensure("slippage", kwargs, float) - self.epsilon: float = self._ensure("policy_epsilon", kwargs, float) - self.agent_registry_address: str = self._ensure( - "agent_registry_address", kwargs, str - ) - self.store_path: Path = self.get_store_path(kwargs) - self.irrelevant_tools: set = set(self._ensure("irrelevant_tools", kwargs, list)) - self.tool_punishment_multiplier: int = self._ensure( - "tool_punishment_multiplier", kwargs, int - ) - self.contract_timeout: float = self._ensure("contract_timeout", kwargs, float) - self.file_hash_to_strategies: Dict[str, List[str]] = ( - nested_list_todict_workaround( - kwargs, - "file_hash_to_strategies_json", - ) - ) - self.strategies_kwargs: Dict[str, List[Any]] = nested_list_todict_workaround( - kwargs, "strategies_kwargs" - ) - self.use_subgraph_for_redeeming = self._ensure( - "use_subgraph_for_redeeming", - kwargs, - bool, - ) - self.use_nevermined = self._ensure("use_nevermined", kwargs, bool) - self.rpc_sleep_time: int = self._ensure("rpc_sleep_time", kwargs, int) - self.mech_to_subscription_params: Dict[str, Any] = ( - nested_list_todict_workaround( - kwargs, - "mech_to_subscription_params", - ) - ) - self.service_endpoint = self._ensure("service_endpoint", kwargs, str) - self.safe_voting_range = self._ensure("safe_voting_range", kwargs, int) - self.rebet_chance = self._ensure("rebet_chance", kwargs, float) - self.policy_store_update_offset = self._ensure( - "policy_store_update_offset", kwargs, int - ) - self.expected_mech_response_time = self._ensure( - "expected_mech_response_time", kwargs, int - ) - self.mech_invalid_response: str = self._ensure( - "mech_invalid_response", kwargs, str - ) - self.policy_threshold: int = self._ensure( - "mech_consecutive_failures_threshold", kwargs, int - ) - self.tool_quarantine_duration: int = self._ensure( - "tool_quarantine_duration", kwargs, int - ) - super().__init__(*args, **kwargs) - - @property - def using_kelly(self) -> bool: - """Get the max bet amount if the `bet_amount_per_conf_threshold` strategy is used.""" - return self.trading_strategy == STRATEGY_KELLY_CRITERION - - @property - def prompt_template(self) -> PromptTemplate: - """Get the prompt template as a string `PromptTemplate`.""" - return PromptTemplate(self._prompt_template) - - @property - def slippage(self) -> float: - """Get the slippage.""" - return self._slippage - - @slippage.setter - def slippage(self, slippage: float) -> None: - """Set the slippage.""" - if slippage < 0 or slippage > 1: - raise ValueError( - f"The configured slippage {slippage!r} is not in the range [0, 1]." - ) - self._slippage = slippage - - def get_store_path(self, kwargs: Dict) -> Path: - """Get the path of the store.""" - path = self._ensure("store_path", kwargs, str) - # check if path exists, and we can write to it - if ( - not os.path.isdir(path) - or not os.access(path, os.W_OK) - or not os.access(path, os.R_OK) - ): - raise ValueError( - f"Policy store path {path!r} is not a directory or is not writable." - ) - return Path(path) - - -class BenchmarkingMode(Model, TypeCheckMixin): - """Configuration for the benchmarking mode.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the `BenchmarkingMode` object.""" - self.enabled: bool = self._ensure("enabled", kwargs, bool) - self.native_balance: int = self._ensure("native_balance", kwargs, int) - self.collateral_balance: int = self._ensure("collateral_balance", kwargs, int) - self.mech_cost: int = self._ensure("mech_cost", kwargs, int) - self.pool_fee: int = self._ensure("pool_fee", kwargs, int) - self.sep: str = self._ensure("sep", kwargs, str) - self.dataset_filename: Path = Path( - self._ensure("dataset_filename", kwargs, str) - ) - self.question_field: str = self._ensure("question_field", kwargs, str) - self.question_id_field: str = self._ensure("question_id_field", kwargs, str) - self.answer_field: str = self._ensure("answer_field", kwargs, str) - self.p_yes_field_part: str = self._ensure("p_yes_field_part", kwargs, str) - self.p_no_field_part: str = self._ensure("p_no_field_part", kwargs, str) - self.confidence_field_part: str = self._ensure( - "confidence_field_part", kwargs, str - ) - self.info_utility_field_part: str = self._ensure( - "info_utility_field_part", kwargs, str - ) - # this is the mode for the p and confidence parts - # if the flag is `True`, then the field parts are used as prefixes, otherwise as suffixes - self.part_prefix_mode: bool = self._ensure("part_prefix_mode", kwargs, bool) - self.bet_amount_field: str = self._ensure("bet_amount_field", kwargs, str) - self.results_filename: Path = Path( - self._ensure("results_filename", kwargs, str) - ) - self.randomness: str = self._ensure("randomness", kwargs, str) - self.nr_mech_calls: int = self._ensure("nr_mech_calls", kwargs, int) - super().__init__(*args, **kwargs) - - -class AccuracyInfoFields(Model, TypeCheckMixin): - """Configuration which holds the accuracy information file's fieldnames.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the `AccuracyInfoFields` object.""" - self.tool: str = self._ensure("tool", kwargs, str) - self.requests: str = self._ensure("requests", kwargs, str) - self.accuracy: str = self._ensure("accuracy", kwargs, str) - self.sep: str = self._ensure("sep", kwargs, str) - self.max: str = self._ensure("max", kwargs, str) - self.datetime_format: str = self._ensure("datetime_format", kwargs, str) - super().__init__(*args, **kwargs) - - -class AgentToolsSpecs(ApiSpecs): - """A model that wraps ApiSpecs for the Mech agent's tools specifications.""" - - -@dataclass -class MultisendBatch: - """A structure representing a single transaction of a multisend.""" - - to: str - data: HexBytes - value: int = 0 - operation: MultiSendOperation = MultiSendOperation.CALL - - -@dataclass -class BenchmarkingMockData: - """The mock data for a `BenchmarkingMode`.""" - - id: str - question: str - answer: str - p_yes: float - - @property - def is_winning(self) -> bool: - """Whether the current position is winning.""" - return ( - self.answer == YES - and self.p_yes > 0.5 - or self.answer == NO - and self.p_yes < 0.5 - ) - - -class TradesSubgraph(Subgraph): - """A model that wraps ApiSpecs for the OMEN's subgraph specifications for trades.""" - - -class ConditionalTokensSubgraph(Subgraph): - """A model that wraps ApiSpecs for the Conditional Tokens' subgraph specifications.""" - - -class RealitioSubgraph(Subgraph): - """A model that wraps ApiSpecs for the Realitio's subgraph specifications.""" diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/payloads.py b/trader_old/vendor/valory/skills/decision_maker_abci/payloads.py deleted file mode 100644 index b15c02b01..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/payloads.py +++ /dev/null @@ -1,129 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the transaction payloads for the decision maker.""" - -from dataclasses import dataclass -from typing import Optional - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload - - -@dataclass(frozen=True) -class DecisionReceivePayload(UpdateBetsPayload): - """Represents a transaction payload for the decision-making.""" - - is_profitable: Optional[bool] - vote: Optional[int] - confidence: Optional[float] - bet_amount: Optional[int] - next_mock_data_row: Optional[int] - policy: Optional[str] - decision_received_timestamp: Optional[int] - - -@dataclass(frozen=True) -class SamplingPayload(UpdateBetsPayload): - """Represents a transaction payload for the sampling of a bet.""" - - index: Optional[int] - benchmarking_finished: Optional[bool] - day_increased: Optional[bool] - - -@dataclass(frozen=True) -class MultisigTxPayload(BaseTxPayload): - """Represents a transaction payload for preparing an on-chain transaction to be sent via the agents' multisig.""" - - tx_submitter: Optional[str] = None - tx_hash: Optional[str] = None - mocking_mode: Optional[bool] = None - - -@dataclass(frozen=True) -class RedeemPayload(MultisigTxPayload): - """Represents a transaction payload for preparing an on-chain transaction for redeeming.""" - - mech_tools: str = "[]" - policy: Optional[str] = None - utilized_tools: Optional[str] = None - redeemed_condition_ids: Optional[str] = None - payout_so_far: Optional[int] = None - - -@dataclass(frozen=True) -class DecisionRequestPayload(BaseTxPayload): - """Represents a transaction payload for preparing mech requests.""" - - mech_requests: Optional[str] = None - mocking_mode: Optional[bool] = None - - -@dataclass(frozen=True) -class SubscriptionPayload(MultisigTxPayload): - """Represents a transaction payload for subscribing.""" - - agreement_id: str = "" - wallet_balance: Optional[int] = None - - -@dataclass(frozen=True) -class ClaimPayload(BaseTxPayload): - """Represents a transaction payload for claiming a subscription.""" - - vote: bool - - -@dataclass(frozen=True) -class VotingPayload(BaseTxPayload): - """Represents a transaction payload for voting.""" - - vote: bool - - -@dataclass(frozen=True) -class BlacklistingPayload(UpdateBetsPayload): - """Represents a transaction payload for blacklisting.""" - - policy: str - - -@dataclass(frozen=True) -class ToolSelectionPayload(BaseTxPayload): - """Represents a transaction payload for selecting a mech tool.""" - - mech_tools: Optional[str] - policy: Optional[str] - utilized_tools: Optional[str] - selected_tool: Optional[str] - - -@dataclass(frozen=True) -class BetPlacementPayload(MultisigTxPayload): - """Represents a transaction payload for placing a bet.""" - - wallet_balance: Optional[int] = None - - -@dataclass(frozen=True) -class HandleFailedTxPayload(VotingPayload): - """Represents a transaction payload for placing a bet.""" - - tx_submitter: str diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/policy.py b/trader_old/vendor/valory/skills/decision_maker_abci/policy.py deleted file mode 100644 index 6d574892b..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/policy.py +++ /dev/null @@ -1,290 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 an Epsilon Greedy Policy implementation.""" - -import json -import random -from dataclasses import asdict, dataclass, field, is_dataclass -from time import time -from typing import Any, Dict, List, Optional, Tuple, Union - -from packages.valory.skills.decision_maker_abci.utils.scaling import scale_value - - -RandomnessType = Union[int, float, str, bytes, bytearray, None] - -VOLUME_FACTOR_REGULARIZATION = 0.5 -UNSCALED_WEIGHTED_ACCURACY_INTERVAL = (-0.5, 100.5) -SCALED_WEIGHTED_ACCURACY_INTERVAL = (0, 1) - - -class DataclassEncoder(json.JSONEncoder): - """A custom JSON encoder for dataclasses.""" - - def default(self, o: Any) -> Any: - """The default JSON encoder.""" - if is_dataclass(o): - return asdict(o) - return super().default(o) - - -def argmax(li: Union[Tuple, List]) -> int: - """Get the index of the max value within the provided tuple or list.""" - return li.index((max(li))) - - -@dataclass -class AccuracyInfo: - """The accuracy information of a tool.""" - - # the number of requests that this tool has responded to - requests: int = 0 - # the number of pending evaluations, i.e., responses for which we have not redeemed yet - pending: int = 0 - # the accuracy of the tool - accuracy: float = 0.0 - - -@dataclass -class ConsecutiveFailures: - """The consecutive failures of a tool.""" - - n_failures: int = 0 - timestamp: int = 0 - - def increase(self, timestamp: int) -> None: - """Increase the number of consecutive failures.""" - self.n_failures += 1 - self.timestamp = timestamp - - def reset(self, timestamp: int) -> None: - """Reset the number of consecutive failures.""" - self.n_failures = 0 - self.timestamp = timestamp - - def update_status(self, timestamp: int, has_failed: bool) -> None: - """Update the number of consecutive failures.""" - if has_failed: - self.increase(timestamp) - else: - self.reset(timestamp) - - -class EGreedyPolicyDecoder(json.JSONDecoder): - """A custom JSON decoder for the e greedy policy.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the custom JSON decoder.""" - super().__init__(object_hook=self.hook, *args, **kwargs) - - @staticmethod - def hook( - data: Dict[str, Any], - ) -> Union[ - "EGreedyPolicy", - AccuracyInfo, - ConsecutiveFailures, - Dict[str, "EGreedyPolicy"], - Dict[str, ConsecutiveFailures], - ]: - """Perform the custom decoding.""" - for cls_ in (AccuracyInfo, ConsecutiveFailures, EGreedyPolicy): - cls_attributes = cls_.__annotations__.keys() # pylint: disable=no-member - if sorted(cls_attributes) == sorted(data.keys()): - # if the attributes match the ones of the current class, use it to perform the deserialization - return cls_(**data) - - return data - - -@dataclass -class EGreedyPolicy: - """An e-Greedy policy for the tool selection based on tool accuracy.""" - - eps: float - consecutive_failures_threshold: int - quarantine_duration: int - accuracy_store: Dict[str, AccuracyInfo] = field(default_factory=dict) - weighted_accuracy: Dict[str, float] = field(default_factory=dict) - consecutive_failures: Dict[str, ConsecutiveFailures] = field(default_factory=dict) - updated_ts: int = 0 - - def __post_init__(self) -> None: - """Perform post-initialization checks.""" - if not (0 <= self.eps <= 1): - error = f"Cannot initialize the policy with an epsilon value of {self.eps}. Must be between 0 and 1." - raise ValueError(error) - self.update_weighted_accuracy() - - @classmethod - def deserialize(cls, policy: str) -> "EGreedyPolicy": - """Deserialize a string to an `EGreedyPolicy` object.""" - return json.loads(policy, cls=EGreedyPolicyDecoder) - - @property - def tools(self) -> List[str]: - """Get the policy's tools.""" - return list(self.accuracy_store.keys()) - - @property - def n_tools(self) -> int: - """Get the number of the policy's tools.""" - return len(self.accuracy_store) - - @property - def n_requests(self) -> int: - """Get the total number of requests.""" - return sum( - acc_info.requests + acc_info.pending - for acc_info in self.accuracy_store.values() - ) - - @property - def has_updated(self) -> bool: - """Whether the policy has ever been updated since its genesis or not.""" - return self.n_requests > 0 - - @property - def random_tool(self) -> str: - """Get the name of a tool randomly.""" - return random.choice(list(self.accuracy_store.keys())) # nosec - - def is_quarantined(self, tool: str) -> bool: - """Check if the policy is valid.""" - if tool not in self.consecutive_failures: - return False - - failures = self.consecutive_failures[tool] - return ( - failures.n_failures > self.consecutive_failures_threshold - and failures.timestamp + self.quarantine_duration > int(time()) - ) - - @property - def valid_tools(self) -> List[str]: - """Get the policy's tools.""" - return list( - tool for tool in self.accuracy_store.keys() if not self.is_quarantined(tool) - ) - - @property - def valid_weighted_accuracy(self) -> Dict[str, float]: - """Get the valid weighted accuracy.""" - if not self.weighted_accuracy: - # Log or raise an error if no tools are present - raise ValueError( - "Weighted accuracy is empty. Ensure tools are initialized." - ) - return { - tool: acc - for tool, acc in self.weighted_accuracy.items() - if not self.is_quarantined(tool) - } - - @property - def best_tool(self) -> Optional[str]: - """Get the best non-quarantined tool, or fallback gracefully.""" - # Get valid weighted accuracies - valid_weighted_accuracy = self.valid_weighted_accuracy - if valid_weighted_accuracy: - valid_tools, valid_weighted_accuracies = zip( - *valid_weighted_accuracy.items() - ) - else: - # Fallback to all tools if no valid tools are available - valid_tools, valid_weighted_accuracies = zip( - *self.weighted_accuracy.items() - ) - - # Determine the best tool based on weighted accuracies - best_index = argmax(valid_weighted_accuracies) - return valid_tools[best_index] - - def update_weighted_accuracy(self) -> None: - """Update the weighted accuracy for each tool.""" - self.weighted_accuracy = { - tool: scale_value( - ( - acc_info.accuracy - + ((acc_info.requests - acc_info.pending) / self.n_requests) - * VOLUME_FACTOR_REGULARIZATION - ), - UNSCALED_WEIGHTED_ACCURACY_INTERVAL, - SCALED_WEIGHTED_ACCURACY_INTERVAL, - ) - for tool, acc_info in self.accuracy_store.items() - } - - def select_tool(self, randomness: RandomnessType = None) -> Optional[str]: - """Select a Mech tool and return its index.""" - if self.n_tools == 0: - return None - - if randomness is not None: - random.seed(randomness) - - if not self.has_updated or random.random() < self.eps: # nosec - return self.random_tool - - return self.best_tool - - def tool_used(self, tool: str) -> None: - """Increase the times used for the given tool.""" - self.accuracy_store[tool].pending += 1 - self.update_weighted_accuracy() - - def tool_responded(self, tool: str, timestamp: int, failed: bool = True) -> None: - """Update the policy based on the given tool's response.""" - if tool not in self.consecutive_failures: - self.consecutive_failures[tool] = ConsecutiveFailures() - self.consecutive_failures[tool].update_status(timestamp, failed) - - def update_accuracy_store(self, tool: str, winning: bool) -> None: - """Update the accuracy store for the given tool.""" - acc_info = self.accuracy_store[tool] - total_correct_answers = acc_info.accuracy * acc_info.requests - if winning: - total_correct_answers += 1 - - acc_info.requests += 1 - acc_info.pending -= 1 - acc_info.accuracy = total_correct_answers / acc_info.requests - self.update_weighted_accuracy() - - def serialize(self) -> str: - """Return the accuracy policy serialized.""" - return json.dumps(self, cls=DataclassEncoder, sort_keys=True) - - def stats_report(self) -> str: - """Report policy statistics.""" - if not self.has_updated: - return "No policy statistics available." - - report = "Policy statistics so far (only for resolved markets):\n" - stats = ( - f"\t{tool} tool:\n" - f"\t\tQuarantined: {self.is_quarantined(tool)}\n" - f"\t\tTimes used: {self.accuracy_store[tool].requests}\n" - f"\t\tWeighted Accuracy: {self.weighted_accuracy[tool]}" - for tool in self.tools - ) - report += "\n".join(stats) - report += f"\nBest non-quarantined tool so far is {self.best_tool!r}." - return report diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/redeem_info.py b/trader_old/vendor/valory/skills/decision_maker_abci/redeem_info.py deleted file mode 100644 index 175103c75..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/redeem_info.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - - -"""Structures for the redeeming.""" - -import dataclasses -from typing import Any, List - -from hexbytes import HexBytes - - -INVALID_MARKET_ANSWER = ( - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -) - - -@dataclasses.dataclass(frozen=True) -class Condition: - """A structure for an OMEN condition.""" - - id: HexBytes - outcomeSlotCount: int - - def __post_init__(self) -> None: - """Post initialization to adjust the values.""" - super().__setattr__("outcomeSlotCount", int(self.outcomeSlotCount)) - - if isinstance(self.id, str): - super().__setattr__("id", HexBytes(self.id)) - - @property - def index_sets(self) -> List[int]: - """Get the index sets.""" - return [i + 1 for i in range(self.outcomeSlotCount)] - - -@dataclasses.dataclass(frozen=True) -class Question: - """A structure for an OMEN question.""" - - id: bytes - data: str - - def __post_init__(self) -> None: - """Post initialization to adjust the values.""" - if isinstance(self.id, str): - super().__setattr__("id", bytes.fromhex(self.id[2:])) - - -@dataclasses.dataclass(frozen=True) -class FPMM: - """A structure for an OMEN FPMM.""" - - answerFinalizedTimestamp: int - collateralToken: str - condition: Condition - creator: str - creationTimestamp: int - currentAnswer: str - question: Question - templateId: int - - def __post_init__(self) -> None: - """Post initialization to adjust the values.""" - super().__setattr__( - "answerFinalizedTimestamp", int(self.answerFinalizedTimestamp) - ) - super().__setattr__("templateId", int(self.templateId)) - super().__setattr__("creationTimestamp", int(self.creationTimestamp)) - - if isinstance(self.condition, dict): - super().__setattr__("condition", Condition(**self.condition)) - - if isinstance(self.question, dict): - super().__setattr__("question", Question(**self.question)) - - @property - def current_answer_index(self) -> int: - """Get the index of the market's current answer.""" - return int(self.currentAnswer, 16) - - -@dataclasses.dataclass(frozen=True) -class Trade: - """A structure for an OMEN trade.""" - - fpmm: FPMM - outcomeIndex: int - outcomeTokenMarginalPrice: float - outcomeTokensTraded: int - transactionHash: str - - def __post_init__(self) -> None: - """Post initialization to adjust the values.""" - super().__setattr__("outcomeIndex", int(self.outcomeIndex)) - super().__setattr__( - "outcomeTokenMarginalPrice", float(self.outcomeTokenMarginalPrice) - ) - super().__setattr__("outcomeTokensTraded", int(self.outcomeTokensTraded)) - - if isinstance(self.fpmm, dict): - super().__setattr__("fpmm", FPMM(**self.fpmm)) - - def __eq__(self, other: Any) -> bool: - """Check equality.""" - return isinstance(other, Trade) and ( - self.fpmm.condition.id == other.fpmm.condition.id - or self.fpmm.question.id == other.fpmm.question.id - ) - - def __hash__(self) -> int: - """Custom hashing operator.""" - return hash(self.fpmm.condition.id) + hash(self.fpmm.question.id) - - @property - def is_winning(self) -> bool: - """Return whether the current position is winning.""" - our_answer = self.outcomeIndex - correct_answer = self.fpmm.current_answer_index - return our_answer == correct_answer or correct_answer == INVALID_MARKET_ANSWER - - @property - def claimable_amount(self) -> int: - """Get the claimable amount of the current market.""" - amount = self.outcomeTokensTraded - if self.is_winning: - return amount - return -amount diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/rounds.py b/trader_old/vendor/valory/skills/decision_maker_abci/rounds.py deleted file mode 100644 index 2a942e2e4..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/rounds.py +++ /dev/null @@ -1,381 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the rounds for the decision-making.""" - -from typing import Dict, Set - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AppState, - get_name, -) -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) -from packages.valory.skills.decision_maker_abci.states.blacklisting import ( - BlacklistingRound, -) -from packages.valory.skills.decision_maker_abci.states.check_benchmarking import ( - CheckBenchmarkingModeRound, -) -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) -from packages.valory.skills.decision_maker_abci.states.decision_receive import ( - DecisionReceiveRound, -) -from packages.valory.skills.decision_maker_abci.states.decision_request import ( - DecisionRequestRound, -) -from packages.valory.skills.decision_maker_abci.states.final_states import ( - BenchmarkingDoneRound, - BenchmarkingModeDisabledRound, - FinishedDecisionMakerRound, - FinishedDecisionRequestRound, - FinishedSubscriptionRound, - FinishedWithoutDecisionRound, - FinishedWithoutRedeemingRound, - ImpossibleRound, - RefillRequiredRound, -) -from packages.valory.skills.decision_maker_abci.states.handle_failed_tx import ( - HandleFailedTxRound, -) -from packages.valory.skills.decision_maker_abci.states.order_subscription import ( - SubscriptionRound, -) -from packages.valory.skills.decision_maker_abci.states.randomness import ( - BenchmarkingRandomnessRound, - RandomnessRound, -) -from packages.valory.skills.decision_maker_abci.states.redeem import RedeemRound -from packages.valory.skills.decision_maker_abci.states.sampling import SamplingRound -from packages.valory.skills.decision_maker_abci.states.tool_selection import ( - ToolSelectionRound, -) -from packages.valory.skills.market_manager_abci.rounds import ( - Event as MarketManagerEvent, -) - - -class DecisionMakerAbciApp(AbciApp[Event]): - """DecisionMakerAbciApp - - Initial round: CheckBenchmarkingModeRound - - Initial states: {CheckBenchmarkingModeRound, ClaimRound, DecisionReceiveRound, HandleFailedTxRound, RandomnessRound, RedeemRound} - - Transition states: - 0. CheckBenchmarkingModeRound - - benchmarking enabled: 1. - - benchmarking disabled: 14. - - no majority: 0. - - round timeout: 0. - - done: 20. - - subscription error: 20. - 1. BenchmarkingRandomnessRound - - done: 3. - - round timeout: 1. - - no majority: 1. - 2. RandomnessRound - - done: 3. - - round timeout: 2. - - no majority: 2. - 3. SamplingRound - - done: 4. - - none: 16. - - no majority: 3. - - round timeout: 3. - - new simulated resample: 3. - - benchmarking enabled: 6. - - benchmarking finished: 21. - - fetch error: 20. - 4. SubscriptionRound - - done: 18. - - mock tx: 6. - - no subscription: 6. - - none: 4. - - subscription error: 4. - - no majority: 4. - - round timeout: 4. - 5. ClaimRound - - done: 6. - - subscription error: 5. - - no majority: 5. - - round timeout: 5. - 6. ToolSelectionRound - - done: 7. - - none: 6. - - no majority: 6. - - round timeout: 6. - 7. DecisionRequestRound - - done: 15. - - mock mech request: 8. - - slots unsupported error: 9. - - no majority: 7. - - round timeout: 7. - 8. DecisionReceiveRound - - done: 10. - - mech response error: 9. - - no majority: 8. - - tie: 9. - - unprofitable: 9. - - round timeout: 8. - 9. BlacklistingRound - - done: 16. - - mock tx: 16. - - none: 20. - - no majority: 9. - - round timeout: 9. - - fetch error: 20. - 10. BetPlacementRound - - done: 13. - - mock tx: 11. - - insufficient balance: 19. - - no majority: 10. - - round timeout: 10. - - none: 20. - 11. RedeemRound - - done: 13. - - mock tx: 3. - - no redeeming: 17. - - no majority: 11. - - redeem round timeout: 17. - - none: 20. - 12. HandleFailedTxRound - - blacklist: 9. - - no op: 11. - - no majority: 12. - 13. FinishedDecisionMakerRound - 14. BenchmarkingModeDisabledRound - 15. FinishedDecisionRequestRound - 16. FinishedWithoutDecisionRound - 17. FinishedWithoutRedeemingRound - 18. FinishedSubscriptionRound - 19. RefillRequiredRound - 20. ImpossibleRound - 21. BenchmarkingDoneRound - - Final states: {BenchmarkingDoneRound, BenchmarkingModeDisabledRound, FinishedDecisionMakerRound, FinishedDecisionRequestRound, FinishedSubscriptionRound, FinishedWithoutDecisionRound, FinishedWithoutRedeemingRound, ImpossibleRound, RefillRequiredRound} - - Timeouts: - round timeout: 30.0 - redeem round timeout: 3600.0 - """ - - initial_round_cls: AppState = CheckBenchmarkingModeRound - initial_states: Set[AppState] = { - CheckBenchmarkingModeRound, - RandomnessRound, - HandleFailedTxRound, - DecisionReceiveRound, - RedeemRound, - ClaimRound, - } - transition_function: AbciAppTransitionFunction = { - CheckBenchmarkingModeRound: { - Event.BENCHMARKING_ENABLED: BenchmarkingRandomnessRound, - Event.BENCHMARKING_DISABLED: BenchmarkingModeDisabledRound, - Event.NO_MAJORITY: CheckBenchmarkingModeRound, - Event.ROUND_TIMEOUT: CheckBenchmarkingModeRound, - # added because of `autonomy analyse fsm-specs` - # falsely reporting them as missing from the transition - Event.DONE: ImpossibleRound, - Event.SUBSCRIPTION_ERROR: ImpossibleRound, - }, - BenchmarkingRandomnessRound: { - Event.DONE: SamplingRound, - Event.ROUND_TIMEOUT: BenchmarkingRandomnessRound, - Event.NO_MAJORITY: BenchmarkingRandomnessRound, - }, - RandomnessRound: { - Event.DONE: SamplingRound, - Event.ROUND_TIMEOUT: RandomnessRound, - Event.NO_MAJORITY: RandomnessRound, - }, - SamplingRound: { - Event.DONE: SubscriptionRound, - Event.NONE: FinishedWithoutDecisionRound, - Event.NO_MAJORITY: SamplingRound, - Event.ROUND_TIMEOUT: SamplingRound, - Event.NEW_SIMULATED_RESAMPLE: SamplingRound, - Event.BENCHMARKING_ENABLED: ToolSelectionRound, - Event.BENCHMARKING_FINISHED: BenchmarkingDoneRound, - # this is here because of `autonomy analyse fsm-specs` - # falsely reporting it as missing from the transition - MarketManagerEvent.FETCH_ERROR: ImpossibleRound, - }, - SubscriptionRound: { - Event.DONE: FinishedSubscriptionRound, - # skip placing the subscription tx and the claiming round - Event.MOCK_TX: ToolSelectionRound, - Event.NO_SUBSCRIPTION: ToolSelectionRound, - Event.NONE: SubscriptionRound, - Event.SUBSCRIPTION_ERROR: SubscriptionRound, - Event.NO_MAJORITY: SubscriptionRound, - Event.ROUND_TIMEOUT: SubscriptionRound, - }, - ClaimRound: { - Event.DONE: ToolSelectionRound, - Event.SUBSCRIPTION_ERROR: ClaimRound, - Event.NO_MAJORITY: ClaimRound, - Event.ROUND_TIMEOUT: ClaimRound, - }, - ToolSelectionRound: { - Event.DONE: DecisionRequestRound, - Event.NONE: ToolSelectionRound, - Event.NO_MAJORITY: ToolSelectionRound, - Event.ROUND_TIMEOUT: ToolSelectionRound, - }, - DecisionRequestRound: { - Event.DONE: FinishedDecisionRequestRound, - # skip the request to the mech - Event.MOCK_MECH_REQUEST: DecisionReceiveRound, - Event.SLOTS_UNSUPPORTED_ERROR: BlacklistingRound, - Event.NO_MAJORITY: DecisionRequestRound, - Event.ROUND_TIMEOUT: DecisionRequestRound, - }, - DecisionReceiveRound: { - Event.DONE: BetPlacementRound, - Event.MECH_RESPONSE_ERROR: BlacklistingRound, - Event.NO_MAJORITY: DecisionReceiveRound, - Event.TIE: BlacklistingRound, - Event.UNPROFITABLE: BlacklistingRound, - # loop on the same state until Mech deliver is received - Event.ROUND_TIMEOUT: DecisionReceiveRound, - }, - BlacklistingRound: { - Event.DONE: FinishedWithoutDecisionRound, - Event.MOCK_TX: FinishedWithoutDecisionRound, - # degenerate round on purpose, should never have reached here - Event.NONE: ImpossibleRound, - Event.NO_MAJORITY: BlacklistingRound, - Event.ROUND_TIMEOUT: BlacklistingRound, - # this is here because of `autonomy analyse fsm-specs` - # falsely reporting it as missing from the transition - MarketManagerEvent.FETCH_ERROR: ImpossibleRound, - }, - BetPlacementRound: { - Event.DONE: FinishedDecisionMakerRound, - # skip the bet placement tx - Event.MOCK_TX: RedeemRound, - # degenerate round on purpose, owner must refill the safe - Event.INSUFFICIENT_BALANCE: RefillRequiredRound, - Event.NO_MAJORITY: BetPlacementRound, - Event.ROUND_TIMEOUT: BetPlacementRound, - # this is here because of `autonomy analyse fsm-specs` - # falsely reporting it as missing from the transition - Event.NONE: ImpossibleRound, - }, - RedeemRound: { - Event.DONE: FinishedDecisionMakerRound, - Event.MOCK_TX: SamplingRound, - Event.NO_REDEEMING: FinishedWithoutRedeemingRound, - Event.NO_MAJORITY: RedeemRound, - # in case of a round timeout, there likely is something wrong with redeeming - # it could be the RPC, or some other issue. - # We don't want to be stuck trying to redeem. - Event.REDEEM_ROUND_TIMEOUT: FinishedWithoutRedeemingRound, - # this is here because of `autonomy analyse fsm-specs` falsely - # reporting it as missing from the transition - Event.NONE: ImpossibleRound, - }, - HandleFailedTxRound: { - Event.BLACKLIST: BlacklistingRound, - Event.NO_OP: RedeemRound, - Event.NO_MAJORITY: HandleFailedTxRound, - }, - FinishedDecisionMakerRound: {}, - BenchmarkingModeDisabledRound: {}, - FinishedDecisionRequestRound: {}, - FinishedWithoutDecisionRound: {}, - FinishedWithoutRedeemingRound: {}, - FinishedSubscriptionRound: {}, - RefillRequiredRound: {}, - ImpossibleRound: {}, - BenchmarkingDoneRound: {}, - } - cross_period_persisted_keys = frozenset( - { - get_name(SynchronizedData.available_mech_tools), - get_name(SynchronizedData.policy), - get_name(SynchronizedData.utilized_tools), - get_name(SynchronizedData.redeemed_condition_ids), - get_name(SynchronizedData.payout_so_far), - get_name(SynchronizedData.mech_price), - get_name(SynchronizedData.mocking_mode), - get_name(SynchronizedData.next_mock_data_row), - get_name(SynchronizedData.agreement_id), - } - ) - final_states: Set[AppState] = { - FinishedDecisionMakerRound, - BenchmarkingModeDisabledRound, - FinishedDecisionRequestRound, - FinishedSubscriptionRound, - FinishedWithoutDecisionRound, - FinishedWithoutRedeemingRound, - RefillRequiredRound, - ImpossibleRound, - BenchmarkingDoneRound, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - Event.REDEEM_ROUND_TIMEOUT: 3600.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = { - RedeemRound: set(), - ClaimRound: set(), - DecisionReceiveRound: { - get_name(SynchronizedData.final_tx_hash), - }, - HandleFailedTxRound: { - get_name(SynchronizedData.bets_hash), - }, - RandomnessRound: set(), - CheckBenchmarkingModeRound: set(), - } - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedDecisionMakerRound: { - get_name(SynchronizedData.sampled_bet_index), - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - }, - BenchmarkingModeDisabledRound: set(), - FinishedDecisionRequestRound: set(), - FinishedSubscriptionRound: { - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.agreement_id), - }, - FinishedWithoutDecisionRound: {get_name(SynchronizedData.sampled_bet_index)}, - FinishedWithoutRedeemingRound: set(), - RefillRequiredRound: set(), - ImpossibleRound: set(), - BenchmarkingDoneRound: { - get_name(SynchronizedData.mocking_mode), - get_name(SynchronizedData.next_mock_data_row), - }, - } diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/skill.yaml b/trader_old/vendor/valory/skills/decision_maker_abci/skill.yaml deleted file mode 100644 index a5dfacc49..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/skill.yaml +++ /dev/null @@ -1,447 +0,0 @@ -name: decision_maker_abci -author: valory -version: 0.1.0 -type: skill -description: This skill is responsible for the decision making and placing the bets. - It samples a market based on its liquidity, it sends a request to a mech to decide - what to vote for, it receives the response from the mech, it decides whether voting - is profitable or not, and ultimately, it either bets or blacklists the market. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeia367zzdwndvlhw27rvnwodytjo3ms7gbc3q7mhrrjqjgfasnk47i - __init__.py: bafybeih563ujnigeci2ldzh7hakbau6a222vsed7leg3b7lq32vcn3nm4a - behaviours/__init__.py: bafybeih6ddz2ocvm6x6ytvlbcz6oi4snb5ee5xh5h65nq4w2qf7fd7zfky - behaviours/base.py: bafybeigakuyrn6hol7s2xyowjushvedihnlkdiv2l7lnklzfjanysuikim - behaviours/bet_placement.py: bafybeig7rdvdk2matibxsllrcxcmsazxaznwrmf5q7va4ads7yzs5xs4pa - behaviours/blacklisting.py: bafybeieuqoup2vrmrtvjfqnr5mzrvkegc7afb2oeujzq2itsbhcsham2se - behaviours/check_benchmarking.py: bafybeiao2lyj7apezkqrpgsyzb3dwvrdgsrgtprf6iuhsmlsufvxfl5bci - behaviours/claim_subscription.py: bafybeigbqkhc6mb73rbwaks32tfiqx6u2xza43uiy6rvbtrnqd6m4fru3e - behaviours/decision_receive.py: bafybeia7zekqamsbjptzsz2zzhxoaeuzf7ytg3hiat7rpx34dyg3l2sa5e - behaviours/decision_request.py: bafybeia22omb7tvocyfe3z2ucn5au5mcas7dg37ha42u7znefzrewjpk7y - behaviours/handle_failed_tx.py: bafybeiashwlfp6ty3g6ukgmliaghwu6yiunbqpjmyrzheokw3pbcr2ckaq - behaviours/order_subscription.py: bafybeib3maqohhx35wzryy4otdcjp5thkr4sbp27ksvwidy3pwm444itra - behaviours/randomness.py: bafybeiaoj3awyyg2onhpsdsn3dyczs23gr4smuzqcbw3e5ocljwxswjkce - behaviours/reedem.py: bafybeidjmhh6c6shbg25d7exmc4nnp4heqbqselwuxj7rp2ss665lrytxe - behaviours/round_behaviour.py: bafybeih63hpia2bwwzu563hxs5yd3t5ycvxvkfnhvxbzghbyy3mw3xjl3i - behaviours/sampling.py: bafybeiet37e4o4s5kdf4u4denls7iaqm6b2a2mqa5eu576waiwmuwozhmi - behaviours/sell_outcome_token.py: bafybeicjpqnukexia457s73yp34yvgefpkgaikainmjf3sxgdk5c4kfqba - behaviours/storage_manager.py: bafybeic6wca37fkwonbsrwme55xnklfbqtheknroudayzfxdge4pxdbm7y - behaviours/tool_selection.py: bafybeienlxcgjs3ogyofli3d7q3p5rst3mcxxcnwqf7qolqjeefjtixeke - dialogues.py: bafybeigpwuzku3we7axmxeamg7vn656maww6emuztau5pg3ebsoquyfdqm - fsm_specification.yaml: bafybeidlnqnd7dwg7r2vhsgm2balrqhxm36qdflkmr7csze2kdeu3a7sbu - handlers.py: bafybeibf42562x3d5i66yf5p3vi6a2oolhwwxr32pjqtuxz5w4gmg3r4oa - io_/__init__.py: bafybeifxgmmwjqzezzn3e6keh2bfo4cyo7y5dq2ept3stfmgglbrzfl5rq - io_/loader.py: bafybeih3sdsx5dhe4kzhtoafexjgkutsujwqy3zcdrlrkhtdks45bc7exa - models.py: bafybeibsozgsarysvpt3dqqzl2qk7foxjcleg336lpxdnrqx5xmdqxafua - payloads.py: bafybeieygushjlrzwzpnhagjgpbs3goot3pnfheh6yawuwctrk3uoeesfm - policy.py: bafybeidofgwvk6sudz75tvuduskuphtn3amtib2irzw5hr3qcfn5pdwuc4 - redeem_info.py: bafybeifiiix4gihfo4avraxt34sfw35v6dqq45do2drrssei2shbps63mm - rounds.py: bafybeidjve7efycfkkbignqky4x6awvrobn4w32grxiubxxiiparr7xd2i - states/__init__.py: bafybeid23llnyp6j257dluxmrnztugo5llsrog7kua53hllyktz4dqhqoy - states/base.py: bafybeiducubeh7oanfufy5xe2dx5njjeyqr3akw2cjjg7wl445slafqw6u - states/bet_placement.py: bafybeih5eopyxubczys5u5t3bdxbxpc7mmfdyqrpqsbm2uha5jc2phza4i - states/blacklisting.py: bafybeiapelgjhbjjn4uq4z5gspyirqzwzgccg5anktrp5kxdwamfnfw5mi - states/check_benchmarking.py: bafybeifvto757zbfzy7mpehblyjd7zqboarxesjfiobtnbxew4nkltfkim - states/claim_subscription.py: bafybeidlubctpk5djsredvvwdhubs34rztud3lw7pwp5kj6ggzah6dvyly - states/decision_receive.py: bafybeidxz4mfzjrjbhghh47erwyo2bucvjenpwcpckpc7ywfra7iyaw2mu - states/decision_request.py: bafybeiarv3r5j7cfvxmudki2llbdl2pvf24p5mvsva6bdgrylnwdyag5xy - states/final_states.py: bafybeicjrrojo3gmfaxzicwloyorlnqgzl6a2avevo4nvhoh424zwzmbti - states/handle_failed_tx.py: bafybeiha5wkl4u4jlj7txpmhuzfnibnu3ix5zw4vmufjunoyuq6s6ubhnu - states/order_subscription.py: bafybeihl3pwrbccaitiukbigygd5u3weyih34pvzql3c6n5k7gjj47f2be - states/randomness.py: bafybeiceoo4nx3t4dofpwczw3v5mclramwmzpwjs6hv7l56arodrjx4l5u - states/redeem.py: bafybeica6cn4xg7shea2wjhbqnddgxe5zao2hkmceltze7qknxdhtsoaxe - states/sampling.py: bafybeif2yuwl5swelp7oh5nfuupdf3vg2ijjzapk2xqht7e6i6ggcsl2zy - states/sell_outcome_token.py: bafybeievk4w3zbi4buicml7nivhpepsoed6dsayauqhyk2bkkyqxdil2xm - states/tool_selection.py: bafybeiak5ihuie4nxh3sguiea6pcdgyxr4k4xyzvq6o2uj5xpf7urocawy - tests/__init__.py: bafybeiakpi3k3kc7wrjj7hrluvjcj36lu2gezpmrctwiz5yg2fe7ggnf3i - tests/behaviours/__init__.py: bafybeic7icz7lfhfepdkqkase7y7zn3a6pwdw6fx4ah2hajmgejawpolc4 - tests/behaviours/data/.gitkeep: bafybeiekl43sjsyqfgl6y27ve5ydo4svcngrptgtffblokmspfezroxvvi - tests/behaviours/dummy_strategy/__init__.py: bafybeiep5w5yckjzy724v63qd5cmzfn3uxytmnizynomxggfobbysfcttq - tests/behaviours/dummy_strategy/dummy_strategy.py: bafybeig5e3xfr7gxsakfj4stbxqcwdiljl7klvgahkuwe3obzxgkg3qt2e - tests/behaviours/test_base.py: bafybeif6pglmr7pvojylatfzaxtlk65igx6a2omyrbxfihnnft6o7p75p4 - tests/conftest.py: bafybeidy5hw56kw5mxudnfbhvogofn6k4rqb4ux2bd45baedrrhmgyrude - tests/states/test_base.py: bafybeieqy7wz5677jathwnolsgrt7zdifauammly3aeoq6dk4hdsqo5fte - tests/states/test_bet_placement.py: bafybeibvc37n2cluep4tasvgmvwxwne2deais6ptirducpogk67v4gj4ga - tests/states/test_blacklising.py: bafybeihm2ex6l7fhorgi3mjj2epztu2r7bqbg56unpgpzfzymghshchqzy - tests/states/test_check_benchmarking.py: bafybeiaauepn46l5z5kx2ifzsqcuravg3zvddecuhdgp4eaeous6vaqyoq - tests/states/test_claim_subscription.py: bafybeiclkxjhceb3ehgmg6klt4uywew5drk5b3w6no7mwxetpubxqrejfy - tests/states/test_decision_receive.py: bafybeibkxalkfxuyokb6y5hkyu4pdlg4yfusbpgtkfr66cprygu7cgyd2y - tests/states/test_decision_request.py: bafybeigqbakm2olkwvcngertjplhnmu6on6tp6hxn7lxygi2gf5a5eurbe - tests/states/test_final_states.py: bafybeiftfd3ovaqpfe7t5ry7maiziavk74wl66d6zo6ikhgodznormd2nm - tests/states/test_handle_failed_tx.py: bafybeiebqgfhncmdexgq7khgkmcsym35547x3j6tr3mmybuyhocv6h5zpq - tests/states/test_order_subscription.py: bafybeidx2tzivsxhpr5xx5e5h2xmpjyewfogt2mujv4sq3hbaeksmcbvhy - tests/states/test_randomness.py: bafybeib3eqjv6mhlprzda7d4viddn5alrfqteq6juyg3ccejseoywcsbey - tests/states/test_redeem.py: bafybeiezdnfrxukb2xpwffrr357g2anmdkwy7wo3nphvlggipq5xrdzr7a - tests/states/test_sampling.py: bafybeifvbzikke6wtex2p5j7fsnpdbj4qqxl5vh2lm2m2apgvuqdonoyzm - tests/states/test_tool_selection.py: bafybeib7js3dj7647t33o5ybfqftwytxktwrvhbri5yuyymg6znj6y7xxa - tests/test_dialogues.py: bafybeibulo64tgfrq4e5qbcqnmifrlehkqciwuavublints353zaj2mlpa - tests/test_handlers.py: bafybeihpkgtjjm3uegpup6zkznpoaxqpu6kmp3ujiggrzbe73p5fzlq7im - tests/test_payloads.py: bafybeiggbcppj4j54r23qvg423elsnd7dcxl3sfo534ek5sd3g65ua57nq - tests/test_rounds.py: bafybeigifftusd4ew42tyvyrr55o2uehhcik2gdq3atkpjwwlqdeskedty - utils/__init__.py: bafybeiazrfg3kwfdl5q45azwz6b6mobqxngxpf4hazmrnkhinpk4qhbbf4 - utils/nevermined.py: bafybeigallaqxhqopznhjhefr6bukh4ojkz5vdtqyzod5dksshrf24fjgi - utils/scaling.py: bafybeialr3z4zogp4k3l2bzcjfi4igvxzjexmlpgze2bai2ufc3plaow4y -fingerprint_ignore_patterns: [] -connections: -- valory/http_server:0.22.0:bafybeihpgu56ovmq4npazdbh6y6ru5i7zuv6wvdglpxavsckyih56smu7m -contracts: -- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge -- valory/market_maker:0.1.0:bafybeibevdc5trbi2qgt2tvwbsr2h5xvonfhcjwfmozftzvef575fdvbjq -- valory/erc20:0.1.0:bafybeid2p2jyvjjlcsqugnawksdzsca6ljghpqbp2kfi3cxuxoy2233dbi -- valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y -- valory/mech:0.1.0:bafybeiejfjfoxqggghcme43sx53q5gruefrws3k2jam2opkxl5uzffoarm -- valory/conditional_tokens:0.1.0:bafybeibnzmqmeph4cj5vfh3s622mo2o5627vjjwc6bptrhj4dk65mzgvhe -- valory/realitio:0.1.0:bafybeietgux6kkhdquspy35qera7gjwwqwrremmoeatjzwwokjb2lzsata -- valory/realitio_proxy:0.1.0:bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4 -- valory/agent_registry:0.1.0:bafybeiblc4i5xjxbywnfccwtv3unhaghrgqls7panfbuqbpstbc34h42xq -- valory/transfer_nft_condition:0.1.0:bafybeid6z2tf7nc4rhwggktxk5f62bowxdczykrxc3y76sbt2ttlw5hmtq -protocols: -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -- valory/ipfs:0.1.0:bafybeiftxi2qhreewgsc5wevogi7yc5g6hbcbo4uiuaibauhv3nhfcdtvm -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/market_manager_abci:0.1.0:bafybeibo63iiziwvqn6fmx36ungyg35z3chfv432kf6spuiszm6na22vdy -- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae -- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm -- valory/staking_abci:0.1.0:bafybeicupccurmrg7qesivonlyt3nryarsmk5qf5yh6auno64wn45bybvq -behaviours: - main: - args: {} - class_name: AgentDecisionMakerRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - multisend_batch_size: 1 - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 350.0 - service_id: decision_maker - service_registry_address: null - agent_registry_address: '0x0000000000000000000000000000000000000000' - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - sleep_time: 1 - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - tx_timeout: 10.0 - use_termination: false - mech_contract_address: '0x77af31de935740567cf4ff1986d04b2c964a786a' - mech_request_price: null - mech_chain_id: gnosis - mech_wrapped_native_token_address: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d' - mech_interaction_sleep_time: 10 - creator_per_subgraph: - omen_subgraph: [] - slot_count: 2 - opening_margin: 300 - languages: - - en_US - average_block_time: 5 - abt_error_mult: 5 - the_graph_error_message_key: message - the_graph_payment_required_error: payment required for subsequent requests for - this API key - sample_bets_closing_days: 10 - trading_strategy: strategy_name - use_fallback_strategy: true - bet_threshold: 100000000000000000 - ipfs_address: https://gateway.autonolas.tech/ipfs/ - tools_accuracy_hash: QmR8etyW3TPFadNtNrW54vfnFqmh8vBrMARWV76EmxCZyk - prompt_template: With the given question "@{question}" and the `yes` option - represented by `@{yes}` and the `no` option represented by `@{no}`, what are - the respective probabilities of `p_yes` and `p_no` occurring? - dust_threshold: 10000000000000 - conditional_tokens_address: '0xCeAfDD6bc0bEF976fdCd1112955828E00543c0Ce' - realitio_proxy_address: '0xAB16D643bA051C11962DA645f74632d3130c81E2' - realitio_address: '0x79e32aE03fb27B07C89c0c568F80287C01ca2E57' - redeem_round_timeout: 3600.0 - event_filtering_batch_size: 5000 - reduce_factor: 0.25 - max_filtering_retries: 6 - minimum_batch_size: 500 - redeeming_batch_size: 5 - store_path: data - slippage: 0.01 - policy_epsilon: 0.1 - use_subgraph_for_redeeming: true - use_nevermined: true - policy_store_update_offset: 259200 - mech_to_subscription_params: - - - base_url - - https://marketplace-api.gnosis.nevermined.app/api/v1/metadata/assets/ddo - - - did - - did:nv:0ea01d5de3b34e3792db825f2a5f5595c393c68b19fd5efdacd00fcc63a53483 - - - escrow_payment_condition_address - - '0x9dDC4F1Ea5b94C138A23b60EC48c0d01d172629a' - - - lock_payment_condition_address - - '0xDE85A368Ee6f374d236500d176814365370778dA' - - - transfer_nft_condition_address - - '0xbBa4A25262745a55f020D0a3E9a82c25bb6F4979' - - - token_address - - '0xa30DE8C6aC39B825192e5F1FADe0770332D279A8' - - - order_address - - '0xc7751eff5396a846e7bc83ac31d3cb7d37cb49e4' - - - nft_amount - - '100' - - - payment_token - - '0x0000000000000000000000000000000000000000' - - - order_address - - '0xc7751eff5396a846e7bc83ac31d3cb7d37cb49e4' - - - price - - '1000000000000000000' - irrelevant_tools: - - openai-text-davinci-002 - - openai-text-davinci-003 - - openai-gpt-3.5-turbo - - openai-gpt-4 - - stabilityai-stable-diffusion-v1-5 - - stabilityai-stable-diffusion-xl-beta-v2-2-2 - - stabilityai-stable-diffusion-512-v2-1 - - stabilityai-stable-diffusion-768-v2-1 - tool_punishment_multiplier: 1 - contract_timeout: 300.0 - file_hash_to_strategies_json: - - - hash - - - strategy_name - strategies_kwargs: - - - bet_kelly_fraction - - 1.0 - - - floor_balance - - 500000000000000000 - - - bet_amount_per_threshold - - 0.0: 0 - 0.1: 0 - 0.2: 0 - 0.3: 0 - 0.4: 0 - 0.5: 0 - 0.6: 0 - 0.7: 0 - 0.8: 0 - 0.9: 0 - 1.0: 0 - service_endpoint: trader.staging.autonolas.tech/ - rpc_sleep_time: 10 - safe_voting_range: 600 - rebet_chance: 0.6 - use_mech_marketplace: false - mech_marketplace_config: - mech_marketplace_address: '0x0000000000000000000000000000000000000000' - priority_mech_address: '0x0000000000000000000000000000000000000000' - priority_mech_staking_instance_address: '0x0000000000000000000000000000000000000000' - priority_mech_service_id: 0 - requester_staking_instance_address: '0x0000000000000000000000000000000000000000' - response_timeout: 300 - agent_balance_threshold: 10000000000000000 - expected_mech_response_time: 300 - mech_invalid_response: Invalid Response - mech_consecutive_failures_threshold: 2 - tool_quarantine_duration: 18000 - class_name: DecisionMakerParams - benchmarking_mode: - args: - enabled: false - native_balance: 10000000000000000000 - collateral_balance: 10000000000000000000 - mech_cost: 10000000000000000 - pool_fee: 20000000000000000 - outcome_token_amounts: - - 11000000000000000000 - - 9000000000000000000 - outcome_token_marginal_prices: - - 0.4 - - 0.6 - sep: ',' - dataset_filename: benchmark_data.csv - question_field: question - question_id_field: question_id - answer_field: answer - p_yes_field_part: p_yes_ - p_no_field_part: p_no_ - confidence_field_part: confidence_ - info_utility_field_part: info_utility_ - part_prefix_mode: true - bet_amount_field: collateral_amount - results_filename: benchmarking_results.csv - randomness: benchmarking_randomness - nr_mech_calls: 60 - class_name: BenchmarkingMode - acc_info_fields: - args: - tool: tool - requests: total_requests - accuracy: tool_accuracy - sep: ',' - max: max - datetime_format: '%Y-%m-%d %H:%M:%S' - class_name: AccuracyInfoFields - trades_subgraph: - args: - api_id: trades - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:fpmmTrades - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/protofire/omen-xdai - class_name: TradesSubgraph - conditional_tokens_subgraph: - args: - api_id: conditional_tokens - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:user:userPositions - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/gnosis/conditional-tokens-gc - class_name: ConditionalTokensSubgraph - realitio_subgraph: - args: - api_id: realitio - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:answers - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/realityeth/realityeth-gnosis - class_name: RealitioSubgraph - agent_tools: - args: - api_id: agent_tools - headers: - Content-Type: application/json - method: GET - parameters: {} - response_key: tools - response_type: list - retries: 5 - url: '' - class_name: AgentToolsSpecs - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: - hexbytes: - version: ==0.3.1 - hypothesis: - version: ==6.21.6 - py-multibase: - version: ==1.0.3 - py-multicodec: - version: ==0.2.1 - web3: - version: <7,>=6.0.0 - eth-abi: - version: ==4.0.0 - pyyaml: - version: <=6.0.1,>=3.10 -is_abstract: true diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/__init__.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/__init__.py deleted file mode 100644 index bddac5611..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 package contains the rounds for the 'decision_maker_abci' skill.""" diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/base.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/base.py deleted file mode 100644 index 3acc844a7..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/base.py +++ /dev/null @@ -1,318 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the base functionality for the rounds of the decision-making abci app.""" - -import json -from enum import Enum -from typing import Dict, List, Optional, Set, Tuple, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - CollectSameUntilThresholdRound, - DeserializedCollection, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import MultisigTxPayload -from packages.valory.skills.decision_maker_abci.policy import EGreedyPolicy -from packages.valory.skills.market_manager_abci.rounds import ( - SynchronizedData as MarketManagerSyncedData, -) -from packages.valory.skills.mech_interact_abci.states.base import ( - MechInteractionResponse, - MechMetadata, -) -from packages.valory.skills.staking_abci.rounds import StakingState -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TxSettlementSyncedData, -) - - -class Event(Enum): - """Event enumeration for the price estimation demo.""" - - DONE = "done" - NONE = "none" - BENCHMARKING_ENABLED = "benchmarking_enabled" - BENCHMARKING_DISABLED = "benchmarking_disabled" - BENCHMARKING_FINISHED = "benchmarking_finished" - MOCK_MECH_REQUEST = "mock_mech_request" - MOCK_TX = "mock_tx" - MECH_RESPONSE_ERROR = "mech_response_error" - SLOTS_UNSUPPORTED_ERROR = "slots_unsupported_error" - TIE = "tie" - UNPROFITABLE = "unprofitable" - INSUFFICIENT_BALANCE = "insufficient_balance" - NO_REDEEMING = "no_redeeming" - BLACKLIST = "blacklist" - NO_OP = "no_op" - SUBSCRIPTION_ERROR = "subscription_error" - NO_SUBSCRIPTION = "no_subscription" - ROUND_TIMEOUT = "round_timeout" - REDEEM_ROUND_TIMEOUT = "redeem_round_timeout" - NO_MAJORITY = "no_majority" - NEW_SIMULATED_RESAMPLE = "new_simulated_resample" - - -class SynchronizedData(MarketManagerSyncedData, TxSettlementSyncedData): - """Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - @property - def sampled_bet_index(self) -> int: - """Get the sampled bet.""" - return int(self.db.get_strict("sampled_bet_index")) - - @property - def benchmarking_finished(self) -> bool: - """Get the flag of benchmarking finished.""" - return bool(self.db.get_strict("benchmarking_finished")) - - @property - def simulated_day(self) -> bool: - """Get the flag of simulated_day.""" - return bool(self.db.get_strict("simulated_day")) - - @property - def is_mech_price_set(self) -> bool: - """Get whether mech's price is known.""" - return bool(self.db.get("mech_price", False)) - - @property - def available_mech_tools(self) -> List[str]: - """Get all the available mech tools.""" - tools = self.db.get_strict("available_mech_tools") - return json.loads(tools) - - @property - def is_policy_set(self) -> bool: - """Get whether the policy is set.""" - return bool(self.db.get("policy", False)) - - @property - def policy(self) -> EGreedyPolicy: - """Get the policy.""" - policy = self.db.get_strict("policy") - return EGreedyPolicy.deserialize(policy) - - @property - def has_tool_selection_run(self) -> bool: - """Get whether the tool selection has run.""" - mech_tool = self.db.get("mech_tool", None) - return mech_tool is not None - - @property - def mech_tool(self) -> str: - """Get the selected mech tool.""" - return str(self.db.get_strict("mech_tool")) - - @property - def utilized_tools(self) -> Dict[str, str]: - """Get a mapping of the utilized tools' indexes for each transaction.""" - tools = str(self.db.get_strict("utilized_tools")) - return json.loads(tools) - - @property - def redeemed_condition_ids(self) -> Set[str]: - """Get the condition ids of all the redeemed positions.""" - ids = self.db.get("redeemed_condition_ids", None) - if ids is None: - return set() - return set(json.loads(ids)) - - @property - def payout_so_far(self) -> int: - """Get the payout of all the redeemed positions so far.""" - payout = self.db.get("payout_so_far", None) - if payout is None: - return 0 - return int(payout) - - @property - def vote(self) -> Optional[int]: - """Get the bet's vote index.""" - vote = self.db.get_strict("vote") - return int(vote) if vote is not None else None - - @property - def previous_vote(self) -> Optional[int]: - """Get the bet's previous vote index.""" - previous_vote = self.db.get_strict("previous_vote") - return int(previous_vote) if previous_vote is not None else None - - @property - def confidence(self) -> float: - """Get the vote's confidence.""" - return float(self.db.get_strict("confidence")) - - @property - def bet_amount(self) -> int: - """Get the calculated bet amount.""" - return int(self.db.get_strict("bet_amount")) - - @property - def weighted_accuracy(self) -> float: - """Get the weighted accuracy of the selected tool.""" - tool_name = self.mech_tool - store_tools = set(self.policy.weighted_accuracy.keys()) - if tool_name not in store_tools: - raise ValueError( - f"The tool {tool_name} was selected but it is not available in the policy!" - ) - return self.policy.weighted_accuracy[tool_name] - - @property - def is_profitable(self) -> bool: - """Get whether the current vote is profitable or not.""" - return bool(self.db.get_strict("is_profitable")) - - @property - def did_transact(self) -> bool: - """Get whether the service performed any transactions in the current period.""" - return bool(self.db.get("tx_submitter", None)) - - @property - def tx_submitter(self) -> str: - """Get the round that submitted a tx to transaction_settlement_abci.""" - return str(self.db.get_strict("tx_submitter")) - - @property - def participant_to_decision(self) -> DeserializedCollection: - """Get the participants to decision-making.""" - return self._get_deserialized("participant_to_decision") - - @property - def participant_to_tx_prep(self) -> DeserializedCollection: - """Get the participants to bet-placement.""" - return self._get_deserialized("participant_to_tx_prep") - - @property - def participant_to_handle_failed_tx(self) -> DeserializedCollection: - """Get the participants to `HandleFailedTxRound`.""" - return self._get_deserialized("participant_to_handle_failed_tx") - - @property - def agreement_id(self) -> str: - """Get the agreement id.""" - return str(self.db.get_strict("agreement_id")) - - @property - def claim(self) -> bool: - """Get the claim.""" - return bool(self.db.get_strict("claim")) - - @property - def mech_price(self) -> int: - """Get the mech's request price.""" - return int(self.db.get_strict("mech_price")) - - @property - def mech_requests(self) -> List[MechMetadata]: - """Get the mech requests.""" - serialized = self.db.get("mech_requests", "[]") - if serialized is None: - serialized = "[]" - requests = json.loads(serialized) - return [MechMetadata(**metadata_item) for metadata_item in requests] - - @property - def mocking_mode(self) -> Optional[bool]: - """Get whether the mocking mode should be enabled.""" - mode = self.db.get_strict("mocking_mode") - if mode is None: - return None - return bool(mode) - - @property - def next_mock_data_row(self) -> int: - """Get the next_mock_data_row.""" - next_mock_data_row = self.db.get("next_mock_data_row", 1) - if next_mock_data_row is None: - return 1 - return int(next_mock_data_row) - - @property - def mech_responses(self) -> List[MechInteractionResponse]: - """Get the mech responses.""" - serialized = self.db.get("mech_responses", "[]") - if serialized is None: - serialized = "[]" - responses = json.loads(serialized) - return [MechInteractionResponse(**response_item) for response_item in responses] - - @property - def wallet_balance(self) -> int: - """Get the balance of the wallet.""" - wallet_balance = self.db.get("wallet_balance", 0) - if wallet_balance is None: - return 0 - return int(wallet_balance) - - @property - def decision_receive_timestamp(self) -> int: - """Get the timestamp of the mech decision.""" - decision_receive_timestamp = self.db.get("decision_receive_timestamp", 0) - if decision_receive_timestamp is None: - return 0 - return int(decision_receive_timestamp) - - @property - def is_staking_kpi_met(self) -> bool: - """Get the status of the staking kpi.""" - return bool(self.db.get("is_staking_kpi_met", False)) - - @property - def service_staking_state(self) -> StakingState: - """Get the service's staking state.""" - return StakingState(self.db.get("service_staking_state", 0)) - - @property - def after_bet_attempt(self) -> bool: - """Get the service's staking state.""" - return bool(self.db.get("after_bet_attempt", False)) - - -class TxPreparationRound(CollectSameUntilThresholdRound): - """A round for preparing a transaction.""" - - payload_class = MultisigTxPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - none_event = Event.NONE - no_majority_event = Event.NO_MAJORITY - selection_key: Tuple[str, ...] = ( - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.mocking_mode), - ) - collection_key = get_name(SynchronizedData.participant_to_tx_prep) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - if event == Event.DONE and synced_data.mocking_mode: - return synced_data, Event.MOCK_TX - - return res diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/bet_placement.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/bet_placement.py deleted file mode 100644 index 35e7c63f1..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/bet_placement.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the sampling state of the decision-making abci app.""" -from enum import Enum -from typing import Optional, Tuple, Type - -from packages.valory.skills.abstract_round_abci.base import BaseSynchronizedData -from packages.valory.skills.decision_maker_abci.payloads import ( - BetPlacementPayload, - MultisigTxPayload, -) -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - TxPreparationRound, -) - - -class BetPlacementRound(TxPreparationRound): - """A round for placing a bet.""" - - payload_class: Type[MultisigTxPayload] = BetPlacementPayload - - none_event = Event.INSUFFICIENT_BALANCE - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - update = super().end_block() - if update is None: - return None - - sync_data, event = update - wallet_balance = self.most_voted_payload_values[-1] - sync_data = sync_data.update(wallet_balance=wallet_balance) - return sync_data, event diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/blacklisting.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/blacklisting.py deleted file mode 100644 index d2a714583..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/blacklisting.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the blacklisting state of the decision-making abci app.""" - -from enum import Enum -from typing import Any, Optional, Tuple, Type, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import BlacklistingPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload -from packages.valory.skills.market_manager_abci.rounds import UpdateBetsRound - - -class BlacklistingRound(UpdateBetsRound): - """A round for updating the bets after blacklisting the sampled one.""" - - payload_class: Type[UpdateBetsPayload] = BlacklistingPayload - done_event = Event.DONE - none_event = Event.NONE - no_majority_event = Event.NO_MAJORITY - selection_key: Any = ( - UpdateBetsRound.selection_key, - get_name(SynchronizedData.policy), - ) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - if event == Event.DONE and self.context.benchmarking_mode.enabled: - return synced_data, Event.MOCK_TX - return res diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/check_benchmarking.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/check_benchmarking.py deleted file mode 100644 index e50d6478b..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/check_benchmarking.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 state of the decision-making abci app which checks if the benchmarking mode is enabled.""" - -from packages.valory.skills.decision_maker_abci.payloads import VotingPayload -from packages.valory.skills.decision_maker_abci.states.base import Event -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) - - -class CheckBenchmarkingModeRound(ClaimRound): - """A round for checking whether the benchmarking mode is enabled.""" - - payload_class = VotingPayload - done_event = Event.BENCHMARKING_ENABLED - negative_event = Event.BENCHMARKING_DISABLED diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/claim_subscription.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/claim_subscription.py deleted file mode 100644 index 40331ef3c..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/claim_subscription.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the decision receiving state of the decision-making abci app.""" - -from typing import Type - -from packages.valory.skills.abstract_round_abci.base import ( - BaseTxPayload, - VotingRound, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import ClaimPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) - - -class ClaimRound(VotingRound): - """A round for preparing a transaction.""" - - payload_class: Type[BaseTxPayload] = ClaimPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - negative_event = Event.SUBSCRIPTION_ERROR - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_votes) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/decision_receive.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/decision_receive.py deleted file mode 100644 index 37ac2c3cb..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/decision_receive.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the decision receiving state of the decision-making abci app.""" - -from enum import Enum -from typing import Any, Optional, Tuple, cast - -from packages.valory.skills.abstract_round_abci.base import ( - CollectSameUntilThresholdRound, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import DecisionReceivePayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.market_manager_abci.rounds import UpdateBetsRound - - -class DecisionReceiveRound(CollectSameUntilThresholdRound): - """A round in which the agents decide on the bet's answer.""" - - payload_class = DecisionReceivePayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - none_event = Event.MECH_RESPONSE_ERROR - no_majority_event = Event.NO_MAJORITY - selection_key: Any = ( - UpdateBetsRound.selection_key, - get_name(SynchronizedData.is_profitable), - get_name(SynchronizedData.vote), - get_name(SynchronizedData.confidence), - get_name(SynchronizedData.bet_amount), - get_name(SynchronizedData.next_mock_data_row), - get_name(SynchronizedData.policy), - ) - collection_key = get_name(SynchronizedData.participant_to_decision) - - def end_block(self) -> Optional[Tuple[SynchronizedData, Enum]]: - """Process the end of the block.""" - - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - - if event == Event.DONE: - decision_receive_timestamp = self.most_voted_payload_values[-1] - - synced_data = cast( - SynchronizedData, - synced_data.update( - decision_receive_timestamp=decision_receive_timestamp - ), - ) - - if event == Event.DONE and synced_data.vote is None: - return synced_data, Event.TIE - - if event == Event.DONE and not synced_data.is_profitable: - return synced_data, Event.UNPROFITABLE - - return synced_data, event diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/decision_request.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/decision_request.py deleted file mode 100644 index 5c4df3e9b..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/decision_request.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the decision requesting state of the decision-making abci app.""" - -from enum import Enum -from typing import Optional, Tuple, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - CollectSameUntilThresholdRound, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import DecisionRequestPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) - - -class DecisionRequestRound(CollectSameUntilThresholdRound): - """A round in which the agents prepare a tx to initiate a request to a mech to determine the answer to a bet.""" - - payload_class = DecisionRequestPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_selection) - selection_key = ( - get_name(SynchronizedData.mech_requests), - get_name(SynchronizedData.mocking_mode), - ) - none_event = Event.SLOTS_UNSUPPORTED_ERROR - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - if event == Event.DONE and synced_data.mocking_mode: - return synced_data, Event.MOCK_MECH_REQUEST - - return res diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/final_states.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/final_states.py deleted file mode 100644 index 6c1294748..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/final_states.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the final states of the decision-making abci app.""" - -import sys -from enum import Enum -from typing import Optional, Tuple - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - DegenerateRound, -) - - -class BenchmarkingModeDisabledRound(DegenerateRound): - """A round representing that the benchmarking mode is disabled.""" - - -class FinishedDecisionMakerRound(DegenerateRound): - """A round representing that decision-making has finished.""" - - -class FinishedDecisionRequestRound(DegenerateRound): - """A round representing that decision request has finished.""" - - -class FinishedSubscriptionRound(DegenerateRound): - """A round representing that subscription has finished.""" - - -class FinishedWithoutRedeemingRound(DegenerateRound): - """A round representing that decision-making has finished without redeeming.""" - - -class FinishedWithoutDecisionRound(DegenerateRound): - """A round representing that decision-making has finished without deciding on a bet.""" - - -class RefillRequiredRound(DegenerateRound): - """A round representing that a refill is required for placing a bet.""" - - -class BenchmarkingDoneRound(DegenerateRound): - """A round representing that the benchmarking has finished.""" - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Gracefully stop the service.""" - sys.exit(0) - - -class ImpossibleRound(DegenerateRound): - """A round representing that decision-making is impossible with the given parametrization.""" diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/handle_failed_tx.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/handle_failed_tx.py deleted file mode 100644 index 0f4c8412d..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/handle_failed_tx.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the blacklisting state of the decision-making abci app.""" - -from enum import Enum -from typing import Optional, Tuple, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - CollectSameUntilThresholdRound, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import HandleFailedTxPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) - - -class HandleFailedTxRound(CollectSameUntilThresholdRound): - """A round for updating the bets after blacklisting the sampled one.""" - - payload_class = HandleFailedTxPayload - synchronized_data_class = SynchronizedData - done_event = Event.BLACKLIST - no_op_event = Event.NO_OP - none_event = Event.NO_OP - no_majority_event = Event.NO_MAJORITY - selection_key = ( - get_name(SynchronizedData.after_bet_attempt), - get_name(SynchronizedData.tx_submitter), - ) - collection_key = get_name(SynchronizedData.participant_to_handle_failed_tx) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - - if event != self.done_event: - return res - - if synced_data.after_bet_attempt: - return synced_data, self.done_event - - return synced_data, self.no_op_event diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/order_subscription.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/order_subscription.py deleted file mode 100644 index 5c5831bd7..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/order_subscription.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the decision receiving state of the decision-making abci app.""" - -from enum import Enum -from typing import Optional, Tuple, Type - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import ( - MultisigTxPayload, - SubscriptionPayload, -) -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, - TxPreparationRound, -) - - -class SubscriptionRound(TxPreparationRound): - """A round in which the agents prepare a tx to initiate a request to a mech to determine the answer to a bet.""" - - payload_class: Type[MultisigTxPayload] = SubscriptionPayload - selection_key = TxPreparationRound.selection_key + ( - get_name(SynchronizedData.agreement_id), - ) - none_event = Event.NO_SUBSCRIPTION - - NO_TX_PAYLOAD = "no_tx" - ERROR_PAYLOAD = "error" - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.threshold_reached: - tx_hash = self.most_voted_payload_values[1] - if tx_hash == self.ERROR_PAYLOAD: - return self.synchronized_data, Event.SUBSCRIPTION_ERROR - - if tx_hash == self.NO_TX_PAYLOAD: - return self.synchronized_data, Event.NO_SUBSCRIPTION - - if self.context.benchmarking_mode.enabled: - return self.synchronized_data, Event.MOCK_TX - - update = super().end_block() - if update is None: - return None - - sync_data, event = update - agreement_id = self.most_voted_payload_values[3] - wallet_balance = self.most_voted_payload_values[4] - sync_data = sync_data.update( - agreement_id=agreement_id, wallet_balance=wallet_balance - ) - return sync_data, event diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/randomness.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/randomness.py deleted file mode 100644 index 9000e153f..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/randomness.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the randomness state of the decision-making abci app.""" - -from typing import Any - -from packages.valory.skills.decision_maker_abci.states.base import Event -from packages.valory.skills.transaction_settlement_abci.rounds import ( - RandomnessTransactionSubmissionRound, -) - - -class RandomnessRound(RandomnessTransactionSubmissionRound): - """A round for gathering randomness.""" - - done_event: Any = Event.DONE - no_majority_event: Any = Event.NO_MAJORITY - - -class BenchmarkingRandomnessRound(RandomnessRound): - """A round for gathering randomness in benchmarking mode.""" diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/redeem.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/redeem.py deleted file mode 100644 index f40ade4c5..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/redeem.py +++ /dev/null @@ -1,107 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the redeem state of the decision-making abci app.""" - -from enum import Enum -from typing import Any, Optional, Tuple, Type, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import ( - MultisigTxPayload, - RedeemPayload, -) -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, - TxPreparationRound, -) - - -IGNORED = "ignored" -MECH_TOOLS_FIELD = "mech_tools" - - -class RedeemRound(TxPreparationRound): - """A round in which the agents prepare a tx to redeem the winnings.""" - - payload_class: Type[MultisigTxPayload] = RedeemPayload - mech_tools_name = get_name(SynchronizedData.available_mech_tools) - selection_key = TxPreparationRound.selection_key + ( - mech_tools_name, - get_name(SynchronizedData.policy), - get_name(SynchronizedData.utilized_tools), - get_name(SynchronizedData.redeemed_condition_ids), - get_name(SynchronizedData.payout_so_far), - ) - none_event = Event.NO_REDEEMING - - @property - def most_voted_payload_values( - self, - ) -> Tuple[Any, ...]: - """Get the most voted payload values in such a way to create a custom none event that ignores the mech tools.""" - most_voted_payload_values = super().most_voted_payload_values - # sender does not matter for the init as the `data` property used below to obtain the dictionary ignores it - most_voted_payload = RedeemPayload(IGNORED, *most_voted_payload_values) - most_voted_payload_dict = most_voted_payload.data - mech_tools = most_voted_payload_dict.pop(MECH_TOOLS_FIELD, None) - if mech_tools is None: - raise ValueError(f"`{MECH_TOOLS_FIELD}` must not be `None`") - if all(val is None for val in most_voted_payload_dict.values()): - return (None,) * len(self.selection_key) - return most_voted_payload_values - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if ( - res is None - and self.block_confirmations == self.synchronized_data.period_count == 0 - ): - # necessary for always setting the persisted keys and not raise an exception when the first period ends - # this also protects us in case a round timeout is raised - update = { - db_key: self.synchronized_data.db.get(db_key, None) - for db_key in RedeemRound.selection_key - } - self.synchronized_data.db.update(**update) - self.block_confirmations = 1 - - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - - # also update the mech tools if there is a majority, because the overridden property does not include it - if event != self.no_majority_event: - most_voted_payload_values = self.payload_values_count.most_common()[0][0] - # sender does not matter for the init as the `data` property used below to obtain the dictionary ignores it - most_voted_payload = RedeemPayload(IGNORED, *most_voted_payload_values) - mech_tools_update = most_voted_payload.mech_tools - updated_data = synced_data.update( - self.synchronized_data_class, - **{self.mech_tools_name: mech_tools_update}, - ) - return updated_data, event - - return res diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/sampling.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/sampling.py deleted file mode 100644 index dbbf08461..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/sampling.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the sampling state of the decision-making abci app.""" - -from enum import Enum -from typing import Any, Optional, Tuple, Type, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import SamplingPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload -from packages.valory.skills.market_manager_abci.rounds import UpdateBetsRound - - -class SamplingRound(UpdateBetsRound): - """A round for sampling a bet.""" - - payload_class: Type[UpdateBetsPayload] = SamplingPayload - done_event = Event.DONE - none_event = Event.NONE - no_majority_event = Event.NO_MAJORITY - selection_key: Any = ( - UpdateBetsRound.selection_key, - get_name(SynchronizedData.sampled_bet_index), - get_name(SynchronizedData.benchmarking_finished), - get_name(SynchronizedData.simulated_day), - ) - synchronized_data_class = SynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - - if event != Event.DONE: - return res - - if synced_data.benchmarking_finished: - return synced_data, Event.BENCHMARKING_FINISHED - - if synced_data.simulated_day: - return synced_data, Event.NEW_SIMULATED_RESAMPLE - - if self.context.benchmarking_mode.enabled: - return synced_data, Event.BENCHMARKING_ENABLED - - return res diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/sell_outcome_token.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/sell_outcome_token.py deleted file mode 100644 index 3fdeb628c..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/sell_outcome_token.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the sell outcome token state of the decision-making abci app.""" - -from packages.valory.skills.decision_maker_abci.states.base import TxPreparationRound - - -class SellOutcomeTokenRound(TxPreparationRound): - """A round for selling a token.""" diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/states/tool_selection.py b/trader_old/vendor/valory/skills/decision_maker_abci/states/tool_selection.py deleted file mode 100644 index 9b6ce6316..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/states/tool_selection.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the tool selection state of the decision-making abci app.""" - -from packages.valory.skills.abstract_round_abci.base import ( - CollectSameUntilThresholdRound, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import ToolSelectionPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) - - -class ToolSelectionRound(CollectSameUntilThresholdRound): - """A round for selecting a Mech tool.""" - - payload_class = ToolSelectionPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - none_event = Event.NONE - no_majority_event = Event.NO_MAJORITY - selection_key = ( - get_name(SynchronizedData.available_mech_tools), - get_name(SynchronizedData.policy), - get_name(SynchronizedData.utilized_tools), - get_name(SynchronizedData.mech_tool), - ) - collection_key = get_name(SynchronizedData.participant_to_selection) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/__init__.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/__init__.py deleted file mode 100644 index da96e5260..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the tests for valory/decision_maker_abci.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/decision_maker_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/__init__.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/__init__.py deleted file mode 100644 index ce9c4fc94..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the tests for valory/decision_maker_abci's behaviours.""" diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/data/.gitkeep b/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/data/.gitkeep deleted file mode 100644 index 12461b81d..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/data/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -keep this folder here for testing purposes diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/__init__.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/__init__.py deleted file mode 100644 index 2f1c30eae..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 dummy strategy for testing purposes.""" diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/dummy_strategy.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/dummy_strategy.py deleted file mode 100644 index 69a942008..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/dummy_strategy/dummy_strategy.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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. -# -# ------------------------------------------------------------------------------ - - -"""Implements a dummy strategy for testing purposes.""" - - -from typing import Any - - -def dummy(*args: Any, **kwargs: Any) -> str: - """The dummy function.""" - return "dummy" diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/test_base.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/test_base.py deleted file mode 100644 index 5f48f32e3..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/behaviours/test_base.py +++ /dev/null @@ -1,275 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the tests for valory/decision_maker_abci's base behaviour.""" - -import re -from pathlib import Path -from typing import Any, Dict, Optional, Tuple, cast -from unittest import mock - -import pytest -from hypothesis import given, settings -from hypothesis import strategies as st - -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.decision_maker_abci.behaviours.base import ( - BET_AMOUNT_FIELD, - DecisionMakerBaseBehaviour, - WXDAI, - remove_fraction_wei, -) -from packages.valory.skills.decision_maker_abci.behaviours.blacklisting import ( - BlacklistingBehaviour, -) -from packages.valory.skills.decision_maker_abci.states.base import SynchronizedData -from packages.valory.skills.decision_maker_abci.tests.conftest import profile_name - - -settings.load_profile(profile_name) -FRACTION_REMOVAL_PRECISION = 2 -CURRENT_FILE_PATH = Path(__file__).resolve() -PACKAGE_DIR = CURRENT_FILE_PATH.parents[2] - - -@st.composite -def remove_fraction_args(draw: st.DrawFn) -> Tuple[int, float, int]: - """A strategy for building the values of the `test_remove_fraction_wei` with the desired constraints.""" - amount = draw(st.integers()) - fraction = draw(st.floats(min_value=0, max_value=1)) - keep_percentage = 1 - fraction - assert 0 <= keep_percentage <= 1 - expected = int(amount * keep_percentage) - return amount, fraction, expected - - -@given(remove_fraction_args()) -def test_remove_fraction_wei(strategy: Tuple[int, float, int]) -> None: - """Test the `remove_fraction_wei` function.""" - amount, fraction, expected = strategy - assert remove_fraction_wei(amount, fraction) == expected - - -@given( - amount=st.integers(), - fraction=st.floats().filter(lambda x: x < 0 or x > 1), -) -def test_remove_fraction_wei_incorrect_fraction(amount: int, fraction: float) -> None: - """Test the `remove_fraction_wei` function.""" - with pytest.raises( - ValueError, - match=re.escape(f"The given fraction {fraction!r} is not in the range [0, 1]."), - ): - remove_fraction_wei(amount, fraction) - - -@st.composite -def strategy_executables( - draw: st.DrawFn, -) -> Tuple[str, Dict[str, Tuple[str, str]], Optional[Tuple[str, str]]]: - """A strategy for building valid availability window data.""" - strategy_name = draw(st.text()) - expected_result = draw(st.tuples(st.text(), st.text())) - negative_case = draw(st.booleans()) - - if negative_case: - return strategy_name, {}, None - - return strategy_name, {strategy_name: expected_result}, expected_result - - -class TestDecisionMakerBaseBehaviour(FSMBehaviourBaseCase): - """Test `DecisionMakerBaseBehaviour`.""" - - path_to_skill = PACKAGE_DIR - - def ffw( - self, - behaviour_cls: Any, - db_items: Optional[Dict] = None, - ) -> None: - """Fast-forward to the given behaviour.""" - if db_items is None: - db_items = {} - - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=behaviour_cls.auto_behaviour_id(), - synchronized_data=SynchronizedData( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists(db_items), - ) - ), - ) - - @given(strategy_executables()) - def test_strategy_exec( - self, - strategy: Tuple[str, Dict[str, Tuple[str, str]], Optional[str]], - ) -> None: - """Test the `strategy_exec` method.""" - strategy_name, strategies_executables, expected_result = strategy - # use `BlacklistingBehaviour` because it overrides the `DecisionMakerBaseBehaviour`. - self.ffw(BlacklistingBehaviour) - behaviour = cast(BlacklistingBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == BlacklistingBehaviour.auto_behaviour_id() - behaviour.shared_state.strategies_executables = strategies_executables - res = behaviour.strategy_exec(strategy_name) - assert res == expected_result - - @pytest.mark.parametrize( - "strategy_path", (Path("dummy_strategy/dummy_strategy.py"),) - ) - @pytest.mark.parametrize( - "args, kwargs, method_name, expected_result", - ( - ((), {}, "", {BET_AMOUNT_FIELD: 0}), - ((), {"unexpected_field": "test"}, "", {BET_AMOUNT_FIELD: 0}), - ((), {"trading_strategy": None}, "", {BET_AMOUNT_FIELD: 0}), - ( - (), - {"trading_strategy": "non_existing_strategy"}, - "", - {BET_AMOUNT_FIELD: 0}, - ), - ( - (), - {"trading_strategy": "test"}, - "non_existing_method", - {BET_AMOUNT_FIELD: 0}, - ), - ((), {"trading_strategy": "test"}, "dummy", "dummy"), - ), - ) - def test_execute_strategy( - self, - strategy_path: str, - args: tuple, - kwargs: dict, - method_name: str, - expected_result: int, - ) -> None: - """Test the `execute_strategy` method.""" - # use `BlacklistingBehaviour` because it overrides the `DecisionMakerBaseBehaviour`. - self.ffw(BlacklistingBehaviour) - behaviour = cast(BlacklistingBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == BlacklistingBehaviour.auto_behaviour_id() - current_dir = CURRENT_FILE_PATH.parent - with open(current_dir / strategy_path) as dummy_strategy: - behaviour.shared_state.strategies_executables["test"] = ( - dummy_strategy.read(), - method_name, - ) - - res = behaviour.execute_strategy(*args, **kwargs) - assert res == expected_result - - @given(st.integers()) - def test_wei_to_native(self, wei: int) -> None: - """Test the `wei_to_native` method.""" - result = DecisionMakerBaseBehaviour.wei_to_native(wei) - assert isinstance(result, float) - assert result == wei / 10**18 - - @given(st.integers(), st.booleans(), st.booleans()) - def test_collateral_amount_info( - self, amount: int, benchmarking_mode_enabled: bool, is_wxdai: bool - ) -> None: - """Test the `collateral_amount_info` method.""" - # use `BlacklistingBehaviour` because it overrides the `DecisionMakerBaseBehaviour`. - self.ffw(BlacklistingBehaviour, {"sampled_bet_index": 0}) - behaviour = cast(BlacklistingBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == BlacklistingBehaviour.auto_behaviour_id() - - behaviour.benchmarking_mode.enabled = benchmarking_mode_enabled - with mock.patch.object(behaviour, "read_bets"): - collateral_token = WXDAI if is_wxdai else "unknown" - behaviour.bets = [(mock.MagicMock(collateralToken=collateral_token))] - result = behaviour._collateral_amount_info(amount) - - if benchmarking_mode_enabled or is_wxdai: - assert result == f"{behaviour.wei_to_native(amount)} wxDAI" - else: - assert ( - result - == f"{amount} WEI of the collateral token with address {collateral_token}" - ) - - @given(st.integers(), st.integers()) - def test_mock_balance_check( - self, collateral_balance: int, native_balance: int - ) -> None: - """Test the `_mock_balance_check` method.""" - # use `BlacklistingBehaviour` because it overrides the `DecisionMakerBaseBehaviour`. - self.ffw(BlacklistingBehaviour) - behaviour = cast(BlacklistingBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == BlacklistingBehaviour.auto_behaviour_id() - - behaviour.benchmarking_mode.collateral_balance = collateral_balance - behaviour.benchmarking_mode.native_balance = native_balance - with mock.patch.object(behaviour, "_report_balance") as mock_report_balance: - behaviour._mock_balance_check() - mock_report_balance.assert_called_once() - assert behaviour.token_balance == collateral_balance - assert behaviour.wallet_balance == native_balance - - @pytest.mark.parametrize( - "mocked_result, expected_result", - ( - ({}, 0), - ({"not the correct field": 80}, 0), - ({BET_AMOUNT_FIELD: 0}, 0), - ({BET_AMOUNT_FIELD: -10}, -10), - ({BET_AMOUNT_FIELD: 10}, 10), - ({BET_AMOUNT_FIELD: 23456}, 23456), - ), - ) - def test_get_bet_amount( - self, - mocked_result: int, - expected_result: int, - ) -> None: - """Test the `get_bet_amount` method.""" - # use `BlacklistingBehaviour` because it overrides the `DecisionMakerBaseBehaviour`. - self.ffw(BlacklistingBehaviour) - behaviour = cast(BlacklistingBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == BlacklistingBehaviour.auto_behaviour_id() - behaviour.download_strategies = lambda: (yield) # type: ignore - behaviour.wait_for_condition_with_sleep = lambda _: (yield) # type: ignore - behaviour.execute_strategy = lambda *_, **__: mocked_result # type: ignore - gen = behaviour.get_bet_amount( - 0, - 0, - 0, - 0, - 0, - 0, - ) - for _ in range(2): - # `download_strategies` and `wait_for_condition_with_sleep` mock calls - next(gen) - try: - next(gen) - except StopIteration as e: - assert e.value == expected_result - else: - raise AssertionError("Expected `StopIteration` exception!") diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/conftest.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/conftest.py deleted file mode 100644 index d690940ab..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/conftest.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Conftest module for decision maker tests.""" - -import os -from pathlib import Path - -from hypothesis import settings - - -# pylint: skip-file - - -CI = "CI" -PACKAGE_DIR = Path(__file__).parent.parent -settings.register_profile(CI, deadline=5000) -profile_name = ("default", "CI")[bool(os.getenv("CI"))] diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_base.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_base.py deleted file mode 100644 index ad41e0e8c..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_base.py +++ /dev/null @@ -1,257 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -import json -from unittest.mock import MagicMock, patch - -import pytest - -from packages.valory.skills.decision_maker_abci.policy import ( - AccuracyInfo, - EGreedyPolicy, -) -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, - TxPreparationRound, -) - - -class MechMetadata: - """The class for test of Mech Data""" - - def __init__(self, request_id: str, data: str) -> None: - """Initialize MechMetadata with request ID and data.""" - self.request_id = request_id - self.data = data - - -@pytest.fixture -def mocked_db() -> MagicMock: - """Fixture to mock the database.""" - return MagicMock() - - -@pytest.fixture -def sync_data(mocked_db: MagicMock) -> SynchronizedData: - """Fixture for SynchronizedData.""" - return SynchronizedData(db=mocked_db) - - -def test_sampled_bet_index(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the sampled_bet_index property.""" - mocked_db.get_strict.return_value = "5" - assert sync_data.sampled_bet_index == 5 - mocked_db.get_strict.assert_called_once_with("sampled_bet_index") - - -def test_is_mech_price_set(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the is_mech_price_set property.""" - mocked_db.get.return_value = True - assert sync_data.is_mech_price_set is True - mocked_db.get.assert_called_once_with("mech_price", False) - - -def test_available_mech_tools( - sync_data: SynchronizedData, mocked_db: MagicMock -) -> None: - """Test the available_mech_tools property.""" - mocked_db.get_strict.return_value = '["tool1", "tool2"]' - assert sync_data.available_mech_tools == ["tool1", "tool2"] - mocked_db.get_strict.assert_called_once_with("available_mech_tools") - - -def test_is_policy_set(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the is_policy_set property.""" - mocked_db.get.return_value = True - assert sync_data.is_policy_set is True - mocked_db.get.assert_called_once_with("policy", False) - - -def test_has_tool_selection_run( - sync_data: SynchronizedData, mocked_db: MagicMock -) -> None: - """Test the has_tool_selection_run property.""" - mocked_db.get.return_value = "tool1" - assert sync_data.has_tool_selection_run is True - mocked_db.get.assert_called_once_with("mech_tool", None) - - -def test_mech_tool(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the mech_tool property.""" - mocked_db.get_strict.return_value = "tool1" - assert sync_data.mech_tool == "tool1" - mocked_db.get_strict.assert_called_once_with("mech_tool") - - -def test_utilized_tools(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the utilized_tools property.""" - mocked_db.get_strict.return_value = '{"tx1": "tool1"}' - assert sync_data.utilized_tools == {"tx1": "tool1"} - mocked_db.get_strict.assert_called_once_with("utilized_tools") - - -def test_redeemed_condition_ids( - sync_data: SynchronizedData, mocked_db: MagicMock -) -> None: - """Test the redeemed_condition_ids property.""" - mocked_db.get.return_value = '["cond1", "cond2"]' - assert sync_data.redeemed_condition_ids == {"cond1", "cond2"} - mocked_db.get.assert_called_once_with("redeemed_condition_ids", None) - - -def test_payout_so_far(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the payout_so_far property.""" - mocked_db.get.return_value = "100" - assert sync_data.payout_so_far == 100 - mocked_db.get.assert_called_once_with("payout_so_far", None) - - -def test_vote(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the vote property.""" - mocked_db.get_strict.return_value = "1" - assert sync_data.vote == 1 - mocked_db.get_strict.assert_called_once_with("vote") - - -def test_confidence(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the confidence property.""" - mocked_db.get_strict.return_value = "0.9" - assert sync_data.confidence == 0.9 - mocked_db.get_strict.assert_called_once_with("confidence") - - -def test_bet_amount(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the bet_amount property.""" - mocked_db.get_strict.return_value = "50" - assert sync_data.bet_amount == 50 - mocked_db.get_strict.assert_called_once_with("bet_amount") - - -def test_is_profitable(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the is_profitable property.""" - mocked_db.get_strict.return_value = True - assert sync_data.is_profitable is True - mocked_db.get_strict.assert_called_once_with("is_profitable") - - -def test_tx_submitter(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the tx_submitter property.""" - mocked_db.get_strict.return_value = "submitter1" - assert sync_data.tx_submitter == "submitter1" - mocked_db.get_strict.assert_called_once_with("tx_submitter") - - -@patch("packages.valory.skills.decision_maker_abci.policy.EGreedyPolicy.deserialize") -def test_policy_property( - mock_deserialize: MagicMock, sync_data: SynchronizedData, mocked_db: MagicMock -) -> None: - """Test for policy property""" - mock_policy_serialized = "serialized_policy_string" - mocked_db.get_strict.return_value = mock_policy_serialized - - expected_policy = EGreedyPolicy( - eps=0.1, consecutive_failures_threshold=1, quarantine_duration=0 - ) - mock_deserialize.return_value = expected_policy - - result = sync_data.policy - - mocked_db.get_strict.assert_called_once_with("policy") - mock_deserialize.assert_called_once_with(mock_policy_serialized) - assert result == expected_policy - - -def test_mech_requests(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the mech_requests property.""" - mocked_db.get.return_value = '[{"request_id": "1", "data": "request_data"}]' - requests = json.loads(mocked_db.get.return_value) - - mech_requests = [ - MechMetadata(request_id=item["request_id"], data=item["data"]) - for item in requests - ] - - assert len(mech_requests) == 1 - assert isinstance(mech_requests[0], MechMetadata) - assert mech_requests[0].request_id == "1" - - -def test_weighted_accuracy(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the weighted_accuracy property.""" - selected_mech_tool = "tool1" - policy_db_name = "policy" - policy_mock = EGreedyPolicy( - eps=0.1, - consecutive_failures_threshold=1, - quarantine_duration=0, - accuracy_store={selected_mech_tool: AccuracyInfo(requests=1)}, - ).serialize() - mocked_db.get_strict = lambda name: ( - policy_mock if name == policy_db_name else selected_mech_tool - ) - policy = EGreedyPolicy.deserialize(policy_mock) - assert selected_mech_tool in policy.weighted_accuracy - assert sync_data.weighted_accuracy == policy.weighted_accuracy[selected_mech_tool] - - -def test_mech_responses(sync_data: SynchronizedData, mocked_db: MagicMock) -> None: - """Test the mech_responses property.""" - - # Mock the response with empty dictionaries to avoid field mismatches - mocked_db.get.return_value = "[{}, {}]" - - # Access the mech_responses property - responses = sync_data.mech_responses - - # Validate the responses length - assert len(responses) == 2 - - # Test when db.get() returns None - mocked_db.get.return_value = None - responses = sync_data.mech_responses - assert responses == [] - - # Test when db.get() returns an empty list - mocked_db.get.return_value = "[]" - responses = sync_data.mech_responses - assert responses == [] - - -def test_end_block(mocked_db: MagicMock) -> None: - """Test the end_block logic in TxPreparationRound.""" - mocked_sync_data = MagicMock(spec=SynchronizedData) - mock_context = MagicMock() - round_instance = TxPreparationRound( - synchronized_data=mocked_sync_data, context=mock_context - ) - - with patch.object( - TxPreparationRound, "end_block", return_value=(mocked_sync_data, Event.DONE) - ): - result = round_instance.end_block() - assert result == (mocked_sync_data, Event.DONE) - - with patch.object( - TxPreparationRound, "end_block", return_value=(mocked_sync_data, Event.NONE) - ): - result = round_instance.end_block() - assert result == (mocked_sync_data, Event.NONE) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_bet_placement.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_bet_placement.py deleted file mode 100644 index 36128e3fb..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_bet_placement.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -from typing import Any, Dict - -import pytest - -from packages.valory.skills.decision_maker_abci.states.base import Event -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) - - -@pytest.fixture -def bet_placement_round() -> BetPlacementRound: - """Fixture to set up a BetPlacementRound instance for testing.""" - synchronized_data: Dict[str, Any] = {} # Added type annotation - context: Dict[str, Any] = {} # Added type annotation - return BetPlacementRound(synchronized_data, context) - - -def test_initial_event(bet_placement_round: BetPlacementRound) -> None: - """Test that the initial event is set correctly.""" - assert bet_placement_round.none_event == Event.INSUFFICIENT_BALANCE diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_blacklising.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_blacklising.py deleted file mode 100644 index 02b7dba0f..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_blacklising.py +++ /dev/null @@ -1,121 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" -from unittest.mock import MagicMock, patch - -import pytest - -from packages.valory.skills.decision_maker_abci.payloads import BlacklistingPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.blacklisting import ( - BlacklistingRound, -) -from packages.valory.skills.market_manager_abci.rounds import UpdateBetsRound - - -@pytest.fixture -def mocked_context() -> MagicMock: - """Fixture to mock the context.""" - context = MagicMock() - context.benchmarking_mode.enabled = False # Default for the test - return context - - -@pytest.fixture -def mocked_synchronized_data() -> MagicMock: - """Fixture to mock the synchronized data.""" - return MagicMock(spec=SynchronizedData) - - -@pytest.fixture -def blacklisting_round( - mocked_context: MagicMock, mocked_synchronized_data: MagicMock -) -> BlacklistingRound: - """Fixture to create an instance of BlacklistingRound.""" - return BlacklistingRound( - context=mocked_context, synchronized_data=mocked_synchronized_data - ) - - -def test_blacklisting_round_initialization( - blacklisting_round: BlacklistingRound, -) -> None: - """Test the initialization of the BlacklistingRound.""" - assert blacklisting_round.done_event == Event.DONE - assert blacklisting_round.none_event == Event.NONE - assert blacklisting_round.no_majority_event == Event.NO_MAJORITY - assert blacklisting_round.payload_class == BlacklistingPayload - assert isinstance(blacklisting_round.selection_key, tuple) - assert len(blacklisting_round.selection_key) == 2 - - -def test_blacklisting_round_end_block_done_event_no_benchmarking( - blacklisting_round: BlacklistingRound, mocked_context: MagicMock -) -> None: - """Test end_block when event is DONE and benchmarking is disabled.""" - # Mock the superclass end_block to return DONE event - synced_data = MagicMock(spec=SynchronizedData) - with patch.object( - UpdateBetsRound, "end_block", return_value=(synced_data, Event.DONE) - ) as mock_super_end_block: - result = blacklisting_round.end_block() - - mock_super_end_block.assert_called_once() - assert result == (synced_data, Event.DONE) - assert not mocked_context.benchmarking_mode.enabled # Benchmarking disabled - - -def test_blacklisting_round_end_block_done_event_with_benchmarking( - blacklisting_round: BlacklistingRound, mocked_context: MagicMock -) -> None: - """Test end_block when event is DONE and benchmarking is enabled.""" - # Set benchmarking mode to enabled - mocked_context.benchmarking_mode.enabled = True - - # Mock the superclass end_block to return DONE event - synced_data = MagicMock(spec=SynchronizedData) - with patch.object( - UpdateBetsRound, "end_block", return_value=(synced_data, Event.DONE) - ) as mock_super_end_block: - result = blacklisting_round.end_block() - - mock_super_end_block.assert_called_once() - assert result == ( - synced_data, - Event.MOCK_TX, - ) # Should return MOCK_TX since benchmarking is enabled - assert mocked_context.benchmarking_mode.enabled # Benchmarking enabled - - -def test_blacklisting_round_end_block_none_event( - blacklisting_round: BlacklistingRound, -) -> None: - """Test end_block when the superclass returns None.""" - # Mock the superclass end_block to return None - with patch.object( - UpdateBetsRound, "end_block", return_value=None - ) as mock_super_end_block: - result = blacklisting_round.end_block() - - mock_super_end_block.assert_called_once() - assert result is None # Should return None when the superclass returns None diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_check_benchmarking.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_check_benchmarking.py deleted file mode 100644 index ebc2b3c06..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_check_benchmarking.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -from unittest.mock import MagicMock - -from packages.valory.skills.decision_maker_abci.rounds import CheckBenchmarkingModeRound -from packages.valory.skills.decision_maker_abci.states.base import Event -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) - - -def test_check_benchmarking_mode_round_initialization() -> None: - """Test the initialization of CheckBenchmarkingModeRound.""" - round_instance = CheckBenchmarkingModeRound(MagicMock(), MagicMock()) - - # Test that the round is properly initialized with the correct event types - assert round_instance.done_event == Event.BENCHMARKING_ENABLED - assert round_instance.negative_event == Event.BENCHMARKING_DISABLED - - # Check that it inherits from ClaimRound - assert isinstance(round_instance, ClaimRound) - - -def test_check_benchmarking_mode_round_events() -> None: - """Test that the correct events are used in the CheckBenchmarkingModeRound.""" - round_instance = CheckBenchmarkingModeRound(MagicMock(), MagicMock()) - - # Assert that the done_event is BENCHMARKING_ENABLED - assert round_instance.done_event == Event.BENCHMARKING_ENABLED - - # Assert that the negative_event is BENCHMARKING_DISABLED - assert round_instance.negative_event == Event.BENCHMARKING_DISABLED diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_claim_subscription.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_claim_subscription.py deleted file mode 100644 index 48d945d43..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_claim_subscription.py +++ /dev/null @@ -1,227 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -import json -from dataclasses import dataclass, field -from typing import ( - Any, - Callable, - Dict, - FrozenSet, - Hashable, - List, - Mapping, - Optional, - Type, -) -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - CollectionRound, - VotingRound, - get_name, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseVotingRoundTest, -) -from packages.valory.skills.decision_maker_abci.payloads import ClaimPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) - - -# Dummy payload data -DUMMY_PAYLOAD_DATA = {"vote": True} - - -# Data class for test cases -@dataclass -class RoundTestCase: - """Data class to hold round test case details.""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, ClaimPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -# Maximum participants -MAX_PARTICIPANTS: int = 4 - - -# Helper functions for payloads and participants -def get_participants() -> FrozenSet[str]: - """Get participants for the test.""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -def get_participant_to_votes( - participants: FrozenSet[str], vote: bool -) -> Dict[str, ClaimPayload]: - """Map participants to votes.""" - return { - participant: ClaimPayload(sender=participant, vote=vote) - for participant in participants - } - - -def get_participant_to_votes_serialized( - participants: FrozenSet[str], vote: bool -) -> Dict[str, Dict[str, Any]]: - """Get serialized votes from participants.""" - return CollectionRound.serialize_collection( - get_participant_to_votes(participants, vote) - ) - - -def get_payloads( - payload_cls: Type[ClaimPayload], data: Optional[str] -) -> Mapping[str, ClaimPayload]: - """Generate payloads for the test.""" - return { - participant: payload_cls(participant, data is not None) - for participant in get_participants() - } - - -def get_dummy_claim_payload_serialized() -> str: - """Get serialized dummy payload.""" - return json.dumps(DUMMY_PAYLOAD_DATA, sort_keys=True) - - -# Base test class for ClaimRound -class BaseClaimRoundTest(BaseVotingRoundTest): - """Base Test Class for ClaimRound""" - - test_class: Type[VotingRound] - test_payload: Type[ClaimPayload] - - def _test_voting_round( - self, vote: bool, expected_event: Any, threshold_check: Callable - ) -> None: - """Helper method to test voting rounds with positive or negative votes.""" - - test_round = self.test_class( - synchronized_data=self.synchronized_data, context=MagicMock() - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_votes(self.participants, vote=vote), - synchronized_data_update_fn=lambda synchronized_data, test_round: synchronized_data.update( - participant_to_votes=get_participant_to_votes_serialized( - self.participants, vote=vote - ) - ), - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.participant_to_votes.keys() - ] - if vote - else [], - exit_event=expected_event, - threshold_check=threshold_check, - ) - ) - - def test_positive_votes(self) -> None: - """Test ClaimRound with positive votes.""" - self._test_voting_round( - vote=True, - expected_event=self._event_class.DONE, - threshold_check=lambda x: x.positive_vote_threshold_reached, - ) - - def test_negative_votes(self) -> None: - """Test ClaimRound with negative votes.""" - self._test_voting_round( - vote=False, - expected_event=self._event_class.SUBSCRIPTION_ERROR, - threshold_check=lambda x: x.negative_vote_threshold_reached, - ) - - -# Test class for ClaimRound -class TestClaimRound(BaseClaimRoundTest): - """Tests for ClaimRound.""" - - test_class = ClaimRound - _event_class = Event - _synchronized_data_class = SynchronizedData - - @pytest.mark.parametrize( - "test_case", - ( - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_payloads( - ClaimPayload, get_dummy_claim_payload_serialized() - ), - final_data={}, - event=Event.DONE, - most_voted_payload=get_dummy_claim_payload_serialized(), - synchronized_data_attr_checks=[ - lambda sync_data: sync_data.db.get( - get_name(SynchronizedData.participant_to_votes) - ) - == CollectionRound.deserialize_collection( - json.loads(get_dummy_claim_payload_serialized()) - ) - ], - ), - RoundTestCase( - name="No majority", - initial_data={}, - payloads=get_payloads( - ClaimPayload, get_dummy_claim_payload_serialized() - ), - final_data={}, - event=Event.NO_MAJORITY, - most_voted_payload=get_dummy_claim_payload_serialized(), - synchronized_data_attr_checks=[], - ), - ), - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run the parameterized tests.""" - if test_case.event == Event.DONE: - self.test_positive_votes() - elif test_case.event == Event.NO_MAJORITY: - self.test_negative_votes() - - -# Test for SynchronizedData initialization -def test_synchronized_data_initialization() -> None: - """Test SynchronizedData initialization.""" - data = SynchronizedData(db=AbciAppDB(setup_data={"test": ["test"]})) - assert data.db._data == {0: {"test": ["test"]}} diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_receive.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_receive.py deleted file mode 100644 index bcf00f1b1..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_receive.py +++ /dev/null @@ -1,224 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" -import datetime -import json -from dataclasses import dataclass, field -from typing import Any, Callable, Dict, FrozenSet, Hashable, List, Mapping, Optional -from unittest import mock - -import pytest - -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.decision_maker_abci.payloads import DecisionReceivePayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.decision_receive import ( - DecisionReceiveRound, -) -from packages.valory.skills.market_manager_abci.rounds import UpdateBetsPayload - - -DUMMY_DECISION_HASH = "dummy_decision_hash" -DUMMY_PARTICIPANT_TO_DECISION_HASH = json.dumps( - { - "agent_0": "decision_1", - "agent_1": "decision_2", - "agent_2": "decision_3", - } -) -DUMMY_BETS_HASH = "dummy_bets_hash" # Added a dummy bets hash - - -def get_participants() -> FrozenSet[str]: - """Participants.""" - return frozenset([f"agent_{i}" for i in range(4)]) - - -def get_payloads( - vote: Optional[int], - confidence: Optional[float], - bet_amount: Optional[int], - next_mock_data_row: Optional[int], - is_profitable: Optional[bool], - bets_hash: str, - policy: str, -) -> Mapping[str, UpdateBetsPayload]: - """Get payloads.""" - return { - participant: DecisionReceivePayload( - sender=participant, - vote=vote, - confidence=confidence, - bet_amount=bet_amount, - next_mock_data_row=next_mock_data_row, - is_profitable=is_profitable, - bets_hash=bets_hash, - policy=policy, - decision_received_timestamp=int(datetime.datetime.utcnow().timestamp()), - ) - for participant in get_participants() - } - - -@dataclass -class RoundTestCase: - """RoundTestCase for DecisionReceiveRound.""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, UpdateBetsPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -class TestDecisionReceiveRound(BaseCollectSameUntilThresholdRoundTest): - """Tests for DecisionReceiveRound.""" - - _synchronized_data_class = SynchronizedData - - @pytest.mark.parametrize( - "test_case", - ( - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_payloads( - vote=1, - confidence=80.0, - bet_amount=100, - next_mock_data_row=1, - is_profitable=True, - policy="", - bets_hash=DUMMY_BETS_HASH, # Added bets_hash - ), - final_data={ - "decision_hash": DUMMY_DECISION_HASH, - "participant_to_decision_hash": DUMMY_PARTICIPANT_TO_DECISION_HASH, - }, - event=Event.DONE, - most_voted_payload=DUMMY_DECISION_HASH, - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.decision_hash, - ], - ), - RoundTestCase( - name="Unprofitable decision", - initial_data={"is_profitable": False}, - payloads=get_payloads( - vote=0, - confidence=50.0, - bet_amount=50, - next_mock_data_row=2, - is_profitable=False, - policy="", - bets_hash=DUMMY_BETS_HASH, # Added bets_hash - ), - final_data={ - "decision_hash": DUMMY_DECISION_HASH, - "participant_to_decision_hash": DUMMY_PARTICIPANT_TO_DECISION_HASH, - }, - event=Event.UNPROFITABLE, - most_voted_payload=DUMMY_DECISION_HASH, - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.decision_hash, - ], - ), - RoundTestCase( - name="No majority", - initial_data={}, - payloads=get_payloads( - vote=None, - confidence=None, - bet_amount=None, - next_mock_data_row=None, - is_profitable=True, - policy="", - bets_hash=DUMMY_BETS_HASH, # Added bets_hash - ), - final_data={}, - event=Event.NO_MAJORITY, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - RoundTestCase( - name="Tie event", - initial_data={}, - payloads=get_payloads( - vote=None, - confidence=None, - bet_amount=None, - next_mock_data_row=None, - is_profitable=True, - policy="", - bets_hash=DUMMY_BETS_HASH, # Added bets_hash - ), - final_data={}, - event=Event.TIE, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - RoundTestCase( - name="Mechanism response error", - initial_data={"mocking_mode": True}, - payloads=get_payloads( - vote=None, - confidence=None, - bet_amount=None, - next_mock_data_row=None, - is_profitable=True, - policy="", - bets_hash=DUMMY_BETS_HASH, # Added bets_hash - ), - final_data={}, - event=Event.MECH_RESPONSE_ERROR, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - ), - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run tests.""" - self.run_test(test_case) - - def run_test(self, test_case: RoundTestCase) -> None: - """Run the test.""" - self.synchronized_data.update(SynchronizedData, **test_case.initial_data) - - test_round = DecisionReceiveRound( - synchronized_data=self.synchronized_data, context=mock.MagicMock() - ) - - self._test_round( - test_round=test_round, - round_payloads=test_case.payloads, - synchronized_data_update_fn=lambda sync_data, _: sync_data.update( - **test_case.final_data - ), - synchronized_data_attr_checks=test_case.synchronized_data_attr_checks, - most_voted_payload=test_case.most_voted_payload, - exit_event=test_case.event, - ) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_request.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_request.py deleted file mode 100644 index e1a9003a3..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_decision_request.py +++ /dev/null @@ -1,157 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -import json -from dataclasses import dataclass, field -from typing import Any, Callable, Dict, FrozenSet, Hashable, List, Mapping, Optional -from unittest import mock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.decision_maker_abci.payloads import DecisionRequestPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.decision_request import ( - DecisionRequestRound, -) - - -DUMMY_REQUEST_HASH = "dummy_request_hash" -DUMMY_PARTICIPANT_TO_SELECTION_HASH = json.dumps( - { - "agent_0": "selection_1", - "agent_1": "selection_2", - "agent_2": "selection_3", - } -) - - -def get_participants() -> FrozenSet[str]: - """Participants.""" - return frozenset([f"agent_{i}" for i in range(4)]) - - -def get_payloads(data: Optional[str]) -> Mapping[str, BaseTxPayload]: - """Get payloads.""" - return { - participant: DecisionRequestPayload(participant, data) - for participant in get_participants() - } - - -@dataclass -class RoundTestCase: - """RoundTestCase for DecisionRequestRound.""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, BaseTxPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -class TestDecisionRequestRound(BaseCollectSameUntilThresholdRoundTest): - """Tests for DecisionRequestRound.""" - - _synchronized_data_class = SynchronizedData # Define the missing attribute - - @pytest.mark.parametrize( - "test_case", - ( - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_payloads(data=DUMMY_REQUEST_HASH), - final_data={ - "request_hash": DUMMY_REQUEST_HASH, - "participant_to_selection_hash": DUMMY_PARTICIPANT_TO_SELECTION_HASH, - }, - event=Event.DONE, - most_voted_payload=DUMMY_REQUEST_HASH, - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.request_hash, - ], - ), - RoundTestCase( - name="Mocking mode", - initial_data={"mocking_mode": True}, - payloads=get_payloads(data=DUMMY_REQUEST_HASH), - final_data={ - "request_hash": DUMMY_REQUEST_HASH, - "participant_to_selection_hash": DUMMY_PARTICIPANT_TO_SELECTION_HASH, - }, - event=Event.MOCK_MECH_REQUEST, - most_voted_payload=DUMMY_REQUEST_HASH, - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.request_hash, - ], - ), - RoundTestCase( - name="No majority", - initial_data={}, - payloads=get_payloads(data=None), # Simulating insufficient votes - final_data={}, - event=Event.NO_MAJORITY, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - RoundTestCase( - name="None event", - initial_data={}, - payloads=get_payloads(data=None), # Simulating unsupported slots - final_data={}, - event=Event.SLOTS_UNSUPPORTED_ERROR, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - ), - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run tests.""" - self.run_test(test_case) - - def run_test(self, test_case: RoundTestCase) -> None: - """Run the test.""" - self.synchronized_data.update(SynchronizedData, **test_case.initial_data) - - test_round = DecisionRequestRound( - synchronized_data=self.synchronized_data, context=mock.MagicMock() - ) - - self._test_round( - test_round=test_round, - round_payloads=test_case.payloads, - synchronized_data_update_fn=lambda sync_data, _: sync_data.update( - **test_case.final_data - ), - synchronized_data_attr_checks=test_case.synchronized_data_attr_checks, - most_voted_payload=test_case.most_voted_payload, - exit_event=test_case.event, - ) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_final_states.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_final_states.py deleted file mode 100644 index 60e26a15b..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_final_states.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -from typing import Any, Dict, List, Tuple - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - BaseSynchronizedData, - DegenerateRound, -) -from packages.valory.skills.decision_maker_abci.states.final_states import ( - BenchmarkingDoneRound, - BenchmarkingModeDisabledRound, - FinishedDecisionMakerRound, - FinishedDecisionRequestRound, - FinishedSubscriptionRound, - FinishedWithoutDecisionRound, - FinishedWithoutRedeemingRound, - ImpossibleRound, - RefillRequiredRound, -) - - -class MockSynchronizedData(BaseSynchronizedData): - """A mock class for SynchronizedData.""" - - def __init__(self, db: AbciAppDB) -> None: - """Mock function""" - super().__init__(db) # Pass db to the parent class - - -class MockContext: - """A mock class for context used in the rounds.""" - - def __init__(self) -> None: - """Mock function""" - self.some_attribute = "mock_value" # Add any necessary attributes here - - -class TestFinalStates: - """The class for test of Final States""" - - @pytest.fixture - def setup_round(self) -> Tuple[MockSynchronizedData, MockContext]: - """Fixture to set up a round instance.""" - setup_data: Dict[str, List[Any]] = {} - mock_db = AbciAppDB(setup_data) - synchronized_data = MockSynchronizedData(db=mock_db) # Provide a mock db value - context = MockContext() - return synchronized_data, context - - def test_benchmarking_mode_disabled_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of BenchmarkingModeDisabledRound.""" - synchronized_data, context = setup_round - round_instance = BenchmarkingModeDisabledRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, BenchmarkingModeDisabledRound) - assert isinstance(round_instance, DegenerateRound) - - def test_finished_decision_maker_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of FinishedDecisionMakerRound.""" - synchronized_data, context = setup_round - round_instance = FinishedDecisionMakerRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, FinishedDecisionMakerRound) - assert isinstance(round_instance, DegenerateRound) - - def test_finished_decision_request_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of FinishedDecisionRequestRound.""" - synchronized_data, context = setup_round - round_instance = FinishedDecisionRequestRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, FinishedDecisionRequestRound) - assert isinstance(round_instance, DegenerateRound) - - def test_finished_subscription_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of FinishedSubscriptionRound.""" - synchronized_data, context = setup_round - round_instance = FinishedSubscriptionRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, FinishedSubscriptionRound) - assert isinstance(round_instance, DegenerateRound) - - def test_finished_without_redeeming_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of FinishedWithoutRedeemingRound.""" - synchronized_data, context = setup_round - round_instance = FinishedWithoutRedeemingRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, FinishedWithoutRedeemingRound) - assert isinstance(round_instance, DegenerateRound) - - def test_finished_without_decision_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of FinishedWithoutDecisionRound.""" - synchronized_data, context = setup_round - round_instance = FinishedWithoutDecisionRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, FinishedWithoutDecisionRound) - assert isinstance(round_instance, DegenerateRound) - - def test_refill_required_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of RefillRequiredRound.""" - synchronized_data, context = setup_round - round_instance = RefillRequiredRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, RefillRequiredRound) - assert isinstance(round_instance, DegenerateRound) - - def test_benchmarking_done_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of BenchmarkingDoneRound and its end_block method.""" - synchronized_data, context = setup_round - round_instance = BenchmarkingDoneRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, BenchmarkingDoneRound) - assert isinstance(round_instance, DegenerateRound) - - # Test the end_block method - with pytest.raises(SystemExit): - round_instance.end_block() # Should exit the program - - def test_impossible_round( - self, setup_round: Tuple[MockSynchronizedData, MockContext] - ) -> None: - """Test instantiation of ImpossibleRound.""" - synchronized_data, context = setup_round - round_instance = ImpossibleRound( - context=context, synchronized_data=synchronized_data - ) - assert isinstance(round_instance, ImpossibleRound) - assert isinstance(round_instance, DegenerateRound) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_handle_failed_tx.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_handle_failed_tx.py deleted file mode 100644 index 53fe7db7d..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_handle_failed_tx.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -from typing import Dict, Optional -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import CollectionRound -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.decision_maker_abci.payloads import HandleFailedTxPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.handle_failed_tx import ( - HandleFailedTxRound, -) - - -class TestEstimateConsensusRound(BaseCollectSameUntilThresholdRoundTest): - """Test EstimateConsensusRound.""" - - _synchronized_data_class = SynchronizedData - _event_class = Event - - def get_participant_to_handle( - self, vote: Optional[bool] - ) -> Dict[str, HandleFailedTxPayload]: - """Map participants to votes.""" - return { - participant: HandleFailedTxPayload( - sender=participant, vote=vote, tx_submitter="tx_submitter" # type: ignore - ) - for participant in self.participants - } - - @pytest.mark.parametrize( - "vote, expected_event", - ( - (None, HandleFailedTxRound.none_event), - (True, HandleFailedTxRound.done_event), - (False, HandleFailedTxRound.no_op_event), - ), - ) - def test_run( - self, - vote: Optional[bool], - expected_event: Event, - ) -> None: - """Runs test.""" - - test_round = HandleFailedTxRound( - synchronized_data=self.synchronized_data, context=MagicMock() - ) - participant_to_handle = self.get_participant_to_handle(vote) - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=participant_to_handle, - synchronized_data_update_fn=lambda _synchronized_data, _test_round: _synchronized_data.update( - participant_to_handle_failed_tx=CollectionRound.serialize_collection( - participant_to_handle - ), - most_voted_estimate=_test_round.most_voted_payload, - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.participant_to_handle_failed_tx.keys() - ], - most_voted_payload=vote, - exit_event=expected_event, - ) - ) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_order_subscription.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_order_subscription.py deleted file mode 100644 index 82c026e62..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_order_subscription.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -from typing import Any, Optional, Type -from unittest.mock import MagicMock, patch - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - BaseSynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.base import Event -from packages.valory.skills.decision_maker_abci.states.order_subscription import ( - SubscriptionRound, -) - - -# Dummy values for testing -class MockSynchronizedData(BaseSynchronizedData): - """The class for testing""" - - def __init__(self, db: AbciAppDB) -> None: - """Mock""" - super().__init__(db=db) - self.agreement_id: Optional[str] = "dummy_agreement_id" - - def update( - self, synchronized_data_class: Optional[Type[Any]] = None, **kwargs: Any - ) -> "MockSynchronizedData": - """Mock the update method to simulate updating agreement_id.""" - updated_data = self.__class__( - self.db - ) # Use self.db directly as AbciAppDB might not have a 'copy' method - updated_data.__dict__.update(kwargs) - return updated_data - - -@pytest.fixture -def setup_subscription_round() -> SubscriptionRound: - """Fixture to set up a basic SubscriptionRound instance.""" - mock_synchronized_data = MockSynchronizedData( - db=AbciAppDB(setup_data={}) - ) # Ensure setup_data is passed - round_instance = SubscriptionRound( - synchronized_data=mock_synchronized_data, context=MagicMock() - ) - return round_instance - - -def test_threshold_reached_with_error( - setup_subscription_round: SubscriptionRound, -) -> None: - """Test when the threshold is reached and the transaction is an error.""" - round_instance = setup_subscription_round - with patch.object( - SubscriptionRound, - "threshold_reached", - new_callable=MagicMock(return_value=True), - ): - with patch.object( - SubscriptionRound, - "most_voted_payload_values", - new_callable=MagicMock(return_value=[None, round_instance.ERROR_PAYLOAD]), - ): - result = round_instance.end_block() - - assert result == ( - round_instance.synchronized_data, - Event.SUBSCRIPTION_ERROR, - ) - - -def test_threshold_reached_with_no_tx( - setup_subscription_round: SubscriptionRound, -) -> None: - """Test when the threshold is reached and there's no transaction.""" - round_instance = setup_subscription_round - with patch.object( - SubscriptionRound, - "threshold_reached", - new_callable=MagicMock(return_value=True), - ): - with patch.object( - SubscriptionRound, - "most_voted_payload_values", - new_callable=MagicMock(return_value=[None, round_instance.NO_TX_PAYLOAD]), - ): - result = round_instance.end_block() - - assert result == (round_instance.synchronized_data, Event.NO_SUBSCRIPTION) - - -def test_threshold_reached_with_mock_tx( - setup_subscription_round: SubscriptionRound, -) -> None: - """Test when the threshold is reached and benchmarking mode is enabled.""" - round_instance = setup_subscription_round - round_instance.context.benchmarking_mode.enabled = True - with patch.object( - SubscriptionRound, - "threshold_reached", - new_callable=MagicMock(return_value=True), - ): - with patch.object( - SubscriptionRound, - "most_voted_payload_values", - new_callable=MagicMock(return_value=[None, "mock_tx_hash"]), - ): - result = round_instance.end_block() - - assert result == (round_instance.synchronized_data, Event.MOCK_TX) - - -def test_end_block_updates_sync_data( - setup_subscription_round: SubscriptionRound, -) -> None: - """Test if the agreement_id is correctly updated in synchronized data.""" - round_instance = setup_subscription_round - # Patch the `most_voted_payload_values` to return a list with the new agreement ID - with patch.object( - SubscriptionRound, - "most_voted_payload_values", - new_callable=MagicMock( - return_value=[None, None, None, "new_agreement_id", 10000] - ), - ): - # Call the `end_block` method to trigger the update - result = round_instance.end_block() - # Check the updated synchronized_data object returned by end_block - if result is not None: - sync_data, event = result - # Assert that the agreement_id was updated to the new_agreement_id - assert getattr(sync_data, "agreement_id", None) == "new_agreement_id" - assert getattr(sync_data, "wallet_balance", None) == 10000 - assert event is not None - - -def test_no_update_when_threshold_not_reached( - setup_subscription_round: SubscriptionRound, -) -> None: - """Test when the threshold is not reached, there should be no changes.""" - round_instance = setup_subscription_round - with patch.object( - SubscriptionRound, - "threshold_reached", - new_callable=MagicMock(return_value=False), - ): - with patch( - "packages.valory.skills.decision_maker_abci.states.order_subscription.SubscriptionRound.end_block", - return_value=None, - ) as mock_super: - result = round_instance.end_block() - - assert result is None - mock_super.assert_called_once() diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_randomness.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_randomness.py deleted file mode 100644 index 4dd8e6256..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_randomness.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 test cases for the RandomnessRound class.""" - -import pytest - -from packages.valory.skills.decision_maker_abci.rounds import RandomnessRound -from packages.valory.skills.decision_maker_abci.states.base import Event -from packages.valory.skills.transaction_settlement_abci.rounds import ( - RandomnessTransactionSubmissionRound, -) - - -class MockSynchronizedData: - """A mock class for SynchronizedData to provide necessary attributes.""" - - pass - - -class MockContext: - """A mock class for context used in RandomnessTransactionSubmissionRound.""" - - def __init__(self) -> None: - """Initialize the MockContext with necessary attributes.""" - self.sender = "mock_sender" - - -class TestRandomnessRound: - """Test suite for the RandomnessRound class.""" - - @pytest.fixture - def setup_randomness_round(self) -> RandomnessRound: - """Fixture to set up a RandomnessRound instance.""" - context = MockContext() - synchronized_data = MockSynchronizedData() - return RandomnessRound(context=context, synchronized_data=synchronized_data) - - def test_randomness_round_properties( - self, setup_randomness_round: RandomnessRound - ) -> None: - """Test the properties of the RandomnessRound class.""" - randomness_round = setup_randomness_round - - assert randomness_round.done_event == Event.DONE - assert randomness_round.no_majority_event == Event.NO_MAJORITY - - def test_randomness_round_inherits_randomness_transaction_submission_round( - self, - ) -> None: - """Test that RandomnessRound inherits from RandomnessTransactionSubmissionRound.""" - assert issubclass(RandomnessRound, RandomnessTransactionSubmissionRound) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_redeem.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_redeem.py deleted file mode 100644 index a35c9c084..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_redeem.py +++ /dev/null @@ -1,170 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test for Redeem round""" - -from typing import Any, Dict, Optional -from unittest.mock import PropertyMock, patch - -import pytest - -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.redeem import RedeemRound - - -class MockDB(AbciAppDB): - """Mock database for testing.""" - - def __init__(self) -> None: - """Initialize the mock database.""" - setup_data: Dict[str, Any] = {} - super().__init__(setup_data=setup_data) - self.data: Dict[str, Optional[int]] = {} - - def get(self, key: str, default: Optional[int] = None) -> Optional[int]: - """Get value from mock db.""" - return self.data.get(key, default) - - def update(self, **kwargs: Any) -> None: - """Update mock db.""" - self.data.update(kwargs) - - -class MockSynchronizedData(SynchronizedData): - """Mock synchronized data for testing.""" - - def __init__(self) -> None: - """Initialize mock synchronized data.""" - db = MockDB() - super().__init__(db) - self._period_count = 0 - - @property - def period_count(self) -> int: - """Get period count.""" - return self._period_count - - @period_count.setter - def period_count(self, value: int) -> None: - """Set period count.""" - self._period_count = value - - -class MockContext: - """Mock context for testing.""" - - def __init__(self) -> None: - """Initialize mock context.""" - self.params: Dict[str, Optional[int]] = {} - - -class TestRedeemRound: - """Tests for the RedeemRound class.""" - - @pytest.fixture - def setup_redeem_round(self) -> RedeemRound: - """Set up a RedeemRound instance.""" - mock_synchronized_data = MockSynchronizedData() - mock_context = MockContext() - redeem_round = RedeemRound( - context=mock_context, synchronized_data=mock_synchronized_data - ) - return redeem_round - - def test_initial_attributes(self, setup_redeem_round: RedeemRound) -> None: - """Test initial attributes.""" - redeem_round = setup_redeem_round - assert redeem_round.payload_class is not None - assert redeem_round.payload_class.__name__ == "RedeemPayload" - assert redeem_round.none_event == Event.NO_REDEEMING - - def test_selection_key(self, setup_redeem_round: RedeemRound) -> None: - """Test selection key generation.""" - redeem_round = setup_redeem_round - assert isinstance(redeem_round.selection_key, tuple) - assert all(isinstance(key, str) for key in redeem_round.selection_key) - - def test_selection_key_contains_mech_tools_name( - self, setup_redeem_round: RedeemRound - ) -> None: - """Test that mech_tools_name is part of the selection key.""" - redeem_round = setup_redeem_round - assert RedeemRound.mech_tools_name in redeem_round.selection_key - - @pytest.mark.parametrize( - "period_count, expected_confirmations, expected_event", - [ - (0, 1, Event.NO_MAJORITY), # Test without update - (1, 0, Event.NO_MAJORITY), # Test with update - ], - ) - def test_end_block_update_behavior( - self, - setup_redeem_round: RedeemRound, - period_count: int, - expected_confirmations: int, - expected_event: Event, - ) -> None: - """Test end_block behavior based on period_count.""" - redeem_round = setup_redeem_round - - with patch.object( - MockSynchronizedData, "period_count", new_callable=PropertyMock - ) as mock_period_count: - mock_period_count.return_value = period_count - - result = redeem_round.end_block() - - if result is None: - # Case where no update occurs - assert redeem_round.block_confirmations == expected_confirmations - else: - # Case where update occurs - synchronized_data, event = result - assert isinstance(synchronized_data, MockSynchronizedData) - assert event == expected_event - - def test_most_voted_payload_values(self, setup_redeem_round: RedeemRound) -> None: - """Test most_voted_payload_values property.""" - redeem_round = setup_redeem_round - # Mock `most_voted_payload_values` to return the expected result - with patch.object( - RedeemRound, "most_voted_payload_values", new_callable=PropertyMock - ) as mock_values: - mock_values.return_value = (None,) - values = redeem_round.most_voted_payload_values - assert values == (None,) - - def test_most_voted_payload_dict_processing( - self, setup_redeem_round: RedeemRound - ) -> None: - """Test processing of most_voted_payload_dict in most_voted_payload_values.""" - redeem_round = setup_redeem_round - # Mock `most_voted_payload_values` to simulate dictionary processing in the property - with patch.object( - RedeemRound, "most_voted_payload_values", new_callable=PropertyMock - ) as mock_values: - mock_values.return_value = ("tool_data",) - - values = redeem_round.most_voted_payload_values - assert values is not None # Ensure it executes without error diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_sampling.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_sampling.py deleted file mode 100644 index 50594d9bd..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_sampling.py +++ /dev/null @@ -1,118 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - -import pytest - -from packages.valory.skills.abstract_round_abci.base import AbciAppDB, get_name -from packages.valory.skills.decision_maker_abci.payloads import SamplingPayload -from packages.valory.skills.decision_maker_abci.rounds import SamplingRound -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.market_manager_abci.rounds import UpdateBetsRound - - -# Mock classes to simulate required attributes -class MockSynchronizedData(SynchronizedData): - """A mock class for SynchronizedData to provide necessary attributes.""" - - sampled_bet_index = 0 # Default value for sampled_bet_index - benchmarking_finished = False - simulated_day = False - - def __init__(self, db: AbciAppDB): - """Initialize MockSynchronizedData with the given db.""" - super().__init__(db) - - -class MockContext: - """A mock class for context used in AbstractRound.""" - - def __init__(self) -> None: - """Mock function""" - self.sender = "mock_sender" - self.bets_hash = "mock_bets_hash" - - -class TestSamplingRound: - """The class for testing Sampling Round""" - - @pytest.fixture - def setup_sampling_round(self) -> SamplingRound: - """Fixture to set up a SamplingRound instance.""" - context = MockContext() - synchronized_data = MockSynchronizedData( - db=AbciAppDB({}) - ) # Passing a mock AbciAppDB instance - return SamplingRound(context=context, synchronized_data=synchronized_data) - - def test_sampling_round_properties( - self, setup_sampling_round: SamplingRound - ) -> None: - """Test the properties of the SamplingRound class.""" - sampling_round = setup_sampling_round - assert sampling_round.payload_class == SamplingPayload - assert sampling_round.done_event == Event.DONE - assert sampling_round.none_event == Event.NONE - assert sampling_round.no_majority_event == Event.NO_MAJORITY - assert sampling_round.selection_key is not None - - def test_sampling_payload_initialization(self) -> None: - """Test the initialization of the SamplingPayload.""" - payload = SamplingPayload( - sender="mock_sender", - bets_hash="mock_bets_hash", - index=0, - benchmarking_finished=False, - day_increased=False, - ) # Added index - assert payload is not None - assert payload.sender == "mock_sender" - assert payload.bets_hash == "mock_bets_hash" - assert payload.index == 0 # Check that the index is correctly initialized - - def test_sampling_round_inherits_update_bets_round(self) -> None: - """Test that SamplingRound inherits from UpdateBetsRound.""" - assert issubclass(SamplingRound, UpdateBetsRound) - - def test_sampling_round_selection_key( - self, setup_sampling_round: SamplingRound - ) -> None: - """Test the selection key property of SamplingRound.""" - sampling_round = setup_sampling_round - expected_selection_key = ( - UpdateBetsRound.selection_key, - get_name(SynchronizedData.sampled_bet_index), - get_name(SynchronizedData.benchmarking_finished), - get_name(SynchronizedData.simulated_day), - # Pass the property, not the value - ) - assert sampling_round.selection_key == expected_selection_key - - def test_sampling_round_event_handling( - self, setup_sampling_round: SamplingRound - ) -> None: - """Test event handling in SamplingRound.""" - sampling_round = setup_sampling_round - # Simulate event handling through method calls or appropriate property checks - assert sampling_round.done_event == Event.DONE - assert sampling_round.no_majority_event == Event.NO_MAJORITY diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_tool_selection.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_tool_selection.py deleted file mode 100644 index 583b774e0..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/states/test_tool_selection.py +++ /dev/null @@ -1,149 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for Decision Maker""" - - -from dataclasses import dataclass, field -from typing import Any, Callable, Dict, Hashable, List, Mapping, Optional -from unittest import mock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.decision_maker_abci.payloads import ToolSelectionPayload -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.tool_selection import ( - ToolSelectionRound, -) - - -DUMMY_TOOL_SELECTION_HASH = "dummy_tool_selection_hash" -DUMMY_POLICY = "dummy_policy" -DUMMY_UTILIZED_TOOLS = "dummy_utilized_tools" -DUMMY_MECH_TOOLS = "dummy_mech_tools" -DUMMY_SELECTED_TOOL = "dummy_selected_tool" -DUMMY_PARTICIPANT_TO_SELECTION_HASH = ( - '{"agent_0": "tool_1", "agent_1": "tool_2", "agent_2": "tool_3"}' -) - - -def get_participants() -> List[str]: - """Returns a list of participants.""" - return [f"agent_{i}" for i in range(4)] - - -def get_payloads(data: Optional[str]) -> Mapping[str, BaseTxPayload]: - """Returns payloads for the test.""" - return { - participant: ToolSelectionPayload( - participant, - policy=DUMMY_POLICY, - utilized_tools=DUMMY_UTILIZED_TOOLS, - selected_tool=data, - mech_tools=DUMMY_MECH_TOOLS, # Add the missing mech_tools argument - ) - for participant in get_participants() - } - - -@dataclass -class RoundTestCase: - """Test case structure for ToolSelectionRound.""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, BaseTxPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -class TestToolSelectionRound(BaseCollectSameUntilThresholdRoundTest): - """Tests for ToolSelectionRound.""" - - _synchronized_data_class = SynchronizedData - - @pytest.mark.parametrize( - "test_case", - [ - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_payloads(data=DUMMY_TOOL_SELECTION_HASH), - final_data={ - "mech_tool": DUMMY_TOOL_SELECTION_HASH, - "participant_to_selection_hash": DUMMY_PARTICIPANT_TO_SELECTION_HASH, - }, - event=Event.DONE, - most_voted_payload=DUMMY_TOOL_SELECTION_HASH, - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.mech_tool, - ], - ), - RoundTestCase( - name="No majority", - initial_data={}, - payloads=get_payloads(data=None), # Simulating no majority - final_data={}, - event=Event.NO_MAJORITY, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - RoundTestCase( - name="None event", - initial_data={}, - payloads=get_payloads(data=None), # Simulating unsupported selection - final_data={}, - event=Event.NONE, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - ], - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run each test case.""" - self.run_test(test_case) - - def run_test(self, test_case: RoundTestCase) -> None: - """Run a single test case.""" - self.synchronized_data.update(SynchronizedData, **test_case.initial_data) - - test_round = ToolSelectionRound( - synchronized_data=self.synchronized_data, context=mock.MagicMock() - ) - - self._test_round( - test_round=test_round, - round_payloads=test_case.payloads, - synchronized_data_update_fn=lambda sync_data, _: sync_data.update( - **test_case.final_data - ), - synchronized_data_attr_checks=test_case.synchronized_data_attr_checks, - most_voted_payload=test_case.most_voted_payload, - exit_event=test_case.event, - ) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/test_dialogues.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/test_dialogues.py deleted file mode 100644 index f2be77cd6..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.decision_maker_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/test_handlers.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/test_handlers.py deleted file mode 100644 index f934bbbe4..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/test_handlers.py +++ /dev/null @@ -1,381 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the tests for the handlers for the decision maker abci.""" -import json -from dataclasses import dataclass -from typing import Any, Dict, Union -from unittest import mock -from unittest.mock import MagicMock, patch - -import pytest -from aea.configurations.data_types import PublicId -from aea.skills.base import Handler - -from packages.valory.connections.http_server.connection import ( - PUBLIC_ID as HTTP_SERVER_PUBLIC_ID, -) -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.ipfs import IpfsMessage -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.decision_maker_abci.handlers import ( - ABCIHandler, - ContractApiHandler, - HttpHandler, - HttpMethod, - IpfsHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, -) - - -@dataclass -class GetHandlerTestCase: - """Get Handler test case.""" - - name: str - url: str - method: str - expected_handler: Union[str, None] - - -@dataclass -class HandleTestCase: - """Handle test case.""" - - name: str - message_performative: str - message_sender: str - get_handler_return_value: tuple - message_url: Union[str, None] = None - message_method: Union[str, None] = None - update_return_value: Union[MagicMock, None] = None - expected_logger_call: Union[str, None] = None - expected_handler_call: bool = False - - -@pytest.mark.parametrize( - "handler, base_handler", - [ - (ABCIHandler, BaseABCIRoundHandler), - (SigningHandler, BaseSigningHandler), - (LedgerApiHandler, BaseLedgerApiHandler), - (ContractApiHandler, BaseContractApiHandler), - (TendermintHandler, BaseTendermintHandler), - ], -) -def test_handler(handler: Handler, base_handler: Handler) -> None: - """Test that the 'handlers.py' of the DecisionMakerAbci can be imported.""" - handler = handler( - name="dummy_handler", - skill_context=MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")), - ) - - assert isinstance(handler, base_handler) - - -class TestIpfsHandler: - """Class for testing the IPFS Handler.""" - - def setup(self) -> None: - """Set up the tests.""" - self.context = MagicMock() - self.handler = IpfsHandler(name="", skill_context=self.context) - - def test_handle(self) -> None: - """Test the 'handle' method.""" - callback = MagicMock() - request_reference = "reference" - self.handler.shared_state.req_to_callback = {} - self.handler.shared_state.req_to_callback[request_reference] = callback - - mock_dialogue = MagicMock() - mock_dialogue.dialogue_label.dialogue_reference = [request_reference] - - with mock.patch.object( - self.handler.context.ipfs_dialogues, "update", return_value=mock_dialogue - ): - mock_message = MagicMock(performative=IpfsMessage.Performative.FILES) - self.handler.handle(mock_message) - - callback.assert_called_once_with(mock_message, mock_dialogue) - - def test_handle_negative_performative_not_allowed(self) -> None: - """Test the 'handle' method, negative case (performative not allowed).""" - self.handler.handle(MagicMock()) - - -class TestHttpHandler: - """Class for testing the Http Handler.""" - - def setup(self) -> None: - """Set up the tests.""" - self.context = MagicMock() - self.context.logger = MagicMock() - self.handler = HttpHandler(name="", skill_context=self.context) - self.handler.context.params.service_endpoint = "http://localhost:8080/some/path" - self.handler.setup() - - def test_setup(self) -> None: - """Test the setup method of HttpHandler.""" - - config_uri_base_hostname = "localhost" - propel_uri_base_hostname = ( - r"https?:\/\/[a-zA-Z0-9]{16}.agent\.propel\.(staging\.)?autonolas\.tech" - ) - local_ip_regex = r"192\.168(\.\d{1,3}){2}" - hostname_regex = rf".*({config_uri_base_hostname}|{propel_uri_base_hostname}|{local_ip_regex}|localhost|127.0.0.1|0.0.0.0)(:\d+)?" - health_url_regex = rf"{hostname_regex}\/healthcheck" - assert self.handler.handler_url_regex == rf"{hostname_regex}\/.*" - assert self.handler.routes == { - (HttpMethod.GET.value, HttpMethod.HEAD.value): [ - (health_url_regex, self.handler._handle_get_health), - ], - } - assert self.handler.json_content_header == "Content-Type: application/json\n" - - @pytest.mark.parametrize( - "test_case", - [ - GetHandlerTestCase( - name="Happy Path", - url="http://localhost:8080/healthcheck", - method=HttpMethod.GET.value, - expected_handler="_handle_get_health", - ), - GetHandlerTestCase( - name="No url match", - url="http://invalid.url/not/matching", - method=HttpMethod.GET.value, - expected_handler=None, - ), - GetHandlerTestCase( - name="No method match", - url="http://localhost:8080/some/path", - method=HttpMethod.POST.value, - expected_handler="_handle_bad_request", - ), - ], - ) - def test_get_handler(self, test_case: GetHandlerTestCase) -> None: - """Test _get_handler.""" - url = test_case.url - method = test_case.method - - if test_case.expected_handler is not None: - expected_handler = getattr(self.handler, test_case.expected_handler) - else: - expected_handler = test_case.expected_handler - expected_captures: Dict[Any, Any] = {} - - handler, captures = self.handler._get_handler(url, method) - - assert handler == expected_handler - assert captures == expected_captures - - @pytest.mark.parametrize( - "test_case", - [ - HandleTestCase( - name="Test Handle", - message_performative=HttpMessage.Performative.RESPONSE, - message_sender="incorrect sender", - get_handler_return_value=(None, {}), - ), - HandleTestCase( - name="Test Handle No Handler", - message_performative=HttpMessage.Performative.REQUEST, - message_sender=str(HTTP_SERVER_PUBLIC_ID.without_hash()), - message_url="http://localhost/test", - message_method="GET", - get_handler_return_value=(None, {}), - ), - HandleTestCase( - name="Test Handle Invalid Dialogue", - message_performative=HttpMessage.Performative.REQUEST, - message_sender=str(HTTP_SERVER_PUBLIC_ID.without_hash()), - message_url="http://localhost/test", - message_method="GET", - get_handler_return_value=(lambda x, y: None, {}), - update_return_value=None, - expected_logger_call="Received invalid http message={}, unidentified dialogue.", - ), - HandleTestCase( - name="Test Handle Valid Message", - message_performative=HttpMessage.Performative.REQUEST, - message_sender=str(HTTP_SERVER_PUBLIC_ID.without_hash()), - message_url="http://localhost/test", - message_method="GET", - get_handler_return_value=(MagicMock(), {"key": "value"}), - update_return_value=MagicMock(), - expected_handler_call=True, - expected_logger_call="Received http request with method={}, url={} and body={!r}", - ), - ], - ) - def test_handle(self, test_case: HandleTestCase) -> None: - """Parameterized test for 'handle' method.""" - - self.message = MagicMock(performative=test_case.message_performative) - self.message.sender = test_case.message_sender - self.message.url = test_case.message_url - self.message.method = test_case.message_method - - with patch.object( - self.handler, - "_get_handler", - return_value=test_case.get_handler_return_value, - ), patch.object( - BaseHttpHandler, "handle", return_value=None - ) as mock_super_handle: - if not test_case.expected_logger_call: - self.handler.handle(self.message) - mock_super_handle.assert_called_once_with(self.message) - else: - http_dialogues_mock = MagicMock() - self.context.http_dialogues = http_dialogues_mock - http_dialogues_mock.update.return_value = test_case.update_return_value - self.handler.handle(self.message) - - if not test_case.expected_handler_call: - self.context.logger.info.assert_called_with( - test_case.expected_logger_call.format(self.message) - ) - else: - test_case.get_handler_return_value[0].assert_called_with( - self.message, - http_dialogues_mock.update.return_value, - key="value", - ) - self.context.logger.info.assert_called_with( - test_case.expected_logger_call.format( - self.message.method, self.message.url, self.message.body - ) - ) - - def test_handle_bad_request(self) -> None: - """Test handle with a bad request.""" - http_msg = MagicMock() - http_dialogue = MagicMock() - - # Configure the mocks - http_msg.version = "1.1" - http_msg.headers = {"Content-Type": "application/json"} - http_dialogue.reply.return_value = MagicMock() - - # Call the method - self.handler._handle_bad_request(http_msg, http_dialogue) - - # Verify that the reply method was called with the correct arguments - http_dialogue.reply.assert_called_once_with( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_msg, - version=http_msg.version, - status_code=400, - status_text="Bad request", - headers=http_msg.headers, - body=b"", - ) - - # Verify that the logger was called with the expected message - http_response = http_dialogue.reply.return_value - self.handler.context.logger.info.assert_called_once_with( - "Responding with: {}".format(http_response) - ) - - # Verify that the message was put into the outbox - self.handler.context.outbox.put_message.assert_called_once_with( - message=http_response - ) - - def test_send_ok_response(self) -> None: - """Test send_ok_response function.""" - http_msg = MagicMock() - http_dialogue = MagicMock() - data = {"key": "value"} - - mock_response = MagicMock() - http_dialogue.reply.return_value = mock_response - - # Call the method - self.handler._send_ok_response(http_msg, http_dialogue, data) - - # Verify that the reply method was called with the correct arguments - http_dialogue.reply.assert_called_once_with( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_msg, - version=http_msg.version, - status_code=200, - status_text="Success", - headers=f"{self.handler.json_content_header}{http_msg.headers}", - body=json.dumps(data).encode("utf-8"), - ) - - self.handler.context.logger.info.assert_called_once_with( - "Responding with: {}".format(mock_response) - ) - self.handler.context.outbox.put_message.assert_called_once_with( - message=mock_response - ) - - def test_send_not_found_response(self) -> None: - """Test _send_not_found_response.""" - - http_msg = MagicMock() - http_dialogue = MagicMock() - - # Create a mock response - mock_response = MagicMock() - http_dialogue.reply.return_value = mock_response - - self.handler._send_not_found_response(http_msg, http_dialogue) - - http_dialogue.reply.assert_called_once_with( - performative=HttpMessage.Performative.RESPONSE, - target_message=http_msg, - version=http_msg.version, - status_code=404, - status_text="Not found", - headers=http_msg.headers, - body=b"", - ) - - self.handler.context.logger.info.assert_called_once_with( - "Responding with: {}".format(mock_response) - ) - self.handler.context.outbox.put_message.assert_called_once_with( - message=mock_response - ) diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/test_payloads.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/test_payloads.py deleted file mode 100644 index f406adc7e..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/test_payloads.py +++ /dev/null @@ -1,136 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the transaction payloads for the decision maker abci.""" - -from datetime import datetime -from typing import Dict, Type - -import pytest - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.decision_maker_abci.payloads import ( - BlacklistingPayload, - ClaimPayload, - DecisionReceivePayload, - DecisionRequestPayload, - MultisigTxPayload, - RedeemPayload, - SamplingPayload, - SubscriptionPayload, - ToolSelectionPayload, - VotingPayload, -) - - -@pytest.mark.parametrize( - "payload_class, payload_kwargs", - [ - ( - DecisionReceivePayload, - { - "bets_hash": "dummy bets hash", - "is_profitable": True, - "vote": True, - "confidence": 0.90, - "bet_amount": 1, - "next_mock_data_row": 1, - "policy": "dummy policy", - "decision_received_timestamp": int(datetime.utcnow().timestamp()), - }, - ), - ( - SamplingPayload, - { - "index": 1, - "bets_hash": "dummy_bets_hash", - "benchmarking_finished": False, - "day_increased": False, - }, - ), - ( - MultisigTxPayload, - { - "tx_submitter": "dummy tx submitter", - "tx_hash": "dummy tx hash", - "mocking_mode": True, - }, - ), - ( - RedeemPayload, - { - "tx_submitter": "dummy tx submitter", - "tx_hash": "dummy tx hash", - "mocking_mode": True, - "mech_tools": "dummy mech tools", - "policy": "dummy policy", - "utilized_tools": "dummy utilized tools", - "redeemed_condition_ids": "dummy redeemed condition ids", - "payout_so_far": 1, - }, - ), - ( - DecisionRequestPayload, - { - "mech_requests": "dummy mech requests", - "mocking_mode": True, - }, - ), - ( - SubscriptionPayload, - { - "agreement_id": "", - "tx_submitter": "dummy tx submitter", - "tx_hash": "dummy tx hash", - "mocking_mode": True, - "wallet_balance": 10000, - }, - ), - ( - ClaimPayload, - {"vote": True}, - ), - ( - VotingPayload, - {"vote": True}, - ), - ( - BlacklistingPayload, - {"policy": "dummy policy", "bets_hash": "dummy bets hash"}, - ), - ( - ToolSelectionPayload, - { - "mech_tools": "dummy mech tools", - "policy": "dummy policy", - "utilized_tools": "dummy utilized tools", - "selected_tool": "dummy selected tool", - }, - ), - ], -) -def test_payload(payload_class: Type[BaseTxPayload], payload_kwargs: Dict) -> None: - """Test payloads.""" - payload = payload_class(sender="sender", **payload_kwargs) - - for key, value in payload_kwargs.items(): - assert getattr(payload, key) == value - - assert payload.sender == "sender" - assert payload.data == payload_kwargs - assert payload_class.from_json(payload.json) == payload diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/tests/test_rounds.py b/trader_old/vendor/valory/skills/decision_maker_abci/tests/test_rounds.py deleted file mode 100644 index 9cbf81d60..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/tests/test_rounds.py +++ /dev/null @@ -1,212 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the test for rounds of decision maker""" -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.decision_maker_abci.rounds import DecisionMakerAbciApp -from packages.valory.skills.decision_maker_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) -from packages.valory.skills.decision_maker_abci.states.blacklisting import ( - BlacklistingRound, -) -from packages.valory.skills.decision_maker_abci.states.check_benchmarking import ( - CheckBenchmarkingModeRound, -) -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) -from packages.valory.skills.decision_maker_abci.states.decision_receive import ( - DecisionReceiveRound, -) -from packages.valory.skills.decision_maker_abci.states.decision_request import ( - DecisionRequestRound, -) -from packages.valory.skills.decision_maker_abci.states.final_states import ( - BenchmarkingModeDisabledRound, - FinishedDecisionMakerRound, - FinishedDecisionRequestRound, - FinishedSubscriptionRound, - FinishedWithoutDecisionRound, -) -from packages.valory.skills.decision_maker_abci.states.order_subscription import ( - SubscriptionRound, -) -from packages.valory.skills.decision_maker_abci.states.randomness import ( - BenchmarkingRandomnessRound, - RandomnessRound, -) -from packages.valory.skills.decision_maker_abci.states.redeem import RedeemRound -from packages.valory.skills.decision_maker_abci.states.sampling import SamplingRound -from packages.valory.skills.decision_maker_abci.states.tool_selection import ( - ToolSelectionRound, -) - - -@pytest.fixture -def setup_app() -> DecisionMakerAbciApp: - """Set up the initial app instance for testing.""" - # Create mock objects for the required arguments - synchronized_data = MagicMock(spec=SynchronizedData) - logger = MagicMock() # Mock logger - context = MagicMock() # Mock context - - # Initialize the app with the mocked dependencies - return DecisionMakerAbciApp(synchronized_data, logger, context) - - -def test_initial_state(setup_app: DecisionMakerAbciApp) -> None: - """Test the initial round of the application.""" - app = setup_app - assert app.initial_round_cls == CheckBenchmarkingModeRound - assert CheckBenchmarkingModeRound in app.initial_states - - -def test_check_benchmarking_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from CheckBenchmarkingModeRound.""" - app = setup_app - transition_function = app.transition_function[CheckBenchmarkingModeRound] - - # Transition on benchmarking enabled - assert ( - transition_function[Event.BENCHMARKING_ENABLED] == BenchmarkingRandomnessRound - ) - - # Transition on benchmarking disabled - assert ( - transition_function[Event.BENCHMARKING_DISABLED] - == BenchmarkingModeDisabledRound - ) - - # Test no majority - assert transition_function[Event.NO_MAJORITY] == CheckBenchmarkingModeRound - - -def test_sampling_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from SamplingRound.""" - app = setup_app - transition_function = app.transition_function[SamplingRound] - - # Transition on done - assert transition_function[Event.DONE] == SubscriptionRound - - # Test none and no majority - assert transition_function[Event.NONE] == FinishedWithoutDecisionRound - assert transition_function[Event.NO_MAJORITY] == SamplingRound - - -def test_subscription_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from SubscriptionRound.""" - app = setup_app - transition_function = app.transition_function[SubscriptionRound] - - # Transition on done - assert transition_function[Event.DONE] == FinishedSubscriptionRound - - # Mock transaction cases - assert transition_function[Event.MOCK_TX] == ToolSelectionRound - assert transition_function[Event.NO_SUBSCRIPTION] == ToolSelectionRound - - -def test_claim_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from ClaimRound.""" - app = setup_app - transition_function = app.transition_function[ClaimRound] - - # Test transition on done - assert transition_function[Event.DONE] == ToolSelectionRound - - -def test_randomness_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from RandomnessRound.""" - app = setup_app - transition_function = app.transition_function[RandomnessRound] - - # Transition on done - assert transition_function[Event.DONE] == SamplingRound - - -def test_tool_selection_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from ToolSelectionRound.""" - app = setup_app - transition_function = app.transition_function[ToolSelectionRound] - - # Test transition on done - assert transition_function[Event.DONE] == DecisionRequestRound - - -def test_decision_request_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from DecisionRequestRound.""" - app = setup_app - transition_function = app.transition_function[DecisionRequestRound] - - # Test transition on done - assert transition_function[Event.DONE] == FinishedDecisionRequestRound - assert transition_function[Event.MOCK_MECH_REQUEST] == DecisionReceiveRound - - -def test_decision_receive_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from DecisionReceiveRound.""" - app = setup_app - transition_function = app.transition_function[DecisionReceiveRound] - - # Test transition on done - assert transition_function[Event.DONE] == BetPlacementRound - - -def test_blacklisting_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from BlacklistingRound.""" - app = setup_app - transition_function = app.transition_function[BlacklistingRound] - - # Test transition on done - assert transition_function[Event.DONE] == FinishedWithoutDecisionRound - - -def test_bet_placement_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from BetPlacementRound.""" - app = setup_app - transition_function = app.transition_function[BetPlacementRound] - - # Test transition on done - assert transition_function[Event.DONE] == FinishedDecisionMakerRound - - -def test_redeem_round_transition(setup_app: DecisionMakerAbciApp) -> None: - """Test transitions from RedeemRound.""" - app = setup_app - transition_function = app.transition_function[RedeemRound] - - # Test transition on done - assert transition_function[Event.DONE] == FinishedDecisionMakerRound - - -def test_final_states(setup_app: DecisionMakerAbciApp) -> None: - """Test the final states of the application.""" - app = setup_app - assert FinishedDecisionMakerRound in app.final_states - assert BenchmarkingModeDisabledRound in app.final_states - assert FinishedWithoutDecisionRound in app.final_states diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/utils/__init__.py b/trader_old/vendor/valory/skills/decision_maker_abci/utils/__init__.py deleted file mode 100644 index fc72e841a..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/utils/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 package contains helpers.""" diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/utils/nevermined.py b/trader_old/vendor/valory/skills/decision_maker_abci/utils/nevermined.py deleted file mode 100644 index e7f808254..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/utils/nevermined.py +++ /dev/null @@ -1,373 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the behaviour for the decision-making of the skill.""" - -import re -import uuid -from typing import Any, Dict, List, Tuple - -from eth_abi import encode -from web3 import Web3 - - -def zero_x_transformer(input_str: str, zero_output: bool = True) -> str: - """Transform a string to a hex string.""" - match = re.match(r"^(?:0x)*([a-f0-9]+)$", input_str, re.IGNORECASE) - valid = match is not None - output = match.group(1) if valid else "" # type: ignore - - return ("0x" if zero_output and valid else "") + output - - -def generate_id(length: int = 64) -> str: - """Generate a random ID.""" - generated_id = "" - while len(generated_id) < length: - generated_id += str(uuid.uuid4()).replace("-", "") - - return generated_id[:length] - - -def find_service_by_type(did_doc: Dict[str, Any], type: str) -> Dict[str, Any]: - """Find a service by name.""" - services = did_doc.get("service", []) - for service in services: - if service.get("type") == type: - return service - - raise Exception(f"No service found with type {type}") - - -def find_service_condition_by_name( - service: Dict[str, Any], name: str -) -> Dict[str, Any]: - """Find a condition by name.""" - conditions = ( - service.get("attributes", {}) - .get("serviceAgreementTemplate", {}) - .get("conditions", []) - ) - - condition = next((c for c in conditions if c["name"] == name), None) - - if condition is None: - raise Exception(f"Condition '{name!r}' not found.") - - return condition - - -def get_asset_price_from_service(service: Dict[str, Any]) -> Dict[str, int]: - """Get the price of a DID.""" - escrow_payment_condition = find_service_condition_by_name(service, "escrowPayment") - - if not escrow_payment_condition: - raise Exception("escrowPayment not found in service") - - amounts: List = next( - ( - p["value"] - for p in escrow_payment_condition.get("parameters", []) - if p["name"] == "_amounts" - ), - [], - ) - receivers: List = next( - ( - p["value"] - for p in escrow_payment_condition.get("parameters", []) - if p["name"] == "_receivers" - ), - [], - ) - - rewards_map = dict(zip(receivers, map(int, amounts))) - - return rewards_map - - -def get_price(did_doc: Dict[str, Any], type: str = "nft-sales") -> Dict[str, int]: - """Get the price of a DID.""" - service = find_service_by_type(did_doc, type) - return get_asset_price_from_service(service) - - -def get_nft_address(did_doc: Dict[str, Any], type: str = "nft-sales") -> str: - """Get the NFT address of a DID.""" - service = find_service_by_type(did_doc, type) - transfer_condition = find_service_condition_by_name(service, "transferNFT") - contract_param = next( - ( - p["value"] - for p in transfer_condition.get("parameters", []) - if p["name"] == "_contractAddress" or p["name"] == "_contract" - ), - None, - ) - - return contract_param if contract_param is not None else "" - - -def get_nft_holder(did_doc: Dict[str, Any], type: str = "nft-sales") -> str: - """Get the NFT holder of a DID.""" - service = find_service_by_type(did_doc, type) - transfer_condition = find_service_condition_by_name(service, "transferNFT") - contract_param = next( - ( - p["value"] - for p in transfer_condition.get("parameters", []) - if p["name"] == "_nftHolder" - ), - None, - ) - - return contract_param if contract_param is not None else "" - - -def get_nft_transfer(did_doc: Dict[str, Any], type: str = "nft-sales") -> str: - """Get the NFT holder of a DID.""" - service = find_service_by_type(did_doc, type) - transfer_condition = find_service_condition_by_name(service, "transferNFT") - contract_param = next( - ( - p["value"] - for p in transfer_condition.get("parameters", []) - if p["name"] == "_nftTransfer" - ), - None, - ) - - return contract_param if contract_param is not None else "" - - -def no_did_prefixed(input_string: str) -> str: - """Remove the DID prefix from a string.""" - return did_transformer(input_string, False) - - -def did_transformer(input_string: str, prefix_output: bool = False) -> str: - """Transform a string to a DID.""" - pattern = re.compile(r"^(?:0x|did:nv:)*([a-f0-9]{64})$", re.IGNORECASE) - match_result = input_match(input_string, pattern) - - valid, output = match_result["valid"], match_result["output"] - - return ("did:nv:" if prefix_output and valid else "") + output - - -def input_match(input_string: str, pattern: re.Pattern) -> Dict[str, Any]: - """Match an input string with a pattern.""" - match_result = re.match(pattern, input_string) - if match_result: - return {"valid": True, "output": match_result.group(1)} - else: - return {"valid": False, "output": ""} - - -def hash_data( - types: List[str], - values: List[Any], -) -> str: - """Hash data.""" - encoded_data = encode(types, values) - return Web3.keccak(encoded_data).hex() - - -def short_id(did: str) -> str: - """Get the short ID of a DID.""" - return did.replace("did:nv:", "") - - -def get_agreement_id(seed: str, creator: str) -> str: - """Get the agreement ID.""" - seed_0x = zero_x_transformer(seed) - creator_0x = Web3.to_checksum_address(creator) - return hash_data(["bytes32", "address"], [bytes.fromhex(seed_0x[2:]), creator_0x]) - - -def get_lock_payment_seed( - agreement_id: str, - did_doc: Dict[str, Any], - lock_payment_condition_address: str, - escrow_payment_condition_address: str, - token_address: str, - amounts: List[int], - receivers: List[str], -) -> Tuple[str, str]: - """Get the lock payment seed.""" - short_id_ = zero_x_transformer(short_id(did_doc["id"])) - escrow_payment_condition_address_0x = zero_x_transformer( - escrow_payment_condition_address - ) - token_address = Web3.to_checksum_address(token_address) - receivers = [Web3.to_checksum_address(receiver) for receiver in receivers] - - hash_values = hash_data( - ["bytes32", "address", "address", "uint256[]", "address[]"], - [ - bytes.fromhex(short_id_[2:]), - escrow_payment_condition_address_0x, - token_address, - amounts, - receivers, - ], - ) - return hash_values, hash_data( - ["bytes32", "address", "bytes32"], - [ - bytes.fromhex(agreement_id[2:]), - lock_payment_condition_address, - bytes.fromhex(hash_values[2:]), - ], - ) - - -def get_transfer_nft_condition_seed( - agreement_id: str, - did_doc: Dict[str, Any], - buyer_address: str, - nft_amount: int, - transfer_nft_condition_address: str, - lock_condition_id: str, - nft_contract_address: str, - expiration: int = 0, -) -> Tuple[str, str]: - """Get the lock payment seed.""" - short_id_ = zero_x_transformer(short_id(did_doc["id"])) - nft_holder = Web3.to_checksum_address(get_nft_holder(did_doc)) - will_transfer = get_nft_transfer(did_doc) == "true" - - hash_values = hash_data( - ["bytes32", "address", "address", "uint256", "bytes32", "address", "bool"], - [ - bytes.fromhex(short_id_[2:]), - nft_holder, - Web3.to_checksum_address(buyer_address), - nft_amount, - bytes.fromhex(lock_condition_id[2:]), - Web3.to_checksum_address(nft_contract_address), - will_transfer, - ], - ) - - return hash_values, hash_data( - ["bytes32", "address", "bytes32"], - [ - bytes.fromhex(agreement_id[2:]), - transfer_nft_condition_address, - bytes.fromhex(hash_values[2:]), - ], - ) - - -def get_escrow_payment_seed( - agreement_id: str, - did_doc: Dict[str, Any], - amounts: List[int], - receivers: List[str], - buyer_address: str, - escrow_payment_condition_address: str, - token_address: str, - lock_seed: str, - access_seed: str, -) -> Tuple[str, str]: - """Get the escrow payment seed.""" - short_id_ = zero_x_transformer(short_id(did_doc["id"])) - escrow_payment_condition_address = Web3.to_checksum_address( - escrow_payment_condition_address - ) - receivers = [Web3.to_checksum_address(receiver) for receiver in receivers] - buyer_address = Web3.to_checksum_address(buyer_address) - token_address = Web3.to_checksum_address(token_address) - - values_hash = hash_data( - [ - "bytes32", - "uint256[]", - "address[]", - "address", - "address", - "address", - "bytes32", - "bytes32[]", - ], - [ - bytes.fromhex(short_id_[2:]), - amounts, - receivers, - buyer_address, - escrow_payment_condition_address, - token_address, - bytes.fromhex(lock_seed[2:]), - [bytes.fromhex(access_seed[2:])], - ], - ) - - return values_hash, hash_data( - ["bytes32", "address", "bytes32"], - [ - bytes.fromhex(agreement_id[2:]), - escrow_payment_condition_address, - bytes.fromhex(values_hash[2:]), - ], - ) - - -def get_timeouts_and_timelocks(did_doc: Dict[str, Any]) -> Tuple[List[int], List[int]]: - """Get timeouts and timelocks""" - type = "nft-sales" - service = find_service_by_type(did_doc, type) - conditions = ( - service.get("attributes", {}) - .get("serviceAgreementTemplate", {}) - .get("conditions", []) - ) - timeouts, timelocks = [], [] - for condition in conditions: - timeouts.append(condition.get("timeout", 0)) - timelocks.append(condition.get("timelock", 0)) - - return timeouts, timelocks - - -def get_reward_address(did_doc: Dict[str, Any], type: str = "nft-sales") -> str: - """Get the reward address of a DID.""" - service = find_service_by_type(did_doc, type) - transfer_condition = find_service_condition_by_name(service, "lockPayment") - contract_param = next( - ( - p["value"] - for p in transfer_condition.get("parameters", []) - if p["name"] == "_rewardAddress" - ), - None, - ) - - return contract_param if contract_param is not None else "" - - -def get_creator(did_doc: Dict[str, Any]) -> str: - """Get the creator of a DID.""" - return did_doc["proof"]["creator"] - - -def get_claim_endpoint(did_doc: Dict[str, Any]) -> str: - """Get the claim endpoint of a DID.""" - service = find_service_by_type(did_doc, "nft-sales") - return service["serviceEndpoint"] diff --git a/trader_old/vendor/valory/skills/decision_maker_abci/utils/scaling.py b/trader_old/vendor/valory/skills/decision_maker_abci/utils/scaling.py deleted file mode 100644 index 147aaa7a6..000000000 --- a/trader_old/vendor/valory/skills/decision_maker_abci/utils/scaling.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 package contains helpers for scaling operations.""" - - -from typing import List, Tuple - - -def min_max(li: List[float]) -> Tuple[float, float]: - """Get the min and max of a list.""" - if not li: - raise ValueError("The list is empty.") - - min_ = max_ = li[0] - - for num in li[1:]: - if num < min_: - min_ = num - elif num > max_: - max_ = num - - return min_, max_ - - -def scale_value( - value: float, - min_max_bounds: Tuple[float, float], - scale_bounds: Tuple[float, float] = (0, 1), -) -> float: - """Perform min-max scaling on a value.""" - min_, max_ = min_max_bounds - current_range = max_ - min_ - # normalize between 0-1 - std = (value - min_) / current_range - # scale between min_bound and max_bound - min_bound, max_bound = scale_bounds - target_range = max_bound - min_bound - return std * target_range + min_bound - - -def min_max_scale( - li: List[float], - scale_bounds: Tuple[float, float] = (0, 1), -) -> List[float]: - """Perform min-max scaling on a list of values.""" - min_max_ = min_max(li) - return [scale_value(value, min_max_, scale_bounds) for value in li] diff --git a/trader_old/vendor/valory/skills/market_manager_abci/README.md b/trader_old/vendor/valory/skills/market_manager_abci/README.md deleted file mode 100644 index 6171b3b17..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Market manager abci - -## Description - -This module contains the MarketManager skill for an AEA. diff --git a/trader_old/vendor/valory/skills/market_manager_abci/__init__.py b/trader_old/vendor/valory/skills/market_manager_abci/__init__.py deleted file mode 100644 index 4a6394a5b..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- 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 the MarketManager skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/market_manager_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/market_manager_abci/behaviours.py b/trader_old/vendor/valory/skills/market_manager_abci/behaviours.py deleted file mode 100644 index 999523130..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/behaviours.py +++ /dev/null @@ -1,236 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviours for the MarketManager skill.""" - -import json -import os.path -from abc import ABC -from json import JSONDecodeError -from typing import Any, Dict, Generator, List, Optional, Set, Type - -from aea.helpers.ipfs.base import IPFSHashOnly - -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.behaviours import AbstractRoundBehaviour -from packages.valory.skills.market_manager_abci.bets import ( - Bet, - BetsDecoder, - serialize_bets, -) -from packages.valory.skills.market_manager_abci.graph_tooling.requests import ( - FetchStatus, - MAX_LOG_SIZE, - QueryingBehaviour, -) -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload -from packages.valory.skills.market_manager_abci.rounds import ( - MarketManagerAbciApp, - UpdateBetsRound, -) - - -BETS_FILENAME = "bets.json" -MULTI_BETS_FILENAME = "multi_bets.json" -READ_MODE = "r" -WRITE_MODE = "w" - - -class BetsManagerBehaviour(BaseBehaviour, ABC): - """Abstract behaviour responsible for bets management, such as storing, hashing, reading.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize `BetsManagerBehaviour`.""" - super().__init__(**kwargs) - self.bets: List[Bet] = [] - self.multi_bets_filepath: str = self.params.store_path / MULTI_BETS_FILENAME - self.bets_filepath: str = self.params.store_path / BETS_FILENAME - - def store_bets(self) -> None: - """Store the bets to the agent's data dir as JSON.""" - serialized = serialize_bets(self.bets) - if serialized is None: - self.context.logger.warning("No bets to store.") - return - - try: - with open(self.multi_bets_filepath, WRITE_MODE) as bets_file: - try: - bets_file.write(serialized) - return - except (IOError, OSError): - err = f"Error writing to file {self.multi_bets_filepath!r}!" - except (FileNotFoundError, PermissionError, OSError): - err = f"Error opening file {self.multi_bets_filepath!r} in write mode!" - - self.context.logger.error(err) - - def read_bets(self) -> None: - """Read the bets from the agent's data dir as JSON.""" - self.bets = [] - _read_path = self.multi_bets_filepath - - if not os.path.isfile(_read_path): - self.context.logger.warning( - f"No stored bets file was detected in {_read_path}. Assuming trader is being run for the first time in multi-bets mode." - ) - _read_path = self.bets_filepath - elif not os.path.isfile(_read_path): - self.context.logger.warning( - f"No stored bets file was detected in {_read_path}. Assuming bets are empty" - ) - return - - try: - with open(_read_path, READ_MODE) as bets_file: - try: - self.bets = json.load(bets_file, cls=BetsDecoder) - return - except (JSONDecodeError, TypeError): - err = f"Error decoding file {_read_path!r} to a list of bets!" - except (FileNotFoundError, PermissionError, OSError): - err = f"Error opening file {_read_path!r} in read mode!" - - self.context.logger.error(err) - - def hash_stored_bets(self) -> str: - """Get the hash of the stored bets' file.""" - return IPFSHashOnly.hash_file(self.multi_bets_filepath) - - -class UpdateBetsBehaviour(BetsManagerBehaviour, QueryingBehaviour): - """Behaviour that fetches and updates the bets.""" - - matching_round = UpdateBetsRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize `UpdateBetsBehaviour`.""" - super().__init__(**kwargs) - - def _requeue_all_bets(self) -> None: - """Requeue all bets.""" - for bet in self.bets: - bet.queue_status = bet.queue_status.move_to_fresh() - - def _blacklist_expired_bets(self) -> None: - """Blacklist bets that are older than the opening margin.""" - for bet in self.bets: - if self.synced_time >= bet.openingTimestamp - self.params.opening_margin: - bet.blacklist_forever() - - def setup(self) -> None: - """Set up the behaviour.""" - - # Read the bets from the agent's data dir as JSON, if they exist - self.read_bets() - - # fetch checkpoint status and if reached requeue all bets - if self.synchronized_data.is_checkpoint_reached: - self._requeue_all_bets() - - # blacklist bets that are older than the opening margin - # if trader ran after a long time - # helps in resetting the queue number to 0 - if self.bets: - self._blacklist_expired_bets() - - def get_bet_idx(self, bet_id: str) -> Optional[int]: - """Get the index of the bet with the given id, if it exists, otherwise `None`.""" - return next((i for i, bet in enumerate(self.bets) if bet.id == bet_id), None) - - def _process_chunk(self, chunk: Optional[List[Dict[str, Any]]]) -> None: - """Process a chunk of bets.""" - if chunk is None: - return - - for raw_bet in chunk: - bet = Bet(**raw_bet, market=self._current_market) - index = self.get_bet_idx(bet.id) - if index is None: - self.bets.append(bet) - else: - self.bets[index].update_market_info(bet) - - def _update_bets( - self, - ) -> Generator: - """Fetch the questions from all the prediction markets and update the local copy of the bets.""" - - # Fetching bets from the prediction markets - while True: - can_proceed = self._prepare_fetching() - if not can_proceed: - break - - bets_market_chunk = yield from self._fetch_bets() - self._process_chunk(bets_market_chunk) - - if self._fetch_status != FetchStatus.SUCCESS: - # this won't wipe the bets as the `store_bets` of the `BetsManagerBehaviour` takes this into consideration - self.bets = [] - - # truncate the bets, otherwise logs get too big - bets_str = str(self.bets)[:MAX_LOG_SIZE] - self.context.logger.info(f"Updated bets: {bets_str}") - - def _bet_freshness_check_and_update(self) -> None: - """Check the freshness of the bets.""" - all_bets_fresh = all( - bet.queue_status.is_fresh() - for bet in self.bets - if not bet.queue_status.is_expired() - ) - - if all_bets_fresh: - for bet in self.bets: - bet.queue_status = bet.queue_status.move_to_process() - - return - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - # Update the bets list with new bets or update existing ones - yield from self._update_bets() - - # if trader is run after a long time, there is a possibility that - # all bets are fresh and this should be updated to DAY_0_FRESH - if self.bets: - self._bet_freshness_check_and_update() - - # Store the bets to the agent's data dir as JSON - self.store_bets() - - bets_hash = self.hash_stored_bets() if self.bets else None - payload = UpdateBetsPayload(self.context.agent_address, bets_hash) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - self.set_done() - - -class MarketManagerRoundBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the MarketManager behaviour.""" - - initial_behaviour_cls = UpdateBetsBehaviour - abci_app_cls = MarketManagerAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - UpdateBetsBehaviour, # type: ignore - } diff --git a/trader_old/vendor/valory/skills/market_manager_abci/bets.py b/trader_old/vendor/valory/skills/market_manager_abci/bets.py deleted file mode 100644 index ec65968f9..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/bets.py +++ /dev/null @@ -1,387 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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. -# -# ------------------------------------------------------------------------------ - - -"""Structures for the bets.""" - -import builtins -import dataclasses -import json -import sys -from enum import Enum -from typing import Any, Dict, List, Optional, Union - - -YES = "yes" -NO = "no" -P_YES_FIELD = "p_yes" -P_NO_FIELD = "p_no" -CONFIDENCE_FIELD = "confidence" -INFO_UTILITY_FIELD = "info_utility" -BINARY_N_SLOTS = 2 - - -class QueueStatus(Enum): - """The status of a bet in the queue.""" - - # Common statuses - EXPIRED = -1 # Bets that have expired, i.e., the market is not live anymore - FRESH = 0 # Fresh bets that have just been added - TO_PROCESS = 1 # Bets that are ready to be processed - PROCESSED = 2 # Bets that have been processed - REPROCESSED = 3 # Bets that have been reprocessed - BENCHMARKING_DONE = 4 - - def is_fresh(self) -> bool: - """Check if the bet is fresh.""" - return self == QueueStatus.FRESH - - def is_expired(self) -> bool: - """Check if the bet is expired.""" - return self == QueueStatus.EXPIRED - - def move_to_process(self) -> "QueueStatus": - """Move the bet to the process status.""" - if self == QueueStatus.FRESH: - return QueueStatus.TO_PROCESS - return self - - def move_to_fresh(self) -> "QueueStatus": - """Move the bet to the fresh status.""" - if self not in [QueueStatus.EXPIRED, QueueStatus.BENCHMARKING_DONE]: - return QueueStatus.FRESH - return self - - def mark_benchmarking_done(self) -> "QueueStatus": - """Function to update the status to benchmarking done""" - return QueueStatus.BENCHMARKING_DONE - - def next_status(self) -> "QueueStatus": - """Get the next status in the queue.""" - if self == QueueStatus.TO_PROCESS: - return QueueStatus.PROCESSED - elif self == QueueStatus.PROCESSED: - return QueueStatus.REPROCESSED - elif self != QueueStatus.REPROCESSED: - return QueueStatus.FRESH - return self - - -@dataclasses.dataclass(init=False) -class PredictionResponse: - """A response of a prediction.""" - - p_yes: float - p_no: float - confidence: float - info_utility: float - - def __init__(self, **kwargs: Any) -> None: - """Initialize the mech's prediction ignoring extra keys.""" - self.p_yes = float(kwargs.pop(P_YES_FIELD)) - self.p_no = float(kwargs.pop(P_NO_FIELD)) - self.confidence = float(kwargs.pop(CONFIDENCE_FIELD)) - self.info_utility = float(kwargs.pop(INFO_UTILITY_FIELD)) - - # all the fields are probabilities; run checks on whether the current prediction response is valid or not. - probabilities = (getattr(self, field_) for field_ in self.__annotations__) - if ( - any(not (0 <= prob <= 1) for prob in probabilities) - or self.p_yes + self.p_no != 1 - ): - raise ValueError("Invalid prediction response initialization.") - - @property - def vote(self) -> Optional[int]: - """Return the vote. `0` represents "yes" and `1` represents "no".""" - if self.p_no != self.p_yes: - return int(self.p_no > self.p_yes) - return None - - @property - def win_probability(self) -> float: - """Return the probability estimation for winning with vote.""" - return max(self.p_no, self.p_yes) - - -def get_default_prediction_response() -> PredictionResponse: - """Get the default prediction response.""" - return PredictionResponse(p_yes=0.5, p_no=0.5, confidence=0.5, info_utility=0.5) - - -@dataclasses.dataclass -class Bet: - """A bet's structure.""" - - id: str - market: str - title: str - collateralToken: str - creator: str - fee: int - openingTimestamp: int - outcomeSlotCount: int - outcomeTokenAmounts: List[int] - outcomeTokenMarginalPrices: List[float] - outcomes: Optional[List[str]] - scaledLiquidityMeasure: float - prediction_response: PredictionResponse = dataclasses.field( - default_factory=get_default_prediction_response - ) - position_liquidity: int = 0 - potential_net_profit: int = 0 - processed_timestamp: int = 0 - queue_status: QueueStatus = QueueStatus.FRESH - # a mapping from vote to investment amounts - investments: Dict[str, List[int]] = dataclasses.field(default_factory=dict) - - @property - def yes_investments(self) -> List[int]: - """Get the yes investments.""" - return self.investments[self.yes] - - @property - def no_investments(self) -> List[int]: - """Get the no investments.""" - return self.investments[self.no] - - @property - def n_yes_bets(self) -> int: - """Get the number of yes bets.""" - return len(self.yes_investments) - - @property - def n_no_bets(self) -> int: - """Get the number of no bets.""" - return len(self.no_investments) - - @property - def n_bets(self) -> int: - """Get the number of bets.""" - return self.n_yes_bets + self.n_no_bets - - @property - def invested_amount_yes(self) -> int: - """Get the amount invested in yes bets.""" - return sum(self.yes_investments) - - @property - def invested_amount_no(self) -> int: - """Get the amount invested in no bets.""" - return sum(self.no_investments) - - @property - def invested_amount(self) -> int: - """Get the amount invested in bets.""" - return self.invested_amount_yes + self.invested_amount_no - - def __post_init__(self) -> None: - """Post initialization to adjust the values.""" - self._validate() - self._cast() - self._check_usefulness() - self.investments = {self.yes: [], self.no: []} - - def __lt__(self, other: "Bet") -> bool: - """Implements less than operator.""" - return self.scaledLiquidityMeasure < other.scaledLiquidityMeasure - - def blacklist_forever(self) -> None: - """Blacklist a bet forever. Should only be used in cases where it is impossible to bet.""" - self.outcomes = None - self.processed_timestamp = sys.maxsize - self.queue_status = QueueStatus.EXPIRED - - def _validate(self) -> None: - """Validate the values of the instance.""" - necessary_values = ( - self.id, - self.market, - self.title, - self.collateralToken, - self.creator, - self.fee, - self.openingTimestamp, - self.outcomeSlotCount, - self.outcomes, - self.scaledLiquidityMeasure, - self.outcomeTokenAmounts, - self.outcomeTokenMarginalPrices, - ) - nulls_exist = any(val is None or val == "null" for val in necessary_values) - - outcomes_lists = ( - self.outcomes, - self.outcomeTokenAmounts, - self.outcomeTokenMarginalPrices, - ) - mismatching_outcomes = any( - self.outcomeSlotCount != len(outcomes) - for outcomes in outcomes_lists - if outcomes is not None - ) - - if nulls_exist or mismatching_outcomes: - self.blacklist_forever() - - def _cast(self) -> None: - """Cast the values of the instance.""" - types_to_cast = ("int", "float", "str") - str_to_type = {getattr(builtins, type_): type_ for type_ in types_to_cast} - for field, hinted_type in self.__annotations__.items(): - uncasted = getattr(self, field) - if uncasted is None: - continue - - for type_to_cast, type_name in str_to_type.items(): - if hinted_type == type_to_cast: - setattr(self, field, hinted_type(uncasted)) - if f"{str(List)}[{type_name}]" == str(hinted_type): - setattr(self, field, list(type_to_cast(val) for val in uncasted)) - - def _check_usefulness(self) -> None: - """If the bet is deemed unhelpful, then blacklist it.""" - if self.scaledLiquidityMeasure == 0: - self.blacklist_forever() - - def get_outcome(self, index: int) -> str: - """Get an outcome given its index.""" - if self.outcomes is None: - raise ValueError(f"Bet {self} has an incorrect outcomes list of `None`.") - try: - return self.outcomes[index] - except KeyError as exc: - error = f"Cannot get outcome with index {index} from {self.outcomes}" - raise ValueError(error) from exc - - def _get_binary_outcome(self, no: bool) -> str: - """Get an outcome only if it is binary.""" - if self.outcomeSlotCount == BINARY_N_SLOTS: - return self.get_outcome(int(no)) - requested_outcome = NO if no else YES - error = ( - f"A {requested_outcome!r} outcome is only available for binary questions." - ) - raise ValueError(error) - - @property - def yes(self) -> str: - """Return the "yes" outcome.""" - return self._get_binary_outcome(False) - - @property - def no(self) -> str: - """Return the "no" outcome.""" - return self._get_binary_outcome(True) - - def update_investments(self, amount: int) -> bool: - """Get the investments for the current vote type.""" - vote = self.prediction_response.vote - if vote is None: - return False - - vote_name = self.get_outcome(vote) - to_update = self.investments[vote_name] - to_update.append(amount) - return True - - def update_market_info(self, bet: "Bet") -> None: - """Update the bet's market information.""" - if ( - self.processed_timestamp == sys.maxsize - or bet.processed_timestamp == sys.maxsize - ): - # do not update the bet if it has been blacklisted forever - return - - self.outcomeTokenAmounts = bet.outcomeTokenAmounts.copy() - self.outcomeTokenMarginalPrices = bet.outcomeTokenMarginalPrices.copy() - self.scaledLiquidityMeasure = bet.scaledLiquidityMeasure - - def rebet_allowed( - self, - prediction_response: PredictionResponse, - liquidity: int, - potential_net_profit: int, - ) -> bool: - """Check if a rebet is allowed based on the previous bet's information.""" - if self.n_bets == 0: - # it's the first time betting, always allow it - return True - - more_confident = ( - self.prediction_response.win_probability - >= prediction_response.win_probability - ) - if self.prediction_response.vote == prediction_response.vote: - higher_liquidity = self.position_liquidity >= liquidity - return more_confident and higher_liquidity - else: - profit_increases = self.potential_net_profit >= potential_net_profit - return more_confident and profit_increases - - -class BetsEncoder(json.JSONEncoder): - """JSON encoder for bets.""" - - def default(self, o: Any) -> Any: - """The default encoder.""" - if dataclasses.is_dataclass(o) and not isinstance(o, type): - return dataclasses.asdict(o) - if isinstance(o, QueueStatus): - return o.value - return super().default(o) - - -class BetsDecoder(json.JSONDecoder): - """JSON decoder for bets.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the Bets JSON decoder.""" - super().__init__(object_hook=self.hook, *args, **kwargs) - - @staticmethod - def hook(data: Dict[str, Any]) -> Union[Bet, PredictionResponse, Dict[str, Bet]]: - """Perform the custom decoding.""" - # if this is a `PredictionResponse` - prediction_attributes = sorted(PredictionResponse.__annotations__.keys()) - data_attributes = sorted(data.keys()) - if prediction_attributes == data_attributes: - return PredictionResponse(**data) - - # if this is a `Bet` - bet_annotations = sorted(Bet.__annotations__.keys()) - if bet_annotations == data_attributes: - data["queue_status"] = QueueStatus(data["queue_status"]) - return Bet(**data) - elif "id" in data_attributes: - common_attributes = set(bet_annotations) & set(data_attributes) - data = {key: data[key] for key in common_attributes} - if "queue_status" in data: - data["queue_status"] = QueueStatus(data["queue_status"]) - return Bet(**data) - - return data - - -def serialize_bets(bets: List[Bet]) -> Optional[str]: - """Get the bets serialized.""" - if len(bets) == 0: - return None - return json.dumps(bets, cls=BetsEncoder) diff --git a/trader_old/vendor/valory/skills/market_manager_abci/dialogues.py b/trader_old/vendor/valory/skills/market_manager_abci/dialogues.py deleted file mode 100644 index 153b6ce50..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/dialogues.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- 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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_old/vendor/valory/skills/market_manager_abci/fsm_specification.yaml b/trader_old/vendor/valory/skills/market_manager_abci/fsm_specification.yaml deleted file mode 100644 index 665d8c38f..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/fsm_specification.yaml +++ /dev/null @@ -1,21 +0,0 @@ -alphabet_in: -- DONE -- FETCH_ERROR -- NO_MAJORITY -- ROUND_TIMEOUT -default_start_state: UpdateBetsRound -final_states: -- FailedMarketManagerRound -- FinishedMarketManagerRound -label: MarketManagerAbciApp -start_states: -- UpdateBetsRound -states: -- FailedMarketManagerRound -- FinishedMarketManagerRound -- UpdateBetsRound -transition_func: - (UpdateBetsRound, DONE): FinishedMarketManagerRound - (UpdateBetsRound, FETCH_ERROR): FailedMarketManagerRound - (UpdateBetsRound, NO_MAJORITY): UpdateBetsRound - (UpdateBetsRound, ROUND_TIMEOUT): UpdateBetsRound diff --git a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/__init__.py b/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/__init__.py deleted file mode 100644 index f83960aa0..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 functionality for interacting with a GraphQL API.""" diff --git a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/__init__.py b/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/__init__.py deleted file mode 100644 index 80ec84132..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""GraphQL queries.""" diff --git a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/conditional_tokens.py b/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/conditional_tokens.py deleted file mode 100644 index c64fbacf8..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/conditional_tokens.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Omen queries.""" - -from string import Template - - -user_positions = Template( - """ - { - user(id: "${id}") { - userPositions( - first: ${first} - where: { - id_gt: "${userPositions_id_gt}" - } - orderBy: id - ) { - balance - id - position { - id - conditionIds - lifetimeValue - } - totalBalance - wrappedBalance - } - } - } - """ -) diff --git a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/network.py b/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/network.py deleted file mode 100644 index d5f4b5900..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/network.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Network queries.""" - -from string import Template - - -block_number = Template( - """ - { - blocks ( - first: 1, - orderBy: timestamp, - orderDirection: asc, - where: { - timestamp_gte: "${timestamp_from}", - timestamp_lte:"${timestamp_to}" - } - ){ - id - } - } - """ -) diff --git a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/omen.py b/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/omen.py deleted file mode 100644 index c82d99899..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/omen.py +++ /dev/null @@ -1,96 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Omen queries.""" - -from string import Template - - -questions = Template( - """ - { - fixedProductMarketMakers( - where: { - creator_in: ${creators}, - outcomeSlotCount: ${slot_count}, - openingTimestamp_gt: ${opening_threshold}, - language_in: ${languages}, - isPendingArbitration: false - }, - orderBy: creationTimestamp - orderDirection: desc - first: 1000 - ){ - id - title - collateralToken - creator - fee - openingTimestamp - outcomeSlotCount - outcomeTokenAmounts - outcomeTokenMarginalPrices - outcomes - scaledLiquidityMeasure - } - } - """ -) - -trades = Template( - """ - { - fpmmTrades ( - where: { - type: Buy, - creator: "${creator}", - fpmm_: { - creationTimestamp_gt: "${creationTimestamp_gt}", - answerFinalizedTimestamp_not: null, - isPendingArbitration: false - } - } - orderBy: fpmm__creationTimestamp - orderDirection: asc - first: ${first} - ){ - fpmm { - answerFinalizedTimestamp - collateralToken - condition { - id - outcomeSlotCount - } - creator - creationTimestamp - currentAnswer - question { - id - data - } - templateId - } - outcomeIndex - outcomeTokenMarginalPrice - outcomeTokensTraded - transactionHash - } - } - """ -) diff --git a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/realitio.py b/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/realitio.py deleted file mode 100644 index f6bb67f48..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/realitio.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Omen queries.""" - -from string import Template - - -answers = Template( - """ - { - answers(where: {question_: {questionId: "${question_id}"}}) { - answer - question { - historyHash - id - user - updatedTimestamp - questionId - } - bondAggregate - lastBond - timestamp - } - } - """ -) diff --git a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/trades.py b/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/trades.py deleted file mode 100644 index 6d2054c74..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/queries/trades.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Trades queries.""" - -from string import Template - - -trades = Template( - """ - { - fpmmTrades( - where: { - type: Buy, - creator: "${creator}", - fpmm_: { - creationTimestamp_gte: "${creationTimestamp_gte}", - creationTimestamp_lt: "${creationTimestamp_lte}" - }, - creationTimestamp_gte: "${creationTimestamp_gte}", - creationTimestamp_lte: "${creationTimestamp_lte}" - creationTimestamp_gt: "${creationTimestamp_gt}" - } - first: ${first} - orderBy: creationTimestamp - orderDirection: asc - ) { - id - title - collateralToken - outcomeTokenMarginalPrice - oldOutcomeTokenMarginalPrice - type - creator { - id - } - creationTimestamp - collateralAmount - collateralAmountUSD - feeAmount - outcomeIndex - outcomeTokensTraded - transactionHash - fpmm { - id - outcomes - title - answerFinalizedTimestamp - currentAnswer - isPendingArbitration - arbitrationOccurred - openingTimestamp - condition { - id - } - } - } - } - """ -) diff --git a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/requests.py b/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/requests.py deleted file mode 100644 index 627be35e8..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/requests.py +++ /dev/null @@ -1,414 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Tooling to perform subgraph requests from a behaviour.""" - -import json -from abc import ABC -from enum import Enum, auto -from typing import Any, Dict, Generator, Iterator, List, Optional, Tuple, cast - -from web3 import Web3 - -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.models import ApiSpecs -from packages.valory.skills.market_manager_abci.graph_tooling.queries.conditional_tokens import ( - user_positions as user_positions_query, -) -from packages.valory.skills.market_manager_abci.graph_tooling.queries.network import ( - block_number, -) -from packages.valory.skills.market_manager_abci.graph_tooling.queries.omen import ( - questions, - trades, -) -from packages.valory.skills.market_manager_abci.graph_tooling.queries.realitio import ( - answers as answers_query, -) -from packages.valory.skills.market_manager_abci.graph_tooling.queries.trades import ( - trades as trades_query, -) -from packages.valory.skills.market_manager_abci.models import ( - MarketManagerParams, - SharedState, -) -from packages.valory.skills.market_manager_abci.rounds import SynchronizedData - - -QUERY_BATCH_SIZE = 1000 -MAX_LOG_SIZE = 1000 - - -def to_content(query: str) -> bytes: - """Convert the given query string to payload content, i.e., add it under a `queries` key and convert it to bytes.""" - finalized_query = {"query": query} - encoded_query = json.dumps(finalized_query, sort_keys=True).encode("utf-8") - - return encoded_query - - -def to_graphql_list(li: list) -> str: - """Convert the given list to a string representing a list for a GraphQL query.""" - return repr(li).replace("'", '"') - - -class FetchStatus(Enum): - """The status of a fetch operation.""" - - SUCCESS = auto() - IN_PROGRESS = auto() - FAIL = auto() - NONE = auto() - - -class QueryingBehaviour(BaseBehaviour, ABC): - """Abstract behaviour that implements subgraph querying functionality.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize a querying behaviour.""" - super().__init__(**kwargs) - self._call_failed: bool = False - self._fetch_status: FetchStatus = FetchStatus.NONE - self._creators_iterator: Iterator[ - Tuple[str, List[str]] - ] = self.params.creators_iterator - self._current_market: str = "" - self._current_creators: List[str] = [] - - @property - def params(self) -> MarketManagerParams: - """Get the params.""" - return cast(MarketManagerParams, self.context.params) - - @property - def shared_state(self) -> SharedState: - """Get the shared state.""" - return cast(SharedState, self.context.state) - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return cast(SynchronizedData, super().synchronized_data) - - @property - def synced_time(self) -> int: - """Get the synchronized time among agents.""" - synced_time = self.shared_state.round_sequence.last_round_transition_timestamp - return int(synced_time.timestamp()) - - @property - def current_subgraph(self) -> ApiSpecs: - """Get a subgraph by prediction market's name.""" - return getattr(self.context, self._current_market) - - def _prepare_fetching(self) -> bool: - """Prepare for fetching a bet.""" - if self._fetch_status in (FetchStatus.SUCCESS, FetchStatus.NONE): - res = next(self._creators_iterator, None) - if res is None: - return False - self._current_market, self._current_creators = res - - if self._fetch_status == FetchStatus.FAIL: - return False - - self._fetch_status = FetchStatus.IN_PROGRESS - return True - - def _handle_response( - self, - subgraph: ApiSpecs, - res: Optional[Dict], - res_context: str, - sleep_on_fail: bool = True, - ) -> Generator[None, None, Optional[Any]]: - """Handle a response from a subgraph. - - :param subgraph: the subgraph to handle the response for. - :param res: the response to handle. - :param res_context: the context of the current response. - :param sleep_on_fail: whether we want to sleep if we fail to get the response's result. - :return: the response's result, using the given keys. `None` if response is `None` (has failed). - :yield: None - """ - if res is None: - self.context.logger.error( - f"Could not get {res_context} from {subgraph.api_id}" - ) - self._call_failed = True - subgraph.increment_retries() - - if subgraph.is_retries_exceeded(): - self._fetch_status = FetchStatus.FAIL - - if sleep_on_fail: - sleep_time = subgraph.retries_info.suggested_sleep_time - yield from self.sleep(sleep_time) - return None - - # truncate the response, otherwise logs get too big - res_str = str(res)[:MAX_LOG_SIZE] - self.context.logger.info(f"Retrieved {res_context}: {res_str}.") - self._call_failed = False - subgraph.reset_retries() - self._fetch_status = FetchStatus.SUCCESS - return res - - def _fetch_bets(self) -> Generator[None, None, Optional[list]]: - """Fetch questions from the current subgraph, for the current creators.""" - self._fetch_status = FetchStatus.IN_PROGRESS - - query = questions.substitute( - creators=to_graphql_list(self._current_creators), - slot_count=self.params.slot_count, - opening_threshold=self.synced_time + self.params.opening_margin, - languages=to_graphql_list(self.params.languages), - ) - - res_raw = yield from self.get_http_response( - content=to_content(query), - **self.current_subgraph.get_spec(), - ) - res = self.current_subgraph.process_response(res_raw) - - bets = yield from self._handle_response( - self.current_subgraph, - res, - res_context="questions", - ) - - return bets - - def _fetch_redeem_info(self) -> Generator[None, None, Optional[list]]: - """Fetch redeeming information from the current subgraph.""" - self._fetch_status = FetchStatus.IN_PROGRESS - - current_subgraph = self.context.trades_subgraph - safe = self.synchronized_data.safe_contract_address - creation_timestamp_gt = ( - 0 # used to allow for batching based on creation timestamp - ) - all_trades: List[Dict[str, Any]] = [] - # fetch trades in batches of `QUERY_BATCH_SIZE` - while True: - query = trades.substitute( - creator=safe.lower(), - first=QUERY_BATCH_SIZE, - creationTimestamp_gt=creation_timestamp_gt, - ) - - res_raw = yield from self.get_http_response( - content=to_content(query), - **current_subgraph.get_spec(), - ) - res = current_subgraph.process_response(res_raw) - trades_chunk = yield from self._handle_response( - current_subgraph, - res, - res_context="trades", - ) - if res is None: - # something went wrong - self.context.logger.error("Failed to process all trades.") - return all_trades - - trades_chunk = cast(List[Dict[str, Any]], trades_chunk) - if len(trades_chunk) == 0: - # no more trades to fetch - return all_trades - - # this is the last trade's creation timestamp - # they are sorted by creation timestamp in ascending order - # so we can use this to fetch the next batch - creation_timestamp_gt = trades_chunk[-1]["fpmm"]["creationTimestamp"] - all_trades.extend(trades_chunk) - - def _fetch_block_number( - self, timestamp: int - ) -> Generator[None, None, Dict[str, str]]: - """Get a block number by its timestamp.""" - self._fetch_status = FetchStatus.IN_PROGRESS - - margin = self.params.average_block_time * self.params.abt_error_mult - query = block_number.substitute( - timestamp_from=timestamp, timestamp_to=timestamp + margin - ) - - current_subgraph = self.context.network_subgraph - res_raw = yield from self.get_http_response( - content=to_content(query), - **current_subgraph.get_spec(), - ) - res = current_subgraph.process_response(res_raw) - - block = yield from self._handle_response( - current_subgraph, - res, - res_context="block number", - ) - - return {} if block is None else block - - def fetch_claim_params( - self, question_id: str - ) -> Generator[None, None, Optional[List[Dict[str, Any]]]]: - """Fetch claim parameters from the subgraph.""" - self._fetch_status = FetchStatus.IN_PROGRESS - current_subgraph = self.context.realitio_subgraph - query = answers_query.substitute( - question_id=question_id, - ) - res_raw = yield from self.get_http_response( - content=to_content(query), - **current_subgraph.get_spec(), - ) - res = current_subgraph.process_response(res_raw) - raw_answers = yield from self._handle_response( - current_subgraph, - res, - res_context="answers", - ) - if raw_answers is None: - # we failed to get the answers - self.context.logger.error( - f"Failing to get answers for question {question_id} from {current_subgraph.api_id}" - ) - return None - answers = [ - { - "args": { - "answer": bytes.fromhex(answer["answer"][2:]), - "question_id": bytes.fromhex(answer["question"]["questionId"][2:]), - "history_hash": bytes.fromhex( - answer["question"]["historyHash"][2:] - ), - "user": Web3.to_checksum_address(answer["question"]["user"]), - "bond": int(answer["bondAggregate"]), - "timestamp": int(answer["timestamp"]), - "is_commitment": False, - } - } - for answer in raw_answers - ] - return answers - - def fetch_trades( - self, - creator: str, - from_timestamp: float, - to_timestamp: float, - ) -> Generator[None, None, Optional[List[Dict[str, Any]]]]: - """Fetch trades from the subgraph.""" - self._fetch_status = FetchStatus.IN_PROGRESS - current_subgraph = self.context.trades_subgraph - - all_trades: List[Dict[str, Any]] = [] - creation_timestamp_gt = ( - 0 # used to allow for batching based on creation timestamp - ) - # fetch trades in batches of `QUERY_BATCH_SIZE` - while True: - query = trades_query.substitute( - creator=creator.lower(), - creationTimestamp_lte=int(to_timestamp), - creationTimestamp_gte=int(from_timestamp), - first=QUERY_BATCH_SIZE, - creationTimestamp_gt=creation_timestamp_gt, - ) - - res_raw = yield from self.get_http_response( - content=to_content(query), - **current_subgraph.get_spec(), - ) - res = current_subgraph.process_response(res_raw) - trades_chunk = yield from self._handle_response( - current_subgraph, - res, - res_context="trades", - ) - if res is None: - # something went wrong - self.context.logger.error("Failed to process all trades.") - return all_trades - - trades_chunk = cast(List[Dict[str, Any]], trades_chunk) - if len(trades_chunk) == 0: - # no more trades to fetch - return all_trades - - # this is the last trade's creation timestamp - # they are sorted by creation timestamp in ascending order - # so we can use this to fetch the next batch - creation_timestamp_gt = trades_chunk[-1]["creationTimestamp"] - all_trades.extend(trades_chunk) - - def fetch_user_positions( - self, user: str - ) -> Generator[None, None, Optional[List[Dict[str, Any]]]]: - """Fetch positions for a user from the subgraph.""" - self._fetch_status = FetchStatus.IN_PROGRESS - current_subgraph = self.context.conditional_tokens_subgraph - - user_positions_id_gt = ( - 0 # used to allow for batching based on user positions id - ) - all_positions: List[Dict[str, Any]] = [] - while True: - query = user_positions_query.substitute( - id=user.lower(), - first=QUERY_BATCH_SIZE, - userPositions_id_gt=user_positions_id_gt, - ) - res_raw = yield from self.get_http_response( - content=to_content(query), - **current_subgraph.get_spec(), - ) - res = current_subgraph.process_response(res_raw) - - positions = yield from self._handle_response( - current_subgraph, - res, - res_context="positions", - ) - if res is None: - # something went wrong - self.context.logger.error("Failed to process all positions.") - return all_positions - - positions = cast(List[Dict[str, Any]], positions) - if len(positions) == 0: - # no more positions to fetch - return all_positions - - all_positions.extend(positions) - user_positions_id_gt = positions[-1]["id"] - - def clean_up(self) -> None: - """Clean up the resources.""" - markets_subgraphs = tuple(market for market, _ in self.params.creators_iterator) - other_subgraphs = ( - "conditional_tokens_subgraph", - "network_subgraph", - "realitio_subgraph", - "trades_subgraph", - ) - for subgraph in markets_subgraphs + other_subgraphs: - subgraph_specs = getattr(self.context, subgraph) - subgraph_specs.reset_retries() diff --git a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/utils.py b/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/utils.py deleted file mode 100644 index 21ec569bf..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/graph_tooling/utils.py +++ /dev/null @@ -1,130 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Utils for graph interactions.""" -import time -from enum import Enum -from typing import Any, Dict, List, Tuple - - -INVALID_MARKET_ANSWER = ( - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -) - - -class MarketState(Enum): - """Market state""" - - OPEN = 1 - PENDING = 2 - FINALIZING = 3 - ARBITRATING = 4 - CLOSED = 5 - - def __str__(self) -> str: - """Prints the market status.""" - return self.name.capitalize() - - -def get_position_balance( - user_positions: List[Dict[str, Any]], - condition_id: str, -) -> int: - """Get the balance of a position.""" - for position in user_positions: - position_condition_ids = position["position"]["conditionIds"] - balance = int(position["balance"]) - if condition_id.lower() in position_condition_ids: - return balance - - return 0 - - -def get_position_lifetime_value( - user_positions: List[Dict[str, Any]], - condition_id: str, -) -> int: - """Get the balance of a position.""" - for position in user_positions: - position_condition_ids = position["position"]["conditionIds"] - balance = int(position["position"]["lifetimeValue"]) - if condition_id.lower() in position_condition_ids: - return balance - - return 0 - - -def get_condition_id_to_balances( - creator_trades: List[Dict[str, Any]], - user_positions: List[Dict[str, Any]], -) -> Tuple[Dict[str, int], Dict[str, int]]: - """Get the condition id to balances.""" - condition_id_to_payout = {} - condition_id_to_balance = {} - for fpmm_trade in creator_trades: - outcome_index = int(fpmm_trade["outcomeIndex"]) - fpmm = fpmm_trade["fpmm"] - answer_finalized_timestamp = fpmm["answerFinalizedTimestamp"] - is_pending_arbitration = fpmm["isPendingArbitration"] - opening_timestamp = fpmm["openingTimestamp"] - market_status = MarketState.CLOSED - if ( - fpmm["currentAnswer"] is None - and opening_timestamp is not None - and time.time() >= float(opening_timestamp) - ): - market_status = MarketState.PENDING - elif fpmm["currentAnswer"] is None: - market_status = MarketState.OPEN - elif is_pending_arbitration: - market_status = MarketState.ARBITRATING - elif time.time() < float(answer_finalized_timestamp): - market_status = MarketState.FINALIZING - - if market_status == MarketState.CLOSED: - current_answer = int(fpmm["currentAnswer"], 16) # type: ignore - # we have the correct answer, or the market was invalid - if ( - outcome_index == current_answer - or current_answer == INVALID_MARKET_ANSWER - ): - condition_id = fpmm_trade["fpmm"]["condition"]["id"] - balance = get_position_balance(user_positions, condition_id) - condition_id_to_balance[condition_id] = balance - # get the payout for this condition - payout = get_position_lifetime_value(user_positions, condition_id) - if payout > 0 and balance == 0: - condition_id_to_payout[condition_id] = payout - - return condition_id_to_payout, condition_id_to_balance - - -def filter_claimed_conditions( - payouts: Dict[str, int], claimed_condition_ids: List[str] -) -> Dict[str, int]: - """Filter out the claimed payouts.""" - claimed_condition_ids = [ - condition_id.lower() for condition_id in claimed_condition_ids - ] - # filter out the claimed payouts, in a case-insensitive way - return { - condition_id: payout - for condition_id, payout in payouts.items() - if condition_id.lower() not in claimed_condition_ids - } diff --git a/trader_old/vendor/valory/skills/market_manager_abci/handlers.py b/trader_old/vendor/valory/skills/market_manager_abci/handlers.py deleted file mode 100644 index b1913b693..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/handlers.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- 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 the handlers for the 'market_manager_abci' skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIMarketManagerHandler = ABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_old/vendor/valory/skills/market_manager_abci/models.py b/trader_old/vendor/valory/skills/market_manager_abci/models.py deleted file mode 100644 index c39c3fc94..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/models.py +++ /dev/null @@ -1,108 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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. -# -# ------------------------------------------------------------------------------ - - -"""Custom objects for the MarketManager ABCI application.""" - -import builtins -from typing import Any, Dict, Iterator, List, Tuple - -from packages.valory.protocols.http import HttpMessage -from packages.valory.skills.abstract_round_abci.models import ApiSpecs, BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.market_manager_abci.bets import BINARY_N_SLOTS -from packages.valory.skills.market_manager_abci.rounds import MarketManagerAbciApp - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = MarketManagerAbciApp - - -class Subgraph(ApiSpecs): - """Specifies `ApiSpecs` with common functionality for subgraphs.""" - - def process_response(self, response: HttpMessage) -> Any: - """Process the response.""" - res = super().process_response(response) - if res is not None: - return res - - error_data = self.response_info.error_data - expected_error_type = getattr(builtins, self.response_info.error_type) - if isinstance(error_data, expected_error_type): - error_message_key = self.context.params.the_graph_error_message_key - error_message = error_data.get(error_message_key, None) - if self.context.params.the_graph_payment_required_error in error_message: - err = "Payment required for subsequent requests for the current 'The Graph' API key!" - self.context.logger.error(err) - return None - - -class OmenSubgraph(Subgraph): - """A model that wraps ApiSpecs for the OMEN's subgraph specifications.""" - - -class NetworkSubgraph(Subgraph): - """A model that wraps ApiSpecs for the network's subgraph specifications.""" - - -class MarketManagerParams(BaseParams): - """Market manager's parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the parameters' object.""" - # this is a mapping from a prediction market spec's attribute to the creators we want to take into account - self.creator_per_market: Dict[str, List[str]] = self._ensure( - "creator_per_subgraph", kwargs, Dict[str, List[str]] - ) - self.slot_count: int = self._ensure("slot_count", kwargs, int) - - if self.slot_count != BINARY_N_SLOTS: - raise ValueError( - f"Only a slot_count `2` is currently supported. `{self.slot_count}` was found in the configuration." - ) - - self.opening_margin: int = self._ensure("opening_margin", kwargs, int) - self.languages: List[str] = self._ensure("languages", kwargs, List[str]) - self.average_block_time: int = self._ensure("average_block_time", kwargs, int) - self.abt_error_mult: int = self._ensure("abt_error_mult", kwargs, int) - self.the_graph_error_message_key: str = self._ensure( - "the_graph_error_message_key", kwargs, str - ) - self.the_graph_payment_required_error: str = self._ensure( - "the_graph_payment_required_error", kwargs, str - ) - super().__init__(*args, **kwargs) - - @property - def creators_iterator(self) -> Iterator[Tuple[str, List[str]]]: - """Return an iterator of market per creators.""" - return iter(self.creator_per_market.items()) diff --git a/trader_old/vendor/valory/skills/market_manager_abci/payloads.py b/trader_old/vendor/valory/skills/market_manager_abci/payloads.py deleted file mode 100644 index d7247c415..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/payloads.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the transaction payloads for the MarketManager.""" - -from dataclasses import dataclass -from typing import Optional - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class UpdateBetsPayload(BaseTxPayload): - """A transaction payload for the updated bets.""" - - bets_hash: Optional[str] diff --git a/trader_old/vendor/valory/skills/market_manager_abci/rounds.py b/trader_old/vendor/valory/skills/market_manager_abci/rounds.py deleted file mode 100644 index 1ac5dc8be..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/rounds.py +++ /dev/null @@ -1,156 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the rounds for the MarketManager ABCI application.""" - -from abc import ABC -from enum import Enum -from typing import Dict, Set, Tuple, Type, cast - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AbstractRound, - AppState, - BaseSynchronizedData, - CollectSameUntilThresholdRound, - CollectionRound, - DegenerateRound, - DeserializedCollection, - get_name, -) -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload - - -class Event(Enum): - """Event enumeration for the MarketManager demo.""" - - DONE = "done" - NO_MAJORITY = "no_majority" - ROUND_TIMEOUT = "round_timeout" - FETCH_ERROR = "fetch_error" - - -class SynchronizedData(BaseSynchronizedData): - """Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - def _get_deserialized(self, key: str) -> DeserializedCollection: - """Strictly get a collection and return it deserialized.""" - serialized = self.db.get_strict(key) - return CollectionRound.deserialize_collection(serialized) - - @property - def bets_hash(self) -> str: - """Get the most voted bets' hash.""" - return str(self.db.get_strict("bets_hash")) - - @property - def participant_to_bets_hash(self) -> DeserializedCollection: - """Get the participants to bets' hash.""" - return self._get_deserialized("participant_to_bets_hash") - - @property - def is_checkpoint_reached(self) -> bool: - """Check if the checkpoint is reached.""" - return bool(self.db.get("is_checkpoint_reached", False)) - - -class MarketManagerAbstractRound(AbstractRound[Event], ABC): - """Abstract round for the MarketManager skill.""" - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return cast(SynchronizedData, super().synchronized_data) - - def _return_no_majority_event(self) -> Tuple[SynchronizedData, Event]: - """ - Trigger the `NO_MAJORITY` event. - - :return: the new synchronized data and a `NO_MAJORITY` event - """ - return self.synchronized_data, Event.NO_MAJORITY - - -class UpdateBetsRound(CollectSameUntilThresholdRound, MarketManagerAbstractRound): - """A round for the bets fetching & updating.""" - - payload_class = UpdateBetsPayload - done_event: Enum = Event.DONE - none_event: Enum = Event.FETCH_ERROR - no_majority_event: Enum = Event.NO_MAJORITY - selection_key = get_name(SynchronizedData.bets_hash) - collection_key = get_name(SynchronizedData.participant_to_bets_hash) - synchronized_data_class = SynchronizedData - - -class FinishedMarketManagerRound(DegenerateRound, ABC): - """A round that represents MarketManager has finished""" - - -class FailedMarketManagerRound(DegenerateRound, ABC): - """A round that represents that the period failed""" - - -class MarketManagerAbciApp(AbciApp[Event]): # pylint: disable=too-few-public-methods - """MarketManagerAbciApp - - Initial round: UpdateBetsRound - - Initial states: {UpdateBetsRound} - - Transition states: - 0. UpdateBetsRound - - done: 1. - - fetch error: 2. - - round timeout: 0. - - no majority: 0. - 1. FinishedMarketManagerRound - 2. FailedMarketManagerRound - - Final states: {FailedMarketManagerRound, FinishedMarketManagerRound} - - Timeouts: - round timeout: 30.0 - """ - - initial_round_cls: Type[AbstractRound] = UpdateBetsRound - transition_function: AbciAppTransitionFunction = { - UpdateBetsRound: { - Event.DONE: FinishedMarketManagerRound, - Event.FETCH_ERROR: FailedMarketManagerRound, - Event.ROUND_TIMEOUT: UpdateBetsRound, - Event.NO_MAJORITY: UpdateBetsRound, - }, - FinishedMarketManagerRound: {}, - FailedMarketManagerRound: {}, - } - cross_period_persisted_keys = frozenset({get_name(SynchronizedData.bets_hash)}) - final_states: Set[AppState] = {FinishedMarketManagerRound, FailedMarketManagerRound} - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = {UpdateBetsRound: set()} - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedMarketManagerRound: {get_name(SynchronizedData.bets_hash)}, - FailedMarketManagerRound: set(), - } diff --git a/trader_old/vendor/valory/skills/market_manager_abci/skill.yaml b/trader_old/vendor/valory/skills/market_manager_abci/skill.yaml deleted file mode 100644 index 7d1de7b60..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/skill.yaml +++ /dev/null @@ -1,197 +0,0 @@ -name: market_manager_abci -author: valory -version: 0.1.0 -type: skill -description: This skill implements the MarketManager for an AEA. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeie6miwn67uin3bphukmf7qgiifh4xtm42i5v3nuyqxzxtehxsqvcq - __init__.py: bafybeigrtedqzlq5mtql2ssjsdriw76ml3666m4e2c3fay6vmyzofl6v6e - behaviours.py: bafybeicfoszavcyrzahe6qaydlaf27mpbwui7a6wgdbstydbzxmdisxhju - bets.py: bafybeia7anwfr5ibesvumzyalcuwcozovkndgjbxadcrgzr5sq23gj3ldi - dialogues.py: bafybeiebofyykseqp3fmif36cqmmyf3k7d2zbocpl6t6wnlpv4szghrxbm - fsm_specification.yaml: bafybeic5cvwfbiu5pywyp3h5s2elvu7jqdrcwayay7o3v3ow47vu2jw53q - graph_tooling/__init__.py: bafybeigzo7nhbzafyq3fuhrlewksjvmzttiuk4vonrggtjtph4rw4ncpk4 - graph_tooling/queries/__init__.py: bafybeihbybnl53i7k57ql5ujt5ru5n2eg324jfndh4lcnm4fk52mwbkjda - graph_tooling/queries/conditional_tokens.py: bafybeic6ohkdp4rvkcfglieksv6gbzm4qocpgdjaz4sroutl37sxijthji - graph_tooling/queries/network.py: bafybeigeq72ys2nrjqspj2uacaudrgljrne5a3o5jvzsktldxdq6m2xmeu - graph_tooling/queries/omen.py: bafybeiesgavgoio6zeovdyvzeezz5qoosdgioktoen5ckrgyxpr4u3m3nu - graph_tooling/queries/realitio.py: bafybeiftewjwk5fi6uqrhmalweun47voau2qkxi7hg3faxcmyy3va44zma - graph_tooling/queries/trades.py: bafybeigu6c25kf3mrlvmwjeskgagswdjnnxsygpriygmip44us4xvuf7ji - graph_tooling/requests.py: bafybeibjyb6av33aswnptttekj6t7k7xysgphh2bigoorcgkc54y2j3xkm - graph_tooling/utils.py: bafybeig5hxhnqgyfn5ym3poc5nziqwpeozqbd6wa4s6c2hjn6iyedg3t3y - handlers.py: bafybeihot2i2yvfkz2gcowvt66wdu6tkjbmv7hsmc4jzt4reqeaiuphbtu - models.py: bafybeibjttnga54y4auz6f33ecfrngyw53b2xzpompm72drjsr4xoytmiy - payloads.py: bafybeicfymvvtdpkcgmkvthfzmb7dqakepkzslqrz6rcs7nxkz7qq3mrzy - rounds.py: bafybeibqqq3vjotaasc67olhlqthka6e6refodguntkmpksgdbqlzme73a - tests/__init__.py: bafybeigaewntxawezvygss345kytjijo56bfwddjtfm6egzxfajsgojam4 - tests/test_dialogues.py: bafybeiet646su5nsjmvruahuwg6un4uvwzyj2lnn2jvkye6cxooz22f3ja - tests/test_handlers.py: bafybeiaz3idwevvlplcyieaqo5oeikuthlte6e2gi4ajw452ylvimwgiki - tests/test_payloads.py: bafybeidvld43p5c4wpwi7m6rfzontkheqqgxdchjnme5b54wmldojc5dmm - tests/test_rounds.py: bafybeidahkavof43y3o4omnihh6yxdx7gqofio7kzukdydymxbebylempu -fingerprint_ignore_patterns: [] -connections: [] -contracts: [] -protocols: -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -behaviours: - main: - args: {} - class_name: MarketManagerRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIMarketManagerHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 350.0 - service_id: market_manager - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - sleep_time: 5 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - termination_sleep: 900 - tx_timeout: 10.0 - use_termination: false - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - creator_per_subgraph: - omen_subgraph: [] - slot_count: 2 - opening_margin: 300 - languages: - - en_US - average_block_time: 5 - abt_error_mult: 5 - the_graph_error_message_key: message - the_graph_payment_required_error: payment required for subsequent requests for - this API key - class_name: MarketManagerParams - network_subgraph: - args: - api_id: network - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:blocks - response_index: 0 - response_type: dict - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/stakewise/ethereum-gnosis - class_name: NetworkSubgraph - omen_subgraph: - args: - api_id: omen - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:fixedProductMarketMakers - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/protofire/omen-xdai - class_name: OmenSubgraph - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState -dependencies: - web3: - version: <7,>=6.0.0 -is_abstract: true diff --git a/trader_old/vendor/valory/skills/market_manager_abci/tests/__init__.py b/trader_old/vendor/valory/skills/market_manager_abci/tests/__init__.py deleted file mode 100644 index 574eff5a1..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/market_manager skill.""" diff --git a/trader_old/vendor/valory/skills/market_manager_abci/tests/test_dialogues.py b/trader_old/vendor/valory/skills/market_manager_abci/tests/test_dialogues.py deleted file mode 100644 index cdcfd1185..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.market_manager_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_old/vendor/valory/skills/market_manager_abci/tests/test_handlers.py b/trader_old/vendor/valory/skills/market_manager_abci/tests/test_handlers.py deleted file mode 100644 index 16f555389..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/tests/test_handlers.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the tests for the handlers for the 'market_manager_abci' skill.""" -from unittest.mock import MagicMock - -import pytest -from aea.configurations.data_types import PublicId -from aea.skills.base import Handler - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.market_manager_abci.handlers import ( - ABCIMarketManagerHandler, - ContractApiHandler, - HttpHandler, - IpfsHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, -) - - -@pytest.mark.parametrize( - "handler, base_handler", - [ - (ABCIMarketManagerHandler, ABCIRoundHandler), - (HttpHandler, BaseHttpHandler), - (SigningHandler, BaseSigningHandler), - (LedgerApiHandler, BaseLedgerApiHandler), - (ContractApiHandler, BaseContractApiHandler), - (TendermintHandler, BaseTendermintHandler), - (IpfsHandler, BaseIpfsHandler), - ], -) -def test_handler(handler: Handler, base_handler: Handler) -> None: - """Test that the 'handlers.py' of the TraderAbci can be imported.""" - handler = handler( - name="dummy_handler", - skill_context=MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")), - ) - - assert isinstance(handler, base_handler) diff --git a/trader_old/vendor/valory/skills/market_manager_abci/tests/test_payloads.py b/trader_old/vendor/valory/skills/market_manager_abci/tests/test_payloads.py deleted file mode 100644 index 898c80b48..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/tests/test_payloads.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the transaction payloads for the market manager abci.""" - -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload - - -def test_update_bets_payload() -> None: - """Test `UpdateBetsPayload`.""" - - payload = UpdateBetsPayload(sender="sender", bets_hash="dummy bets hash") - - assert payload.bets_hash == "dummy bets hash" - assert UpdateBetsPayload.from_json(payload.json) == payload diff --git a/trader_old/vendor/valory/skills/market_manager_abci/tests/test_rounds.py b/trader_old/vendor/valory/skills/market_manager_abci/tests/test_rounds.py deleted file mode 100644 index 33b184c69..000000000 --- a/trader_old/vendor/valory/skills/market_manager_abci/tests/test_rounds.py +++ /dev/null @@ -1,324 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the test for rounds for the MarketManager ABCI application.""" - -import json -from dataclasses import dataclass, field -from typing import ( - Any, - Callable, - Dict, - FrozenSet, - Hashable, - List, - Mapping, - Optional, - Union, -) -from unittest import mock -from unittest.mock import MagicMock, patch - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - BaseTxPayload, - get_name, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.market_manager_abci.payloads import UpdateBetsPayload -from packages.valory.skills.market_manager_abci.rounds import ( - Event, - FailedMarketManagerRound, - FinishedMarketManagerRound, - MarketManagerAbciApp, - SynchronizedData, - UpdateBetsRound, -) - - -@pytest.fixture -def abci_app() -> MarketManagerAbciApp: - """Fixture for MarketManagerAbciApp.""" - # Create mocks for the required parameters - synchronized_data = MagicMock() - logger = MagicMock() - context = MagicMock() - - # Instantiate MarketManagerAbciApp with the required arguments - return MarketManagerAbciApp( - synchronized_data=synchronized_data, logger=logger, context=context - ) - - -DUMMY_BETS_HASH = "dummy_bets_hash" -DUMMY_PARTICIPANT_TO_BETS_HASH = json.dumps( - { - "agent_0": "bet_1", - "agent_1": "bet_2", - "agent_2": "bet_3", - } -) - - -def get_participants() -> FrozenSet[str]: - """Participants""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -def get_payloads( - data: Optional[str], -) -> Mapping[str, BaseTxPayload]: - """Get payloads.""" - return { - participant: UpdateBetsPayload(participant, data) - for participant in get_participants() - } - - -@dataclass -class RoundTestCase: - """RoundTestCase""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, BaseTxPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -MAX_PARTICIPANTS: int = 4 - - -class BaseMarketManagerRoundTestClass(BaseCollectSameUntilThresholdRoundTest): - """Base test class for MarketManager rounds.""" - - synchronized_data: SynchronizedData - _synchronized_data_class = SynchronizedData - _event_class = Event - round_class = UpdateBetsRound - - def run_test(self, test_case: RoundTestCase) -> None: - """Run the test""" - - # Set initial data - self.synchronized_data.update( - self._synchronized_data_class, **test_case.initial_data - ) - - test_round = self.round_class( - synchronized_data=self.synchronized_data, context=mock.MagicMock() - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=test_case.payloads, - synchronized_data_update_fn=lambda sync_data, _: sync_data.update( - **test_case.final_data - ), - synchronized_data_attr_checks=test_case.synchronized_data_attr_checks, - most_voted_payload=test_case.most_voted_payload, - exit_event=test_case.event, - ) - ) - - -class TestUpdateBetsRound(BaseMarketManagerRoundTestClass): - """Tests for UpdateBetsRound.""" - - round_class = UpdateBetsRound - synchronized_data: SynchronizedData - _synchronized_data_class = SynchronizedData - _event_class = Event - - @pytest.mark.parametrize( - "test_case", - ( - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_payloads( - data=DUMMY_BETS_HASH, - ), - final_data={ - "bets_hash": DUMMY_BETS_HASH, - "participant_to_bets_hash": DUMMY_PARTICIPANT_TO_BETS_HASH, - }, - event=Event.DONE, - most_voted_payload=DUMMY_BETS_HASH, - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.bets_hash, - ], - ), - RoundTestCase( - name="Fetch error", - initial_data={}, - payloads=get_payloads( - data=None, - ), - final_data={}, - event=Event.FETCH_ERROR, - most_voted_payload=None, - synchronized_data_attr_checks=[], - ), - ), - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run tests.""" - - self.run_test(test_case) - - def test_return_no_majority_event(self) -> None: - """Test the _return_no_majority_event method.""" - # Mock synchronized data and create an instance of the round - synchronized_data = MagicMock(spec=SynchronizedData) - update_bets_round = UpdateBetsRound( - synchronized_data=synchronized_data, context=MagicMock() - ) - - # Call the method and check the results - result = update_bets_round._return_no_majority_event() - assert result == (synchronized_data, Event.NO_MAJORITY) - - -class TestFinishedMarketManagerRound: - """Tests for FinishedMarketManagerRound.""" - - def test_finished_market_manager_round_initialization(self) -> None: - """Test the initialization of FinishedMarketManagerRound.""" - round_ = FinishedMarketManagerRound( - synchronized_data=MagicMock(), context=MagicMock() - ) - assert isinstance(round_, FinishedMarketManagerRound) - - -class TestFailedMarketManagerRound: - """Tests for FailedMarketManagerRound.""" - - def test_failed_market_manager_round_initialization(self) -> None: - """Test the initialization of FailedMarketManagerRound.""" - round_ = FailedMarketManagerRound( - synchronized_data=MagicMock(), context=MagicMock() - ) - assert isinstance(round_, FailedMarketManagerRound) - - -def test_market_manager_abci_app_initialization(abci_app: MarketManagerAbciApp) -> None: - """Test the initialization of MarketManagerAbciApp.""" - assert abci_app.initial_round_cls is UpdateBetsRound - assert abci_app.final_states == { - FinishedMarketManagerRound, - FailedMarketManagerRound, - } - assert abci_app.transition_function == { - UpdateBetsRound: { - Event.DONE: FinishedMarketManagerRound, - Event.FETCH_ERROR: FailedMarketManagerRound, - Event.ROUND_TIMEOUT: UpdateBetsRound, - Event.NO_MAJORITY: UpdateBetsRound, - }, - FinishedMarketManagerRound: {}, - FailedMarketManagerRound: {}, - } - assert abci_app.event_to_timeout == {Event.ROUND_TIMEOUT: 30.0} - assert abci_app.db_pre_conditions == {UpdateBetsRound: set()} - assert abci_app.db_post_conditions == { - FinishedMarketManagerRound: {get_name(SynchronizedData.bets_hash)}, - FailedMarketManagerRound: set(), - } - - -# Mock serialized collections for different keys -DUMMY_PARTICIPANT_TO_BETS_HASH = json.dumps( - { - "agent_0": {"sender": "agent_0", "data": "bet_1"}, - "agent_1": {"sender": "agent_1", "data": "bet_2"}, - } -) -DUMMY_BETS_HASH = json.dumps({"bets_hash": "dummy_bets_hash"}) - -DUMMY_SERIALIZED_PARTICIPANT_TO_BETS_HASH = json.dumps(DUMMY_PARTICIPANT_TO_BETS_HASH) -DUMMY_SERIALIZED_BETS_HASH = json.dumps(DUMMY_BETS_HASH) - - -@pytest.mark.parametrize( - "key,serialized_data,expected_result,property_to_check", - [ - ( - "participant_to_bets_hash", - DUMMY_SERIALIZED_PARTICIPANT_TO_BETS_HASH, - json.loads(DUMMY_PARTICIPANT_TO_BETS_HASH), - "participant_to_bets_hash", - ), - ( - "bets_hash", - DUMMY_SERIALIZED_BETS_HASH, - json.loads(DUMMY_BETS_HASH), - "bets_hash", - ), - ], -) -@patch( - "packages.valory.skills.market_manager_abci.rounds.CollectionRound.deserialize_collection" -) -def test_synchronized_data_get_deserialized( - mock_deserialize_collection: MagicMock, - key: str, - serialized_data: str, - expected_result: Mapping[str, Any], - property_to_check: str, -) -> None: - """Test the _get_deserialized method and properties in SynchronizedData.""" - # Mock the db.get_strict to return the serialized data - mock_db = mock.MagicMock() - mock_db.get_strict.return_value = serialized_data - - # Initialize SynchronizedData with the mocked db - synchronized_data = SynchronizedData(db=mock_db) - - # Mock the deserialize_collection function to return the expected deserialized result - mock_deserialize_collection.return_value = expected_result - - deserialized_data: Union[str, Mapping[str, BaseTxPayload]] - if property_to_check == "participant_to_bets_hash": - deserialized_data = synchronized_data.participant_to_bets_hash - else: - deserialized_data = synchronized_data.bets_hash - - # Ensure that get_strict is called with the correct key - mock_db.get_strict.assert_called_once_with(key) - - # Ensure that deserialize_collection is called with the correct serialized data only for collection fields - if property_to_check == "participant_to_bets_hash": - mock_deserialize_collection.assert_called_once_with(serialized_data) - assert deserialized_data == expected_result - - -def test_synchronized_data_initialization() -> None: - """Test the initialization and attributes of SynchronizedData.""" - setup_data = {"test": ["test"]} - synchronized_data = SynchronizedData(db=AbciAppDB(setup_data=setup_data)) - - assert synchronized_data.db._data == {0: {"test": ["test"]}} diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/__init__.py b/trader_old/vendor/valory/skills/mech_interact_abci/__init__.py deleted file mode 100644 index 3a0f255cf..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- 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 the implementation of the mech interact skill.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/mech_interact_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/__init__.py b/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/__init__.py deleted file mode 100644 index eecc0b1c1..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 package contains the behaviours for the mech interact skill.""" diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/base.py b/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/base.py deleted file mode 100644 index 45444cb8f..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/base.py +++ /dev/null @@ -1,221 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the base behaviour for the mech interact abci skill.""" - -import json -from abc import ABC -from dataclasses import asdict, is_dataclass -from datetime import datetime, timedelta -from typing import Any, Callable, Generator, List, Optional, cast - -from aea.configurations.data_types import PublicId - -from packages.valory.contracts.mech.contract import Mech -from packages.valory.contracts.mech_marketplace.contract import MechMarketplace -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - BaseBehaviour, - TimeoutException, -) -from packages.valory.skills.mech_interact_abci.models import ( - MechMarketplaceConfig, - MechParams, - MultisendBatch, -) -from packages.valory.skills.mech_interact_abci.states.base import SynchronizedData - - -WaitableConditionType = Generator[None, None, bool] - - -class MechInteractBaseBehaviour(BaseBehaviour, ABC): - """Represents the base class for the mech interaction FSM behaviour.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize the bet placement behaviour.""" - super().__init__(**kwargs) - self.multisend_batches: List[MultisendBatch] = [] - self.multisend_data = b"" - self._safe_tx_hash = "" - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return cast(SynchronizedData, super().synchronized_data) - - @property - def params(self) -> MechParams: - """Return the params.""" - return cast(MechParams, self.context.params) - - @property - def mech_marketplace_config(self) -> MechMarketplaceConfig: - """Return the mech marketplace config.""" - return cast(MechMarketplaceConfig, self.context.params.mech_marketplace_config) - - def default_error( - self, contract_id: str, contract_callable: str, response_msg: ContractApiMessage - ) -> None: - """Return a default contract interaction error message.""" - self.context.logger.error( - f"Could not successfully interact with the {contract_id} contract " - f"using {contract_callable!r}: {response_msg}" - ) - - def contract_interaction_error( - self, contract_id: str, contract_callable: str, response_msg: ContractApiMessage - ) -> None: - """Return a contract interaction error message.""" - # contracts can only return one message, i.e., multiple levels cannot exist. - for level in ("info", "warning", "error"): - msg = response_msg.raw_transaction.body.get(level, None) - logger = getattr(self.context.logger, level) - if msg is not None: - logger(msg) - return - - self.default_error(contract_id, contract_callable, response_msg) - - def contract_interact( - self, - performative: ContractApiMessage.Performative, - contract_address: str, - contract_public_id: PublicId, - contract_callable: str, - data_key: str, - placeholder: str, - **kwargs: Any, - ) -> WaitableConditionType: - """Interact with a contract.""" - contract_id = str(contract_public_id) - - self.context.logger.info( - f"Interacting with contract {contract_id} at address {contract_address}\n" - f"Calling method {contract_callable} with parameters: {kwargs}" - ) - - response_msg = yield from self.get_contract_api_response( - performative, - contract_address, - contract_id, - contract_callable, - **kwargs, - ) - - self.context.logger.info(f"Contract response: {response_msg}") - - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.default_error(contract_id, contract_callable, response_msg) - return False - - data = response_msg.raw_transaction.body.get(data_key, None) - if data is None: - self.contract_interaction_error( - contract_id, contract_callable, response_msg - ) - return False - - setattr(self, placeholder, data) - return True - - def _mech_contract_interact( - self, contract_callable: str, data_key: str, placeholder: str, **kwargs: Any - ) -> WaitableConditionType: - """Interact with the mech contract.""" - status = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.mech_contract_address, - contract_public_id=Mech.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def _mech_marketplace_contract_interact( - self, - contract_callable: str, - data_key: str, - placeholder: str, - **kwargs: Any, - ) -> WaitableConditionType: - """Interact with the mech marketplace contract.""" - status = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.mech_marketplace_config.mech_marketplace_address, - contract_public_id=MechMarketplace.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def wait_for_condition_with_sleep( - self, - condition_gen: Callable[[], WaitableConditionType], - timeout: Optional[float] = None, - ) -> Generator: - """Wait for a condition to happen and sleep in-between checks. - - This is a modified version of the base `wait_for_condition` method which: - 1. accepts a generator that creates the condition instead of a callable - 2. sleeps in-between checks - - :param condition_gen: a generator of the condition to wait for - :param timeout: the maximum amount of time to wait - :yield: None - """ - - deadline = ( - datetime.now() + timedelta(0, timeout) - if timeout is not None - else datetime.max - ) - - while True: - condition_satisfied = yield from condition_gen() - if condition_satisfied: - break - if timeout is not None and datetime.now() > deadline: - raise TimeoutException() - msg = f"Retrying in {self.params.mech_interaction_sleep_time} seconds." - self.context.logger.info(msg) - yield from self.sleep(self.params.mech_interaction_sleep_time) - - def finish_behaviour(self, payload: BaseTxPayload) -> Generator: - """Finish the behaviour.""" - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class DataclassEncoder(json.JSONEncoder): - """A custom JSON encoder for dataclasses.""" - - def default(self, o: Any) -> Any: - """The default JSON encoder.""" - if is_dataclass(o): - return asdict(o) - return super().default(o) diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/request.py b/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/request.py deleted file mode 100644 index 51410893f..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/request.py +++ /dev/null @@ -1,499 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the request state of the mech interaction abci app.""" - -import json -from dataclasses import asdict -from pathlib import Path -from tempfile import mkdtemp -from typing import Any, Generator, List, Optional, cast - -import multibase -import multicodec -from aea.exceptions import AEAEnforceError -from aea.helpers.cid import to_v1 -from hexbytes import HexBytes - -from packages.valory.contracts.erc20.contract import ERC20 -from packages.valory.contracts.gnosis_safe.contract import ( - GnosisSafeContract, - SafeOperation, -) -from packages.valory.contracts.multisend.contract import MultiSendContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.abstract_round_abci.io_.store import SupportedFiletype -from packages.valory.skills.mech_interact_abci.behaviours.base import ( - DataclassEncoder, - MechInteractBaseBehaviour, - WaitableConditionType, -) -from packages.valory.skills.mech_interact_abci.models import MultisendBatch -from packages.valory.skills.mech_interact_abci.payloads import MechRequestPayload -from packages.valory.skills.mech_interact_abci.states.base import ( - MechInteractionResponse, - MechMetadata, -) -from packages.valory.skills.mech_interact_abci.states.request import MechRequestRound -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - hash_payload_to_hex, -) -from packages.valory.skills.transaction_settlement_abci.rounds import TX_HASH_LENGTH - - -METADATA_FILENAME = "metadata.json" -V1_HEX_PREFIX = "f01" -Ox = "0x" - -# setting the safe gas to 0 means that all available gas will be used -# which is what we want in most cases -# more info here: https://safe-docs.dev.gnosisdev.com/safe/docs/contracts_tx_execution/ -SAFE_GAS = 0 - - -class MechRequestBehaviour(MechInteractBaseBehaviour): - """A behaviour in which the agents prepare a tx to initiate a request to a mech.""" - - matching_round = MechRequestRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize Behaviour.""" - super().__init__(**kwargs) - self._v1_hex_truncated: str = "" - self._request_data: bytes = b"" - self._price: int = 0 - self._mech_requests: List[MechMetadata] = [] - self._pending_responses: List[MechInteractionResponse] = [] - - @property - def metadata_filepath(self) -> str: - """Get the filepath to the metadata.""" - return str(Path(mkdtemp()) / METADATA_FILENAME) - - @property - def request_data(self) -> bytes: - """Get the request data.""" - return self._request_data - - @request_data.setter - def request_data(self, data: bytes) -> None: - """Set the request data.""" - self._request_data = data - - @property - def price(self) -> int: - """Get the price.""" - return self._price - - @price.setter - def price(self, price: int) -> None: - """Set the price.""" - self._price = price - - @property - def safe_tx_hash(self) -> str: - """Get the safe_tx_hash.""" - return self._safe_tx_hash - - @safe_tx_hash.setter - def safe_tx_hash(self, safe_hash: str) -> None: - """Set the safe_tx_hash.""" - length = len(safe_hash) - if length != TX_HASH_LENGTH: - raise ValueError( - f"Incorrect length {length} != {TX_HASH_LENGTH} detected " - f"when trying to assign a safe transaction hash: {safe_hash}" - ) - self._safe_tx_hash = safe_hash[2:] - - @property - def multi_send_txs(self) -> List[dict]: - """Get the multisend transactions as a list of dictionaries.""" - return [asdict(batch) for batch in self.multisend_batches] - - @property - def txs_value(self) -> int: - """Get the total value of the transactions.""" - return sum(batch.value for batch in self.multisend_batches) - - @property - def tx_hex(self) -> Optional[str]: - """Serialize the safe tx to a hex string.""" - if self.safe_tx_hash == "": - raise ValueError( - "Cannot prepare a multisend transaction without a safe transaction hash." - ) - return hash_payload_to_hex( - self.safe_tx_hash, - self.txs_value, - SAFE_GAS, - self.params.multisend_address, - self.multisend_data, - SafeOperation.DELEGATE_CALL.value, - ) - - @staticmethod - def wei_to_unit(wei: int) -> float: - """Convert WEI to unit token.""" - return wei / 10**18 - - def _get_native_balance(self, account: str) -> Generator[None, None, Optional[int]]: - """Get native balance for account.""" - ledger_api_response = yield from self.get_ledger_api_response( - performative=LedgerApiMessage.Performative.GET_STATE, # type: ignore - ledger_callable="get_balance", - block_identifier="latest", - account=account, - chain_id=self.params.mech_chain_id, - ) - - try: - balance = int(ledger_api_response.state.body["get_balance_result"]) - except (AEAEnforceError, KeyError, ValueError, TypeError): - balance = None - - if balance is None: - log_msg = f"Failed to get the native balance for account {account}." - self.context.logger.error(f"{log_msg}: {ledger_api_response}") - return None - - self.context.logger.info( - f"Account {account} has {self.wei_to_unit(balance)} native tokens." - ) - return balance - - def _get_wrapped_native_balance( - self, account: str - ) -> Generator[None, None, Optional[int]]: - """Get wrapped native balance for account.""" - - error_message = f"Failed to get the wrapped native balance for account {account} (mech_wrapped_native_token_address={self.params.mech_wrapped_native_token_address})." - config_message = "Please configure 'mech_wrapped_native_token_address' appropriately if you want to use wrapped native tokens for mech requests." - if not self.params.mech_wrapped_native_token_address: - self.context.logger.info( - f"Wrapped native token address has not been configured. Assumed wrapped native token = 0. {config_message}" - ) - return 0 - - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.mech_wrapped_native_token_address, - contract_id=str(ERC20.contract_id), - contract_callable="check_balance", - account=account, - ) - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.context.logger.error( - f"{error_message} {config_message} {response_msg}" - ) - return None - - token = response_msg.raw_transaction.body.get("token", None) - wallet = response_msg.raw_transaction.body.get("wallet", None) - if token is None or wallet is None: - self.context.logger.error( - f"{error_message} {config_message} {response_msg}" - ) - return None - - self.context.logger.info( - f"Account {account} has {self.wei_to_unit(token)} wrapped native tokens." - ) - return token - - def update_safe_balances(self) -> WaitableConditionType: - """Check the safe's balance.""" - account = self.synchronized_data.safe_contract_address - wallet = yield from self._get_native_balance(account) - if wallet is None: - return False - - token = yield from self._get_wrapped_native_balance(account) - if token is None: - return False - - self.token_balance = int(token) - self.wallet_balance = int(wallet) - return True - - def _build_unwrap_tokens_tx(self) -> WaitableConditionType: - """Exchange wrapped native tokens to native tokens.""" - - if not self.params.mech_wrapped_native_token_address: - return True - - # A total of price - wallet_balance wrapped native tokens are required - amount = self.price - self.wallet_balance - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.params.mech_wrapped_native_token_address, - contract_id=str(ERC20.contract_id), - contract_callable="build_withdraw_tx", - amount=amount, - ) - - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.info(f"Could not build withdraw tx: {response_msg}") - return False - - withdraw_data = response_msg.state.body.get("data") - if withdraw_data is None: - self.context.logger.info(f"Could not build withdraw tx: {response_msg}") - return False - - batch = MultisendBatch( - to=self.params.mech_wrapped_native_token_address, - data=HexBytes(withdraw_data), - ) - self.multisend_batches.append(batch) - self.context.logger.info(f"Built transaction to unwrap {amount} tokens.") - return True - - def _ensure_available_balance(self) -> WaitableConditionType: - """Ensures available payment for the mech request and unwraps tokens if needed.""" - yield from self.wait_for_condition_with_sleep(self.update_safe_balances) - - # There is enough balance using native tokens - if self.price <= self.wallet_balance: - return True - - # There is enough balance using native and wrapped tokens - if self.price <= self.wallet_balance + self.token_balance: - yield from self.wait_for_condition_with_sleep(self._build_unwrap_tokens_tx) - return True - - shortage = self.price - self.wallet_balance - self.token_balance - balance_info = "The balance is not enough to pay for the mech's price." - refill_info = f"Please refill the safe with at least {self.wei_to_unit(shortage)} native tokens." - if self.params.mech_wrapped_native_token_address: - refill_info = f"Please refill the safe with at least {self.wei_to_unit(shortage)} native tokens or wrapped native tokens." - - self.context.logger.warning(balance_info + " " + refill_info) - self.sleep(self.params.sleep_time) - return False - - def _build_multisend_data( - self, - ) -> WaitableConditionType: - """Get the multisend tx.""" - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.multisend_address, - contract_id=str(MultiSendContract.contract_id), - contract_callable="get_tx_data", - multi_send_txs=self.multi_send_txs, - chain_id=self.params.mech_chain_id, - ) - expected_performative = ContractApiMessage.Performative.RAW_TRANSACTION - if response_msg.performative != expected_performative: - self.context.logger.error( - f"Couldn't compile the multisend tx. " - f"Expected response performative {expected_performative.value}, " # type: ignore - f"received {response_msg.performative.value}: {response_msg}" - ) - return False - - multisend_data_str = response_msg.raw_transaction.body.get("data", None) - if multisend_data_str is None: - self.context.logger.error( - f"Something went wrong while trying to prepare the multisend data: {response_msg}" - ) - return False - - # strip "0x" from the response - multisend_data_str = str(response_msg.raw_transaction.body["data"])[2:] - self.multisend_data = bytes.fromhex(multisend_data_str) - return True - - def _build_multisend_safe_tx_hash(self) -> WaitableConditionType: - """Prepares and returns the safe tx hash for a multisend tx.""" - self.context.logger.info( - f"Building multisend safe tx hash: safe={self.synchronized_data.safe_contract_address}" - ) - response_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_raw_safe_transaction_hash", - to_address=self.params.multisend_address, - value=self.txs_value, - data=self.multisend_data, - safe_tx_gas=SAFE_GAS, - operation=SafeOperation.DELEGATE_CALL.value, - chain_id=self.params.mech_chain_id, - ) - - if response_msg.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - "Couldn't get safe tx hash. Expected response performative " - f"{ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response_msg.performative.value}: {response_msg}." - ) - return False - - tx_hash = response_msg.state.body.get("tx_hash", None) - if tx_hash is None or len(tx_hash) != TX_HASH_LENGTH: - self.context.logger.error( - "Something went wrong while trying to get the buy transaction's hash. " - f"Invalid hash {tx_hash!r} was returned." - ) - return False - - self.safe_tx_hash = tx_hash - return True - - def setup(self) -> None: - """Set up the `MechRequest` behaviour.""" - self._mech_requests = self.synchronized_data.mech_requests - self.context.logger.info(f"Processing mech requests: {self._mech_requests}") - - def _send_metadata_to_ipfs( - self, - ) -> WaitableConditionType: - """Send Mech metadata to IPFS.""" - metadata = self._mech_requests.pop() - metadata_hash = yield from self.send_to_ipfs( - self.metadata_filepath, asdict(metadata), filetype=SupportedFiletype.JSON - ) - if metadata_hash is None: - return False - - v1_file_hash = to_v1(metadata_hash) - cid_bytes = cast(bytes, multibase.decode(v1_file_hash)) - multihash_bytes = multicodec.remove_prefix(cid_bytes) - v1_file_hash_hex = V1_HEX_PREFIX + multihash_bytes.hex() - ipfs_link = self.params.ipfs_address + v1_file_hash_hex - self.context.logger.info(f"Prompt uploaded: {ipfs_link}") - mech_request_data = v1_file_hash_hex[9:] - pending_response = MechInteractionResponse( - nonce=metadata.nonce, data=mech_request_data - ) - self._v1_hex_truncated = Ox + mech_request_data - self._pending_responses.append(pending_response) - return True - - def _build_request_data(self) -> WaitableConditionType: - """Get the request tx data encoded.""" - if self.params.use_mech_marketplace: - status = yield from self._mech_marketplace_contract_interact( - "get_request_data", - "data", - get_name(MechRequestBehaviour.request_data), - request_data=self._v1_hex_truncated, - priority_mech=self.mech_marketplace_config.priority_mech_address, - priority_mech_staking_instance=self.mech_marketplace_config.priority_mech_staking_instance_address, - priority_mech_service_id=self.mech_marketplace_config.priority_mech_service_id, - requester_staking_instance=self.mech_marketplace_config.requester_staking_instance_address, - requester_service_id=self.params.on_chain_service_id, - response_timeout=self.mech_marketplace_config.response_timeout, - chain_id=self.params.mech_chain_id, - ) - else: - status = yield from self._mech_contract_interact( - "get_request_data", - "data", - get_name(MechRequestBehaviour.request_data), - request_data=self._v1_hex_truncated, - chain_id=self.params.mech_chain_id, - ) - - if status: - to = ( - self.mech_marketplace_config.mech_marketplace_address - if self.params.use_mech_marketplace - else self.params.mech_contract_address - ) - batch = MultisendBatch( - to=to, - data=HexBytes(self.request_data), - value=self.price, - ) - self.multisend_batches.append(batch) - - return status - - def _get_price(self) -> WaitableConditionType: - """Get the price of the mech request.""" - # If the optional parameter 'mech_request_price' is set, then - # use that price (wei). Otherwise, determine the request price - # by calling the contract. - # This parameter is useful to set 'mech_request_price=0' when the - # agent is using a Nevermined subscription. - price = self.params.mech_request_price - - if price is not None: - self.price = price - return True - - result = yield from self._mech_contract_interact( - "get_price", - "price", - get_name(MechRequestBehaviour.price), - chain_id=self.params.mech_chain_id, - ) - return result - - def _prepare_safe_tx(self) -> Generator: - """Prepare a multisend safe tx for sending requests to a mech and return the hex for the tx settlement skill.""" - n_iters = min(self.params.multisend_batch_size, len(self._mech_requests)) - steps = (self._get_price,) - steps += (self._ensure_available_balance,) - steps += (self._send_metadata_to_ipfs, self._build_request_data) * n_iters - steps += (self._build_multisend_data, self._build_multisend_safe_tx_hash) - - for step in steps: - yield from self.wait_for_condition_with_sleep(step) - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - if not self._mech_requests: - payload = MechRequestPayload( - self.context.agent_address, - self.matching_round.auto_round_id(), - None, - None, - self.params.mech_chain_id, - None, - None, - ) - else: - self.context.logger.info( - f"Preparing mech requests: {self._mech_requests}" - ) - yield from self._prepare_safe_tx() - serialized_data = ( - json.dumps(data, cls=DataclassEncoder) - for data in (self._mech_requests, self._pending_responses) - ) - self.context.logger.info( - f"Preparing mech request:\ntx_hex: {self.tx_hex}\nprice: {self.price}\nserialized_data: {serialized_data}\n" - ) - payload = MechRequestPayload( - self.context.agent_address, - self.matching_round.auto_round_id(), - self.tx_hex, - self.price, - self.params.mech_chain_id, - *serialized_data, - ) - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/response.py b/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/response.py deleted file mode 100644 index 61a2ba60f..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/response.py +++ /dev/null @@ -1,270 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the response state of the mech interaction abci app.""" - -import json -from typing import Any, Callable, Dict, Generator, List, Optional - -from web3.constants import ADDRESS_ZERO - -from packages.valory.contracts.mech.contract import Mech -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.mech_interact_abci.behaviours.base import ( - DataclassEncoder, - MechInteractBaseBehaviour, - WaitableConditionType, -) -from packages.valory.skills.mech_interact_abci.behaviours.request import V1_HEX_PREFIX -from packages.valory.skills.mech_interact_abci.models import MechResponseSpecs -from packages.valory.skills.mech_interact_abci.payloads import MechResponsePayload -from packages.valory.skills.mech_interact_abci.states.base import ( - MechInteractionResponse, - MechRequest, -) -from packages.valory.skills.mech_interact_abci.states.response import MechResponseRound - - -IPFS_HASH_PREFIX = f"{V1_HEX_PREFIX}701220" - - -class MechResponseBehaviour(MechInteractBaseBehaviour): - """A behaviour in which the agents receive the Mech's responses.""" - - matching_round = MechResponseRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize Behaviour.""" - super().__init__(**kwargs) - self._from_block: int = 0 - self._requests: List[MechRequest] = [] - self._response_hex: str = "" - self._mech_responses: List[ - MechInteractionResponse - ] = self.synchronized_data.mech_responses - self._current_mech_response: MechInteractionResponse = MechInteractionResponse( - error="The mech's response has not been set!" - ) - - @property - def from_block(self) -> int: - """Get the block number in which the request to the mech was settled.""" - return self._from_block - - @from_block.setter - def from_block(self, from_block: int) -> None: - """Set the block number in which the request to the mech was settled.""" - self._from_block = from_block - - @property - def requests(self) -> List[MechRequest]: - """Get the requests.""" - return self._requests - - @requests.setter - def requests(self, requests: List[Dict[str, str]]) -> None: - """Set the requests.""" - self._requests = [MechRequest(**request) for request in requests] - - @property - def response_hex(self) -> str: - """Get the hash of the response data.""" - return self._response_hex - - @response_hex.setter - def response_hex(self, response_hash: bytes) -> None: - """Set the hash of the response data.""" - try: - self._response_hex = response_hash.hex() - except AttributeError: - msg = f"Response hash {response_hash!r} is not valid hex bytes!" - self.context.logger.error(msg) - - @property - def mech_response_api(self) -> MechResponseSpecs: - """Get the mech response api specs.""" - return self.context.mech_response - - @property - def serialized_responses(self) -> str: - """Get the Mech's responses serialized.""" - return json.dumps(self._mech_responses, cls=DataclassEncoder) - - def setup(self) -> None: - """Set up the `MechResponse` behaviour.""" - self._mech_responses = self.synchronized_data.mech_responses - - def set_mech_response_specs(self, request_id: int) -> None: - """Set the mech's response specs.""" - full_ipfs_hash = IPFS_HASH_PREFIX + self.response_hex - ipfs_link = self.params.ipfs_address + full_ipfs_hash + f"/{request_id}" - # The url must be dynamically generated as it depends on the ipfs hash - self.mech_response_api.__dict__["_frozen"] = False - self.mech_response_api.url = ipfs_link - self.mech_response_api.__dict__["_frozen"] = True - - def _get_block_number(self) -> WaitableConditionType: - """Get the block number in which the request to the mech was settled.""" - result = yield from self.contract_interact( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - # we do not need the address to get the block number, but the base method does - contract_address=ADDRESS_ZERO, - contract_public_id=Mech.contract_id, - contract_callable="get_block_number", - data_key="number", - placeholder=get_name(MechResponseBehaviour.from_block), - tx_hash=self.synchronized_data.final_tx_hash, - chain_id=self.params.mech_chain_id, - ) - - return result - - @property - def mech_contract_interact(self) -> Callable[..., WaitableConditionType]: - """Interact with the mech contract.""" - if self.params.use_mech_marketplace: - return self._mech_marketplace_contract_interact - - return self._mech_contract_interact - - def _process_request_event(self) -> WaitableConditionType: - """Process the request event.""" - result = yield from self.mech_contract_interact( - contract_callable="process_request_event", - data_key="results", - placeholder=get_name(MechResponseBehaviour.requests), - tx_hash=self.synchronized_data.final_tx_hash, - expected_logs=len(self._mech_responses), - chain_id=self.params.mech_chain_id, - ) - return result - - def _get_response_hash(self) -> WaitableConditionType: - """Get the hash of the response data.""" - request_id = self._current_mech_response.requestId - self.context.logger.info( - f"Filtering the mech's events from block {self.from_block} " - f"for a response to our request with id {request_id!r}." - ) - result = yield from self.mech_contract_interact( - contract_callable="get_response", - data_key="data", - placeholder=get_name(MechResponseBehaviour.response_hex), - request_id=request_id, - from_block=self.from_block, - chain_id=self.params.mech_chain_id, - ) - - if result: - self.set_mech_response_specs(request_id) - - return result - - def _handle_response( - self, - res: Optional[str], - ) -> Optional[Any]: - """Handle the response from the IPFS. - - :param res: the response to handle. - :return: the response's result, using the given keys. `None` if response is `None` (has failed). - """ - if res is None: - msg = f"Could not get the mech's response from {self.mech_response_api.api_id}" - self.context.logger.error(msg) - self.mech_response_api.increment_retries() - return None - - self.context.logger.info(f"Retrieved the mech's response: {res}.") - self.mech_response_api.reset_retries() - return res - - def _get_response(self) -> WaitableConditionType: - """Get the response data from IPFS.""" - specs = self.mech_response_api.get_spec() - res_raw = yield from self.get_http_response(**specs) - res = self.mech_response_api.process_response(res_raw) - res = self._handle_response(res) - - if self.mech_response_api.is_retries_exceeded(): - self._current_mech_response.retries_exceeded() - return True - - if res is None: - return False - - try: - self._current_mech_response.result = res - except (ValueError, TypeError): - self._current_mech_response.incorrect_format(res) - - return True - - def _set_current_response(self, request: MechRequest) -> None: - """Set the current Mech response.""" - for pending_response in self._mech_responses: - if ( - pending_response.data == request.data.hex() - ): # TODO: why is request.data bytes now? - pending_response.requestId = request.requestId - self._current_mech_response = pending_response - break - - def _process_responses( - self, - ) -> Generator: - """Get the response.""" - for step in ( - self._get_block_number, - self._process_request_event, - ): - yield from self.wait_for_condition_with_sleep(step) - - for request in self.requests: - self._set_current_response(request) - - for step in (self._get_response_hash, self._get_response): - yield from self.wait_for_condition_with_sleep(step) - - self.context.logger.info( - f"Response has been received:\n{self._current_mech_response}" - ) - if self._current_mech_response.result is None: - self.context.logger.error( - f"There was an error in the mech's response: {self._current_mech_response.error}" - ) - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - if self.synchronized_data.final_tx_hash: - yield from self._process_responses() - - self.context.logger.info( - f"Received mech responses: {self.serialized_responses}" - ) - - payload = MechResponsePayload( - self.context.agent_address, - self.serialized_responses, - ) - - yield from self.finish_behaviour(payload) diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/round_behaviour.py b/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/round_behaviour.py deleted file mode 100644 index c5c40d819..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/behaviours/round_behaviour.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- 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 package contains the round behaviour of MechInteractAbciApp.""" - -from typing import Set, Type - -from packages.valory.skills.abstract_round_abci.behaviour_utils import BaseBehaviour -from packages.valory.skills.abstract_round_abci.behaviours import AbstractRoundBehaviour -from packages.valory.skills.mech_interact_abci.behaviours.request import ( - MechRequestBehaviour, -) -from packages.valory.skills.mech_interact_abci.behaviours.response import ( - MechResponseBehaviour, -) -from packages.valory.skills.mech_interact_abci.rounds import MechInteractAbciApp - - -class MechInteractRoundBehaviour(AbstractRoundBehaviour): - """MechInteractRoundBehaviour""" - - initial_behaviour_cls = MechRequestBehaviour - abci_app_cls = MechInteractAbciApp # type: ignore - behaviours: Set[Type[BaseBehaviour]] = {MechRequestBehaviour, MechResponseBehaviour} diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/dialogues.py b/trader_old/vendor/valory/skills/mech_interact_abci/dialogues.py deleted file mode 100644 index a6963e0a5..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/dialogues.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- 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 the dialogues of the MechInteractAbciApp.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/fsm_specification.yaml b/trader_old/vendor/valory/skills/mech_interact_abci/fsm_specification.yaml deleted file mode 100644 index 60923b53e..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/fsm_specification.yaml +++ /dev/null @@ -1,30 +0,0 @@ -alphabet_in: -- DONE -- NO_MAJORITY -- ROUND_TIMEOUT -- SKIP_REQUEST -default_start_state: MechRequestRound -final_states: -- FinishedMechRequestRound -- FinishedMechRequestSkipRound -- FinishedMechResponseRound -- FinishedMechResponseTimeoutRound -label: MechInteractAbciApp -start_states: -- MechRequestRound -- MechResponseRound -states: -- FinishedMechRequestRound -- FinishedMechRequestSkipRound -- FinishedMechResponseRound -- FinishedMechResponseTimeoutRound -- MechRequestRound -- MechResponseRound -transition_func: - (MechRequestRound, DONE): FinishedMechRequestRound - (MechRequestRound, NO_MAJORITY): MechRequestRound - (MechRequestRound, ROUND_TIMEOUT): MechRequestRound - (MechRequestRound, SKIP_REQUEST): FinishedMechRequestSkipRound - (MechResponseRound, DONE): FinishedMechResponseRound - (MechResponseRound, NO_MAJORITY): MechResponseRound - (MechResponseRound, ROUND_TIMEOUT): FinishedMechResponseTimeoutRound diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/handlers.py b/trader_old/vendor/valory/skills/mech_interact_abci/handlers.py deleted file mode 100644 index e664d676d..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/handlers.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- 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 the handlers for the skill of MechInteractAbciApp.""" - -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIHandler = BaseABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/models.py b/trader_old/vendor/valory/skills/mech_interact_abci/models.py deleted file mode 100644 index 96fc52cce..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/models.py +++ /dev/null @@ -1,135 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the models for the abci skill of MechInteractAbciApp.""" - -from dataclasses import dataclass -from typing import Any, Dict, Optional - -from aea.exceptions import enforce -from hexbytes import HexBytes - -from packages.valory.contracts.multisend.contract import MultiSendOperation -from packages.valory.skills.abstract_round_abci.models import ApiSpecs, BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.mech_interact_abci.rounds import MechInteractAbciApp - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -class MechResponseSpecs(ApiSpecs): - """A model that wraps ApiSpecs for the Mech's response specifications.""" - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = MechInteractAbciApp - - -@dataclass(frozen=True) -class MechMarketplaceConfig: - """The configuration for the Mech marketplace.""" - - mech_marketplace_address: str - priority_mech_address: str - priority_mech_staking_instance_address: str - priority_mech_service_id: int - requester_staking_instance_address: str - response_timeout: int - - @classmethod - def from_dict(cls, data: Dict[str, Any]) -> "MechMarketplaceConfig": - """Create an instance from a dictionary.""" - return cls( - mech_marketplace_address=data["mech_marketplace_address"], - priority_mech_address=data["priority_mech_address"], - priority_mech_staking_instance_address=data[ - "priority_mech_staking_instance_address" - ], - priority_mech_service_id=data["priority_mech_service_id"], - requester_staking_instance_address=data[ - "requester_staking_instance_address" - ], - response_timeout=data["response_timeout"], - ) - - -class MechParams(BaseParams): - """The mech interact abci skill's parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Set up the mech-interaction parameters.""" - multisend_address = kwargs.get("multisend_address", None) - enforce(multisend_address is not None, "Multisend address not specified!") - self.multisend_address: str = multisend_address - self.multisend_batch_size: int = self._ensure( - "multisend_batch_size", kwargs, int - ) - self.mech_contract_address: str = self._ensure( - "mech_contract_address", kwargs, str - ) - self.mech_request_price: Optional[int] = kwargs.get("mech_request_price", None) - self._ipfs_address: str = self._ensure("ipfs_address", kwargs, str) - self.mech_chain_id: Optional[str] = kwargs.get("mech_chain_id", "gnosis") - self.mech_wrapped_native_token_address: Optional[str] = kwargs.get( - "mech_wrapped_native_token_address", None - ) - self.mech_interaction_sleep_time: int = self._ensure( - "mech_interaction_sleep_time", kwargs, int - ) - self.use_mech_marketplace = self._ensure("use_mech_marketplace", kwargs, bool) - self.mech_marketplace_config: MechMarketplaceConfig = ( - MechMarketplaceConfig.from_dict(kwargs["mech_marketplace_config"]) - ) - enforce( - not self.use_mech_marketplace - or self.mech_contract_address - == self.mech_marketplace_config.priority_mech_address, - "The mech contract address must be the same as the priority mech address when using the marketplace.", - ) - super().__init__(*args, **kwargs) - - @property - def ipfs_address(self) -> str: - """Get the IPFS address.""" - if self._ipfs_address.endswith("/"): - return self._ipfs_address - return f"{self._ipfs_address}/" - - -Params = MechParams - - -@dataclass -class MultisendBatch: - """A structure representing a single transaction of a multisend.""" - - to: str - data: HexBytes - value: int = 0 - operation: MultiSendOperation = MultiSendOperation.CALL diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/payloads.py b/trader_old/vendor/valory/skills/mech_interact_abci/payloads.py deleted file mode 100644 index 250843c28..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/payloads.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the transaction payloads of the MechInteractAbciApp.""" - -from dataclasses import dataclass -from typing import Optional - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class MechRequestPayload(BaseTxPayload): - """Represent a transaction payload for the MechRequestRound.""" - - tx_submitter: Optional[str] - tx_hash: Optional[str] - price: Optional[int] - chain_id: Optional[str] - mech_requests: Optional[str] - mech_responses: Optional[str] - - -@dataclass(frozen=True) -class MechResponsePayload(BaseTxPayload): - """Represent a transaction payload for the MechResponseRound.""" - - mech_responses: str diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/rounds.py b/trader_old/vendor/valory/skills/mech_interact_abci/rounds.py deleted file mode 100644 index 0195b03e6..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/rounds.py +++ /dev/null @@ -1,119 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the rounds of MechInteractAbciApp.""" - -from typing import Dict, Set - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AppState, - EventToTimeout, - get_name, -) -from packages.valory.skills.mech_interact_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.mech_interact_abci.states.final_states import ( - FinishedMechRequestRound, - FinishedMechRequestSkipRound, - FinishedMechResponseRound, - FinishedMechResponseTimeoutRound, -) -from packages.valory.skills.mech_interact_abci.states.request import MechRequestRound -from packages.valory.skills.mech_interact_abci.states.response import MechResponseRound - - -class MechInteractAbciApp(AbciApp[Event]): - """MechInteractAbciApp - - Initial round: MechRequestRound - - Initial states: {MechRequestRound, MechResponseRound} - - Transition states: - 0. MechRequestRound - - done: 2. - - skip request: 5. - - no majority: 0. - - round timeout: 0. - 1. MechResponseRound - - done: 3. - - no majority: 1. - - round timeout: 4. - 2. FinishedMechRequestRound - 3. FinishedMechResponseRound - 4. FinishedMechResponseTimeoutRound - 5. FinishedMechRequestSkipRound - - Final states: {FinishedMechRequestRound, FinishedMechRequestSkipRound, FinishedMechResponseRound, FinishedMechResponseTimeoutRound} - - Timeouts: - round timeout: 30.0 - """ - - initial_round_cls: AppState = MechRequestRound - initial_states: Set[AppState] = {MechRequestRound, MechResponseRound} - transition_function: AbciAppTransitionFunction = { - MechRequestRound: { - Event.DONE: FinishedMechRequestRound, - Event.SKIP_REQUEST: FinishedMechRequestSkipRound, - Event.NO_MAJORITY: MechRequestRound, - Event.ROUND_TIMEOUT: MechRequestRound, - }, - MechResponseRound: { - Event.DONE: FinishedMechResponseRound, - Event.NO_MAJORITY: MechResponseRound, - Event.ROUND_TIMEOUT: FinishedMechResponseTimeoutRound, - }, - FinishedMechRequestRound: {}, - FinishedMechResponseRound: {}, - FinishedMechResponseTimeoutRound: {}, - FinishedMechRequestSkipRound: {}, - } - final_states: Set[AppState] = { - FinishedMechRequestRound, - FinishedMechResponseRound, - FinishedMechResponseTimeoutRound, - FinishedMechRequestSkipRound, - } - event_to_timeout: EventToTimeout = { - Event.ROUND_TIMEOUT: 30.0, - } - cross_period_persisted_keys: Set[str] = {get_name(SynchronizedData.mech_responses)} - db_pre_conditions: Dict[AppState, Set[str]] = { - # using `set(get_name(SynchronizedData.mech_requests))` - # makes the checks complain that "db pre and post conditions intersect" - MechRequestRound: set(), - # we should be able to include `SynchronizedData.final_tx_hash` in the set below, - # however, we can't, because the checks incorrectly report that "db pre and post conditions intersect" - MechResponseRound: set(), - } - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedMechRequestRound: { - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.mech_price), - }, - FinishedMechRequestSkipRound: set(), - FinishedMechResponseRound: set(get_name(SynchronizedData.mech_responses)), - FinishedMechResponseTimeoutRound: set(), - } diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/skill.yaml b/trader_old/vendor/valory/skills/mech_interact_abci/skill.yaml deleted file mode 100644 index 0bd20797b..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/skill.yaml +++ /dev/null @@ -1,200 +0,0 @@ -name: mech_interact_abci -author: valory -version: 0.1.0 -type: skill -description: The mech interact skill can be used to send requests to a mech and receive - the responses. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeidf3nlv5fpvfy4libtscayhirdw64shgmhfmvjiftjmjkmhu7auxq - behaviours/__init__.py: bafybeie3zsi6p3yanz5mqwpkdrcgywaqvkit3hdintsb4awnvalgxpxa4i - behaviours/base.py: bafybeif4dvt4p5wfh6q3ybqwnzy62lbr3vqy322sr3wm6pkcrha2ggin6q - behaviours/request.py: bafybeihaevbnfn66atdutf7rt7v3lw3vbw3tr4bugfdssebtmydgnuvjyq - behaviours/response.py: bafybeibigqdtdxxzufx7cclzjrafszg2lb6y5ommp3jzbyoit735wtm7tq - behaviours/round_behaviour.py: bafybeib33inrpyzzlx7k7i3okkslsx4p46dgdaww2m5k7rno57o5nndage - dialogues.py: bafybeigjmyzd2bx6mgqiet2c223k6wkc5jk7kdkstbhpaxlqxatey26tlm - fsm_specification.yaml: bafybeiapzwz6zcneelc2b2wrcb7cae7x6vbthmf6a57cm4mv6hucp67lz4 - handlers.py: bafybeiduy2nwkqdynainuimkjulcv7u2qq6iglkuut3gfurkckydapitg4 - models.py: bafybeidfes4ovzsyntxvqtx55qi2tznmllhzznf5qmozi52zrukiyrtbni - payloads.py: bafybeihhnbwsnaqxcltqxp4camiw3tz7gcymrdvxhmqlk4nww24tujiy7q - rounds.py: bafybeif7taciv6pqupb7xuewurqssziplbjeobbv4d7ea3vbngz3kpjnee - states/__init__.py: bafybeie34wx5znr2hxwh3gs2fchmbeuzjcfnraymdvtzjaxaq5zsiw233q - states/base.py: bafybeidnyaofckmpq6dts5a7rkfbljmxkazjz4shsv5vyh3cbxamt2dmci - states/final_states.py: bafybeihjntrbc666blxj4viz74y4p2hfc5e4vijs3bqng2k4vqbwkud7sq - states/request.py: bafybeifdkqn4o2tx57yflnxfhy6eoy42z7bdpadcevre64aw7l2hh2kpjy - states/response.py: bafybeibaxnp2oxwjptoq7qzm6o7ww2qrdj2vnxzg2qt523vz2ftqzx5hyi - tests/__init__.py: bafybeifojfnffwlsv6aiku25nwyjwm7h4m45yci3fgmaawpeoyoogzonum - tests/test_behaviours.py: bafybeidj7git7zaego7k75eejtxlr3usj6wnnqisu7urqwvalpwh5w7nyq - tests/test_dialogues.py: bafybeig6uzk7fklieyxapemiobdvv5tyx7hgdkdpl4vnacohgw2ecphdpq - tests/test_handlers.py: bafybeidwrmekr5tydmehvkolyksw37sah5js7buy3ca5fxkpgkppmgb3wi - tests/test_models.py: bafybeid3cvcttdxlklwvr6tqmiurb2qywvmgr5bnsn62pb5gl5p552eagy - tests/test_payloads.py: bafybeiakqhgochfu4ra4hp65hi7jvxtjd7fdub5wqmhlccrc4va26hb7da - tests/test_rounds.py: bafybeiauu5adaoxu7yvtrfa6uwdw4sxr5gn2pj7qjh6vowd556iji6vtca -fingerprint_ignore_patterns: [] -connections: [] -contracts: -- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge -- valory/mech:0.1.0:bafybeiejfjfoxqggghcme43sx53q5gruefrws3k2jam2opkxl5uzffoarm -- valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y -- valory/erc20:0.1.0:bafybeid2p2jyvjjlcsqugnawksdzsca6ljghpqbp2kfi3cxuxoy2233dbi -- valory/mech_marketplace:0.1.0:bafybeiba7kh3wygwtpyf7oo3sili6givzo2gyadhbb66rvwsokswsywvuu -protocols: -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae -behaviours: - main: - args: {} - class_name: MechInteractRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - finalize_timeout: 60.0 - genesis_config: - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_duration: '172800000000000' - max_age_num_blocks: '100000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - genesis_time: '2022-05-20T16:00:21.735122717Z' - voting_power: '10' - history_check_timeout: 1205 - ipfs_domain_name: null - keeper_allowed_retries: 3 - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 30.0 - service_id: mech_interact - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - consensus_threshold: null - safe_contract_address: '0x0000000000000000000000000000000000000000' - share_tm_config_on_startup: false - sleep_time: 1 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - tx_timeout: 10.0 - validate_timeout: 1205 - multisend_batch_size: 50 - mech_contract_address: '0x77af31De935740567Cf4fF1986D04B2c964A786a' - mech_request_price: null - mech_chain_id: gnosis - mech_wrapped_native_token_address: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d' - ipfs_address: https://gateway.autonolas.tech/ipfs/ - use_termination: false - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - mech_interaction_sleep_time: 10 - use_mech_marketplace: false - mech_marketplace_config: - mech_marketplace_address: '0x0000000000000000000000000000000000000000' - priority_mech_address: '0x0000000000000000000000000000000000000000' - priority_mech_staking_instance_address: '0x0000000000000000000000000000000000000000' - priority_mech_service_id: 0 - requester_staking_instance_address: '0x0000000000000000000000000000000000000000' - response_timeout: 300 - class_name: Params - mech_response: - args: - api_id: mech_response - headers: - Content-Type: application/json - method: GET - parameters: {} - response_key: result - response_type: str - retries: 5 - url: '' - class_name: MechResponseSpecs - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: - web3: - version: <7,>=6.0.0 - hexbytes: {} - py-multicodec: {} - py-multibase: {} -is_abstract: true diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/states/__init__.py b/trader_old/vendor/valory/skills/mech_interact_abci/states/__init__.py deleted file mode 100644 index c126495fd..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/states/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 package contains the rounds for the mech interact abci skill.""" diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/states/base.py b/trader_old/vendor/valory/skills/mech_interact_abci/states/base.py deleted file mode 100644 index 4f4fb6c08..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/states/base.py +++ /dev/null @@ -1,148 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the base functionality for the rounds of the mech interact abci app.""" - -import json -from dataclasses import dataclass -from enum import Enum -from typing import Any, List, Mapping, Optional, cast - -from packages.valory.skills.abstract_round_abci.base import ( - BaseTxPayload, - CollectSameUntilThresholdRound, - CollectionRound, -) -from packages.valory.skills.mech_interact_abci.payloads import ( - MechRequestPayload, - MechResponsePayload, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TxSynchronizedData, -) - - -class Event(Enum): - """MechInteractAbciApp Events""" - - DONE = "done" - NO_MAJORITY = "no_majority" - ROUND_TIMEOUT = "round_timeout" - SKIP_REQUEST = "skip_request" - - -@dataclass -class MechMetadata: - """A Mech's metadata.""" - - prompt: str - tool: str - nonce: str - - -@dataclass -class MechRequest: - """A Mech's request.""" - - data: str = "" - requestId: int = 0 - - -@dataclass -class MechInteractionResponse(MechRequest): - """A structure for the response of a mech interaction task.""" - - nonce: str = "" - result: Optional[str] = None - error: str = "Unknown" - - def retries_exceeded(self) -> None: - """Set an incorrect format response.""" - self.error = "Retries were exceeded while trying to get the mech's response." - - def incorrect_format(self, res: Any) -> None: - """Set an incorrect format response.""" - self.error = f"The response's format was unexpected: {res}" - - -class SynchronizedData(TxSynchronizedData): - """ - Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - @property - def mech_price(self) -> int: - """Get the mech's request price.""" - return int(self.db.get_strict("mech_price")) - - @property - def mech_requests(self) -> List[MechMetadata]: - """Get the mech requests.""" - requests = self.db.get("mech_requests", "[]") - if isinstance(requests, str): - requests = json.loads(requests) - return [MechMetadata(**metadata_item) for metadata_item in requests] - - @property - def mech_responses(self) -> List[MechInteractionResponse]: - """Get the mech responses.""" - responses = self.db.get("mech_responses", "[]") - if isinstance(responses, str): - responses = json.loads(responses) - return [MechInteractionResponse(**response_item) for response_item in responses] - - @property - def participant_to_requests(self) -> Mapping[str, MechRequestPayload]: - """Get the `participant_to_requests`.""" - serialized = self.db.get_strict("participant_to_requests") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(Mapping[str, MechRequestPayload], deserialized) - - @property - def participant_to_responses(self) -> Mapping[str, MechResponsePayload]: - """Get the `participant_to_responses`.""" - serialized = self.db.get_strict("participant_to_responses") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(Mapping[str, MechResponsePayload], deserialized) - - @property - def final_tx_hash(self) -> Optional[str]: - """Get the verified tx hash.""" - return cast(str, self.db.get("final_tx_hash", None)) - - @property - def chain_id(self) -> Optional[str]: - """Get the chain name where to send the transactions.""" - return cast(str, self.db.get("chain_id", None)) - - @property - def tx_submitter(self) -> str: - """Get the round that submitted a tx to transaction_settlement_abci.""" - return str(self.db.get_strict("tx_submitter")) - - -class MechInteractionRound(CollectSameUntilThresholdRound): - """A base round for the mech interactions.""" - - payload_class = BaseTxPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - no_majority_event = Event.NO_MAJORITY diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/states/final_states.py b/trader_old/vendor/valory/skills/mech_interact_abci/states/final_states.py deleted file mode 100644 index c2ad59cbb..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/states/final_states.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the final states of the mech interact abci app.""" - -from packages.valory.skills.abstract_round_abci.base import DegenerateRound - - -class FinishedMechRequestRound(DegenerateRound): - """FinishedMechRequestRound""" - - -class FinishedMechRequestSkipRound(DegenerateRound): - """FinishedMechRequestSkipRound""" - - -class FinishedMechResponseRound(DegenerateRound): - """FinishedMechResponseRound""" - - -class FinishedMechResponseTimeoutRound(DegenerateRound): - """FinishedMechResponseTimeoutRound""" diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/states/request.py b/trader_old/vendor/valory/skills/mech_interact_abci/states/request.py deleted file mode 100644 index 2e0d7765e..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/states/request.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the request state of the mech interaction abci app.""" - -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.mech_interact_abci.payloads import MechRequestPayload -from packages.valory.skills.mech_interact_abci.states.base import ( - Event, - MechInteractionRound, - SynchronizedData, -) - - -class MechRequestRound(MechInteractionRound): - """A round for performing requests to a Mech.""" - - payload_class = MechRequestPayload - - selection_key = ( - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.mech_price), - get_name(SynchronizedData.chain_id), - get_name(SynchronizedData.mech_requests), - get_name(SynchronizedData.mech_responses), - ) - collection_key = get_name(SynchronizedData.participant_to_requests) - none_event = Event.SKIP_REQUEST diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/states/response.py b/trader_old/vendor/valory/skills/mech_interact_abci/states/response.py deleted file mode 100644 index 6b700f2fb..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/states/response.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- 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 the response state of the mech interaction abci app.""" - -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.mech_interact_abci.payloads import MechResponsePayload -from packages.valory.skills.mech_interact_abci.states.base import ( - MechInteractionRound, - SynchronizedData, -) - - -class MechResponseRound(MechInteractionRound): - """A round for collecting the responses from a Mech.""" - - payload_class = MechResponsePayload - selection_key = get_name(SynchronizedData.mech_responses) - collection_key = get_name(SynchronizedData.participant_to_responses) diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/tests/__init__.py b/trader_old/vendor/valory/skills/mech_interact_abci/tests/__init__.py deleted file mode 100644 index 6ea42d4cc..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for the mech interact abci skill.""" diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_behaviours.py b/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_behaviours.py deleted file mode 100644 index 2905d0b7b..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_behaviours.py +++ /dev/null @@ -1,132 +0,0 @@ -# -*- 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 package contains round behaviours of MechInteractAbciApp.""" - -from dataclasses import dataclass, field -from pathlib import Path -from typing import Any, Dict, Hashable, Optional, Type - -import pytest - -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.behaviours import BaseBehaviour -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.mech_interact_abci.behaviours.base import ( - MechInteractBaseBehaviour, -) -from packages.valory.skills.mech_interact_abci.behaviours.request import ( - MechRequestBehaviour, -) -from packages.valory.skills.mech_interact_abci.behaviours.response import ( - MechResponseBehaviour, -) -from packages.valory.skills.mech_interact_abci.behaviours.round_behaviour import ( - MechInteractRoundBehaviour, -) -from packages.valory.skills.mech_interact_abci.states.base import ( - Event, - SynchronizedData, -) - - -@dataclass -class BehaviourTestCase: - """BehaviourTestCase""" - - name: str - initial_data: Dict[str, Hashable] - event: Event - kwargs: Dict[str, Any] = field(default_factory=dict) - - -class BaseMechInteractTest(FSMBehaviourBaseCase): - """Base test case.""" - - path_to_skill = Path(__file__).parent.parent - - behaviour: MechInteractRoundBehaviour - behaviour_class: Type[MechInteractBaseBehaviour] - next_behaviour_class: Type[MechInteractBaseBehaviour] - synchronized_data: SynchronizedData - done_event = Event.DONE - - @property - def current_behaviour_id(self) -> str: - """Current RoundBehaviour's behaviour id""" - - return self.behaviour.current_behaviour.behaviour_id - - def fast_forward(self, data: Optional[Dict[str, Any]] = None) -> None: - """Fast-forward on initialization""" - - data = data if data is not None else {} - self.fast_forward_to_behaviour( - self.behaviour, - self.behaviour_class.behaviour_id, - SynchronizedData(AbciAppDB(setup_data=AbciAppDB.data_to_lists(data))), - ) - assert self.current_behaviour_id == self.behaviour_class.behaviour_id - - def complete(self, event: Event) -> None: - """Complete test""" - - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(done_event=event) - assert self.current_behaviour_id == self.next_behaviour_class.behaviour_id - - -class TestMechRequestBehaviour(BaseMechInteractTest): - """Tests MechRequestBehaviour""" - - # TODO: set next_behaviour_class - behaviour_class: Type[BaseBehaviour] = MechRequestBehaviour - next_behaviour_class: Type[BaseBehaviour] = ... - - # TODO: provide test cases - @pytest.mark.parametrize("test_case", []) - def test_run(self, test_case: BehaviourTestCase) -> None: - """Run tests.""" - - self.fast_forward(test_case.initial_data) - # TODO: mock the necessary calls - # self.mock_ ... - self.complete(test_case.event) - - -class TestMechResponseBehaviour(BaseMechInteractTest): - """Tests MechResponseBehaviour""" - - # TODO: set next_behaviour_class - behaviour_class: Type[BaseBehaviour] = MechResponseBehaviour - next_behaviour_class: Type[BaseBehaviour] = ... - - # TODO: provide test cases - @pytest.mark.parametrize("test_case", []) - def test_run(self, test_case: BehaviourTestCase) -> None: - """Run tests.""" - - self.fast_forward(test_case.initial_data) - # TODO: mock the necessary calls - # self.mock_ ... - self.complete(test_case.event) diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_dialogues.py b/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_dialogues.py deleted file mode 100644 index 7913ae0db..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_dialogues.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the MechInteract.""" - -import packages.valory.skills.mech_interact_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' of the MechInteract can be imported.""" diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_handlers.py b/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_handlers.py deleted file mode 100644 index 8a7c03aa0..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_handlers.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Test the handlers.py module of the MechInteract.""" - -import packages.valory.skills.mech_interact_abci.handlers # noqa - - -def test_import() -> None: - """Test that the 'handlers.py' of the MechInteract can be imported.""" diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_models.py b/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_models.py deleted file mode 100644 index 1b18facea..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_models.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - -"""Test the models.py module of the MechInteract.""" - -from packages.valory.skills.abstract_round_abci.test_tools.base import DummyContext -from packages.valory.skills.mech_interact_abci.models import SharedState - - -class TestSharedState: - """Test SharedState of MechInteract.""" - - def test_initialization(self) -> None: - """Test initialization.""" - SharedState(name="", skill_context=DummyContext()) diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_payloads.py b/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_payloads.py deleted file mode 100644 index 40c5d022a..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_payloads.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- 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 package contains payload tests for the MechInteractAbciApp.""" - -from dataclasses import dataclass -from typing import Hashable, Type - -import pytest - -from packages.valory.skills.mech_interact_abci.payloads import BaseTxPayload - - -@dataclass -class PayloadTestCase: - """PayloadTestCase""" - - name: str - payload_cls: Type[BaseTxPayload] - content: Hashable - - -# TODO: provide test cases -@pytest.mark.parametrize("test_case", []) -def test_payloads(test_case: PayloadTestCase) -> None: - """Tests for MechInteractAbciApp payloads""" - - payload = test_case.payload_cls(sender="sender", content=test_case.content) - assert payload.sender == "sender" - assert payload.from_json(payload.json) == payload diff --git a/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_rounds.py b/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_rounds.py deleted file mode 100644 index bd5914e95..000000000 --- a/trader_old/vendor/valory/skills/mech_interact_abci/tests/test_rounds.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- 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 package contains the tests for rounds of MechInteract.""" - -from dataclasses import dataclass, field -from typing import Any, Callable, Dict, Hashable, List, Mapping, Type - -import pytest - -from packages.valory.skills.abstract_round_abci.base import AbstractRound, BaseTxPayload -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseRoundTestClass, -) -from packages.valory.skills.mech_interact_abci.states.base import ( - Event, - SynchronizedData, -) -from packages.valory.skills.mech_interact_abci.states.request import MechRequestRound -from packages.valory.skills.mech_interact_abci.states.response import MechResponseRound - - -@dataclass -class RoundTestCase: - """RoundTestCase""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, BaseTxPayload] - final_data: Dict[str, Hashable] - event: Event - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - kwargs: Dict[str, Any] = field(default_factory=dict) - - -MAX_PARTICIPANTS: int = 4 - - -class BaseMechInteractRoundTest(BaseRoundTestClass): - """Base test class for MechInteract rounds.""" - - round_cls: Type[AbstractRound] - synchronized_data: SynchronizedData - _synchronized_data_class = SynchronizedData - _event_class = Event - - def run_test(self, test_case: RoundTestCase) -> None: - """Run the test""" - - self.synchronized_data.update(**test_case.initial_data) - - test_round = self.round_cls( - synchronized_data=self.synchronized_data, - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=test_case.payloads, - synchronized_data_update_fn=lambda sync_data, _: sync_data.update( - **test_case.final_data - ), - synchronized_data_attr_checks=test_case.synchronized_data_attr_checks, - exit_event=test_case.event, - **test_case.kwargs, # varies per BaseRoundTestClass child - ) - ) - - -class TestMechRequestRound(BaseMechInteractRoundTest): - """Tests for MechRequestRound.""" - - round_class = MechRequestRound - - # TODO: provide test cases - @pytest.mark.parametrize("test_case", []) - def test_run(self, test_case: RoundTestCase) -> None: - """Run tests.""" - - self.run_test(test_case) - - -class TestMechResponseRound(BaseMechInteractRoundTest): - """Tests for MechResponseRound.""" - - round_class = MechResponseRound - - # TODO: provide test cases - @pytest.mark.parametrize("test_case", []) - def test_run(self, test_case: RoundTestCase) -> None: - """Run tests.""" - - self.run_test(test_case) diff --git a/trader_old/vendor/valory/skills/registration_abci/README.md b/trader_old/vendor/valory/skills/registration_abci/README.md deleted file mode 100644 index a8eeb2265..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Registration abci - -## Description - -This module contains the ABCI registration skill for an AEA. - -## Behaviours - -* `RegistrationBaseBehaviour` - - Register to the next periods. - -* `RegistrationBehaviour` - - Register to the next periods. - -* `RegistrationStartupBehaviour` - - Register to the next periods. - - -## Handlers - -No Handlers (the skill is purely behavioural). - diff --git a/trader_old/vendor/valory/skills/registration_abci/__init__.py b/trader_old/vendor/valory/skills/registration_abci/__init__.py deleted file mode 100644 index e69b708ed..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the ABCI registration skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/registration_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/registration_abci/behaviours.py b/trader_old/vendor/valory/skills/registration_abci/behaviours.py deleted file mode 100644 index 4a617b4d1..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/behaviours.py +++ /dev/null @@ -1,492 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the behaviours for the 'registration_abci' skill.""" - -import datetime -import json -from abc import ABC -from enum import Enum -from typing import Any, Dict, Generator, Optional, Set, Type, cast - -from aea.mail.base import EnvelopeContext - -from packages.valory.connections.p2p_libp2p_client.connection import ( - PUBLIC_ID as P2P_LIBP2P_CLIENT_PUBLIC_ID, -) -from packages.valory.contracts.service_registry.contract import ServiceRegistryContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.http import HttpMessage -from packages.valory.protocols.tendermint import TendermintMessage -from packages.valory.skills.abstract_round_abci.base import ABCIAppInternalError -from packages.valory.skills.abstract_round_abci.behaviour_utils import TimeoutException -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.abstract_round_abci.utils import parse_tendermint_p2p_url -from packages.valory.skills.registration_abci.dialogues import TendermintDialogues -from packages.valory.skills.registration_abci.models import SharedState -from packages.valory.skills.registration_abci.payloads import RegistrationPayload -from packages.valory.skills.registration_abci.rounds import ( - AgentRegistrationAbciApp, - RegistrationRound, - RegistrationStartupRound, -) - - -NODE = "node_{address}" -WAIT_FOR_BLOCK_TIMEOUT = 60.0 # 1 minute - - -class RegistrationBaseBehaviour(BaseBehaviour, ABC): - """Agent registration to the FSM App.""" - - def async_act(self) -> Generator: - """ - Do the action. - - Steps: - - Build a registration transaction. - - Send the transaction and wait for it to be mined. - - Wait until ABCI application transitions to the next round. - - Go to the next behaviour (set done event). - """ - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - serialized_db = self.synchronized_data.db.serialize() - payload = RegistrationPayload( - self.context.agent_address, initialisation=serialized_db - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class RegistrationStartupBehaviour(RegistrationBaseBehaviour): - """Agent registration to the FSM App.""" - - ENCODING: str = "utf-8" - matching_round = RegistrationStartupRound - local_tendermint_params: Dict[str, Any] = {} - updated_genesis_data: Dict[str, Any] = {} - collection_complete: bool = False - - @property - def initial_tm_configs(self) -> Dict[str, Dict[str, Any]]: - """A mapping of the other agents' addresses to their initial Tendermint configuration.""" - return self.context.state.initial_tm_configs - - @initial_tm_configs.setter - def initial_tm_configs(self, configs: Dict[str, Dict[str, Any]]) -> None: - """A mapping of the other agents' addresses to their initial Tendermint configuration.""" - self.context.state.initial_tm_configs = configs - - class LogMessages(Enum): - """Log messages used in RegistrationStartupBehaviour""" - - config_sharing = "Sharing Tendermint config on start-up?" - # request personal tendermint configuration - request_personal = "Request validator config from personal Tendermint node" - response_personal = "Response validator config from personal Tendermint node" - failed_personal = "Failed validator config from personal Tendermint node" - # verify deployment on-chain contract - request_verification = "Request service registry contract verification" - response_verification = "Response service registry contract verification" - failed_verification = "Failed service registry contract verification" - # request service info from on-chain contract - request_service_info = "Request on-chain service info" - response_service_info = "Response on-chain service info" - failed_service_info = "Failed on-chain service info" - # request tendermint configuration other agents - request_others = "Request Tendermint config info from other agents" - collection_complete = "Completed collecting Tendermint configuration responses" - # update personal tendermint node config - request_update = "Request update Tendermint node configuration" - response_update = "Response update Tendermint node configuration" - failed_update = "Failed update Tendermint node configuration" - # exceptions - no_contract_address = "Service registry contract address not provided" - no_on_chain_service_id = "On-chain service id not provided" - contract_incorrect = "Service registry contract not correctly deployed" - no_agents_registered = "No agents registered on-chain" - self_not_registered = "This agent is not registered on-chain" - - def __str__(self) -> str: - """For ease of use in formatted string literals""" - return self.value - - @property - def tendermint_parameter_url(self) -> str: - """Tendermint URL for obtaining and updating parameters""" - return f"{self.params.tendermint_com_url}/params" - - def _decode_result( - self, message: HttpMessage, error_log: LogMessages - ) -> Optional[Dict[str, Any]]: - """Decode a http message's body. - - :param message: the http message. - :param error_log: a log to prefix potential errors with. - :return: the message's body, as a dictionary - """ - try: - response = json.loads(message.body.decode()) - except json.JSONDecodeError as error: - self.context.logger.error(f"{error_log}: {error}") - return None - - if not response["status"]: # pragma: no cover - self.context.logger.error(f"{error_log}: {response['error']}") - return None - - return response - - def is_correct_contract( - self, service_registry_address: str - ) -> Generator[None, None, bool]: - """Contract deployment verification.""" - - self.context.logger.info(self.LogMessages.request_verification) - - performative = ContractApiMessage.Performative.GET_STATE - kwargs = dict( - performative=performative, - contract_address=service_registry_address, - contract_id=str(ServiceRegistryContract.contract_id), - contract_callable="verify_contract", - chain_id=self.params.default_chain_id, - ) - contract_api_response = yield from self.get_contract_api_response(**kwargs) # type: ignore - if ( - contract_api_response.performative - is not ContractApiMessage.Performative.STATE - ): - verified = False - log_method = self.context.logger.error - log_message = f"{self.LogMessages.failed_verification} ({kwargs}): {contract_api_response}" - else: - verified = cast(bool, contract_api_response.state.body["verified"]) - log_method = self.context.logger.info - log_message = f"{self.LogMessages.response_verification}: {verified}" - - log_method(log_message) - return verified - - def get_agent_instances( - self, service_registry_address: str, on_chain_service_id: int - ) -> Generator[None, None, Dict[str, Any]]: - """Get service info available on-chain""" - - log_message = self.LogMessages.request_service_info - self.context.logger.info(f"{log_message}") - - performative = ContractApiMessage.Performative.GET_STATE - kwargs = dict( - performative=performative, - contract_address=service_registry_address, - contract_id=str(ServiceRegistryContract.contract_id), - contract_callable="get_agent_instances", - service_id=on_chain_service_id, - chain_id=self.params.default_chain_id, - ) - contract_api_response = yield from self.get_contract_api_response(**kwargs) # type: ignore - if contract_api_response.performative != ContractApiMessage.Performative.STATE: - log_message = self.LogMessages.failed_service_info - self.context.logger.error( - f"{log_message} ({kwargs}): {contract_api_response}" - ) - return {} - - log_message = self.LogMessages.response_service_info - self.context.logger.info(f"{log_message}: {contract_api_response}") - return cast(dict, contract_api_response.state.body) - - def get_addresses(self) -> Generator: # pylint: disable=too-many-return-statements - """Get addresses of agents registered for the service""" - - service_registry_address = self.params.service_registry_address - if service_registry_address is None: - log_message = self.LogMessages.no_contract_address.value - self.context.logger.error(log_message) - return False - - correctly_deployed = yield from self.is_correct_contract( - service_registry_address - ) - if not correctly_deployed: - return False - - on_chain_service_id = self.params.on_chain_service_id - if on_chain_service_id is None: - log_message = self.LogMessages.no_on_chain_service_id.value - self.context.logger.error(log_message) - return False - - service_info = yield from self.get_agent_instances( - service_registry_address, on_chain_service_id - ) - if not service_info: - return False - - registered_addresses = set(service_info["agentInstances"]) - if not registered_addresses: - log_message = self.LogMessages.no_agents_registered.value - self.context.logger.error(f"{log_message}: {service_info}") - return False - - my_address = self.context.agent_address - if my_address not in registered_addresses: - log_message = f"{self.LogMessages.self_not_registered} ({my_address})" - self.context.logger.error(f"{log_message}: {registered_addresses}") - return False - - # put service info in the shared state for p2p message handler - info: Dict[str, Dict[str, str]] = {i: {} for i in registered_addresses} - tm_host, tm_port = parse_tendermint_p2p_url(url=self.params.tendermint_p2p_url) - validator_config = dict( - hostname=tm_host, - p2p_port=tm_port, - address=self.local_tendermint_params["address"], - pub_key=self.local_tendermint_params["pub_key"], - peer_id=self.local_tendermint_params["peer_id"], - ) - info[self.context.agent_address] = validator_config - self.initial_tm_configs = info - log_message = self.LogMessages.response_service_info.value - self.context.logger.info(f"{log_message}: {info}") - return True - - def get_tendermint_configuration(self) -> Generator[None, None, bool]: - """Make HTTP GET request to obtain agent's local Tendermint node parameters""" - - url = self.tendermint_parameter_url - log_message = self.LogMessages.request_personal - self.context.logger.info(f"{log_message}: {url}") - - result = yield from self.get_http_response(method="GET", url=url) - response = self._decode_result(result, self.LogMessages.failed_personal) - if response is None: - return False - - self.local_tendermint_params = response["params"] - log_message = self.LogMessages.response_personal - self.context.logger.info(f"{log_message}: {response}") - return True - - def request_tendermint_info(self) -> Generator[None, None, bool]: - """Request Tendermint info from other agents""" - - still_missing = {k for k, v in self.initial_tm_configs.items() if not v} - { - self.context.agent_address - } - log_message = self.LogMessages.request_others - self.context.logger.info(f"{log_message}: {still_missing}") - - for address in still_missing: - dialogues = cast(TendermintDialogues, self.context.tendermint_dialogues) - performative = TendermintMessage.Performative.GET_GENESIS_INFO - message, _ = dialogues.create( - counterparty=address, performative=performative - ) - message = cast(TendermintMessage, message) - context = EnvelopeContext(connection_id=P2P_LIBP2P_CLIENT_PUBLIC_ID) - self.context.outbox.put_message(message=message, context=context) - # we wait for the messages that were put in the outbox. - yield from self.sleep(self.params.sleep_time) - - if all(self.initial_tm_configs.values()): - log_message = self.LogMessages.collection_complete - self.context.logger.info(f"{log_message}: {self.initial_tm_configs}") - validator_to_agent = { - config["address"]: agent - for agent, config in self.initial_tm_configs.items() - } - self.context.state.setup_slashing(validator_to_agent) - self.collection_complete = True - return self.collection_complete - - def format_genesis_data( - self, - collected_agent_info: Dict[str, Any], - ) -> Dict[str, Any]: - """Format collected agent info for genesis update""" - - validators = [] - for address, validator_config in collected_agent_info.items(): - validator = dict( - hostname=validator_config["hostname"], - p2p_port=validator_config["p2p_port"], - address=validator_config["address"], - pub_key=validator_config["pub_key"], - peer_id=validator_config["peer_id"], - power=self.params.genesis_config.voting_power, - name=NODE.format(address=address[2:]), # skip 0x part - ) - validators.append(validator) - - genesis_data = dict( - validators=validators, - genesis_config=self.params.genesis_config.to_json(), - external_address=self.params.tendermint_p2p_url, - ) - return genesis_data - - def request_update(self) -> Generator[None, None, bool]: - """Make HTTP POST request to update agent's local Tendermint node""" - - url = self.tendermint_parameter_url - genesis_data = self.format_genesis_data(self.initial_tm_configs) - log_message = self.LogMessages.request_update - self.context.logger.info(f"{log_message}: {genesis_data}") - - content = json.dumps(genesis_data).encode(self.ENCODING) - result = yield from self.get_http_response( - method="POST", url=url, content=content - ) - response = self._decode_result(result, self.LogMessages.failed_update) - if response is None: - return False - - log_message = self.LogMessages.response_update - self.context.logger.info(f"{log_message}: {response}") - self.updated_genesis_data.update(genesis_data) - return True - - def wait_for_block(self, timeout: float) -> Generator[None, None, bool]: - """Wait for a block to be received in the specified timeout.""" - # every agent will finish with the reset at a different time - # hence the following will be different for all agents - start_time = datetime.datetime.now() - - def received_block() -> bool: - """Check whether we have received a block after "start_time".""" - try: - shared_state = cast(SharedState, self.context.state) - last_timestamp = shared_state.round_sequence.last_timestamp - if last_timestamp > start_time: - return True - return False - except ABCIAppInternalError: - # this can happen if we haven't received a block yet - return False - - try: - yield from self.wait_for_condition( - condition=received_block, timeout=timeout - ) - # if the `wait_for_condition` finish without an exception, - # it means that the condition has been satisfied on time - return True - except TimeoutException: - # the agent wasn't able to receive blocks in the given amount of time (timeout) - return False - - def async_act(self) -> Generator: # pylint: disable=too-many-return-statements - """ - Do the action. - - Steps: - 1. Collect personal Tendermint configuration - 2. Make Service Registry contract call to retrieve addresses - of the other agents registered on-chain for the service. - 3. Request Tendermint configuration from registered agents. - This is done over the Agent Communication Network using - the p2p_libp2p_client connection. - 4. Update Tendermint configuration via genesis.json with the - information of the other validators (agents). - 5. Restart Tendermint to establish the validator network. - """ - - exchange_config = self.params.share_tm_config_on_startup - log_message = self.LogMessages.config_sharing.value - self.context.logger.info(f"{log_message}: {exchange_config}") - - if not exchange_config: - yield from super().async_act() - return - - self.context.logger.info(f"My address: {self.context.agent_address}") - - # collect personal Tendermint configuration - if not self.local_tendermint_params: - successful = yield from self.get_tendermint_configuration() - if not successful: - yield from self.sleep(self.params.sleep_time) - return - - # if the agent doesn't have it's tm config info set, then make service registry contract call - # to get the rest of the agents, so we can get their tm config info later - info = self.initial_tm_configs.get(self.context.agent_address, None) - if info is None: - successful = yield from self.get_addresses() - if not successful: - yield from self.sleep(self.params.sleep_time) - return - - # collect Tendermint config information from other agents - if not self.collection_complete: - successful = yield from self.request_tendermint_info() - if not successful: - yield from self.sleep(self.params.sleep_time) - return - - # update Tendermint configuration - if not self.updated_genesis_data: - successful = yield from self.request_update() - if not successful: - yield from self.sleep(self.params.sleep_time) - return - - # restart Tendermint with updated configuration - successful = yield from self.reset_tendermint_with_wait(on_startup=True) - if not successful: - yield from self.sleep(self.params.sleep_time) - return - - # the reset has gone through, and at this point tendermint should start - # sending blocks to the agent. However, that might take a while, since - # we rely on 2/3 of the voting power to be active in order for block production - # to begin. In other words, we wait for >=2/3 of the agents to become active. - successful = yield from self.wait_for_block(timeout=WAIT_FOR_BLOCK_TIMEOUT) - if not successful: - yield from self.sleep(self.params.sleep_time) - return - - yield from super().async_act() - - -class RegistrationBehaviour(RegistrationBaseBehaviour): - """Agent registration to the FSM App.""" - - matching_round = RegistrationRound - - -class AgentRegistrationRoundBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the registration.""" - - initial_behaviour_cls = RegistrationStartupBehaviour - abci_app_cls = AgentRegistrationAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - RegistrationBehaviour, # type: ignore - RegistrationStartupBehaviour, # type: ignore - } diff --git a/trader_old/vendor/valory/skills/registration_abci/dialogues.py b/trader_old/vendor/valory/skills/registration_abci/dialogues.py deleted file mode 100644 index fcc14acb6..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/dialogues.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the classes required for dialogue management.""" -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_old/vendor/valory/skills/registration_abci/fsm_specification.yaml b/trader_old/vendor/valory/skills/registration_abci/fsm_specification.yaml deleted file mode 100644 index 478f352c3..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/fsm_specification.yaml +++ /dev/null @@ -1,18 +0,0 @@ -alphabet_in: -- DONE -- NO_MAJORITY -default_start_state: RegistrationStartupRound -final_states: -- FinishedRegistrationRound -label: AgentRegistrationAbciApp -start_states: -- RegistrationRound -- RegistrationStartupRound -states: -- FinishedRegistrationRound -- RegistrationRound -- RegistrationStartupRound -transition_func: - (RegistrationRound, DONE): FinishedRegistrationRound - (RegistrationRound, NO_MAJORITY): RegistrationRound - (RegistrationStartupRound, DONE): FinishedRegistrationRound diff --git a/trader_old/vendor/valory/skills/registration_abci/handlers.py b/trader_old/vendor/valory/skills/registration_abci/handlers.py deleted file mode 100644 index 36053488f..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/handlers.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the handler for the 'registration_abci' skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIHandler = BaseABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_old/vendor/valory/skills/registration_abci/models.py b/trader_old/vendor/valory/skills/registration_abci/models.py deleted file mode 100644 index 98c7e53e1..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/models.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the shared state for the registration abci skill.""" - -from packages.valory.skills.abstract_round_abci.models import BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.registration_abci.rounds import AgentRegistrationAbciApp - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = AgentRegistrationAbciApp - - -Params = BaseParams -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool diff --git a/trader_old/vendor/valory/skills/registration_abci/payloads.py b/trader_old/vendor/valory/skills/registration_abci/payloads.py deleted file mode 100644 index bea2fc50a..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/payloads.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the transaction payloads for common apps.""" - -from dataclasses import dataclass - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class RegistrationPayload(BaseTxPayload): - """Represent a transaction payload of type 'registration'.""" - - initialisation: str diff --git a/trader_old/vendor/valory/skills/registration_abci/rounds.py b/trader_old/vendor/valory/skills/registration_abci/rounds.py deleted file mode 100644 index a191ddd02..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/rounds.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the data classes for common apps ABCI application.""" - -from enum import Enum -from typing import Dict, Optional, Set, Tuple - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AppState, - BaseSynchronizedData, - CollectSameUntilAllRound, - CollectSameUntilThresholdRound, - DegenerateRound, - SlashingNotConfiguredError, - get_name, -) -from packages.valory.skills.abstract_round_abci.models import BaseParams -from packages.valory.skills.registration_abci.payloads import RegistrationPayload - - -class Event(Enum): - """Event enumeration for the price estimation demo.""" - - DONE = "done" - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - - -class FinishedRegistrationRound(DegenerateRound): - """A round representing that agent registration has finished""" - - -class RegistrationStartupRound(CollectSameUntilAllRound): - """ - A round in which the agents get registered. - - This round waits until all agents have registered. - """ - - payload_class = RegistrationPayload - synchronized_data_class = BaseSynchronizedData - - @property - def params(self) -> BaseParams: - """Return the params.""" - return self.context.params - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - if not self.collection_threshold_reached: - return None - - try: - _ = self.context.state.round_sequence.offence_status - # only use slashing if it is configured and the `use_slashing` is set to True - if self.params.use_slashing: - self.context.state.round_sequence.enable_slashing() - except SlashingNotConfiguredError: - self.context.logger.warning("Slashing has not been enabled!") - - self.context.state.round_sequence.sync_db_and_slashing(self.common_payload) - - synchronized_data = self.synchronized_data.update( - participants=tuple(sorted(self.collection)), - synchronized_data_class=self.synchronized_data_class, - ) - - return synchronized_data, Event.DONE - - -class RegistrationRound(CollectSameUntilThresholdRound): - """ - A round in which the agents get registered. - - This rounds waits until the threshold of agents has been reached - and then a further x block confirmations. - """ - - payload_class = RegistrationPayload - required_block_confirmations = 10 - done_event = Event.DONE - synchronized_data_class = BaseSynchronizedData - - # this allows rejoining agents to send payloads - _allow_rejoin_payloads = True - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - if self.threshold_reached: - self.block_confirmations += 1 - if ( - self.threshold_reached - and self.block_confirmations - > self.required_block_confirmations # we also wait here as it gives more (available) agents time to join - ): - self.synchronized_data.db.sync(self.most_voted_payload) - synchronized_data = self.synchronized_data.update( - participants=tuple(sorted(self.collection)), - synchronized_data_class=self.synchronized_data_class, - ) - return synchronized_data, Event.DONE - if ( - not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ) - and self.block_confirmations > self.required_block_confirmations - ): - return self.synchronized_data, Event.NO_MAJORITY - return None - - -class AgentRegistrationAbciApp(AbciApp[Event]): - """AgentRegistrationAbciApp - - Initial round: RegistrationStartupRound - - Initial states: {RegistrationRound, RegistrationStartupRound} - - Transition states: - 0. RegistrationStartupRound - - done: 2. - 1. RegistrationRound - - done: 2. - - no majority: 1. - 2. FinishedRegistrationRound - - Final states: {FinishedRegistrationRound} - - Timeouts: - round timeout: 30.0 - """ - - initial_round_cls: AppState = RegistrationStartupRound - initial_states: Set[AppState] = {RegistrationStartupRound, RegistrationRound} - transition_function: AbciAppTransitionFunction = { - RegistrationStartupRound: { - Event.DONE: FinishedRegistrationRound, - }, - RegistrationRound: { - Event.DONE: FinishedRegistrationRound, - Event.NO_MAJORITY: RegistrationRound, - }, - FinishedRegistrationRound: {}, - } - final_states: Set[AppState] = { - FinishedRegistrationRound, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = { - RegistrationStartupRound: set(), - RegistrationRound: set(), - } - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedRegistrationRound: { - get_name(BaseSynchronizedData.participants), - }, - } diff --git a/trader_old/vendor/valory/skills/registration_abci/skill.yaml b/trader_old/vendor/valory/skills/registration_abci/skill.yaml deleted file mode 100644 index 9a6fe5674..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/skill.yaml +++ /dev/null @@ -1,151 +0,0 @@ -name: registration_abci -author: valory -version: 0.1.0 -type: skill -description: ABCI application for common apps. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeieztbubb6yn5umyt5ulknvb2xxppz5ecxaosxqsaejnrcrrwfu2ji - __init__.py: bafybeigqj2uodavhrygpqn6iah3ljp53z54c5fxyh5ykgkxuhh5lof6pda - behaviours.py: bafybeihal7ku3mvwfbcdm3twzuktnet2io3inshsrpnoee5d5o6mbavg5q - dialogues.py: bafybeicm4bqedlyytfo4icqqbyolo36j2hk7pqh32d3zc5yqg75bt4demm - fsm_specification.yaml: bafybeicx5eutgr4lin7mhwr73xhanuzwdmps7pfoy5f2k7gfxmuec4qbyu - handlers.py: bafybeifby6yecei2d7jvxbqrc3tpyemb7xdb4ood2kny5dqja26qnxrf24 - models.py: bafybeifkfjsfkjy2x32cbuoewxujfgpcl3wk3fji6kq27ofr2zcfe7l5oe - payloads.py: bafybeiacrixfazch2a5ydj7jfk2pnvlxwkygqlwzkfmdeldrj4fqgwyyzm - rounds.py: bafybeifch5qouoop77ef6ghsdflzuy7bcgn4upxjuusxalqzbk53vrxj4q - tests/__init__.py: bafybeiab2s4vkmbz5bc4wggcclapdbp65bosv4en5zaazk5dwmldojpqja - tests/test_behaviours.py: bafybeicwlo3y44sf7gzkyzfuzhwqkax4hln3oforbcvy4uitlgleft3cge - tests/test_dialogues.py: bafybeibeqnpzuzgcfb6yz76htslwsbbpenihswbp7j3qdyq42yswjq25l4 - tests/test_handlers.py: bafybeifpnwaktxckbvclklo6flkm5zqs7apmb33ffs4jrmunoykjbl5lni - tests/test_models.py: bafybeiewxl7nio5av2aukql2u7hlhodzdvjjneleba32abr42xeirrycb4 - tests/test_payloads.py: bafybeifik6ek75ughyd4y6t2lchlmjadkzbrz4hsb332k6ul4pwhlo2oga - tests/test_rounds.py: bafybeidk4d3w5csj6ka7mcq3ikjmv2yccbpwxhp27ujvd7huag3zl5vu2m -fingerprint_ignore_patterns: [] -connections: -- valory/p2p_libp2p_client:0.1.0:bafybeid3xg5k2ol5adflqloy75ibgljmol6xsvzvezebsg7oudxeeolz7e -contracts: -- valory/service_registry:0.1.0:bafybeiaop64kwdoetxtedoehabmsalojmms7ihuoqcdwxtwb2hk5i6bzye -protocols: -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/http:1.0.0:bafybeifugzl63kfdmwrxwphrnrhj7bn6iruxieme3a4ntzejf6kmtuwmae -- valory/tendermint:0.1.0:bafybeig4mi3vmlv5zpbjbfuzcgida6j5f2nhrpedxicmrrfjweqc5r7cra -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -behaviours: - main: - args: {} - class_name: AgentRegistrationRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - light_slash_unit_amount: 5000000000000000 - max_attempts: 10 - max_healthcheck: 120 - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 30.0 - serious_slash_unit_amount: 8000000000000000 - service_id: registration - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - sleep_time: 1 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - tx_timeout: 10.0 - use_slashing: false - use_termination: false - class_name: Params - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: {} -is_abstract: true -customs: [] diff --git a/trader_old/vendor/valory/skills/registration_abci/tests/__init__.py b/trader_old/vendor/valory/skills/registration_abci/tests/__init__.py deleted file mode 100644 index e4fb2e5eb..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/registration_abci skill.""" diff --git a/trader_old/vendor/valory/skills/registration_abci/tests/test_behaviours.py b/trader_old/vendor/valory/skills/registration_abci/tests/test_behaviours.py deleted file mode 100644 index 1c19c139e..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/tests/test_behaviours.py +++ /dev/null @@ -1,644 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/registration_abci skill's behaviours.""" - -# pylint: skip-file - -import collections -import datetime -import json -import logging -import time -from contextlib import ExitStack, contextmanager -from copy import deepcopy -from pathlib import Path -from typing import Any, Callable, Dict, Generator, Iterable, List, Optional, cast -from unittest import mock -from unittest.mock import MagicMock -from urllib.parse import urlparse - -import pytest -from _pytest.logging import LogCaptureFixture - -from packages.valory.contracts.service_registry.contract import ServiceRegistryContract -from packages.valory.protocols.contract_api.message import ContractApiMessage -from packages.valory.protocols.tendermint.message import TendermintMessage -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - BaseBehaviour, - TimeoutException, - make_degenerate_behaviour, -) -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.registration_abci import PUBLIC_ID -from packages.valory.skills.registration_abci.behaviours import ( - RegistrationBaseBehaviour, - RegistrationBehaviour, - RegistrationStartupBehaviour, -) -from packages.valory.skills.registration_abci.models import SharedState -from packages.valory.skills.registration_abci.rounds import ( - BaseSynchronizedData as RegistrationSynchronizedData, -) -from packages.valory.skills.registration_abci.rounds import ( - Event, - FinishedRegistrationRound, -) - - -PACKAGE_DIR = Path(__file__).parent.parent - - -SERVICE_REGISTRY_ADDRESS = "0xa51c1fc2f0d1a1b8494ed1fe312d7c3a78ed91c0" -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" -CONTRACT_ID = str(ServiceRegistryContract.contract_id) -ON_CHAIN_SERVICE_ID = 42 -DUMMY_ADDRESS = "localhost" -DUMMY_VALIDATOR_CONFIG = { - "hostname": DUMMY_ADDRESS, - "address": "address", - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "7y7ycBMMABj5Onf74ITYtUS3uZ6SsCQKZML87mIX", - }, - "peer_id": "peer_id", - "p2p_port": 80, -} - - -def test_skill_public_id() -> None: - """Test skill module public ID""" - - assert PUBLIC_ID.name == Path(__file__).parents[1].name - assert PUBLIC_ID.author == Path(__file__).parents[3].name - - -def consume(iterator: Iterable) -> None: - """Consume the iterator""" - collections.deque(iterator, maxlen=0) - - -@contextmanager -def as_context(*contexts: Any) -> Generator[None, None, None]: - """Set contexts""" - with ExitStack() as stack: - consume(map(stack.enter_context, contexts)) - yield - - -class RegistrationAbciBaseCase(FSMBehaviourBaseCase): - """Base case for testing RegistrationAbci FSMBehaviour.""" - - path_to_skill = PACKAGE_DIR - - -class BaseRegistrationTestBehaviour(RegistrationAbciBaseCase): - """Base test case to test RegistrationBehaviour.""" - - behaviour_class = RegistrationBaseBehaviour - next_behaviour_class = BaseBehaviour - - @pytest.mark.parametrize( - "setup_data, expected_initialisation", - ( - ({}, '{"db_data": {"0": {}}, "slashing_config": ""}'), - ({"test": []}, '{"db_data": {"0": {}}, "slashing_config": ""}'), - ( - {"test": [], "valid": [1, 2]}, - '{"db_data": {"0": {"valid": [1, 2]}}, "slashing_config": ""}', - ), - ), - ) - def test_registration( - self, setup_data: Dict, expected_initialisation: Optional[str] - ) -> None: - """Test registration.""" - self.fast_forward_to_behaviour( - self.behaviour, - self.behaviour_class.auto_behaviour_id(), - RegistrationSynchronizedData(AbciAppDB(setup_data=setup_data)), - ) - assert isinstance(self.behaviour.current_behaviour, BaseBehaviour) - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - with mock.patch.object( - self.behaviour.current_behaviour, - "send_a2a_transaction", - side_effect=self.behaviour.current_behaviour.send_a2a_transaction, - ): - self.behaviour.act_wrapper() - assert isinstance( - self.behaviour.current_behaviour.send_a2a_transaction, MagicMock - ) - assert ( - self.behaviour.current_behaviour.send_a2a_transaction.call_args[0][ - 0 - ].initialisation - == expected_initialisation - ) - self.mock_a2a_transaction() - - self._test_done_flag_set() - self.end_round(Event.DONE) - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.next_behaviour_class.auto_behaviour_id() - ) - - -class TestRegistrationStartupBehaviour(RegistrationAbciBaseCase): - """Test case to test RegistrationStartupBehaviour.""" - - behaviour_class = RegistrationStartupBehaviour - next_behaviour_class = make_degenerate_behaviour(FinishedRegistrationRound) - - other_agents: List[str] = ["0xAlice", "0xBob", "0xCharlie"] - _time_in_future = datetime.datetime.now() + datetime.timedelta(hours=10) - _time_in_past = datetime.datetime.now() - datetime.timedelta(hours=10) - - def setup(self, **kwargs: Any) -> None: - """Setup""" - super().setup(**kwargs) - self.state.params.__dict__["sleep_time"] = 0.01 - self.state.params.__dict__["share_tm_config_on_startup"] = True - - def teardown(self, **kwargs: Any) -> None: - """Teardown.""" - super().teardown(**kwargs) - self.state.initial_tm_configs = {} - - @property - def agent_instances(self) -> List[str]: - """Agent instance addresses""" - return [*self.other_agents, self.state.context.agent_address] - - @property - def state(self) -> RegistrationStartupBehaviour: - """Current behavioural state""" - return cast(RegistrationStartupBehaviour, self.behaviour.current_behaviour) - - @property - def logger(self) -> str: - """Logger""" - return "aea.test_agent_name.packages.valory.skills.registration_abci" - - # mock patches - @property - def mocked_service_registry_address(self) -> mock._patch_dict: - """Mocked service registry address""" - return mock.patch.dict( - self.state.params.__dict__, - {"service_registry_address": SERVICE_REGISTRY_ADDRESS}, - ) - - @property - def mocked_on_chain_service_id(self) -> mock._patch_dict: - """Mocked on chain service id""" - return mock.patch.dict( - self.state.params.__dict__, {"on_chain_service_id": ON_CHAIN_SERVICE_ID} - ) - - def mocked_wait_for_condition(self, should_timeout: bool) -> mock._patch: - """Mock BaseBehaviour.wait_for_condition""" - - def dummy_wait_for_condition( - condition: Callable[[], bool], timeout: Optional[float] = None - ) -> Generator[None, None, None]: - """A mock implementation of BaseBehaviour.wait_for_condition""" - # call the condition - condition() - if should_timeout: - # raise in case required - raise TimeoutException() - return - yield - - return mock.patch.object( - self.behaviour.current_behaviour, - "wait_for_condition", - side_effect=dummy_wait_for_condition, - ) - - @property - def mocked_yield_from_sleep(self) -> mock._patch: - """Mock yield from sleep""" - return mock.patch.object(self.behaviour.current_behaviour, "sleep") - - # mock contract calls - def mock_is_correct_contract(self, error_response: bool = False) -> None: - """Mock service registry contract call to for contract verification""" - request_kwargs = dict(performative=ContractApiMessage.Performative.GET_STATE) - state = ContractApiMessage.State(ledger_id="ethereum", body={"verified": True}) - performative = ContractApiMessage.Performative.STATE - if error_response: - performative = ContractApiMessage.Performative.ERROR - response_kwargs = dict( - performative=performative, - callable="verify_contract", - state=state, - ) - self.mock_contract_api_request( - contract_id=CONTRACT_ID, - request_kwargs=request_kwargs, - response_kwargs=response_kwargs, - ) - - def mock_get_agent_instances( - self, *agent_instances: str, error_response: bool = False - ) -> None: - """Mock get agent instances""" - request_kwargs = dict(performative=ContractApiMessage.Performative.GET_STATE) - performative = ContractApiMessage.Performative.STATE - if error_response: - performative = ContractApiMessage.Performative.ERROR - body = {"agentInstances": list(agent_instances)} - state = ContractApiMessage.State(ledger_id="ethereum", body=body) - response_kwargs = dict( - performative=performative, - callable="get_agent_instances", - state=state, - ) - self.mock_contract_api_request( - contract_id=CONTRACT_ID, - request_kwargs=request_kwargs, - response_kwargs=response_kwargs, - ) - - # mock Tendermint config request - def mock_tendermint_request( - self, request_kwargs: Dict, response_kwargs: Dict - ) -> None: - """Mock Tendermint request.""" - - actual_tendermint_message = self.get_message_from_outbox() - assert actual_tendermint_message is not None, "No message in outbox." - has_attributes, error_str = self.message_has_attributes( - actual_message=actual_tendermint_message, - message_type=TendermintMessage, - performative=TendermintMessage.Performative.GET_GENESIS_INFO, - sender=self.state.context.agent_address, - to=actual_tendermint_message.to, - **request_kwargs, - ) - assert has_attributes, error_str - incoming_message = self.build_incoming_message( - message_type=TendermintMessage, - dialogue_reference=( - actual_tendermint_message.dialogue_reference[0], - "stub", - ), - performative=TendermintMessage.Performative.GENESIS_INFO, - target=actual_tendermint_message.message_id, - message_id=-1, - to=self.state.context.agent_address, - sender=actual_tendermint_message.to, - **response_kwargs, - ) - self.tendermint_handler.handle(cast(TendermintMessage, incoming_message)) - - def mock_get_tendermint_info(self, *addresses: str) -> None: - """Mock get Tendermint info""" - for i in addresses: - request_kwargs: Dict = dict() - config = deepcopy(DUMMY_VALIDATOR_CONFIG) - config["address"] = str(config["address"]) + i - info = json.dumps(config) - response_kwargs = dict(info=info) - self.mock_tendermint_request(request_kwargs, response_kwargs) - # give room to the behaviour to finish sleeping - # using the same sleep time here and in the behaviour - # can lead to problems when the sleep here is finished - # before the one in the behaviour - time.sleep(self.state.params.sleep_time * 2) - self.behaviour.act_wrapper() - - # mock HTTP requests - def mock_get_local_tendermint_params(self, valid_response: bool = True) -> None: - """Mock Tendermint get local params""" - url = self.state.tendermint_parameter_url - request_kwargs = dict(method="GET", url=url) - body = b"" - if valid_response: - params = dict(params=DUMMY_VALIDATOR_CONFIG, status=True, error=None) - body = json.dumps(params).encode(self.state.ENCODING) - response_kwargs = dict(status_code=200, body=body) - self.mock_http_request(request_kwargs, response_kwargs) - - def mock_tendermint_update(self, valid_response: bool = True) -> None: - """Mock Tendermint update""" - - validator_configs = self.state.format_genesis_data( - self.state.initial_tm_configs - ) - body = json.dumps(validator_configs).encode(self.state.ENCODING) - url = self.state.tendermint_parameter_url - request_kwargs = dict(method="POST", url=url, body=body) - body = ( - json.dumps({"status": True, "error": None}).encode(self.state.ENCODING) - if valid_response - else b"" - ) - response_kwargs = dict(status_code=200, body=body) - self.mock_http_request(request_kwargs, response_kwargs) - - def set_last_timestamp(self, last_timestamp: Optional[datetime.datetime]) -> None: - """Set last timestamp""" - if last_timestamp is not None: - state = cast(SharedState, self._skill.skill_context.state) - state.round_sequence.blockchain._blocks.append( - MagicMock(timestamp=last_timestamp) - ) - - @staticmethod - def dummy_reset_tendermint_with_wait_wrapper( - valid_response: bool, - ) -> Callable[[], Generator[None, None, Optional[bool]]]: - """Wrapper for a Dummy `reset_tendermint_with_wait` method.""" - - def dummy_reset_tendermint_with_wait( - **_: bool, - ) -> Generator[None, None, Optional[bool]]: - """Dummy `reset_tendermint_with_wait` method.""" - yield - return valid_response - - return dummy_reset_tendermint_with_wait - - # tests - def test_init(self) -> None: - """Empty init""" - assert self.state.initial_tm_configs == {} - assert self.state.local_tendermint_params == {} - assert self.state.updated_genesis_data == {} - - def test_no_contract_address(self, caplog: LogCaptureFixture) -> None: - """Test service registry contract address not provided""" - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_yield_from_sleep, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - log_message = self.state.LogMessages.no_contract_address - assert log_message.value in caplog.text - - @pytest.mark.parametrize("valid_response", [True, False]) - def test_request_personal( - self, valid_response: bool, caplog: LogCaptureFixture - ) -> None: - """Test get tendermint configuration""" - - failed_message = self.state.LogMessages.failed_personal - response_message = self.state.LogMessages.response_personal - log_message = [failed_message, response_message][valid_response] - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_yield_from_sleep, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params(valid_response=valid_response) - assert log_message.value in caplog.text - - def test_failed_verification(self, caplog: LogCaptureFixture) -> None: - """Test service registry contract not correctly deployed""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract(error_response=True) - log_message = self.state.LogMessages.failed_verification - assert log_message.value in caplog.text - - def test_on_chain_service_id_not_set(self, caplog: LogCaptureFixture) -> None: - """Test `get_addresses` when `on_chain_service_id` is `None`.""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - log_message = self.state.LogMessages.no_on_chain_service_id - assert log_message.value in caplog.text - - def test_failed_service_info(self, caplog: LogCaptureFixture) -> None: - """Test get service info failure""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances(error_response=True) - log_message = self.state.LogMessages.failed_service_info - assert log_message.value in caplog.text - - def test_no_agents_registered(self, caplog: LogCaptureFixture) -> None: - """Test no agent instances registered""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances() - log_message = self.state.LogMessages.no_agents_registered - assert log_message.value in caplog.text - - def test_self_not_registered(self, caplog: LogCaptureFixture) -> None: - """Test node operator agent not registered""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances(*self.other_agents) - log_message = self.state.LogMessages.self_not_registered - assert log_message.value in caplog.text - - def test_response_service_info(self, caplog: LogCaptureFixture) -> None: - """Test registered addresses retrieved""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances(*self.agent_instances) - - assert set(self.state.initial_tm_configs) == set(self.agent_instances) - my_info = self.state.initial_tm_configs[self.state.context.agent_address] - assert ( - my_info["hostname"] - == urlparse(self.state.context.params.tendermint_url).hostname - ) - assert not any(map(self.state.initial_tm_configs.get, self.other_agents)) - log_message = self.state.LogMessages.response_service_info - assert log_message.value in caplog.text - - def test_collection_complete(self, caplog: LogCaptureFixture) -> None: - """Test registered addresses retrieved""" - - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - mock.patch.object( - self._skill.skill_context.state, - "acn_container", - side_effect=lambda: self.agent_instances, - ), - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances(*self.agent_instances) - self.mock_get_tendermint_info(*self.other_agents) - - initial_tm_configs = self.state.initial_tm_configs - validator_to_agent = ( - self.state.context.state.round_sequence.validator_to_agent - ) - - assert all(map(initial_tm_configs.get, self.other_agents)) - assert tuple(validator_to_agent.keys()) == tuple( - config["address"] for config in initial_tm_configs.values() - ) - assert tuple(validator_to_agent.values()) == tuple( - initial_tm_configs.keys() - ) - log_message = self.state.LogMessages.collection_complete - assert log_message.value in caplog.text - - @pytest.mark.parametrize("valid_response", [True, False]) - @mock.patch.object(BaseBehaviour, "reset_tendermint_with_wait") - def test_request_update( - self, _: mock.Mock, valid_response: bool, caplog: LogCaptureFixture - ) -> None: - """Test Tendermint config update""" - - self.state.updated_genesis_data = {} - failed_message = self.state.LogMessages.failed_update - response_message = self.state.LogMessages.response_update - log_message = [failed_message, response_message][valid_response] - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - self.mocked_yield_from_sleep, - mock.patch.object( - self._skill.skill_context.state, - "acn_container", - side_effect=lambda: self.agent_instances, - ), - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances(*self.agent_instances) - self.mock_get_tendermint_info(*self.other_agents) - self.mock_tendermint_update(valid_response) - assert log_message.value in caplog.text - - @pytest.mark.parametrize( - "valid_response, last_timestamp, timeout", - [ - (True, _time_in_past, False), - (False, _time_in_past, False), - (True, _time_in_future, False), - (False, _time_in_future, False), - (True, None, False), - (False, None, False), - (True, None, True), - (False, None, True), - ], - ) - def test_request_restart( - self, - valid_response: bool, - last_timestamp: Optional[datetime.datetime], - timeout: bool, - caplog: LogCaptureFixture, - ) -> None: - """Test Tendermint start""" - self.state.updated_genesis_data = {} - self.set_last_timestamp(last_timestamp) - with as_context( - caplog.at_level(logging.INFO, logger=self.logger), - self.mocked_service_registry_address, - self.mocked_on_chain_service_id, - self.mocked_wait_for_condition(timeout), - self.mocked_yield_from_sleep, - mock.patch.object( - self.behaviour.current_behaviour, - "reset_tendermint_with_wait", - side_effect=self.dummy_reset_tendermint_with_wait_wrapper( - valid_response - ), - ), - mock.patch.object( - self._skill.skill_context.state, - "acn_container", - side_effect=lambda: self.agent_instances, - ), - ): - self.behaviour.act_wrapper() - self.mock_get_local_tendermint_params() - self.mock_is_correct_contract() - self.mock_get_agent_instances(*self.agent_instances) - self.mock_get_tendermint_info(*self.other_agents) - self.mock_tendermint_update() - self.behaviour.act_wrapper() - - -class TestRegistrationStartupBehaviourNoConfigShare(BaseRegistrationTestBehaviour): - """Test case to test RegistrationBehaviour.""" - - behaviour_class = RegistrationStartupBehaviour - next_behaviour_class = make_degenerate_behaviour(FinishedRegistrationRound) - - -class TestRegistrationBehaviour(BaseRegistrationTestBehaviour): - """Test case to test RegistrationBehaviour.""" - - behaviour_class = RegistrationBehaviour - next_behaviour_class = make_degenerate_behaviour(FinishedRegistrationRound) diff --git a/trader_old/vendor/valory/skills/registration_abci/tests/test_dialogues.py b/trader_old/vendor/valory/skills/registration_abci/tests/test_dialogues.py deleted file mode 100644 index 55d61a50b..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.registration_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_old/vendor/valory/skills/registration_abci/tests/test_handlers.py b/trader_old/vendor/valory/skills/registration_abci/tests/test_handlers.py deleted file mode 100644 index aae35f091..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/tests/test_handlers.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.registration_abci.handlers # noqa - - -def test_import() -> None: - """Test that the 'handlers.py' Python module can be imported.""" diff --git a/trader_old/vendor/valory/skills/registration_abci/tests/test_models.py b/trader_old/vendor/valory/skills/registration_abci/tests/test_models.py deleted file mode 100644 index eb6d4d72f..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/tests/test_models.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the models.py module of the skill.""" - -# pylint: skip-file - -from packages.valory.skills.abstract_round_abci.test_tools.base import DummyContext -from packages.valory.skills.registration_abci.models import SharedState - - -class TestSharedState: - """Test SharedState(Model) class.""" - - def test_initialization( - self, - ) -> None: - """Test initialization.""" - SharedState(name="", skill_context=DummyContext()) diff --git a/trader_old/vendor/valory/skills/registration_abci/tests/test_payloads.py b/trader_old/vendor/valory/skills/registration_abci/tests/test_payloads.py deleted file mode 100644 index b9b0a4093..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/tests/test_payloads.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the payloads.py module of the skill.""" - -# pylint: skip-file - -import pytest - -from packages.valory.skills.abstract_round_abci.base import Transaction -from packages.valory.skills.registration_abci.payloads import RegistrationPayload - - -def test_registration_abci_payload() -> None: - """Test `RegistrationPayload`.""" - - payload = RegistrationPayload(sender="sender", initialisation="dummy") - - assert payload.initialisation == "dummy" - assert payload.data == {"initialisation": "dummy"} - assert RegistrationPayload.from_json(payload.json) == payload - - -def test_registration_abci_payload_raises() -> None: - """Test `RegistrationPayload`.""" - payload = RegistrationPayload(sender="sender", initialisation="0" * 10**7) - signature = "signature" - tx = Transaction(payload, signature) - with pytest.raises(ValueError, match="Transaction must be smaller"): - tx.encode() diff --git a/trader_old/vendor/valory/skills/registration_abci/tests/test_rounds.py b/trader_old/vendor/valory/skills/registration_abci/tests/test_rounds.py deleted file mode 100644 index d4428005a..000000000 --- a/trader_old/vendor/valory/skills/registration_abci/tests/test_rounds.py +++ /dev/null @@ -1,371 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the rounds.py module of the skill.""" - -import json -from typing import Any, Dict, Optional, cast -from unittest import mock -from unittest.mock import MagicMock, PropertyMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData as SynchronizedData, -) -from packages.valory.skills.abstract_round_abci.base import ( - CollectSameUntilAllRound, - SlashingNotConfiguredError, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilAllRoundTest, - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.registration_abci.payloads import RegistrationPayload -from packages.valory.skills.registration_abci.rounds import Event as RegistrationEvent -from packages.valory.skills.registration_abci.rounds import ( - RegistrationRound, - RegistrationStartupRound, -) - - -# pylint: skip-file - - -class TestRegistrationStartupRound(BaseCollectSameUntilAllRoundTest): - """Test RegistrationStartupRound.""" - - _synchronized_data_class = SynchronizedData - _event_class = RegistrationEvent - - @pytest.mark.parametrize("slashing_config", ("", json.dumps({"valid": "config"}))) - def test_run_default( - self, - slashing_config: str, - ) -> None: - """Run test.""" - - self.synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - safe_contract_address="stub_safe_contract_address", - oracle_contract_address="stub_oracle_contract_address", - ), - ) - - test_round = RegistrationStartupRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self.synchronized_data.slashing_config = slashing_config - - if not slashing_config: - seq = test_round.context.state.round_sequence - type(seq).offence_status = PropertyMock( - side_effect=SlashingNotConfiguredError - ) - - most_voted_payload = self.synchronized_data.db.serialize() - round_payloads = { - participant: RegistrationPayload( - sender=participant, - initialisation=most_voted_payload, - ) - for participant in self.participants - } - - self._run_with_round( - test_round, - round_payloads, - most_voted_payload, - RegistrationEvent.DONE, - ) - - assert all( - ( - self.synchronized_data.all_participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.safe_contract_address - == "stub_safe_contract_address", - self.synchronized_data.db.get("oracle_contract_address") - == "stub_oracle_contract_address", - ) - ) - - test_round.context.state.round_sequence.sync_db_and_slashing.assert_called_once_with( - most_voted_payload - ) - - if slashing_config: - test_round.context.state.round_sequence.enable_slashing.assert_called_once() - else: - test_round.context.state.round_sequence.enable_slashing.assert_not_called() - - def test_run_default_not_finished( - self, - ) -> None: - """Run test.""" - - self.synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - safe_contract_address="stub_safe_contract_address", - oracle_contract_address="stub_oracle_contract_address", - ), - ) - test_round = RegistrationStartupRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - with mock.patch.object( - CollectSameUntilAllRound, - "collection_threshold_reached", - new_callable=mock.PropertyMock, - ) as threshold_mock: - threshold_mock.return_value = False - self._run_with_round( - test_round, - finished=False, - most_voted_payload="none", - ) - - assert all( - ( - self.synchronized_data.all_participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.safe_contract_address - == "stub_safe_contract_address", - self.synchronized_data.db.get("oracle_contract_address") - == "stub_oracle_contract_address", - ) - ) - - def _run_with_round( - self, - test_round: RegistrationStartupRound, - round_payloads: Optional[Dict[str, RegistrationPayload]] = None, - most_voted_payload: Optional[Any] = None, - expected_event: Optional[RegistrationEvent] = None, - finished: bool = True, - ) -> None: - """Run with given round.""" - - round_payloads = round_payloads or { - p: RegistrationPayload(sender=p, initialisation="none") - for p in self.participants - } - - test_runner = self._test_round( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=( - lambda *x: SynchronizedData( - AbciAppDB( - setup_data=dict(participants=[tuple(self.participants)]), - ) - ) - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.participants - ], - most_voted_payload=most_voted_payload, - exit_event=expected_event, - finished=finished, - ) - - next(test_runner) - next(test_runner) - next(test_runner) - if finished: - next(test_runner) - - -class TestRegistrationRound(BaseCollectSameUntilThresholdRoundTest): - """Test RegistrationRound.""" - - _synchronized_data_class = SynchronizedData - _event_class = RegistrationEvent - - def test_run_default( - self, - ) -> None: - """Run test.""" - self.synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - safe_contract_address="stub_safe_contract_address", - oracle_contract_address="stub_oracle_contract_address", - ), - ) - test_round = RegistrationRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - payload_data = self.synchronized_data.db.serialize() - - round_payloads = { - participant: RegistrationPayload( - sender=participant, - initialisation=payload_data, - ) - for participant in self.participants - } - - self._run_with_round( - test_round=test_round, - expected_event=RegistrationEvent.DONE, - confirmations=11, - most_voted_payload=payload_data, - round_payloads=round_payloads, - ) - - assert all( - ( - self.synchronized_data.all_participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.safe_contract_address - == "stub_safe_contract_address", - self.synchronized_data.db.get("oracle_contract_address") - == "stub_oracle_contract_address", - ) - ) - - def test_run_default_not_finished( - self, - ) -> None: - """Run test.""" - self.synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - safe_contract_address="stub_safe_contract_address", - oracle_contract_address="stub_oracle_contract_address", - ), - ) - test_round = RegistrationRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - self._run_with_round( - test_round, - confirmations=None, - ) - - assert all( - ( - self.synchronized_data.all_participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.safe_contract_address - == "stub_safe_contract_address", - self.synchronized_data.db.get("oracle_contract_address") - == "stub_oracle_contract_address", - ) - ) - - def _run_with_round( - self, - test_round: RegistrationRound, - round_payloads: Optional[Dict[str, RegistrationPayload]] = None, - most_voted_payload: Optional[Any] = None, - expected_event: Optional[RegistrationEvent] = None, - confirmations: Optional[int] = None, - finished: bool = True, - ) -> None: - """Run with given round.""" - - round_payloads = round_payloads or { - p: RegistrationPayload(sender=p, initialisation="none") - for p in self.participants - } - - test_runner = self._test_round( - test_round=test_round, - round_payloads=round_payloads, - synchronized_data_update_fn=( - lambda *x: SynchronizedData( - AbciAppDB( - setup_data=dict(participants=[tuple(self.participants)]), - ) - ) - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.participants - ], - most_voted_payload=most_voted_payload, - exit_event=expected_event, - ) - - next(test_runner) - if confirmations is None: - assert ( - test_round.block_confirmations - <= test_round.required_block_confirmations - ) - - else: - test_round.block_confirmations = confirmations - test_round = next(test_runner) - prior_confirmations = test_round.block_confirmations - next(test_runner) - assert test_round.block_confirmations == prior_confirmations + 1 - if finished: - next(test_runner) - - def test_no_majority(self) -> None: - """Test the NO_MAJORITY event.""" - self.synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - safe_contract_address="stub_safe_contract_address", - oracle_contract_address="stub_oracle_contract_address", - ), - ) - - test_round = RegistrationRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - with mock.patch.object(test_round, "is_majority_possible", return_value=False): - with mock.patch.object(test_round, "block_confirmations", 11): - self._test_no_majority_event(test_round) - - assert all( - ( - self.synchronized_data.all_participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.participants - == frozenset({"agent_2", "agent_0", "agent_1", "agent_3"}), - self.synchronized_data.safe_contract_address - == "stub_safe_contract_address", - self.synchronized_data.db.get("oracle_contract_address") - == "stub_oracle_contract_address", - ) - ) diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/README.md b/trader_old/vendor/valory/skills/reset_pause_abci/README.md deleted file mode 100644 index 99ca7988c..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Reset and pause abci - -## Description - -This module contains the ABCI reset and pause skill for an AEA. It implements an ABCI -application. - -## Behaviours - -* `ResetAndPauseBehaviour` - - Reset state. - -* `ResetPauseABCIConsensusBehaviour` - - This behaviour manages the consensus stages for the reset and pause abci app. - -## Handlers - -* `ResetPauseABCIHandler` -* `HttpHandler` -* `SigningHandler` - diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/__init__.py b/trader_old/vendor/valory/skills/reset_pause_abci/__init__.py deleted file mode 100644 index 850ef3947..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the Reset & Pause skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/reset_pause_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/behaviours.py b/trader_old/vendor/valory/skills/reset_pause_abci/behaviours.py deleted file mode 100644 index 9ee30a1e9..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/behaviours.py +++ /dev/null @@ -1,99 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the behaviours for the 'reset_pause_abci' skill.""" - -from abc import ABC -from typing import Generator, Set, Type, cast - -from packages.valory.skills.abstract_round_abci.base import BaseSynchronizedData -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.reset_pause_abci.models import Params, SharedState -from packages.valory.skills.reset_pause_abci.payloads import ResetPausePayload -from packages.valory.skills.reset_pause_abci.rounds import ( - ResetAndPauseRound, - ResetPauseAbciApp, -) - - -class ResetAndPauseBaseBehaviour(BaseBehaviour, ABC): - """Reset behaviour.""" - - @property - def synchronized_data(self) -> BaseSynchronizedData: - """Return the synchronized data.""" - return cast( - BaseSynchronizedData, - cast(SharedState, self.context.state).synchronized_data, - ) - - @property - def params(self) -> Params: - """Return the params.""" - return cast(Params, self.context.params) - - -class ResetAndPauseBehaviour(ResetAndPauseBaseBehaviour): - """Reset and pause behaviour.""" - - matching_round = ResetAndPauseRound - - def async_act(self) -> Generator: - """ - Do the action. - - Steps: - - Trivially log the behaviour. - - Sleep for configured interval. - - Build a registration transaction. - - Send the transaction and wait for it to be mined. - - Wait until ABCI application transitions to the next round. - - Go to the next behaviour (set done event). - """ - # + 1 because `period_count` starts from 0 - n_periods_done = self.synchronized_data.period_count + 1 - reset_tm_nodes = n_periods_done % self.params.reset_tendermint_after == 0 - if reset_tm_nodes: - tendermint_reset = yield from self.reset_tendermint_with_wait() - if not tendermint_reset: - return - else: - yield from self.wait_from_last_timestamp(self.params.reset_pause_duration) - self.context.logger.info("Period end.") - self.context.benchmark_tool.save(self.synchronized_data.period_count) - - payload = ResetPausePayload( - self.context.agent_address, self.synchronized_data.period_count - ) - yield from self.send_a2a_transaction(payload, reset_tm_nodes) - yield from self.wait_until_round_end() - self.set_done() - - -class ResetPauseABCIConsensusBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the reset_pause_abci app.""" - - initial_behaviour_cls = ResetAndPauseBehaviour - abci_app_cls = ResetPauseAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - ResetAndPauseBehaviour, # type: ignore - } diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/dialogues.py b/trader_old/vendor/valory/skills/reset_pause_abci/dialogues.py deleted file mode 100644 index e244bde0b..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/dialogues.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/fsm_specification.yaml b/trader_old/vendor/valory/skills/reset_pause_abci/fsm_specification.yaml deleted file mode 100644 index b4882ef0a..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/fsm_specification.yaml +++ /dev/null @@ -1,19 +0,0 @@ -alphabet_in: -- DONE -- NO_MAJORITY -- RESET_AND_PAUSE_TIMEOUT -default_start_state: ResetAndPauseRound -final_states: -- FinishedResetAndPauseErrorRound -- FinishedResetAndPauseRound -label: ResetPauseAbciApp -start_states: -- ResetAndPauseRound -states: -- FinishedResetAndPauseErrorRound -- FinishedResetAndPauseRound -- ResetAndPauseRound -transition_func: - (ResetAndPauseRound, DONE): FinishedResetAndPauseRound - (ResetAndPauseRound, NO_MAJORITY): FinishedResetAndPauseErrorRound - (ResetAndPauseRound, RESET_AND_PAUSE_TIMEOUT): FinishedResetAndPauseErrorRound diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/handlers.py b/trader_old/vendor/valory/skills/reset_pause_abci/handlers.py deleted file mode 100644 index d6c6335de..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/handlers.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the handler for the 'reset_pause_abci' skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIHandler = BaseABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/models.py b/trader_old/vendor/valory/skills/reset_pause_abci/models.py deleted file mode 100644 index 89d44fc9a..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/models.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the shared state for the 'reset_pause_abci' application.""" - -from packages.valory.skills.abstract_round_abci.models import BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.reset_pause_abci.rounds import Event, ResetPauseAbciApp - - -MARGIN = 5 - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = ResetPauseAbciApp - - def setup(self) -> None: - """Set up.""" - super().setup() - ResetPauseAbciApp.event_to_timeout[ - Event.ROUND_TIMEOUT - ] = self.context.params.round_timeout_seconds - ResetPauseAbciApp.event_to_timeout[Event.RESET_AND_PAUSE_TIMEOUT] = ( - self.context.params.reset_pause_duration + MARGIN - ) - - -Params = BaseParams diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/payloads.py b/trader_old/vendor/valory/skills/reset_pause_abci/payloads.py deleted file mode 100644 index d5c005863..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/payloads.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the transaction payloads for the reset_pause_abci app.""" - -from dataclasses import dataclass - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class ResetPausePayload(BaseTxPayload): - """Represent a transaction payload of type 'reset'.""" - - period_count: int diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/rounds.py b/trader_old/vendor/valory/skills/reset_pause_abci/rounds.py deleted file mode 100644 index 1fd666acb..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/rounds.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the data classes for the reset_pause_abci application.""" - -from enum import Enum -from typing import Dict, Optional, Set, Tuple - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AppState, - BaseSynchronizedData, - CollectSameUntilThresholdRound, - DegenerateRound, -) -from packages.valory.skills.reset_pause_abci.payloads import ResetPausePayload - - -class Event(Enum): - """Event enumeration for the reset_pause_abci app.""" - - DONE = "done" - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - RESET_AND_PAUSE_TIMEOUT = "reset_and_pause_timeout" - - -class ResetAndPauseRound(CollectSameUntilThresholdRound): - """A round that represents that consensus is reached (the final round)""" - - payload_class = ResetPausePayload - _allow_rejoin_payloads = True - synchronized_data_class = BaseSynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - if self.threshold_reached: - return self.synchronized_data.create(), Event.DONE - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, Event.NO_MAJORITY - return None - - -class FinishedResetAndPauseRound(DegenerateRound): - """A round that represents reset and pause has finished""" - - -class FinishedResetAndPauseErrorRound(DegenerateRound): - """A round that represents reset and pause has finished with errors""" - - -class ResetPauseAbciApp(AbciApp[Event]): - """ResetPauseAbciApp - - Initial round: ResetAndPauseRound - - Initial states: {ResetAndPauseRound} - - Transition states: - 0. ResetAndPauseRound - - done: 1. - - reset and pause timeout: 2. - - no majority: 2. - 1. FinishedResetAndPauseRound - 2. FinishedResetAndPauseErrorRound - - Final states: {FinishedResetAndPauseErrorRound, FinishedResetAndPauseRound} - - Timeouts: - round timeout: 30.0 - reset and pause timeout: 30.0 - """ - - initial_round_cls: AppState = ResetAndPauseRound - transition_function: AbciAppTransitionFunction = { - ResetAndPauseRound: { - Event.DONE: FinishedResetAndPauseRound, - Event.RESET_AND_PAUSE_TIMEOUT: FinishedResetAndPauseErrorRound, - Event.NO_MAJORITY: FinishedResetAndPauseErrorRound, - }, - FinishedResetAndPauseRound: {}, - FinishedResetAndPauseErrorRound: {}, - } - final_states: Set[AppState] = { - FinishedResetAndPauseRound, - FinishedResetAndPauseErrorRound, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - Event.RESET_AND_PAUSE_TIMEOUT: 30.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = {ResetAndPauseRound: set()} - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedResetAndPauseRound: set(), - FinishedResetAndPauseErrorRound: set(), - } diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/skill.yaml b/trader_old/vendor/valory/skills/reset_pause_abci/skill.yaml deleted file mode 100644 index ddc4e4b4e..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/skill.yaml +++ /dev/null @@ -1,141 +0,0 @@ -name: reset_pause_abci -author: valory -version: 0.1.0 -type: skill -description: ABCI application for resetting and pausing app executions. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeigyx3zutnbq2sqlgeo2hi2vjgpmnlspnkyh4wemjfrqkrpel27bwi - __init__.py: bafybeicx55fcmu5t2lrrs4wqi6bdvsmoq2csfqebyzwy6oh4olmhnvmelu - behaviours.py: bafybeich7tmipn2zsuqsmhtbrmmqys3mpvn3jctx6g3kz2atet2atl3j6q - dialogues.py: bafybeigabhaykiyzbluu4mk6bbrmqhzld2kyp32pg24bvjmzrrb74einwm - fsm_specification.yaml: bafybeietrxvm2odv3si3ecep3by6rftsirzzazxpmeh73yvtsis2mfaali - handlers.py: bafybeie22h45jr2opf2waszr3qt5km2fppcaahalcavhzutgb6pyyywqxq - models.py: bafybeiagj2e73wvzfqti6chbgkxh5tawzdjwqnxlo2bcfa5lyzy6ogzh2u - payloads.py: bafybeihychpsosovpyq7bh6aih2cyjkxr23j7becd5apetrqivvnolzm7i - rounds.py: bafybeifi2gpj2piilxtqcvv6lxhwpnbl7xs3a3trh3wvlv2wihowoon4tm - tests/__init__.py: bafybeiclijinxvycj7agcagt2deuuyh7zxyp7k2s55la6lh3jghzqvfux4 - tests/test_behaviours.py: bafybeigblrmkjci6at74yetaevgw5zszhivpednbok7fby4tqn7zt2vemy - tests/test_dialogues.py: bafybeif7pe7v34cfznzv4htyuevx733ersmk4bqjcgajn2535jmuujdmzm - tests/test_handlers.py: bafybeiggog2k65ijtvqwkvjvmaoo6khwgfkeodddzl6u76gcvvongwjawy - tests/test_payloads.py: bafybeifj343tlaiasebfgahfxehn4oi74omgah3ju2pze2fefoouid2zdq - tests/test_rounds.py: bafybeifz67lfay4pkz5ipblpfpadl4zmd5riajkv6sdsiby22z24gp3cxa -fingerprint_ignore_patterns: [] -connections: [] -contracts: [] -protocols: [] -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -behaviours: - main: - args: {} - class_name: ResetPauseABCIConsensusBehaviour -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - light_slash_unit_amount: 5000000000000000 - max_attempts: 10 - max_healthcheck: 120 - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 30.0 - serious_slash_unit_amount: 8000000000000000 - service_id: reset_pause_abci - service_registry_address: null - setup: {} - share_tm_config_on_startup: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - sleep_time: 1 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - tx_timeout: 10.0 - use_slashing: false - use_termination: false - class_name: Params - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: {} -is_abstract: true -customs: [] diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/tests/__init__.py b/trader_old/vendor/valory/skills/reset_pause_abci/tests/__init__.py deleted file mode 100644 index db0918fb6..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/reset_pause_abci skill.""" diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_behaviours.py b/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_behaviours.py deleted file mode 100644 index 54356764c..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_behaviours.py +++ /dev/null @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/reset_pause_abci skill's behaviours.""" - -# pylint: skip-file - -from pathlib import Path -from typing import Callable, Generator, Optional -from unittest import mock -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData as ResetSynchronizedSata, -) -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - make_degenerate_behaviour, -) -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.reset_pause_abci import PUBLIC_ID -from packages.valory.skills.reset_pause_abci.behaviours import ResetAndPauseBehaviour -from packages.valory.skills.reset_pause_abci.rounds import Event as ResetEvent -from packages.valory.skills.reset_pause_abci.rounds import FinishedResetAndPauseRound - - -PACKAGE_DIR = Path(__file__).parent.parent - - -def test_skill_public_id() -> None: - """Test skill module public ID""" - - assert PUBLIC_ID.name == Path(__file__).parents[1].name - assert PUBLIC_ID.author == Path(__file__).parents[3].name - - -class ResetPauseAbciFSMBehaviourBaseCase(FSMBehaviourBaseCase): - """Base case for testing PauseReset FSMBehaviour.""" - - path_to_skill = PACKAGE_DIR - - -def dummy_reset_tendermint_with_wait_wrapper( - reset_successfully: Optional[bool], -) -> Callable[[], Generator[None, None, Optional[bool]]]: - """Wrapper for a Dummy `reset_tendermint_with_wait` method.""" - - def dummy_reset_tendermint_with_wait() -> Generator[None, None, Optional[bool]]: - """Dummy `reset_tendermint_with_wait` method.""" - yield - return reset_successfully - - return dummy_reset_tendermint_with_wait - - -class TestResetAndPauseBehaviour(ResetPauseAbciFSMBehaviourBaseCase): - """Test ResetBehaviour.""" - - behaviour_class = ResetAndPauseBehaviour - next_behaviour_class = make_degenerate_behaviour(FinishedResetAndPauseRound) - - @pytest.mark.parametrize("tendermint_reset_status", (None, True, False)) - def test_reset_behaviour( - self, - tendermint_reset_status: Optional[bool], - ) -> None: - """Test reset behaviour.""" - dummy_participants = [[i for i in range(4)]] - - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.behaviour_class.auto_behaviour_id(), - synchronized_data=ResetSynchronizedSata( - AbciAppDB( - setup_data=dict( - all_participants=dummy_participants, - participants=dummy_participants, - safe_contract_address=[""], - consensus_threshold=[3], - most_voted_estimate=[0.1], - tx_hashes_history=[["68656c6c6f776f726c64"]], - ), - ) - ), - ) - - assert self.behaviour.current_behaviour is not None - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - - with mock.patch.object( - self.behaviour.current_behaviour, - "send_a2a_transaction", - side_effect=self.behaviour.current_behaviour.send_a2a_transaction, - ), mock.patch.object( - self.behaviour.current_behaviour, - "reset_tendermint_with_wait", - side_effect=dummy_reset_tendermint_with_wait_wrapper( - tendermint_reset_status - ), - ) as mock_reset_tendermint_with_wait, mock.patch.object( - self.behaviour.current_behaviour, - "wait_from_last_timestamp", - side_effect=lambda _: (yield), - ): - if tendermint_reset_status is not None: - # Increase the period_count to force the call to reset_tendermint_with_wait() - self.behaviour.current_behaviour.synchronized_data.create() - - self.behaviour.act_wrapper() - self.behaviour.act_wrapper() - - # now if the first reset attempt has been simulated to fail, let's simulate the second attempt to succeed. - if tendermint_reset_status is not None and not tendermint_reset_status: - mock_reset_tendermint_with_wait.side_effect = ( - dummy_reset_tendermint_with_wait_wrapper(True) - ) - self.behaviour.act_wrapper() - # make sure that the behaviour does not send any txs to other agents when Tendermint reset fails - assert isinstance( - self.behaviour.current_behaviour.send_a2a_transaction, MagicMock - ) - self.behaviour.current_behaviour.send_a2a_transaction.assert_not_called() - self.behaviour.act_wrapper() - - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(ResetEvent.DONE) - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.next_behaviour_class.auto_behaviour_id() - ) diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_dialogues.py b/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_dialogues.py deleted file mode 100644 index d9b2904ca..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.reset_pause_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_handlers.py b/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_handlers.py deleted file mode 100644 index 347f9e9fc..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_handlers.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.reset_pause_abci.handlers # noqa - - -def test_import() -> None: - """Test that the 'handlers.py' Python module can be imported.""" diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_payloads.py b/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_payloads.py deleted file mode 100644 index 15b67fae4..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_payloads.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the payloads.py module of the skill.""" - -# pylint: skip-file - -from packages.valory.skills.reset_pause_abci.payloads import ResetPausePayload - - -def test_reset_pause_payload() -> None: - """Test `ResetPausePayload`.""" - - payload = ResetPausePayload(sender="sender", period_count=1) - - assert payload.period_count == 1 - assert payload.data == {"period_count": 1} - assert ResetPausePayload.from_json(payload.json) == payload diff --git a/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_rounds.py b/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_rounds.py deleted file mode 100644 index adadb778b..000000000 --- a/trader_old/vendor/valory/skills/reset_pause_abci/tests/test_rounds.py +++ /dev/null @@ -1,106 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the rounds of the skill.""" - -# pylint: skip-file - -import hashlib -import logging # noqa: F401 -from typing import Dict, FrozenSet -from unittest.mock import MagicMock - -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData as ResetSynchronizedSata, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.reset_pause_abci.payloads import ResetPausePayload -from packages.valory.skills.reset_pause_abci.rounds import Event as ResetEvent -from packages.valory.skills.reset_pause_abci.rounds import ResetAndPauseRound - - -MAX_PARTICIPANTS: int = 4 -DUMMY_RANDOMNESS = hashlib.sha256("hash".encode() + str(0).encode()).hexdigest() - - -def get_participant_to_period_count( - participants: FrozenSet[str], period_count: int -) -> Dict[str, ResetPausePayload]: - """participant_to_selection""" - return { - participant: ResetPausePayload(sender=participant, period_count=period_count) - for participant in participants - } - - -class TestResetAndPauseRound(BaseCollectSameUntilThresholdRoundTest): - """Test ResetRound.""" - - _synchronized_data_class = ResetSynchronizedSata - _event_class = ResetEvent - - def test_runs( - self, - ) -> None: - """Runs tests.""" - - synchronized_data = self.synchronized_data.update( - most_voted_randomness=DUMMY_RANDOMNESS, consensus_threshold=3 - ) - synchronized_data._db._cross_period_persisted_keys = frozenset( - {"most_voted_randomness"} - ) - test_round = ResetAndPauseRound( - synchronized_data=synchronized_data, - context=MagicMock(), - ) - next_period_count = 1 - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_period_count( - self.participants, next_period_count - ), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.create(), - synchronized_data_attr_checks=[], # [lambda _synchronized_data: _synchronized_data.participants], - most_voted_payload=next_period_count, - exit_event=self._event_class.DONE, - ) - ) - - def test_accepting_payloads_from(self) -> None: - """Test accepting payloads from""" - - alice, *others = self.participants - participants = list(others) - all_participants = participants + [alice] - - synchronized_data = self.synchronized_data.update( - participants=participants, all_participants=all_participants - ) - - test_round = ResetAndPauseRound( - synchronized_data=synchronized_data, - context=MagicMock(), - ) - - assert test_round.accepting_payloads_from != participants - assert test_round.accepting_payloads_from == frozenset(all_participants) diff --git a/trader_old/vendor/valory/skills/staking_abci/README.md b/trader_old/vendor/valory/skills/staking_abci/README.md deleted file mode 100644 index bc35afb23..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Staking abci - -## Description - -This module contains the Staking skill for an AEA. diff --git a/trader_old/vendor/valory/skills/staking_abci/__init__.py b/trader_old/vendor/valory/skills/staking_abci/__init__.py deleted file mode 100644 index 84bfa5c61..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- 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 the staking skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/staking_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/staking_abci/behaviours.py b/trader_old/vendor/valory/skills/staking_abci/behaviours.py deleted file mode 100644 index 74df6e501..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/behaviours.py +++ /dev/null @@ -1,551 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviours for the staking skill.""" - -from abc import ABC -from datetime import datetime, timedelta -from pathlib import Path -from typing import Any, Callable, Generator, Optional, Set, Tuple, Type, Union, cast - -from aea.configurations.data_types import PublicId -from aea.contracts.base import Contract - -from packages.valory.contracts.gnosis_safe.contract import GnosisSafeContract -from packages.valory.contracts.mech_activity.contract import MechActivityContract -from packages.valory.contracts.service_staking_token.contract import ( - ServiceStakingTokenContract, -) -from packages.valory.contracts.staking_token.contract import StakingTokenContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.abstract_round_abci.base import get_name -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - BaseBehaviour, - TimeoutException, -) -from packages.valory.skills.abstract_round_abci.behaviours import AbstractRoundBehaviour -from packages.valory.skills.staking_abci.models import StakingParams -from packages.valory.skills.staking_abci.payloads import CallCheckpointPayload -from packages.valory.skills.staking_abci.rounds import ( - CallCheckpointRound, - StakingAbciApp, - StakingState, - SynchronizedData, -) -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - hash_payload_to_hex, -) -from packages.valory.skills.transaction_settlement_abci.rounds import TX_HASH_LENGTH - - -WaitableConditionType = Generator[None, None, bool] - - -ETH_PRICE = 0 -# setting the safe gas to 0 means that all available gas will be used -# which is what we want in most cases -# more info here: https://safe-docs.dev.gnosisdev.com/safe/docs/contracts_tx_execution/ -SAFE_GAS = 0 - - -NULL_ADDRESS = "0x0000000000000000000000000000000000000000" -CHECKPOINT_FILENAME = "checkpoint.txt" -READ_MODE = "r" -WRITE_MODE = "w" - - -class StakingInteractBaseBehaviour(BaseBehaviour, ABC): - """Base behaviour that contains methods to interact with the staking contract.""" - - def __init__(self, **kwargs: Any) -> None: - """Initialize the behaviour.""" - super().__init__(**kwargs) - self._service_staking_state: StakingState = StakingState.UNSTAKED - self._checkpoint_ts = 0 - - @property - def params(self) -> StakingParams: - """Return the params.""" - return cast(StakingParams, self.context.params) - - @property - def use_v2(self) -> bool: - """Whether to use the v2 staking contract.""" - return self.params.mech_activity_checker_contract != NULL_ADDRESS - - @property - def synced_timestamp(self) -> int: - """Return the synchronized timestamp across the agents.""" - return int(self.round_sequence.last_round_transition_timestamp.timestamp()) - - @property - def staking_contract_address(self) -> str: - """Get the staking contract address.""" - return self.params.staking_contract_address - - @property - def mech_activity_checker_contract(self) -> str: - """Get the staking contract address.""" - return self.params.mech_activity_checker_contract - - @property - def service_staking_state(self) -> StakingState: - """Get the service's staking state.""" - return self._service_staking_state - - @service_staking_state.setter - def service_staking_state(self, state: Union[StakingState, int]) -> None: - """Set the service's staking state.""" - if isinstance(state, int): - state = StakingState(state) - self._service_staking_state = state - - @property - def next_checkpoint(self) -> int: - """Get the next checkpoint.""" - return self._next_checkpoint - - @next_checkpoint.setter - def next_checkpoint(self, next_checkpoint: int) -> None: - """Set the next checkpoint.""" - self._next_checkpoint = next_checkpoint - - @property - def is_checkpoint_reached(self) -> bool: - """Whether the next checkpoint is reached.""" - return self.next_checkpoint <= self.synced_timestamp - - @property - def ts_checkpoint(self) -> int: - """Get the last checkpoint timestamp.""" - return self._checkpoint_ts - - @ts_checkpoint.setter - def ts_checkpoint(self, checkpoint_ts: int) -> None: - """Set the last checkpoint timestamp.""" - self._checkpoint_ts = checkpoint_ts - - @property - def liveness_period(self) -> int: - """Get the liveness period.""" - return self._liveness_period - - @liveness_period.setter - def liveness_period(self, liveness_period: int) -> None: - """Set the liveness period.""" - self._liveness_period = liveness_period - - @property - def liveness_ratio(self) -> int: - """Get the liveness ratio.""" - return self._liveness_ratio - - @liveness_ratio.setter - def liveness_ratio(self, liveness_ratio: int) -> None: - """Set the liveness period.""" - self._liveness_ratio = liveness_ratio - - @property - def service_info(self) -> Tuple[Any, Any, Tuple[Any, Any]]: - """Get the service info.""" - return self._service_info - - @service_info.setter - def service_info(self, service_info: Tuple[Any, Any, Tuple[Any, Any]]) -> None: - """Set the service info.""" - self._service_info = service_info - - def wait_for_condition_with_sleep( - self, - condition_gen: Callable[[], WaitableConditionType], - timeout: Optional[float] = None, - ) -> Generator[None, None, None]: - """Wait for a condition to happen and sleep in-between checks. - - This is a modified version of the base `wait_for_condition` method which: - 1. accepts a generator that creates the condition instead of a callable - 2. sleeps in-between checks - - :param condition_gen: a generator of the condition to wait for - :param timeout: the maximum amount of time to wait - :yield: None - """ - - deadline = ( - datetime.now() + timedelta(0, timeout) - if timeout is not None - else datetime.max - ) - - while True: - condition_satisfied = yield from condition_gen() - if condition_satisfied: - break - if timeout is not None and datetime.now() > deadline: - raise TimeoutException() - msg = f"Retrying in {self.params.staking_interaction_sleep_time} seconds." - self.context.logger.info(msg) - yield from self.sleep(self.params.staking_interaction_sleep_time) - - def default_error( - self, contract_id: str, contract_callable: str, response_msg: ContractApiMessage - ) -> None: - """Return a default contract interaction error message.""" - self.context.logger.error( - f"Could not successfully interact with the {contract_id} contract " - f"using {contract_callable!r}: {response_msg}" - ) - - def contract_interact( - self, - contract_address: str, - contract_public_id: PublicId, - contract_callable: str, - data_key: str, - placeholder: str, - **kwargs: Any, - ) -> WaitableConditionType: - """Interact with a contract.""" - contract_id = str(contract_public_id) - response_msg = yield from self.get_contract_api_response( - ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address, - contract_id, - contract_callable, - **kwargs, - ) - if response_msg.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.default_error(contract_id, contract_callable, response_msg) - return False - - data = response_msg.raw_transaction.body.get(data_key, None) - if data is None: - self.default_error(contract_id, contract_callable, response_msg) - return False - - setattr(self, placeholder, data) - return True - - def _staking_contract_interact( - self, - contract_callable: str, - placeholder: str, - data_key: str = "data", - **kwargs: Any, - ) -> WaitableConditionType: - """Interact with the staking contract.""" - contract_public_id = cast( - Contract, - StakingTokenContract if self.use_v2 else ServiceStakingTokenContract, - ) - status = yield from self.contract_interact( - contract_address=self.staking_contract_address, - contract_public_id=contract_public_id.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def _mech_activity_checker_contract_interact( - self, - contract_callable: str, - placeholder: str, - data_key: str = "data", - **kwargs: Any, - ) -> WaitableConditionType: - """Interact with the staking contract.""" - status = yield from self.contract_interact( - contract_address=self.mech_activity_checker_contract, - contract_public_id=MechActivityContract.contract_id, - contract_callable=contract_callable, - data_key=data_key, - placeholder=placeholder, - **kwargs, - ) - return status - - def _check_service_staked(self) -> WaitableConditionType: - """Check whether the service is staked.""" - service_id = self.params.on_chain_service_id - if service_id is None: - self.context.logger.warning( - "Cannot perform any staking-related operations without a configured on-chain service id. " - "Assuming service status 'UNSTAKED'." - ) - return True - - status = yield from self._staking_contract_interact( - contract_callable="get_service_staking_state", - placeholder=get_name(CallCheckpointBehaviour.service_staking_state), - service_id=service_id, - ) - - return status - - def _get_next_checkpoint(self) -> WaitableConditionType: - """Get the timestamp in which the next checkpoint is reached.""" - status = yield from self._staking_contract_interact( - contract_callable="get_next_checkpoint_ts", - placeholder=get_name(CallCheckpointBehaviour.next_checkpoint), - ) - return status - - def _get_ts_checkpoint(self) -> WaitableConditionType: - """Get the timestamp in which the next checkpoint is reached.""" - status = yield from self._staking_contract_interact( - contract_callable="ts_checkpoint", - placeholder=get_name(CallCheckpointBehaviour.ts_checkpoint), - ) - return status - - def _get_liveness_period(self) -> WaitableConditionType: - """Get the liveness period.""" - status = yield from self._staking_contract_interact( - contract_callable="get_liveness_period", - placeholder=get_name(CallCheckpointBehaviour.liveness_period), - ) - return status - - def _get_liveness_ratio(self) -> WaitableConditionType: - """Get the liveness ratio.""" - contract_interact = ( - self._mech_activity_checker_contract_interact - if self.use_v2 - else self._staking_contract_interact - ) - status = yield from contract_interact( - contract_callable="liveness_ratio", - placeholder=get_name(CallCheckpointBehaviour.liveness_ratio), - ) - return status - - def _get_service_info(self) -> WaitableConditionType: - """Get the service info.""" - service_id = self.params.on_chain_service_id - if service_id is None: - self.context.logger.warning( - "Cannot perform any staking-related operations without a configured on-chain service id. " - "Assuming service status 'UNSTAKED'." - ) - return True - - status = yield from self._staking_contract_interact( - contract_callable="get_service_info", - placeholder=get_name(CallCheckpointBehaviour.service_info), - service_id=service_id, - ) - return status - - -class CallCheckpointBehaviour( - StakingInteractBaseBehaviour -): # pylint-disable too-many-ancestors - """Behaviour that calls the checkpoint contract function if the service is staked and if it is necessary.""" - - matching_round = CallCheckpointRound - - def __init__(self, **kwargs: Any) -> None: - """Initialize the behaviour.""" - super().__init__(**kwargs) - self._service_staking_state: StakingState = StakingState.UNSTAKED - self._next_checkpoint: int = 0 - self._checkpoint_data: bytes = b"" - self._safe_tx_hash: str = "" - self._checkpoint_filepath: Path = self.params.store_path / CHECKPOINT_FILENAME - - @property - def params(self) -> StakingParams: - """Return the params.""" - return cast(StakingParams, self.context.params) - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return SynchronizedData(super().synchronized_data.db) - - @property - def is_first_period(self) -> bool: - """Return whether it is the first period of the service.""" - return self.synchronized_data.period_count == 0 - - @property - def new_checkpoint_detected(self) -> bool: - """Whether a new checkpoint has been detected.""" - previous_checkpoint = self.synchronized_data.previous_checkpoint - return bool(previous_checkpoint) and previous_checkpoint != self.ts_checkpoint - - @property - def checkpoint_data(self) -> bytes: - """Get the checkpoint data.""" - return self._checkpoint_data - - @checkpoint_data.setter - def checkpoint_data(self, data: bytes) -> None: - """Set the request data.""" - self._checkpoint_data = data - - @property - def safe_tx_hash(self) -> str: - """Get the safe_tx_hash.""" - return self._safe_tx_hash - - @safe_tx_hash.setter - def safe_tx_hash(self, safe_hash: str) -> None: - """Set the safe_tx_hash.""" - length = len(safe_hash) - if length != TX_HASH_LENGTH: - raise ValueError( - f"Incorrect length {length} != {TX_HASH_LENGTH} detected " - f"when trying to assign a safe transaction hash: {safe_hash}" - ) - self._safe_tx_hash = safe_hash[2:] - - def read_stored_timestamp(self) -> Optional[int]: - """Read the timestamp from the agent's data dir.""" - try: - with open(self._checkpoint_filepath, READ_MODE) as checkpoint_file: - try: - return int(checkpoint_file.readline()) - except (ValueError, TypeError, StopIteration): - err = f"Stored checkpoint timestamp could not be parsed from {self._checkpoint_filepath!r}!" - except (FileNotFoundError, PermissionError, OSError): - err = f"Error opening file {self._checkpoint_filepath!r} in {READ_MODE!r} mode!" - - self.context.logger.error(err) - return None - - def store_timestamp(self) -> int: - """Store the timestamp to the agent's data dir.""" - if self.ts_checkpoint == 0: - self.context.logger.warning("No checkpoint timestamp to store!") - return 0 - - try: - with open(self._checkpoint_filepath, WRITE_MODE) as checkpoint_file: - try: - return checkpoint_file.write(str(self.ts_checkpoint)) - except (IOError, OSError): - err = f"Error writing to file {self._checkpoint_filepath!r}!" - except (FileNotFoundError, PermissionError, OSError): - err = f"Error opening file {self._checkpoint_filepath!r} in {WRITE_MODE!r} mode!" - - self.context.logger.error(err) - return 0 - - def _build_checkpoint_tx(self) -> WaitableConditionType: - """Get the request tx data encoded.""" - result = yield from self._staking_contract_interact( - contract_callable="build_checkpoint_tx", - placeholder=get_name(CallCheckpointBehaviour.checkpoint_data), - ) - - return result - - def _get_safe_tx_hash(self) -> WaitableConditionType: - """Prepares and returns the safe tx hash.""" - status = yield from self.contract_interact( - contract_address=self.synchronized_data.safe_contract_address, - contract_public_id=GnosisSafeContract.contract_id, - contract_callable="get_raw_safe_transaction_hash", - data_key="tx_hash", - placeholder=get_name(CallCheckpointBehaviour.safe_tx_hash), - to_address=self.params.staking_contract_address, - value=ETH_PRICE, - data=self.checkpoint_data, - ) - return status - - def _prepare_safe_tx(self) -> Generator[None, None, str]: - """Prepare the safe transaction for calling the checkpoint and return the hex for the tx settlement skill.""" - yield from self.wait_for_condition_with_sleep(self._build_checkpoint_tx) - yield from self.wait_for_condition_with_sleep(self._get_safe_tx_hash) - return hash_payload_to_hex( - self.safe_tx_hash, - ETH_PRICE, - SAFE_GAS, - self.params.staking_contract_address, - self.checkpoint_data, - ) - - def check_new_epoch(self) -> Generator[None, None, bool]: - """Check if a new epoch has been reached.""" - yield from self.wait_for_condition_with_sleep(self._get_ts_checkpoint) - stored_timestamp_invalidated = False - - # if it is the first period of the service, - # 1. check if the stored timestamp is the same as the current checkpoint - # 2. if not, update the corresponding flag - # That way, we protect from the case in which the user stops their service - # before the next checkpoint is reached and restarts it afterward. - if self.is_first_period: - stored_timestamp = self.read_stored_timestamp() - stored_timestamp_invalidated = stored_timestamp != self.ts_checkpoint - - is_checkpoint_reached = ( - stored_timestamp_invalidated or self.new_checkpoint_detected - ) - if is_checkpoint_reached: - self.context.logger.info("An epoch change has been detected.") - status = self.store_timestamp() - if status: - self.context.logger.info( - "Successfully updated the stored checkpoint timestamp." - ) - - return is_checkpoint_reached - - def async_act(self) -> Generator: - """Do the action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - yield from self.wait_for_condition_with_sleep(self._check_service_staked) - - checkpoint_tx_hex = None - if self.service_staking_state == StakingState.STAKED: - yield from self.wait_for_condition_with_sleep(self._get_next_checkpoint) - if self.is_checkpoint_reached: - checkpoint_tx_hex = yield from self._prepare_safe_tx() - - if self.service_staking_state == StakingState.EVICTED: - self.context.logger.critical("Service has been evicted!") - - tx_submitter = self.matching_round.auto_round_id() - is_checkpoint_reached = yield from self.check_new_epoch() - payload = CallCheckpointPayload( - self.context.agent_address, - tx_submitter, - checkpoint_tx_hex, - self.service_staking_state.value, - self.ts_checkpoint, - is_checkpoint_reached, - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - self.set_done() - - -class StakingRoundBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the staking behaviour.""" - - initial_behaviour_cls = CallCheckpointBehaviour - abci_app_cls = StakingAbciApp - behaviours: Set[Type[BaseBehaviour]] = {CallCheckpointBehaviour} # type: ignore diff --git a/trader_old/vendor/valory/skills/staking_abci/dialogues.py b/trader_old/vendor/valory/skills/staking_abci/dialogues.py deleted file mode 100644 index 153b6ce50..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/dialogues.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- 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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_old/vendor/valory/skills/staking_abci/fsm_specification.yaml b/trader_old/vendor/valory/skills/staking_abci/fsm_specification.yaml deleted file mode 100644 index f68a2c6a2..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/fsm_specification.yaml +++ /dev/null @@ -1,27 +0,0 @@ -alphabet_in: -- DONE -- NEXT_CHECKPOINT_NOT_REACHED_YET -- NO_MAJORITY -- ROUND_TIMEOUT -- SERVICE_EVICTED -- SERVICE_NOT_STAKED -default_start_state: CallCheckpointRound -final_states: -- CheckpointCallPreparedRound -- FinishedStakingRound -- ServiceEvictedRound -label: StakingAbciApp -start_states: -- CallCheckpointRound -states: -- CallCheckpointRound -- CheckpointCallPreparedRound -- FinishedStakingRound -- ServiceEvictedRound -transition_func: - (CallCheckpointRound, DONE): CheckpointCallPreparedRound - (CallCheckpointRound, NEXT_CHECKPOINT_NOT_REACHED_YET): FinishedStakingRound - (CallCheckpointRound, NO_MAJORITY): CallCheckpointRound - (CallCheckpointRound, ROUND_TIMEOUT): CallCheckpointRound - (CallCheckpointRound, SERVICE_EVICTED): ServiceEvictedRound - (CallCheckpointRound, SERVICE_NOT_STAKED): FinishedStakingRound diff --git a/trader_old/vendor/valory/skills/staking_abci/handlers.py b/trader_old/vendor/valory/skills/staking_abci/handlers.py deleted file mode 100644 index f085415b4..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/handlers.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- 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 the handlers for the 'staking_abci' skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIStakingHandler = ABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_old/vendor/valory/skills/staking_abci/models.py b/trader_old/vendor/valory/skills/staking_abci/models.py deleted file mode 100644 index b9ee386a2..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/models.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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. -# -# ------------------------------------------------------------------------------ - - -"""Models for the Staking ABCI application.""" - -import os -from pathlib import Path -from typing import Any - -from packages.valory.skills.abstract_round_abci.models import BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.staking_abci.rounds import StakingAbciApp - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -def get_store_path(kwargs: dict) -> Path: - """Get the path of the store.""" - path = kwargs.get("store_path", "") - if not path: - msg = "The path to the store must be provided as a keyword argument." - raise ValueError(msg) - - # check if the path exists, and we can write to it - if ( - not os.path.isdir(path) - or not os.access(path, os.W_OK) - or not os.access(path, os.R_OK) - ): - msg = f"The store path {path!r} is not a directory or is not writable." - raise ValueError(msg) - - return Path(path) - - -class StakingParams(BaseParams): - """Staking parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the parameters' object.""" - self.staking_contract_address: str = self._ensure( - "staking_contract_address", kwargs, str - ) - self.staking_interaction_sleep_time: int = self._ensure( - "staking_interaction_sleep_time", kwargs, int - ) - self.mech_activity_checker_contract: str = self._ensure( - "mech_activity_checker_contract", kwargs, str - ) - self.store_path = get_store_path(kwargs) - super().__init__(*args, **kwargs) - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = StakingAbciApp diff --git a/trader_old/vendor/valory/skills/staking_abci/payloads.py b/trader_old/vendor/valory/skills/staking_abci/payloads.py deleted file mode 100644 index 4b1f47e2c..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/payloads.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the transaction payloads for the staking abci.""" - -from dataclasses import dataclass -from typing import Optional - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class MultisigTxPayload(BaseTxPayload): - """Represents a transaction payload for preparing an on-chain transaction to be sent via the agents' multisig.""" - - tx_submitter: str - tx_hash: Optional[str] - - -@dataclass(frozen=True) -class CallCheckpointPayload(MultisigTxPayload): - """A transaction payload for the checkpoint call.""" - - service_staking_state: int - ts_checkpoint: int - is_checkpoint_reached: bool diff --git a/trader_old/vendor/valory/skills/staking_abci/rounds.py b/trader_old/vendor/valory/skills/staking_abci/rounds.py deleted file mode 100644 index c6de99b2a..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/rounds.py +++ /dev/null @@ -1,226 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the rounds for the Staking ABCI application.""" - -from abc import ABC -from enum import Enum -from typing import Dict, Optional, Set, Tuple, Type, cast - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AbstractRound, - AppState, - BaseSynchronizedData, - CollectSameUntilThresholdRound, - CollectionRound, - DegenerateRound, - DeserializedCollection, - get_name, -) -from packages.valory.skills.staking_abci.payloads import CallCheckpointPayload -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TxSettlementSyncedData, -) - - -class StakingState(Enum): - """Staking state enumeration for the staking.""" - - UNSTAKED = 0 - STAKED = 1 - EVICTED = 2 - - -class Event(Enum): - """Event enumeration for the staking skill.""" - - DONE = "done" - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - SERVICE_NOT_STAKED = "service_not_staked" - SERVICE_EVICTED = "service_evicted" - NEXT_CHECKPOINT_NOT_REACHED_YET = "next_checkpoint_not_reached_yet" - - -class SynchronizedData(TxSettlementSyncedData): - """Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - def _get_deserialized(self, key: str) -> DeserializedCollection: - """Strictly get a collection and return it deserialized.""" - serialized = self.db.get_strict(key) - return CollectionRound.deserialize_collection(serialized) - - @property - def tx_submitter(self) -> str: - """Get the round that submitted a tx to transaction_settlement_abci.""" - return str(self.db.get_strict("tx_submitter")) - - @property - def service_staking_state(self) -> StakingState: - """Get the service's staking state.""" - return StakingState(self.db.get("service_staking_state", 0)) - - @property - def participant_to_checkpoint(self) -> DeserializedCollection: - """Get the participants to the checkpoint round.""" - return self._get_deserialized("participant_to_checkpoint") - - @property - def previous_checkpoint(self) -> Optional[int]: - """Get the previous checkpoint.""" - previous_checkpoint = self.db.get("previous_checkpoint", None) - if previous_checkpoint is None: - return None - return int(previous_checkpoint) - - @property - def is_checkpoint_reached(self) -> bool: - """Check if the checkpoint is reached.""" - return bool(self.db.get("is_checkpoint_reached", False)) - - -class CallCheckpointRound(CollectSameUntilThresholdRound): - """A round for the checkpoint call preparation.""" - - payload_class = CallCheckpointPayload - done_event: Enum = Event.DONE - no_majority_event: Enum = Event.NO_MAJORITY - selection_key = ( - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.service_staking_state), - get_name(SynchronizedData.previous_checkpoint), - get_name(SynchronizedData.is_checkpoint_reached), - ) - collection_key = get_name(SynchronizedData.participant_to_checkpoint) - synchronized_data_class = SynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - res = super().end_block() - if res is None: - return None - - synced_data, event = cast(Tuple[SynchronizedData, Enum], res) - - if event != Event.DONE: - return res - - if synced_data.service_staking_state == StakingState.UNSTAKED: - return synced_data, Event.SERVICE_NOT_STAKED - - if synced_data.service_staking_state == StakingState.EVICTED: - return synced_data, Event.SERVICE_EVICTED - - if synced_data.most_voted_tx_hash is None: - return synced_data, Event.NEXT_CHECKPOINT_NOT_REACHED_YET - - return res - - -class CheckpointCallPreparedRound(DegenerateRound, ABC): - """A round that represents staking has finished with a checkpoint call safe tx prepared.""" - - -class FinishedStakingRound(DegenerateRound, ABC): - """A round that represents staking has finished.""" - - -class ServiceEvictedRound(DegenerateRound, ABC): - """A round that terminates the service if it has been evicted.""" - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """End block.""" - - -class StakingAbciApp(AbciApp[Event]): # pylint: disable=too-few-public-methods - """StakingAbciApp - - Initial round: CallCheckpointRound - - Initial states: {CallCheckpointRound} - - Transition states: - 0. CallCheckpointRound - - done: 1. - - service not staked: 2. - - service evicted: 3. - - next checkpoint not reached yet: 2. - - round timeout: 0. - - no majority: 0. - 1. CheckpointCallPreparedRound - 2. FinishedStakingRound - 3. ServiceEvictedRound - - Final states: {CheckpointCallPreparedRound, FinishedStakingRound, ServiceEvictedRound} - - Timeouts: - round timeout: 30.0 - """ - - initial_round_cls: Type[AbstractRound] = CallCheckpointRound - transition_function: AbciAppTransitionFunction = { - CallCheckpointRound: { - Event.DONE: CheckpointCallPreparedRound, - Event.SERVICE_NOT_STAKED: FinishedStakingRound, - Event.SERVICE_EVICTED: ServiceEvictedRound, - Event.NEXT_CHECKPOINT_NOT_REACHED_YET: FinishedStakingRound, - Event.ROUND_TIMEOUT: CallCheckpointRound, - Event.NO_MAJORITY: CallCheckpointRound, - }, - CheckpointCallPreparedRound: {}, - FinishedStakingRound: {}, - ServiceEvictedRound: {}, - } - cross_period_persisted_keys = frozenset( - { - get_name(SynchronizedData.service_staking_state), - get_name(SynchronizedData.previous_checkpoint), - get_name(SynchronizedData.is_checkpoint_reached), - } - ) - final_states: Set[AppState] = { - CheckpointCallPreparedRound, - FinishedStakingRound, - ServiceEvictedRound, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = {CallCheckpointRound: set()} - db_post_conditions: Dict[AppState, Set[str]] = { - CheckpointCallPreparedRound: { - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.service_staking_state), - get_name(SynchronizedData.previous_checkpoint), - get_name(SynchronizedData.is_checkpoint_reached), - }, - FinishedStakingRound: { - get_name(SynchronizedData.service_staking_state), - }, - ServiceEvictedRound: { - get_name(SynchronizedData.service_staking_state), - }, - } diff --git a/trader_old/vendor/valory/skills/staking_abci/skill.yaml b/trader_old/vendor/valory/skills/staking_abci/skill.yaml deleted file mode 100644 index 9d866d5c2..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/skill.yaml +++ /dev/null @@ -1,152 +0,0 @@ -name: staking_abci -author: valory -version: 0.1.0 -type: skill -description: This skill implements the Staking for an AEA. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeifrpl36fddmgvniwvghqtxdzc44ry6l2zvqy37vu3y2xvwyd23ugy - __init__.py: bafybeiageyes36ujnvvodqd5vlnihgz44rupysrk2ebbhskjkueetj6dai - behaviours.py: bafybeiels3us2s5sf2lrloekjky46o2owlo3awsocuxt67h76ap2k5qaqy - dialogues.py: bafybeiebofyykseqp3fmif36cqmmyf3k7d2zbocpl6t6wnlpv4szghrxbm - fsm_specification.yaml: bafybeicuoejmaks3ndwhbflp64kkfdkrdyn74a2fplarg4l3gxlonfmeoq - handlers.py: bafybeichsi2y5zvzffupj2vhgagocwvnm7cbzr6jmavp656mfrzsdvkfnu - models.py: bafybeibhzoi25wqpgxwn7ibgz3juax2aeqep7qdl6q7u3abdnb6jahc264 - payloads.py: bafybeib7hxsibtabb5vt6gjtco2x2s2yodhs24ojqecgrcexqsiv3pvmuy - rounds.py: bafybeiezsn42e2qqdpwgtkvrlgjzfwtg7fldfqglf5ofc36g7uyaobvuhq - tests/__init__.py: bafybeid7m6ynosqeb4mvsss2hqg75aly5o2d47r7yfg2xtgwzkkilv2d2m - tests/test_dialogues.py: bafybeidwjk52mufwvkj4cr3xgqycbdzxc6gvosmqyuqdjarnrgwth6wcai - tests/test_handers.py: bafybeibnxlwznx3tsdpjpzh62bnp6lq7zdpolyjxfvxeumzz52ljxfzpme - tests/test_payloads.py: bafybeidtkbudsmrx77xs2oooji6cpj7kx7nembf77u32if2sb2kvkavvhq - tests/test_rounds.py: bafybeidge7sp3udobhvjpbdj5kirkukd6w5qycqkcuc6sy3qqiedco2q4i -fingerprint_ignore_patterns: [] -connections: [] -contracts: -- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge -- valory/service_staking_token:0.1.0:bafybeihhcs3ewwzhy7yto4y36uqmice3pdvyl54fvxxv6jsxonesie4dxu -- valory/staking_token:0.1.0:bafybeiep4r6qyilbfgzdvx6t7zvpgaioxqktmxm7puwtnbpb2ftlib43gy -- valory/mech_activity:0.1.0:bafybeibmqmle5fnal3gxlpdmcos2kogzra4q3pr3o5nh7shplxuilji3t4 -protocols: -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae -behaviours: - main: - args: {} - class_name: StakingRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIStakingHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 350.0 - service_id: staking - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - sleep_time: 5 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - termination_sleep: 900 - tx_timeout: 10.0 - use_termination: false - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - mech_activity_checker_contract: '0x0000000000000000000000000000000000000000' - staking_contract_address: '0x2Ef503950Be67a98746F484DA0bBAdA339DF3326' - staking_interaction_sleep_time: 5 - store_path: data - class_name: StakingParams - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState -dependencies: {} -is_abstract: true diff --git a/trader_old/vendor/valory/skills/staking_abci/tests/__init__.py b/trader_old/vendor/valory/skills/staking_abci/tests/__init__.py deleted file mode 100644 index cce0712e9..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/staking skill.""" diff --git a/trader_old/vendor/valory/skills/staking_abci/tests/test_dialogues.py b/trader_old/vendor/valory/skills/staking_abci/tests/test_dialogues.py deleted file mode 100644 index b7073dec1..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.staking_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_old/vendor/valory/skills/staking_abci/tests/test_handers.py b/trader_old/vendor/valory/skills/staking_abci/tests/test_handers.py deleted file mode 100644 index ebab67ce4..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/tests/test_handers.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the tests for the handlers for the staking abci.""" - -from unittest.mock import MagicMock - -import pytest -from aea.configurations.data_types import PublicId -from aea.skills.base import Handler - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.staking_abci.handlers import ( - ABCIStakingHandler, - ContractApiHandler, - HttpHandler, - IpfsHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, -) - - -@pytest.mark.parametrize( - "handler, base_handler", - [ - (ABCIStakingHandler, ABCIRoundHandler), - (HttpHandler, BaseHttpHandler), - (SigningHandler, BaseSigningHandler), - (LedgerApiHandler, BaseLedgerApiHandler), - (ContractApiHandler, BaseContractApiHandler), - (TendermintHandler, BaseTendermintHandler), - (IpfsHandler, BaseIpfsHandler), - ], -) -def test_handler(handler: Handler, base_handler: Handler) -> None: - """Test that the 'handlers.py' of the StakingAbci can be imported.""" - handler = handler( - name="dummy_handler", - skill_context=MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")), - ) - - assert isinstance(handler, base_handler) diff --git a/trader_old/vendor/valory/skills/staking_abci/tests/test_payloads.py b/trader_old/vendor/valory/skills/staking_abci/tests/test_payloads.py deleted file mode 100644 index f9a7b316b..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/tests/test_payloads.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the transaction payloads for the staking abci.""" -from typing import Dict, Type - -import pytest - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload -from packages.valory.skills.staking_abci.payloads import ( - CallCheckpointPayload, - MultisigTxPayload, -) - - -@pytest.mark.parametrize( - "payload_class, payload_kwargs", - [ - ( - MultisigTxPayload, - {"tx_submitter": "dummy tx submitter", "tx_hash": "dummy tx hash"}, - ), - ( - CallCheckpointPayload, - { - "service_staking_state": 1, - "tx_submitter": "dummy tx submitter", - "tx_hash": "dummy tx hash", - "ts_checkpoint": 1, - "is_checkpoint_reached": True, - }, - ), - ], -) -def test_payload(payload_class: Type[BaseTxPayload], payload_kwargs: Dict) -> None: - """Test payloads.""" - payload = payload_class(sender="sender", **payload_kwargs) - - # Check each attribute in expected_data - for key, value in payload_kwargs.items(): - assert getattr(payload, key) == value - - assert payload.sender == "sender" - assert payload.data == payload_kwargs - assert payload_class.from_json(payload.json) == payload diff --git a/trader_old/vendor/valory/skills/staking_abci/tests/test_rounds.py b/trader_old/vendor/valory/skills/staking_abci/tests/test_rounds.py deleted file mode 100644 index 2a0564afd..000000000 --- a/trader_old/vendor/valory/skills/staking_abci/tests/test_rounds.py +++ /dev/null @@ -1,381 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the tests for rounds of StakingAbciApp.""" - -import json -from dataclasses import dataclass, field -from typing import Any, Callable, Dict, FrozenSet, Hashable, List, Mapping -from unittest import mock -from unittest.mock import MagicMock, patch - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - AbciAppDB, - BaseTxPayload, - get_name, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectSameUntilThresholdRoundTest, -) -from packages.valory.skills.staking_abci.payloads import CallCheckpointPayload -from packages.valory.skills.staking_abci.rounds import ( - CallCheckpointRound, - CheckpointCallPreparedRound, - Event, - FinishedStakingRound, - ServiceEvictedRound, - StakingAbciApp, - StakingState, - SynchronizedData, -) - - -@pytest.fixture -def abci_app() -> StakingAbciApp: - """Fixture for StakingAbciApp.""" - synchronized_data = MagicMock() - logger = MagicMock() - context = MagicMock() - - return StakingAbciApp( - synchronized_data=synchronized_data, logger=logger, context=context - ) - - -DUMMY_SERVICE_STATE = { - "service_staking_state": StakingState.UNSTAKED.value, - "tx_submitter": "dummy_submitter", - "tx_hash": "dummy_tx_hash", - "ts_checkpoint": 0, - "is_checkpoint_reached": True, -} - - -def get_participants() -> FrozenSet[str]: - """Participants""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -def get_checkpoint_payloads(data: Dict) -> Mapping[str, CallCheckpointPayload]: - """Get payloads.""" - return { - participant: CallCheckpointPayload( - participant, - **data, - ) - for participant in get_participants() - } - - -@dataclass -class RoundTestCase: - """RoundTestCase""" - - name: str - initial_data: Dict[str, Hashable] - payloads: Mapping[str, BaseTxPayload] - final_data: Dict[str, Hashable] - event: Event - most_voted_payload: Any - synchronized_data_attr_checks: List[Callable] = field(default_factory=list) - - -MAX_PARTICIPANTS: int = 4 - - -class BaseStakingRoundTestClass(BaseCollectSameUntilThresholdRoundTest): - """Base test class for Staking rounds.""" - - round_class = CallCheckpointRound - synchronized_data: SynchronizedData - _synchronized_data_class = SynchronizedData - _event_class = Event - - def run_test(self, test_case: RoundTestCase) -> None: - """Run the test""" - # Set initial data - self.synchronized_data.update( - self._synchronized_data_class, **test_case.initial_data - ) - - test_round = self.round_class( - synchronized_data=self.synchronized_data, context=mock.MagicMock() - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=test_case.payloads, - synchronized_data_update_fn=lambda sync_data, _: sync_data.update( - **test_case.final_data - ), - synchronized_data_attr_checks=test_case.synchronized_data_attr_checks, - most_voted_payload=test_case.most_voted_payload, - exit_event=test_case.event, - ) - ) - - -class TestCallCheckpointRound(BaseStakingRoundTestClass): - """Tests for CallCheckpointRound.""" - - round_class = CallCheckpointRound - - @pytest.mark.parametrize( - "test_case", - [ - RoundTestCase( - name="Happy path", - initial_data={}, - payloads=get_checkpoint_payloads( - { - "service_staking_state": StakingState.STAKED.value, - "tx_submitter": "dummy_submitter", - "tx_hash": "dummy_tx_hash", - "ts_checkpoint": 0, - "is_checkpoint_reached": True, - } - ), - final_data={ - "service_staking_state": StakingState.STAKED.value, - "tx_submitter": "dummy_submitter", - "tx_hash": "dummy_tx_hash", - "ts_checkpoint": 0, - "is_checkpoint_reached": True, - }, - event=Event.DONE, - most_voted_payload=DUMMY_SERVICE_STATE["tx_submitter"], - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.service_staking_state - == StakingState.STAKED.value, - lambda synchronized_data: synchronized_data.tx_submitter - == "dummy_submitter", - ], - ), - RoundTestCase( - name="Service not staked", - initial_data={}, - payloads=get_checkpoint_payloads(DUMMY_SERVICE_STATE), - final_data={}, - event=Event.SERVICE_NOT_STAKED, - most_voted_payload=DUMMY_SERVICE_STATE["tx_submitter"], - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.service_staking_state - == 0, - ], - ), - RoundTestCase( - name="Service evicted", - initial_data={}, - payloads=get_checkpoint_payloads( - { - "service_staking_state": StakingState.EVICTED.value, - "tx_submitter": "dummy_submitter", - "tx_hash": "dummy_tx_hash", - "ts_checkpoint": 0, - "is_checkpoint_reached": True, - } - ), - final_data={}, - event=Event.SERVICE_EVICTED, - most_voted_payload=DUMMY_SERVICE_STATE["tx_submitter"], - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.service_staking_state - == 0, - ], - ), - RoundTestCase( - name="Next checkpoint not reached", - initial_data={}, - payloads=get_checkpoint_payloads( - { - "service_staking_state": StakingState.STAKED.value, - "tx_submitter": "dummy_submitter", - "tx_hash": None, - "ts_checkpoint": 0, - "is_checkpoint_reached": True, - } - ), - final_data={}, - event=Event.NEXT_CHECKPOINT_NOT_REACHED_YET, - most_voted_payload=DUMMY_SERVICE_STATE["tx_submitter"], - synchronized_data_attr_checks=[ - lambda synchronized_data: synchronized_data.service_staking_state - == 0, - ], - ), - ], - ) - def test_run(self, test_case: RoundTestCase) -> None: - """Run the test.""" - - self.run_test(test_case) - - -class TestCheckpointCallPreparedRound: - """Tests for CheckpointCallPreparedRound.""" - - def test_checkpoint_call_prepared_round_initialization(self) -> None: - """Test the initialization of CheckpointCallPreparedRound.""" - round_ = CheckpointCallPreparedRound( - synchronized_data=MagicMock(), context=MagicMock() - ) - assert isinstance(round_, CheckpointCallPreparedRound) - - -class TestFinishedStakingRound: - """Tests for FinishedStakingRound.""" - - def test_finished_staking_round_initialization(self) -> None: - """Test the initialization of FinishedStakingRound.""" - round_ = FinishedStakingRound( - synchronized_data=MagicMock(), context=MagicMock() - ) - assert isinstance(round_, FinishedStakingRound) - - -class TestServiceEvictedRound: - """Tests for ServiceEvictedRound.""" - - def test_service_evicted_round_initialization(self) -> None: - """Test the initialization of ServiceEvictedRound.""" - round_ = ServiceEvictedRound(synchronized_data=MagicMock(), context=MagicMock()) - assert isinstance(round_, ServiceEvictedRound) - - -def test_staking_abci_app_initialization(abci_app: StakingAbciApp) -> None: - """Test the initialization of StakingAbciApp.""" - assert abci_app.initial_round_cls is CallCheckpointRound - assert abci_app.final_states == { - CheckpointCallPreparedRound, - FinishedStakingRound, - ServiceEvictedRound, - } - assert abci_app.transition_function == { - CallCheckpointRound: { - Event.DONE: CheckpointCallPreparedRound, - Event.SERVICE_NOT_STAKED: FinishedStakingRound, - Event.SERVICE_EVICTED: ServiceEvictedRound, - Event.NEXT_CHECKPOINT_NOT_REACHED_YET: FinishedStakingRound, - Event.ROUND_TIMEOUT: CallCheckpointRound, - Event.NO_MAJORITY: CallCheckpointRound, - }, - CheckpointCallPreparedRound: {}, - FinishedStakingRound: {}, - ServiceEvictedRound: {}, - } - assert abci_app.event_to_timeout == {Event.ROUND_TIMEOUT: 30.0} - assert abci_app.db_pre_conditions == {CallCheckpointRound: set()} - assert abci_app.db_post_conditions == { - CheckpointCallPreparedRound: { - get_name(SynchronizedData.tx_submitter), - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.service_staking_state), - get_name(SynchronizedData.previous_checkpoint), - get_name(SynchronizedData.is_checkpoint_reached), - }, - FinishedStakingRound: { - get_name(SynchronizedData.service_staking_state), - }, - ServiceEvictedRound: { - get_name(SynchronizedData.service_staking_state), - }, - } - - -DUMMY_PARTICIPANT_TO_CHECKPOINT = json.dumps( - { - "agent_0": {"sender": "agent_0", "data": "checkpoint_1"}, - "agent_1": {"sender": "agent_1", "data": "checkpoint_2"}, - } -) - - -@pytest.mark.parametrize( - "key,serialized_data,expected_result,property_to_check", - [ - ( - "participant_to_checkpoint", - DUMMY_PARTICIPANT_TO_CHECKPOINT, - json.loads(DUMMY_PARTICIPANT_TO_CHECKPOINT), - "participant_to_checkpoint", # Corresponds to _get_deserialized method - ), - ], -) -@patch( - "packages.valory.skills.staking_abci.rounds.CollectionRound.deserialize_collection" -) -def test_synchronized_data_get_deserialized( - mock_deserialize_collection: MagicMock, - key: str, - serialized_data: str, - expected_result: Mapping[str, Any], - property_to_check: str, -) -> None: - """Test the deserialization and property access in SynchronizedData.""" - # Mock the db.get_strict to return the serialized data - mock_db = mock.MagicMock() - mock_db.get_strict.return_value = serialized_data - - # Initialize SynchronizedData with the mocked db - synchronized_data = SynchronizedData(db=mock_db) - - # Mock the deserialize_collection function to return the expected deserialized result - mock_deserialize_collection.return_value = expected_result - - # Access the property using the appropriate property access method - deserialized_data = synchronized_data.participant_to_checkpoint - - # Ensure that get_strict is called with the correct key - mock_db.get_strict.assert_called_once_with(key) - - # Ensure that deserialize_collection is called with the correct serialized data - mock_deserialize_collection.assert_called_once_with(serialized_data) - assert deserialized_data == expected_result - - -def test_synchronized_data_tx_submitter() -> None: - """Test the tx_submitter property in SynchronizedData.""" - mock_db = mock.MagicMock() - mock_db.get_strict.return_value = "agent_0" - - synchronized_data = SynchronizedData(db=mock_db) - - assert synchronized_data.tx_submitter == "agent_0" - mock_db.get_strict.assert_called_once_with("tx_submitter") - - -def test_synchronized_data_service_staking_state() -> None: - """Test the service_staking_state property in SynchronizedData.""" - mock_db = mock.MagicMock() - mock_db.get.return_value = 0 - - synchronized_data = SynchronizedData(db=mock_db) - - staking_state = synchronized_data.service_staking_state - assert isinstance(staking_state, StakingState) - mock_db.get.assert_called_once_with("service_staking_state", 0) - - -def test_synchronized_data_initialization() -> None: - """Test the initialization and attributes of SynchronizedData.""" - data = SynchronizedData(db=AbciAppDB(setup_data={"test": ["test"]})) - assert data.db._data == {0: {"test": ["test"]}} diff --git a/trader_old/vendor/valory/skills/termination_abci/__init__.py b/trader_old/vendor/valory/skills/termination_abci/__init__.py deleted file mode 100644 index 787baac41..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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 the ABCI Termination skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/termination_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/termination_abci/behaviours.py b/trader_old/vendor/valory/skills/termination_abci/behaviours.py deleted file mode 100644 index 9e5e1ee1f..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/behaviours.py +++ /dev/null @@ -1,568 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2024 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 the termination behaviour classes.""" -import sys -from typing import Callable, Dict, Generator, List, Optional, Set, Type, cast - -from aea.protocols.base import Message -from hexbytes import HexBytes - -from packages.valory.contracts.gnosis_safe.contract import ( - GnosisSafeContract, - SafeOperation, -) -from packages.valory.contracts.multisend.contract import ( - MultiSendContract, - MultiSendOperation, -) -from packages.valory.contracts.service_registry.contract import ServiceRegistryContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - AsyncBehaviour, - BaseBehaviour, -) -from packages.valory.skills.abstract_round_abci.behaviours import AbstractRoundBehaviour -from packages.valory.skills.termination_abci.models import TerminationParams -from packages.valory.skills.termination_abci.payloads import BackgroundPayload -from packages.valory.skills.termination_abci.rounds import ( - BackgroundRound, - SynchronizedData, - TerminationAbciApp, - TerminationRound, -) -from packages.valory.skills.transaction_settlement_abci.behaviours import ( - TransactionSettlementRoundBehaviour, -) -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - hash_payload_to_hex, -) - - -# setting the safe gas to 0 means that all available gas will be used -# which is what we want in most cases -# more info here: https://safe-docs.dev.gnosisdev.com/safe/docs/contracts_tx_execution/ -_SAFE_GAS = 0 - -# hardcoded to 0 because we don't need to send any ETH when handing over multisig ownership -_ETHER_VALUE = 0 - -# payload to represent a non-existing event -_NO_EVENT_FOUND: Dict = {} - - -class BackgroundBehaviour(BaseBehaviour): - """A behaviour responsible for picking up the termination signal, it runs concurrently with other behaviours.""" - - matching_round = BackgroundRound - _service_owner_address: Optional[str] = None - - def async_act(self) -> Generator: - """ - Performs the termination logic. - - This method responsible for checking whether the on-chain termination signal is present. - When an agent picks up the termination signal, it prepares a multisend transaction, - on which the majority of agents in the service have to reach consensus on. - - :return: None - :yield: None - """ - if not self._is_majority_possible() or self._is_termination_majority(): - # if the service has not enough participants to reach - # consensus or if termination majority has already - # been reached, ie the multisend transaction has been - # prepared by enough participants, - # there is no need to run the rest of the act - return - - signal_present = yield from self.check_for_signal() - if signal_present is None: - # if the response is None, something went wrong - self.context.logger.error("Failed checking the termination signal.") - return - if not signal_present: - # the signal is not present, so we sleep and try again - yield from self.sleep(self.params.termination_sleep) - return - - self.context.logger.info( - "Termination signal was picked up, preparing termination transaction." - ) - - background_data = yield from self.get_multisend_payload() - if background_data is None: - self.context.logger.error( - "Couldn't prepare multisend transaction for termination." - ) - return - - self.context.logger.info("Successfully prepared termination multisend tx.") - termination_payload = BackgroundPayload( - self.context.agent_address, background_data=background_data - ) - yield from self.send_a2a_transaction(termination_payload) - yield from self.wait_for_termination_majority() - - @property - def synchronized_data(self) -> SynchronizedData: - """ - Return the synchronized data. - - Note: we instantiate here, rather than cast, as this runs - concurrently and so the instantiation needs to happen somewhere. - """ - return SynchronizedData(db=super().synchronized_data.db) - - @property - def params(self) -> TerminationParams: - """Return the params.""" - return cast(TerminationParams, super().params) - - def check_for_signal(self) -> Generator[None, None, Optional[bool]]: - """ - This method checks for the termination signal. - - We check for the signal by looking at the "SafeReceived" events on the safe contract. - https://github.com/safe-global/safe-contracts/blob/v1.3.0/contracts/common/EtherPaymentFallback.sol#L10 - In order for an SafeReceived event to qualify as a termination signal it has to fulfill the following: - 1. It MUST be sent by the service owner (self._service_owner). - 2. It MUST be 0 value tx. - - :returns: True if the termination signal is found, false otherwise - """ - if self._service_owner_address is None: - self._service_owner_address = yield from self._get_service_owner() - - termination_signal = yield from self._get_latest_termination_signal() - if termination_signal is None: - # something went wrong, we stop executing the rest of the logic - return None - if termination_signal == _NO_EVENT_FOUND: - # no termination signal has ever been sent to safe - return False - - service_owner_removal = yield from self._get_latest_removed_owner_event() - if service_owner_removal is None: - # something went wrong, we stop executing the rest of the logic - return None - if service_owner_removal == _NO_EVENT_FOUND: - # the service owner has never been removed from the safe - # this means that the observed `termination_signal` is the - # first termination signal ever sent to this safe contract - # as such it is valid signal for terminating the service - return True - - # if both the `termination_signal` and the `service_owner` removal events are present, - # we need to make sure this is not a previous termination that is already taken care of - # if a termination has been previously made, we assume that: - # 1. the service owner has been previously set as the safe owner - # 2. since the service is running again, the ownership of the safe has been handed back to the agent instances - # for 2. to happen, the service owner needs to be removed from being an owner of the safe. When this is done, - # a `RemovedOwner` event is thrown, which is what `_get_latest_removed_owner_event()` captures. - - termination_signal_occurrence = int(termination_signal["block_number"]) - service_owner_removal_occurrence = int(service_owner_removal["block_number"]) - - # if the termination signal has occurred after the owner has been removed the service should terminate, - # otherwise it's a signal that has already been handled previously - return termination_signal_occurrence > service_owner_removal_occurrence - - def _get_latest_removed_owner_event(self) -> Generator[None, None, Optional[Dict]]: - """Returns the latest event in which the service owner was removed from the set of owners of the safe.""" - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_removed_owner_events", - contract_address=self.synchronized_data.safe_contract_address, - removed_owner=self._service_owner_address, - from_block=self.params.termination_from_block, - chain_id=self.params.default_chain_id, - ) - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get the latest `RemovedOwner` event. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - removed_owner_events = cast(List[Dict], response.state.body.get("data")) - if len(removed_owner_events) == 0: - return _NO_EVENT_FOUND - - latest_removed_owner_event = removed_owner_events[0] - for removed_owner_event in removed_owner_events[1:]: - if int(removed_owner_event["block_number"]) > int( - latest_removed_owner_event["block_number"] - ): - latest_removed_owner_event = removed_owner_event - - return latest_removed_owner_event - - def _get_latest_termination_signal(self) -> Generator[None, None, Optional[Dict]]: - """Get the latest termination signal sent by the service owner.""" - self.context.logger.info( - f"Retrieving termination events on chain '{self.params.default_chain_id}' from block {self.params.termination_from_block}" - ) - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_zero_transfer_events", - contract_address=self.synchronized_data.safe_contract_address, - sender_address=self._service_owner_address, - from_block=self.params.termination_from_block, - chain_id=self.params.default_chain_id, - ) - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get the latest Zero Transfer (`SafeReceived`) event. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - zero_transfer_events = cast(List[Dict], response.state.body.get("data")) - if len(zero_transfer_events) == 0: - return _NO_EVENT_FOUND - - latest_zero_transfer_event = zero_transfer_events[0] - for zero_transfer_event in zero_transfer_events[1:]: - if int(zero_transfer_event["block_number"]) > int( - latest_zero_transfer_event["block_number"] - ): - latest_zero_transfer_event = zero_transfer_event - - return latest_zero_transfer_event - - def _get_service_owner(self) -> Generator[None, None, Optional[str]]: - """Method that returns the service owner.""" - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_id=str(ServiceRegistryContract.contract_id), - contract_callable="get_service_owner", - contract_address=self.params.service_registry_address, - service_id=self.params.on_chain_service_id, - chain_id=self.params.default_chain_id, - ) - - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get the service owner for service with id={self.params.on_chain_service_id}. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - service_owner = cast( - Optional[str], response.state.body.get("service_owner", None) - ) - return service_owner - - def get_multisend_payload(self) -> Generator[None, None, Optional[str]]: - """Prepares and returns the multisend to hand over safe ownership to the service_owner.""" - multisend_data_str = yield from self._get_multisend_tx() - if multisend_data_str is None: - return None - multisend_data = bytes.fromhex(multisend_data_str) - tx_hash = yield from self._get_safe_tx_hash(multisend_data) - if tx_hash is None: - return None - - payload_data = hash_payload_to_hex( - safe_tx_hash=tx_hash, - ether_value=_ETHER_VALUE, - safe_tx_gas=_SAFE_GAS, - operation=SafeOperation.DELEGATE_CALL.value, - to_address=self.params.multisend_address, - data=multisend_data, - ) - return payload_data - - def _get_safe_owners(self) -> Generator[None, None, Optional[List[str]]]: - """Retrieves safe owners.""" - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_owners", - contract_address=self.synchronized_data.safe_contract_address, - chain_id=self.params.default_chain_id, - ) - - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get the safe owners for safe deployed at {self.synchronized_data.safe_contract_address}. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - owners = cast(Optional[List[str]], response.state.body.get("owners", None)) - return owners - - def _get_remove_owner_tx( - self, owner: str, threshold: int - ) -> Generator[None, None, Optional[str]]: - """ - Gets a remove owner tx. - - :param owner: the owner to be removed. - :param threshold: the new safe threshold to be set. - :return: the tx data - """ - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_remove_owner_data", - contract_address=self.synchronized_data.safe_contract_address, - owner=owner, - threshold=threshold, - chain_id=self.params.default_chain_id, - ) - - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get a remove owner tx. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - # strip "0x" from the response - tx_data = cast(str, response.state.body.get("data", None))[2:] - return tx_data - - def _get_swap_owner_tx( - self, old_owner: str, new_owner: str - ) -> Generator[None, None, Optional[str]]: - """ - Gets a swap owner tx. - - :param old_owner: the owner to be removed. - :param new_owner: the new safe threshold to be set. - :return: the tx data - """ - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_swap_owner_data", - contract_address=self.synchronized_data.safe_contract_address, - old_owner=old_owner, - new_owner=new_owner, - chain_id=self.params.default_chain_id, - ) - - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get a swap owner tx. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - # strip "0x" from the response - tx_data = cast(str, response.state.body.get("data", None))[2:] - return tx_data - - def _get_safe_tx_hash(self, data: bytes) -> Generator[None, None, Optional[str]]: - """ - Prepares and returns the safe tx hash. - - :param data: the safe tx data. - :return: the tx hash - """ - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_raw_safe_transaction_hash", - to_address=self.params.multisend_address, - value=_ETHER_VALUE, - data=data, - safe_tx_gas=_SAFE_GAS, - operation=SafeOperation.DELEGATE_CALL.value, - chain_id=self.params.default_chain_id, - ) - - if response.performative != ContractApiMessage.Performative.STATE: - self.context.logger.error( - f"Couldn't get safe hash. " - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - # strip "0x" from the response hash - tx_hash = cast(str, response.state.body["tx_hash"])[2:] - return tx_hash - - def _get_multisend_tx(self) -> Generator[None, None, Optional[str]]: - """This method compiles a multisend transaction to give ownership of the safe contract to the service owner.""" - transactions: List[Dict] = [] - threshold = 1 - safe_owners = yield from self._get_safe_owners() - if safe_owners is None: - return None - owner_to_be_swapped = safe_owners[0] - # we remove all but one safe owner - # reverse the list to avoid errors when removing owners - # this is because the owners are stored as a linked list - # in the safe, hence the order is important - safe_owners = list(reversed(safe_owners[1:])) - for owner in safe_owners: - # we generate a tx to remove the current owner - remove_tx_str = yield from self._get_remove_owner_tx(owner, threshold) - if remove_tx_str is None: - return None - remove_tx = bytes.fromhex(remove_tx_str) - # we append it to the list of the multisend txs - transactions.append( - { - "operation": MultiSendOperation.CALL, - "to": self.synchronized_data.safe_contract_address, - "value": _ETHER_VALUE, - "data": HexBytes(remove_tx), - } - ) - - if owner_to_be_swapped != cast(str, self._service_owner_address): - # if the service owner is not the owner to be swapped - # we swap, otherwise it's not necessary - swap_tx = yield from self._get_swap_owner_tx( - owner_to_be_swapped, - cast(str, self._service_owner_address), - ) - if swap_tx is None: - return None - - transactions.append( - { - "operation": MultiSendOperation.CALL, - "to": self.synchronized_data.safe_contract_address, - "value": _ETHER_VALUE, - "data": HexBytes(swap_tx), - } - ) - - response = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.params.multisend_address, - contract_id=str(MultiSendContract.contract_id), - contract_callable="get_tx_data", - multi_send_txs=transactions, - chain_id=self.params.default_chain_id, - ) - if response.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.context.logger.error( - f"Couldn't compile the multisend tx. " - f"Expected response performative {ContractApiMessage.Performative.RAW_TRANSACTION.value}, " # type: ignore - f"received {response.performative.value}." - ) - return None - - # strip "0x" from the response - multisend_data = cast(str, response.raw_transaction.body["data"])[2:] - return multisend_data - - def wait_for_termination_majority(self) -> Generator: - """ - Wait until we reach majority on the termination transaction. - - :yield: None - """ - yield from self.wait_for_condition(self._is_termination_majority) - - def _is_termination_majority(self) -> bool: - """Rely on the round to decide when majority is reached.""" - return self.synchronized_data.termination_majority_reached - - def _is_majority_possible(self) -> bool: - """Checks whether the service has enough participants to reach consensus.""" - return ( - self.synchronized_data.nb_participants - >= self.synchronized_data.consensus_threshold - ) - - def get_callback_request(self) -> Callable[[Message, "BaseBehaviour"], None]: - """Wrapper for callback_request(), overridden to avoid mix-ups with normal (non-background) behaviours.""" - - def callback_request( - message: Message, _current_behaviour: BaseBehaviour - ) -> None: - """ - This method gets called when a response for a prior request is received. - - Overridden to remove the check that checks whether the behaviour that made the request is still active. - The received message gets passed to the behaviour that invoked it, in this case it's always the - background behaviour. - - :param message: the response. - :param _current_behaviour: not used, left in to satisfy the interface. - :return: none - """ - if self.is_stopped: - self.context.logger.info( - "dropping message as behaviour has stopped: %s", message - ) - return - - if self.state != AsyncBehaviour.AsyncState.WAITING_MESSAGE: - self.context.logger.warning( - f"could not send message {message} to {self.behaviour_id}" - ) - return - - self.try_send(message) - - return callback_request - - def is_round_ended(self, round_id: str) -> Callable[[], bool]: - """ - Get a callable to check whether the current round has ended. - - We consider the background round ended when we have majority on the termination transaction. - Overriden to allow for the behaviour to send transactions at any time. - - :return: the termination majority callable - """ - return self._is_termination_majority - - -class TerminationBehaviour(BaseBehaviour): - """Behaviour responsible for terminating the agent.""" - - matching_round = TerminationRound - - def async_act(self) -> Generator: - """Logs termination and terminates.""" - self.context.logger.info("Terminating the agent.") - sys.exit() - yield - - -class TerminationAbciBehaviours(AbstractRoundBehaviour): - """This class defines the behaviours required in terminating a service.""" - - initial_behaviour_cls = TransactionSettlementRoundBehaviour.initial_behaviour_cls - abci_app_cls = TerminationAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - BackgroundBehaviour, # type: ignore - TerminationBehaviour, # type: ignore - *TransactionSettlementRoundBehaviour.behaviours, - } diff --git a/trader_old/vendor/valory/skills/termination_abci/dialogues.py b/trader_old/vendor/valory/skills/termination_abci/dialogues.py deleted file mode 100644 index 9ea32cd87..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/dialogues.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_old/vendor/valory/skills/termination_abci/handlers.py b/trader_old/vendor/valory/skills/termination_abci/handlers.py deleted file mode 100644 index d2e76dd11..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/handlers.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 the handler for the Termination skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIHandler = BaseABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_old/vendor/valory/skills/termination_abci/models.py b/trader_old/vendor/valory/skills/termination_abci/models.py deleted file mode 100644 index 2e7c2b2fe..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/models.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2024 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 the shared state for TerminationAbci.""" - -from typing import Any - -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.termination_abci.rounds import TerminationAbciApp -from packages.valory.skills.transaction_settlement_abci.models import ( - RandomnessApi as TransactionSettlementRandomness, -) -from packages.valory.skills.transaction_settlement_abci.models import TransactionParams - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = TerminationAbciApp - - -class TerminationParams(TransactionParams): - """Defines the class to hold the termination parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Set up the termination parameters.""" - self.termination_sleep: int = self._ensure("termination_sleep", kwargs, int) - self.multisend_address: str = self._ensure("multisend_address", kwargs, str) - self.termination_from_block: int = self._ensure( - "termination_from_block", kwargs, int - ) - super().__init__(*args, **kwargs) - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool -RandomnessApi = TransactionSettlementRandomness diff --git a/trader_old/vendor/valory/skills/termination_abci/payloads.py b/trader_old/vendor/valory/skills/termination_abci/payloads.py deleted file mode 100644 index f384da563..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/payloads.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 the termination payload classes.""" - -from dataclasses import dataclass - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class BackgroundPayload(BaseTxPayload): - """Defines the background round payload.""" - - background_data: str diff --git a/trader_old/vendor/valory/skills/termination_abci/rounds.py b/trader_old/vendor/valory/skills/termination_abci/rounds.py deleted file mode 100644 index b11cece66..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/rounds.py +++ /dev/null @@ -1,192 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2024 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 the termination round classes.""" - -from enum import Enum -from typing import Dict, Optional, Set, Tuple, cast - -from packages.valory.skills.abstract_round_abci.abci_app_chain import ( - AbciAppTransitionMapping, - chain, -) -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciApp, - AbstractRound, - AppState, - BaseSynchronizedData, - BaseTxPayload, - CollectSameUntilThresholdRound, - TransactionNotValidError, - get_name, -) -from packages.valory.skills.termination_abci.payloads import BackgroundPayload -from packages.valory.skills.transaction_settlement_abci.rounds import ( - FailedRound, - FinishedTransactionSubmissionRound, - TransactionSubmissionAbciApp, -) - - -class Event(Enum): - """Defines the (background) round events.""" - - TERMINATE = "terminate" - - -class SynchronizedData(BaseSynchronizedData): - """ - Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - @property - def termination_majority_reached(self) -> bool: - """Get termination_majority_reached.""" - return cast(bool, self.db.get("termination_majority_reached", False)) - - @property - def most_voted_tx_hash(self) -> str: - """Get the most_voted_tx_hash.""" - return cast(str, self.db.get_strict("most_voted_tx_hash")) # pragma: no cover - - @property - def chain_id(self) -> Optional[str]: - """Get the chain name where to send the transactions to.""" - return cast(str, self.db.get("chain_id", None)) - - -class BackgroundRound(CollectSameUntilThresholdRound): - """Defines the background round, which runs concurrently with other rounds.""" - - payload_class = BackgroundPayload - synchronized_data_class = SynchronizedData - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - # for background round payloads, we don't need to check the round_count, as round_count is irrelevant for the - # background since it's running concurrently in the background. - sender = payload.sender - if sender not in self.accepting_payloads_from: - raise ABCIAppInternalError( - f"{sender} not in list of participants: {sorted(self.accepting_payloads_from)}" - ) - - if sender in self.collection: - raise ABCIAppInternalError( - f"sender {sender} has already sent value for round: {self.round_id}" - ) - - self.collection[sender] = payload - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check Payload""" - # NOTE: the TransactionNotValidError is intercepted in ABCIRoundHandler.deliver_tx - # which means it will be logged instead of raised - # for background round payloads, we don't need to check the round_count, as round_count is irrelevant for the - # background since it's running concurrently in the background. - sender_in_participant_set = payload.sender in self.accepting_payloads_from - if not sender_in_participant_set: - raise TransactionNotValidError( - f"{payload.sender} not in list of participants: {sorted(self.accepting_payloads_from)}" - ) - - if payload.sender in self.collection: - raise TransactionNotValidError( - f"sender {payload.sender} has already sent value for round: {self.round_id}" - ) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - if self.threshold_reached: - state = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{ - get_name(SynchronizedData.termination_majority_reached): True, - get_name( - SynchronizedData.most_voted_tx_hash - ): self.most_voted_payload, - get_name( - SynchronizedData.chain_id - ): self.context.params.default_chain_id, - }, - ) - return state, Event.TERMINATE - - return None - - -class TerminationRound(AbstractRound): - """Round to act as the counterpart of the behaviour responsible for terminating the agent.""" - - payload_class = None - synchronized_data_class = SynchronizedData - - def check_payload(self, payload: BaseTxPayload) -> None: - """No logic required here.""" - - def process_payload(self, payload: BaseTxPayload) -> None: - """No logic required here.""" - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """No logic required here.""" - return None - - -class PostTerminationTxAbciApp(AbciApp[Event]): - """PostTerminationTxAbciApp - - Initial round: TerminationRound - - Initial states: {TerminationRound} - - Transition states: - 0. TerminationRound - - terminate: 0. - - Final states: {} - - Timeouts: - - """ - - initial_round_cls = TerminationRound - # the following is not needed, it is added to satisfy the round check - # the TerminationRound when run it terminates the agent, so nothing can come after it - transition_function = {TerminationRound: {Event.TERMINATE: TerminationRound}} - db_pre_conditions: Dict[AppState, Set[str]] = {TerminationRound: set()} - - -termination_transition_function: AbciAppTransitionMapping = { - FinishedTransactionSubmissionRound: PostTerminationTxAbciApp.initial_round_cls, - FailedRound: TransactionSubmissionAbciApp.initial_round_cls, -} -TerminationAbciApp = chain( - ( - TransactionSubmissionAbciApp, - PostTerminationTxAbciApp, - ), - termination_transition_function, -) - -TerminationAbciApp.transition_function[BackgroundRound] = { - Event.TERMINATE: TransactionSubmissionAbciApp.initial_round_cls, -} diff --git a/trader_old/vendor/valory/skills/termination_abci/skill.yaml b/trader_old/vendor/valory/skills/termination_abci/skill.yaml deleted file mode 100644 index 4206159ce..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/skill.yaml +++ /dev/null @@ -1,155 +0,0 @@ -name: termination_abci -author: valory -version: 0.1.0 -type: skill -description: Termination skill. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeidztixckwwbn4ujl6kkvghgsk23xecbgnbiw3e4t3owxldhyjo3au - behaviours.py: bafybeihd7m2w5bzqj24rlpnyyxa4xt72ebcgmnvonwjexygvs4xyaqxdeu - dialogues.py: bafybeif7uhfjkcz3ryhti6gafqxhvciw4ec5bdshxvq3355tun5ydkzrna - handlers.py: bafybeibh5b3p4bdvbnwiqwormduqjvuievylb3s2wgj4ald4led7gx2kji - models.py: bafybeihak6dcfqpjxbryeixksdn5lbdifq5ondzlh4wiweoptzzn42wco4 - payloads.py: bafybeihbwfunongkws5lck67sdgpnytq6bdbiv22yuehmyfth4qeypjcpa - rounds.py: bafybeifouwd4dv6ummirb45e7qxnyyadg2bsrl4kx6xbr6rvodz3lsqgqa - tests/__init__.py: bafybeigsjjibb2gcybzp5yrsy25vyiu54rw6oaeyw5onaqemsvul7bmroi - tests/test_behaviours.py: bafybeibkogjosxk6ktneru5ddgzguuiw2wuvx2n63d3rpyqhoy7llnoc5i - tests/test_dialogues.py: bafybeicb6gfanfyt3wiq3svdlvtxiuzpk72oxp7cfdeq4ezed7ixee5yae - tests/test_handlers.py: bafybeiefz2ebr5rlyxziwr4bts2r75abpqgji3k47a6hnrj7e7t2yvgmpu - tests/test_models.py: bafybeih5wtdjuv4hc25fxneeg7mgjiks55xj353zxfamvtrthkw2ydmbbe - tests/test_payloads.py: bafybeibai4dzjjdeyeinyirjndcfzbj2qst6roj6prjvcqwut5m3won3fa - tests/test_rounds.py: bafybeiafy4hqww4qqjfd7wrqhnezf47n66pnodect6hquf4bpkrwiqmufq -fingerprint_ignore_patterns: [] -connections: [] -contracts: -- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge -- valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y -- valory/service_registry:0.1.0:bafybeiaop64kwdoetxtedoehabmsalojmms7ihuoqcdwxtwb2hk5i6bzye -protocols: -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae -behaviours: - main: - args: {} - class_name: TerminationAbciBehaviours -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - finalize_timeout: 60.0 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - history_check_timeout: 1205 - init_fallback_gas: 0 - ipfs_domain_name: null - keeper_allowed_retries: 3 - keeper_timeout: 30.0 - light_slash_unit_amount: 5000000000000000 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761' - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 30.0 - serious_slash_unit_amount: 8000000000000000 - service_id: termination_abci - service_registry_address: '0x48b6af7B12C71f09e2fC8aF4855De4Ff54e775cA' - setup: {} - share_tm_config_on_startup: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - sleep_time: 1 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - termination_from_block: 0 - termination_sleep: 900 - tx_timeout: 10.0 - use_slashing: false - use_termination: false - validate_timeout: 1205 - class_name: TerminationParams - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: - hexbytes: {} -is_abstract: true -customs: [] diff --git a/trader_old/vendor/valory/skills/termination_abci/tests/__init__.py b/trader_old/vendor/valory/skills/termination_abci/tests/__init__.py deleted file mode 100644 index 9c9c65fc1..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/tests/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/termination_abci skill.""" diff --git a/trader_old/vendor/valory/skills/termination_abci/tests/test_behaviours.py b/trader_old/vendor/valory/skills/termination_abci/tests/test_behaviours.py deleted file mode 100644 index eaf3f13f7..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/tests/test_behaviours.py +++ /dev/null @@ -1,649 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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 package contains round behaviours of Background Behaviours.""" - -import logging -import platform -from dataclasses import dataclass -from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Type -from unittest import mock - -import pytest - -from packages.valory.contracts.gnosis_safe.contract import GnosisSafeContract -from packages.valory.contracts.multisend.contract import MultiSendContract -from packages.valory.contracts.service_registry.contract import ServiceRegistryContract -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.contract_api.custom_types import RawTransaction, State -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.behaviour_utils import AsyncBehaviour -from packages.valory.skills.abstract_round_abci.behaviours import BaseBehaviour -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.termination_abci import PUBLIC_ID -from packages.valory.skills.termination_abci.behaviours import ( - BackgroundBehaviour, - TerminationAbciBehaviours, - TerminationBehaviour, -) -from packages.valory.skills.termination_abci.rounds import Event, SynchronizedData -from packages.valory.skills.transaction_settlement_abci.behaviours import ( - TransactionSettlementRoundBehaviour, -) - - -SERVICE_REGISTRY_ADDRESS = "0x48b6af7B12C71f09e2fC8aF4855De4Ff54e775cA" -SAFE_ADDRESS = "0x0" -MULTISEND_ADDRESS = "0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761" -SERVICE_OWNER_ADDRESS = "0x0" -SERVICE_ID = None - - -def test_skill_public_id() -> None: - """Test skill module public ID""" - - # pylint: disable=no-member - assert PUBLIC_ID.name == Path(__file__).parents[1].name - assert PUBLIC_ID.author == Path(__file__).parents[3].name - - -@dataclass -class BehaviourTestCase: - """BehaviourTestCase""" - - name: str - initial_data: Dict[str, Any] - ok_reqs: List[Callable] - err_reqs: List[Callable] - expected_log: str - expected_log_level: int - - -class BaseTerminationTest(FSMBehaviourBaseCase): - """Base test case.""" - - path_to_skill = Path(__file__).parents[1] - - behaviour: TerminationAbciBehaviours - behaviour_class: Type[BaseBehaviour] - next_behaviour_class: Type[ - BaseBehaviour - ] = TransactionSettlementRoundBehaviour.initial_behaviour_cls - synchronized_data: SynchronizedData - done_event = Event.TERMINATE - - def fast_forward(self, data: Optional[Dict[str, Any]] = None) -> None: - """Fast-forward on initialization""" - - data = data or {} - self.fast_forward_to_behaviour( - self.behaviour, - self.behaviour_class.auto_behaviour_id(), - SynchronizedData(AbciAppDB(setup_data=AbciAppDB.data_to_lists(data))), - ) - assert ( - self.behaviour.current_behaviour is not None - and self.behaviour.current_behaviour.behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - - def complete(self) -> None: - """Complete test""" - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self.end_round(done_event=self.done_event) - assert ( - self.behaviour.current_behaviour is not None - and self.behaviour.current_behaviour.behaviour_id - == self.next_behaviour_class.auto_behaviour_id() - ) - - -class TestBackgroundBehaviour(BaseTerminationTest): - """Test the background behaviour.""" - - behaviour_class = BackgroundBehaviour - next_behaviour_class = TransactionSettlementRoundBehaviour.initial_behaviour_cls - - # when the service owner ordered termination - _ZERO_TRANSFER_EVENTS = [ - {"block_number": 1}, - {"block_number": 10}, - {"block_number": 20}, - ] - _NUM_ZERO_TRANSFER_EVENTS = len(_ZERO_TRANSFER_EVENTS) - # when the service owner got removed from being a safe owner - # this happens when the operators take over the safe again - _SERVICE_OWNER_REMOVED_EVENTS = [ - {"block_number": 2}, - {"block_number": 11}, - ] - _NUM_SERVICE_OWNER_REMOVED_EVENTS = len(_SERVICE_OWNER_REMOVED_EVENTS) - _SAFE_OWNERS = ["0x1", "0x2", "0x3", "0x4"] - _NUM_SAFE_OWNERS = len(_SAFE_OWNERS) - _SAFE_THRESHOLD = 1 - _MOCK_TX_RESPONSE = b"0xIrrelevantForTests".hex() - _MOCK_TX_HASH = "0x" + "0" * 64 - _INITIAL_DATA: Dict[str, Any] = dict( - all_participants=_SAFE_OWNERS, - safe_contract_address=SAFE_ADDRESS, - participants=_SAFE_OWNERS, - consensus_threshold=3, - ) - - _STATE_ERR_LOG = ( - f"Expected response performative {ContractApiMessage.Performative.STATE.value}, " # type: ignore - f"received {ContractApiMessage.Performative.ERROR}." - ) - _RAW_TRANSACTION_ERR = ( - f"Expected response performative {ContractApiMessage.Performative.RAW_TRANSACTION.value}, " # type: ignore - f"received {ContractApiMessage.Performative.ERROR}." - ) - _SERVICE_OWNER_ERR_LOG = ( - f"Couldn't get the service owner for service with id={SERVICE_ID}. " - f"{_STATE_ERR_LOG}" - ) - _ZERO_TRANSFER_EVENTS_ERR_LOG = ( - f"Couldn't get the latest Zero Transfer (`SafeReceived`) event. " - f"{_STATE_ERR_LOG}" - ) - _SERVICE_OWNER_REMOVED_EVENTS_ERR_LOG = ( - f"Couldn't get the latest `RemovedOwner` event. " f"{_STATE_ERR_LOG}" - ) - _SAFE_OWNERS_ERR_LOG = ( - f"Couldn't get the safe owners for safe deployed at {SAFE_ADDRESS}. " - f"{_STATE_ERR_LOG}" - ) - _REMOVE_OWNER_ERR_LOG = f"Couldn't get a remove owner tx. " f"{_STATE_ERR_LOG}" - _SWAP_OWNER_ERR_LOG = f"Couldn't get a swap owner tx. " f"{_STATE_ERR_LOG}" - _SAFE_HASH_ERR_LOG = f"Couldn't get safe hash. " f"{_STATE_ERR_LOG}" - _MULTISEND_ERR_LOG = "Couldn't compile the multisend tx. " - _SUCCESS_LOG = "Successfully prepared termination multisend tx." - _IS_STOPPED_LOG = "dropping message as behaviour has stopped:" - _IS_NOT_WAITING_MESSAGE = "could not send message" - - def _mock_get_service_owner_request( - self, - error: bool = False, - ) -> None: - """Mock a ServiceRegistryContract.get_service_owner() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(service_owner=SERVICE_OWNER_ADDRESS) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - - self.mock_contract_api_request( - contract_id=str(ServiceRegistryContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SERVICE_REGISTRY_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_zero_transfer_events_request( - self, - error: bool = False, - num_events: int = _NUM_ZERO_TRANSFER_EVENTS, - ) -> None: - """Mock a GnosisSafeContract.get_zero_transfer_events() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(data=self._ZERO_TRANSFER_EVENTS[:num_events]) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - self.mock_contract_api_request( - contract_id=str(GnosisSafeContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SAFE_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_removed_owner_events_request( - self, - error: bool = False, - num_events: int = _NUM_SERVICE_OWNER_REMOVED_EVENTS, - ) -> None: - """Mock a GnosisSafeContract.get_removed_owner_events() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(data=self._SERVICE_OWNER_REMOVED_EVENTS[:num_events]) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - - self.mock_contract_api_request( - contract_id=str(GnosisSafeContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SAFE_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_owners_request( - self, - error: bool = False, - ) -> None: - """Mock a GnosisSafeContract.get_owners() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(owners=self._SAFE_OWNERS) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - self.mock_contract_api_request( - contract_id=str(GnosisSafeContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SAFE_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_remove_owner_data_request(self, error: bool = False) -> None: - """Mock a GnosisSafeContract.get_remove_owner_data() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(data=self._MOCK_TX_RESPONSE) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - self.mock_contract_api_request( - contract_id=str(GnosisSafeContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SAFE_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_swap_owner_data_request( - self, - error: bool = False, - ) -> None: - """Mock a GnosisSafeContract.get_swap_owner_data() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(data=self._MOCK_TX_RESPONSE) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - self.mock_contract_api_request( - contract_id=str(GnosisSafeContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SAFE_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_raw_safe_transaction_hash_request( - self, - error: bool = False, - ) -> None: - """Mock a GnosisSafeContract.get_raw_safe_transaction_hash() request.""" - if not error: - response_performative = ContractApiMessage.Performative.STATE - response_body = dict(tx_hash=self._MOCK_TX_HASH) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - self.mock_contract_api_request( - contract_id=str(GnosisSafeContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE, - contract_address=SAFE_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - state=State( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_get_tx_data_request( - self, - error: bool = False, - ) -> None: - """Mock a MultiSendContract.get_tx_data() request.""" - if not error: - response_performative = ContractApiMessage.Performative.RAW_TRANSACTION - response_body = dict(data=self._MOCK_TX_RESPONSE) - else: - response_body = dict() - response_performative = ContractApiMessage.Performative.ERROR - self.mock_contract_api_request( - contract_id=str(MultiSendContract.contract_id), - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=MULTISEND_ADDRESS, - ), - response_kwargs=dict( - performative=response_performative, - raw_transaction=RawTransaction( - ledger_id="ethereum", - body=response_body, - ), - ), - ) - - def _mock_is_stopped( # pylint: disable=unused-argument, disable=protected-access - self, - error: bool = False, - ) -> None: - """Mock a MultiSendContract.get_tx_data() request.""" - assert self.behaviour.current_behaviour is not None - self.behaviour.current_behaviour._AsyncBehaviour__stopped = True - - def _mock_state_is_not_waiting_message( # pylint: disable=unused-argument, disable=protected-access - self, - error: bool = False, - ) -> None: - """Mock a MultiSendContract.get_tx_data() request.""" - assert self.behaviour.current_behaviour is not None - self.behaviour.current_behaviour._AsyncBehaviour__state = ( - AsyncBehaviour.AsyncState.RUNNING - ) - - @pytest.mark.parametrize( - "test_case", - [ - BehaviourTestCase( - name="agent fails to get the service owner", - initial_data=_INITIAL_DATA, - ok_reqs=[], - err_reqs=[_mock_get_service_owner_request], - expected_log=_SERVICE_OWNER_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to get zero transfer event", - initial_data=_INITIAL_DATA, - ok_reqs=[_mock_get_service_owner_request], - err_reqs=[_mock_get_zero_transfer_events_request], - expected_log=_ZERO_TRANSFER_EVENTS_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to get owner removal event", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - ], - err_reqs=[_mock_get_removed_owner_events_request], - expected_log=_SERVICE_OWNER_REMOVED_EVENTS_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to get the safe owners", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - _mock_get_removed_owner_events_request, - ], - err_reqs=[_mock_get_owners_request], - expected_log=_SAFE_OWNERS_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to get a remove safe owner tx", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - _mock_get_removed_owner_events_request, - _mock_get_owners_request, - ], - err_reqs=[_mock_get_remove_owner_data_request], - expected_log=_REMOVE_OWNER_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to get a swap safe owner tx", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - _mock_get_removed_owner_events_request, - _mock_get_owners_request, - *[_mock_get_remove_owner_data_request] * (_NUM_SAFE_OWNERS - 1), - ], - err_reqs=[_mock_get_swap_owner_data_request], - expected_log=_SWAP_OWNER_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to prepare multisend tx", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - _mock_get_removed_owner_events_request, - _mock_get_owners_request, - *[_mock_get_remove_owner_data_request] * (_NUM_SAFE_OWNERS - 1), - _mock_get_swap_owner_data_request, - ], - err_reqs=[_mock_get_tx_data_request], - expected_log=_MULTISEND_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent fails to get a hash for the multisend tx", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - _mock_get_removed_owner_events_request, - _mock_get_owners_request, - *[_mock_get_remove_owner_data_request] * (_NUM_SAFE_OWNERS - 1), - _mock_get_swap_owner_data_request, - _mock_get_tx_data_request, - ], - err_reqs=[_mock_get_raw_safe_transaction_hash_request], - expected_log=_SAFE_HASH_ERR_LOG, - expected_log_level=logging.ERROR, - ), - BehaviourTestCase( - name="agent completes the whole flow", - initial_data=_INITIAL_DATA, - ok_reqs=[ - _mock_get_service_owner_request, - _mock_get_zero_transfer_events_request, - _mock_get_removed_owner_events_request, - _mock_get_owners_request, - *[_mock_get_remove_owner_data_request] * (_NUM_SAFE_OWNERS - 1), - _mock_get_swap_owner_data_request, - _mock_get_tx_data_request, - _mock_get_raw_safe_transaction_hash_request, - ], - err_reqs=[], - expected_log=_SUCCESS_LOG, - expected_log_level=logging.INFO, - ), - BehaviourTestCase( - name="agent drops message because app already stopped", - initial_data=_INITIAL_DATA, - ok_reqs=[], - err_reqs=[ - _mock_is_stopped, - _mock_get_service_owner_request, - ], - expected_log=_IS_STOPPED_LOG, - expected_log_level=logging.INFO, - ), - BehaviourTestCase( - name="agent could not send message because state != WAITING_MESSAGE", - initial_data=_INITIAL_DATA, - ok_reqs=[], - err_reqs=[ - _mock_state_is_not_waiting_message, - _mock_get_service_owner_request, - ], - expected_log=_IS_NOT_WAITING_MESSAGE, - expected_log_level=logging.WARNING, - ), - ], - ) - def test_run(self, test_case: BehaviourTestCase) -> None: - """Test multiple paths of termination.""" - self.fast_forward(data=test_case.initial_data) - # repeating this check for the `current_behaviour` here to avoid `mypy` reporting: - # `error: Item "None" of "Optional[BaseBehaviour]" has no attribute "context"` when accessing the context below - assert self.behaviour.current_behaviour is not None - - with mock.patch.object( - self.behaviour.current_behaviour.context.logger, "log" - ) as mock_logger: - self.behaviour.act_wrapper() - - # apply the OK mocks first - for ok_req in test_case.ok_reqs: - ok_req(self) - - # apply the failing mocks - for err_req in test_case.err_reqs: - err_req(self, error=True) - - log_found = False - for log_args in mock_logger.call_args_list: - if platform.python_version().startswith("3.7"): - actual_log_level, actual_log = log_args[0][:2] - else: - actual_log_level, actual_log = log_args.args[:2] - - if actual_log.startswith(test_case.expected_log): - assert actual_log_level == test_case.expected_log_level, ( - f"{test_case.expected_log} was expected to log on {test_case.expected_log_level} log level, " - f"but logged on {log_args[0]} instead." - ) - log_found = True - break - - if not log_found: - raise AssertionError( - f'Expected log message "{test_case.expected_log}" was not found in captured logs: ' - f"{mock_logger.call_args_list}." - ) - - if len(test_case.err_reqs) == 0: - # no mocked requests fail, - # the behaviour should complete - self.complete() - - def test_termination_majority_already_reached(self) -> None: - """Tests the background behaviour when the termination is already reached.""" - self.fast_forward( - data=dict( - termination_majority_reached=True, - all_participants=["a"], - participants=["a"], - consensus_threshold=1, - ) - ) - with mock.patch.object( - self.behaviour_class, "check_for_signal" - ) as check_for_signal: - self.behaviour.act_wrapper() - check_for_signal.assert_not_called() - - def test_no_termination_signal_is_present(self) -> None: - """Tests the background behaviour when no termination signal is present.""" - self.fast_forward(self._INITIAL_DATA) - with mock.patch.object(AsyncBehaviour, "sleep") as sleep: - self.behaviour.act_wrapper() - self._mock_get_service_owner_request() - self._mock_get_zero_transfer_events_request(num_events=0) - sleep.assert_called() - - def test_no_remove_owner_event_is_present(self) -> None: - """Tests the background behaviour when the safe owner hasn't been removed.""" - self.fast_forward(self._INITIAL_DATA) - self.behaviour.act_wrapper() - self._mock_get_service_owner_request() - self._mock_get_zero_transfer_events_request() - self._mock_get_removed_owner_events_request(num_events=0) - self._mock_get_owners_request() - for _ in range(self._NUM_SAFE_OWNERS - 1): - self._mock_get_remove_owner_data_request() - self._mock_get_swap_owner_data_request() - self._mock_get_tx_data_request() - self._mock_get_raw_safe_transaction_hash_request() - self.complete() - - -class TestTerminationBehaviour(BaseTerminationTest): - """Test termination behaviour.""" - - behaviour_class = TerminationBehaviour - - def test_run(self) -> None: - """Test that the Termination Behaviour exits the app.""" - self.fast_forward() - with mock.patch("sys.exit") as sys_exit: - self.behaviour.act_wrapper() - sys_exit.assert_called() diff --git a/trader_old/vendor/valory/skills/termination_abci/tests/test_dialogues.py b/trader_old/vendor/valory/skills/termination_abci/tests/test_dialogues.py deleted file mode 100644 index 07360efcf..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ -# pylint: disable=unused-import - -"""Test the dialogues.py module of the skill.""" - - -import packages.valory.skills.termination_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_old/vendor/valory/skills/termination_abci/tests/test_handlers.py b/trader_old/vendor/valory/skills/termination_abci/tests/test_handlers.py deleted file mode 100644 index 244d6c19f..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/tests/test_handlers.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ -# pylint: disable=unused-import - -"""Test the dialogues.py module of the skill.""" - - -import packages.valory.skills.termination_abci.handlers # noqa - - -def test_import() -> None: - """Test that the 'handlers.py' Python module can be imported.""" diff --git a/trader_old/vendor/valory/skills/termination_abci/tests/test_models.py b/trader_old/vendor/valory/skills/termination_abci/tests/test_models.py deleted file mode 100644 index acf0ac453..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/tests/test_models.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022 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. -# -# ------------------------------------------------------------------------------ -# pylint: disable=unused-import - -"""Test the models.py module of the skill.""" - - -from packages.valory.skills.abstract_round_abci.test_tools.base import DummyContext -from packages.valory.skills.termination_abci.models import SharedState - - -class TestSharedState: # pylint: disable=too-few-public-methods - """Test SharedState(Model) class.""" - - def test_initialization( # pylint: disable=no-self-use - self, - ) -> None: - """Test initialization.""" - SharedState(name="", skill_context=DummyContext()) diff --git a/trader_old/vendor/valory/skills/termination_abci/tests/test_payloads.py b/trader_old/vendor/valory/skills/termination_abci/tests/test_payloads.py deleted file mode 100644 index e6ae87379..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/tests/test_payloads.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Test the payloads.py module of the skill.""" - - -from packages.valory.skills.termination_abci.payloads import BackgroundPayload - - -def test_background_payload() -> None: - """Test `BackgroundPayload`.""" - data = "0xdata" - payload = BackgroundPayload(sender="sender", background_data=data) - - assert payload.background_data == data - assert payload.data == {"background_data": data} diff --git a/trader_old/vendor/valory/skills/termination_abci/tests/test_rounds.py b/trader_old/vendor/valory/skills/termination_abci/tests/test_rounds.py deleted file mode 100644 index 163a548ca..000000000 --- a/trader_old/vendor/valory/skills/termination_abci/tests/test_rounds.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Test the rounds of the skill.""" - -from copy import deepcopy -from typing import FrozenSet, cast -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciAppDB, - TransactionNotValidError, -) -from packages.valory.skills.termination_abci.payloads import BackgroundPayload -from packages.valory.skills.termination_abci.rounds import ( - BackgroundRound, - Event, - SynchronizedData, - TerminationRound, -) - - -MAX_PARTICIPANTS: int = 4 - - -def get_participants() -> FrozenSet[str]: - """Participants""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -class BaseRoundTestClass: # pylint: disable=too-few-public-methods - """Base test class for Rounds.""" - - synchronized_data: SynchronizedData - participants: FrozenSet[str] - - def setup( - self, - ) -> None: - """Setup the test class.""" - - self.participants = get_participants() - self.synchronized_data = SynchronizedData( - AbciAppDB( - setup_data=dict( - participants=[tuple(self.participants)], - all_participants=[tuple(self.participants)], - consensus_threshold=[3], - ), - ) - ) - - -class TestBackgroundRound(BaseRoundTestClass): - """Tests for BackgroundRound.""" - - def test_run( - self, - ) -> None: - """Run tests.""" - - test_round = BackgroundRound( - synchronized_data=deepcopy(self.synchronized_data), - context=MagicMock( - params=MagicMock( - default_chain_id=1, - ) - ), - ) - payload_data = "0xdata" - first_payload, *payloads = [ - BackgroundPayload(sender=participant, background_data=payload_data) - for participant in self.participants - ] - - test_round.process_payload(first_payload) - assert test_round.collection == {first_payload.sender: first_payload} - assert test_round.end_block() is None - - for payload in payloads: - test_round.process_payload(payload) - - expected_state = self.synchronized_data.update( - most_voted_tx_hash=payload_data, - termination_majority_reached=True, - ) - - res = test_round.end_block() - assert res is not None - actual_state, event = res - - assert ( - cast(SynchronizedData, actual_state).termination_majority_reached - == cast( # pylint: disable=no-member - SynchronizedData, expected_state - ).termination_majority_reached - ) - - assert event == Event.TERMINATE - - def test_bad_payloads(self) -> None: - """Tests the background round when bad payloads are sent.""" - test_round = BackgroundRound( - synchronized_data=deepcopy(self.synchronized_data), - context=MagicMock(), - ) - payload_data = "0xdata" - bad_participant = "non_existent" - bad_participant_payload = BackgroundPayload( - sender=bad_participant, background_data=payload_data - ) - first_payload, *_ = [ - BackgroundPayload(sender=participant, background_data=payload_data) - for participant in self.participants - ] - - with pytest.raises( - TransactionNotValidError, - match=f"{bad_participant} not in list of participants", - ): - test_round.check_payload(bad_participant_payload) - - with pytest.raises( - ABCIAppInternalError, - match=f"{bad_participant} not in list of participants", - ): - test_round.process_payload(bad_participant_payload) - - # a valid payload gets sent for the first time and it goes through - test_round.process_payload(first_payload) - - # a duplicate (valid) payload will not go through - with pytest.raises( - TransactionNotValidError, - match=f"sender {first_payload.sender} has already sent value for round", - ): - test_round.check_payload(first_payload) - - with pytest.raises( - ABCIAppInternalError, - match=f"sender {first_payload.sender} has already sent value for round", - ): - test_round.process_payload(first_payload) - - -class TestTerminationRound(BaseRoundTestClass): - """Tests for TerminationRound.""" - - def test_run( - self, - ) -> None: - """Run tests.""" - - test_round = TerminationRound( - synchronized_data=deepcopy(self.synchronized_data), - context=MagicMock(), - ) - res = test_round.end_block() # pylint: disable=assignment-from-none - assert res is None diff --git a/trader_old/vendor/valory/skills/trader_abci/README.md b/trader_old/vendor/valory/skills/trader_abci/README.md deleted file mode 100644 index 6d0eb56d3..000000000 --- a/trader_old/vendor/valory/skills/trader_abci/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Trader abci - -## Description - -This module contains the trader chained skill for an AEA. diff --git a/trader_old/vendor/valory/skills/trader_abci/__init__.py b/trader_old/vendor/valory/skills/trader_abci/__init__.py deleted file mode 100644 index 219bbfad2..000000000 --- a/trader_old/vendor/valory/skills/trader_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- 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 the trader chained skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/trader_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/trader_abci/behaviours.py b/trader_old/vendor/valory/skills/trader_abci/behaviours.py deleted file mode 100644 index 3abcf2b38..000000000 --- a/trader_old/vendor/valory/skills/trader_abci/behaviours.py +++ /dev/null @@ -1,79 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the behaviours for the trader skill.""" - -from typing import Set, Type - -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.check_stop_trading_abci.behaviours import ( - CheckStopTradingRoundBehaviour, -) -from packages.valory.skills.decision_maker_abci.behaviours.round_behaviour import ( - AgentDecisionMakerRoundBehaviour, -) -from packages.valory.skills.market_manager_abci.behaviours import ( - MarketManagerRoundBehaviour, -) -from packages.valory.skills.mech_interact_abci.behaviours.round_behaviour import ( - MechInteractRoundBehaviour, -) -from packages.valory.skills.registration_abci.behaviours import ( - AgentRegistrationRoundBehaviour, - RegistrationStartupBehaviour, -) -from packages.valory.skills.reset_pause_abci.behaviours import ( - ResetPauseABCIConsensusBehaviour, -) -from packages.valory.skills.staking_abci.behaviours import StakingRoundBehaviour -from packages.valory.skills.termination_abci.behaviours import ( - BackgroundBehaviour, - TerminationAbciBehaviours, -) -from packages.valory.skills.trader_abci.composition import TraderAbciApp -from packages.valory.skills.transaction_settlement_abci.behaviours import ( - TransactionSettlementRoundBehaviour, -) -from packages.valory.skills.tx_settlement_multiplexer_abci.behaviours import ( - PostTxSettlementFullBehaviour, -) - - -class TraderConsensusBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the trader.""" - - initial_behaviour_cls = RegistrationStartupBehaviour - abci_app_cls = TraderAbciApp - - behaviours: Set[Type[BaseBehaviour]] = { - *AgentRegistrationRoundBehaviour.behaviours, - *AgentDecisionMakerRoundBehaviour.behaviours, - *MarketManagerRoundBehaviour.behaviours, - *MechInteractRoundBehaviour.behaviours, - *ResetPauseABCIConsensusBehaviour.behaviours, - *TerminationAbciBehaviours.behaviours, - *TransactionSettlementRoundBehaviour.behaviours, - *PostTxSettlementFullBehaviour.behaviours, - *StakingRoundBehaviour.behaviours, - *CheckStopTradingRoundBehaviour.behaviours, - } - background_behaviours_cls = {BackgroundBehaviour} # type: ignore diff --git a/trader_old/vendor/valory/skills/trader_abci/composition.py b/trader_old/vendor/valory/skills/trader_abci/composition.py deleted file mode 100644 index 0817e97c1..000000000 --- a/trader_old/vendor/valory/skills/trader_abci/composition.py +++ /dev/null @@ -1,168 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the trader ABCI application.""" - -from packages.valory.skills.abstract_round_abci.abci_app_chain import ( - AbciAppTransitionMapping, - chain, -) -from packages.valory.skills.abstract_round_abci.base import BackgroundAppConfig -from packages.valory.skills.check_stop_trading_abci.rounds import ( - CheckStopTradingAbciApp, - CheckStopTradingRound, - FinishedCheckStopTradingRound, - FinishedWithSkipTradingRound, -) -from packages.valory.skills.decision_maker_abci.rounds import DecisionMakerAbciApp -from packages.valory.skills.decision_maker_abci.states.check_benchmarking import ( - CheckBenchmarkingModeRound, -) -from packages.valory.skills.decision_maker_abci.states.claim_subscription import ( - ClaimRound, -) -from packages.valory.skills.decision_maker_abci.states.decision_receive import ( - DecisionReceiveRound, -) -from packages.valory.skills.decision_maker_abci.states.final_states import ( - BenchmarkingDoneRound, - BenchmarkingModeDisabledRound, - FinishedDecisionMakerRound, - FinishedDecisionRequestRound, - FinishedSubscriptionRound, - FinishedWithoutDecisionRound, - FinishedWithoutRedeemingRound, - RefillRequiredRound, -) -from packages.valory.skills.decision_maker_abci.states.handle_failed_tx import ( - HandleFailedTxRound, -) -from packages.valory.skills.decision_maker_abci.states.randomness import RandomnessRound -from packages.valory.skills.decision_maker_abci.states.redeem import RedeemRound -from packages.valory.skills.market_manager_abci.rounds import ( - FailedMarketManagerRound, - FinishedMarketManagerRound, - MarketManagerAbciApp, - UpdateBetsRound, -) -from packages.valory.skills.mech_interact_abci.rounds import MechInteractAbciApp -from packages.valory.skills.mech_interact_abci.states.final_states import ( - FinishedMechRequestRound, - FinishedMechRequestSkipRound, - FinishedMechResponseRound, - FinishedMechResponseTimeoutRound, -) -from packages.valory.skills.mech_interact_abci.states.request import MechRequestRound -from packages.valory.skills.mech_interact_abci.states.response import MechResponseRound -from packages.valory.skills.registration_abci.rounds import ( - AgentRegistrationAbciApp, - FinishedRegistrationRound, -) -from packages.valory.skills.reset_pause_abci.rounds import ( - FinishedResetAndPauseErrorRound, - FinishedResetAndPauseRound, - ResetAndPauseRound, - ResetPauseAbciApp, -) -from packages.valory.skills.staking_abci.rounds import ( - CallCheckpointRound, - CheckpointCallPreparedRound, - FinishedStakingRound, - StakingAbciApp, -) -from packages.valory.skills.termination_abci.rounds import ( - BackgroundRound, - Event, - TerminationAbciApp, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - FailedRound as FailedTransactionSubmissionRound, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - FinishedTransactionSubmissionRound, - RandomnessTransactionSubmissionRound, - TransactionSubmissionAbciApp, -) -from packages.valory.skills.tx_settlement_multiplexer_abci.rounds import ( - ChecksPassedRound, - FinishedBetPlacementTxRound, - FinishedMechRequestTxRound, - FinishedRedeemingTxRound, - FinishedStakingTxRound, - FinishedSubscriptionTxRound, - PostTxSettlementRound, - PreTxSettlementRound, - TxSettlementMultiplexerAbciApp, -) - - -abci_app_transition_mapping: AbciAppTransitionMapping = { - FinishedRegistrationRound: CheckBenchmarkingModeRound, - BenchmarkingModeDisabledRound: UpdateBetsRound, - FinishedMarketManagerRound: CheckStopTradingRound, - FinishedCheckStopTradingRound: RandomnessRound, - FinishedWithSkipTradingRound: RedeemRound, - FailedMarketManagerRound: ResetAndPauseRound, - FinishedDecisionMakerRound: PreTxSettlementRound, - ChecksPassedRound: RandomnessTransactionSubmissionRound, - RefillRequiredRound: ResetAndPauseRound, - FinishedTransactionSubmissionRound: PostTxSettlementRound, - FinishedSubscriptionTxRound: ClaimRound, - FailedTransactionSubmissionRound: HandleFailedTxRound, - FinishedDecisionRequestRound: MechRequestRound, - FinishedMechRequestRound: PreTxSettlementRound, - FinishedMechRequestTxRound: MechResponseRound, - FinishedMechResponseRound: DecisionReceiveRound, - FinishedMechResponseTimeoutRound: MechResponseRound, - FinishedMechRequestSkipRound: RedeemRound, - FinishedSubscriptionRound: PreTxSettlementRound, - FinishedBetPlacementTxRound: RedeemRound, - FinishedRedeemingTxRound: CallCheckpointRound, - FinishedWithoutDecisionRound: RedeemRound, - FinishedWithoutRedeemingRound: CallCheckpointRound, - FinishedStakingRound: ResetAndPauseRound, - CheckpointCallPreparedRound: PreTxSettlementRound, - FinishedStakingTxRound: ResetAndPauseRound, - FinishedResetAndPauseRound: CheckBenchmarkingModeRound, - FinishedResetAndPauseErrorRound: ResetAndPauseRound, - # this has no effect, because the `BenchmarkingDoneRound` is terminal - BenchmarkingDoneRound: ResetAndPauseRound, -} - -termination_config = BackgroundAppConfig( - round_cls=BackgroundRound, - start_event=Event.TERMINATE, - abci_app=TerminationAbciApp, -) - - -TraderAbciApp = chain( - ( - AgentRegistrationAbciApp, - DecisionMakerAbciApp, - MarketManagerAbciApp, - MechInteractAbciApp, - TransactionSubmissionAbciApp, - TxSettlementMultiplexerAbciApp, - ResetPauseAbciApp, - StakingAbciApp, - CheckStopTradingAbciApp, - ), - abci_app_transition_mapping, -).add_background_app(termination_config) diff --git a/trader_old/vendor/valory/skills/trader_abci/dialogues.py b/trader_old/vendor/valory/skills/trader_abci/dialogues.py deleted file mode 100644 index 153b6ce50..000000000 --- a/trader_old/vendor/valory/skills/trader_abci/dialogues.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- 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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_old/vendor/valory/skills/trader_abci/fsm_specification.yaml b/trader_old/vendor/valory/skills/trader_abci/fsm_specification.yaml deleted file mode 100644 index b2a80f938..000000000 --- a/trader_old/vendor/valory/skills/trader_abci/fsm_specification.yaml +++ /dev/null @@ -1,258 +0,0 @@ -alphabet_in: -- BENCHMARKING_DISABLED -- BENCHMARKING_ENABLED -- BENCHMARKING_FINISHED -- BET_PLACEMENT_NO_SELL_DONE -- BET_PLACEMENT_SELL_DONE -- BLACKLIST -- CHECKS_PASSED -- CHECK_HISTORY -- CHECK_LATE_ARRIVING_MESSAGE -- CHECK_TIMEOUT -- DONE -- FETCH_ERROR -- FINALIZATION_FAILED -- FINALIZE_TIMEOUT -- INCORRECT_SERIALIZATION -- INSUFFICIENT_BALANCE -- INSUFFICIENT_FUNDS -- MECH_REQUESTING_DONE -- MECH_RESPONSE_ERROR -- MOCK_MECH_REQUEST -- MOCK_TX -- NEGATIVE -- NEW_SIMULATED_RESAMPLE -- NEXT_CHECKPOINT_NOT_REACHED_YET -- NONE -- NO_MAJORITY -- NO_OP -- NO_REDEEMING -- NO_SUBSCRIPTION -- REDEEMING_DONE -- REDEEM_ROUND_TIMEOUT -- REFILL_REQUIRED -- RESET_AND_PAUSE_TIMEOUT -- RESET_TIMEOUT -- ROUND_TIMEOUT -- SELL_OUTCOME_TOKEN_DONE -- SERVICE_EVICTED -- SERVICE_NOT_STAKED -- SKIP_REQUEST -- SKIP_TRADING -- SLOTS_UNSUPPORTED_ERROR -- STAKING_DONE -- SUBSCRIPTION_DONE -- SUBSCRIPTION_ERROR -- SUSPICIOUS_ACTIVITY -- TIE -- UNPROFITABLE -- UNRECOGNIZED -- VALIDATE_TIMEOUT -default_start_state: RegistrationStartupRound -final_states: -- FailedMultiplexerRound -- FinishedSellOutcomeTokenTxRound -- ImpossibleRound -- ServiceEvictedRound -label: TraderAbciApp -start_states: -- RegistrationRound -- RegistrationStartupRound -states: -- BenchmarkingRandomnessRound -- BetPlacementRound -- BlacklistingRound -- CallCheckpointRound -- CheckBenchmarkingModeRound -- CheckLateTxHashesRound -- CheckStopTradingRound -- CheckTransactionHistoryRound -- ClaimRound -- CollectSignatureRound -- DecisionReceiveRound -- DecisionRequestRound -- FailedMultiplexerRound -- FinalizationRound -- FinishedSellOutcomeTokenTxRound -- HandleFailedTxRound -- ImpossibleRound -- MechRequestRound -- MechResponseRound -- PostTxSettlementRound -- PreTxSettlementRound -- RandomnessRound -- RandomnessTransactionSubmissionRound -- RedeemRound -- RegistrationRound -- RegistrationStartupRound -- ResetAndPauseRound -- ResetRound -- SamplingRound -- SelectKeeperTransactionSubmissionARound -- SelectKeeperTransactionSubmissionBAfterTimeoutRound -- SelectKeeperTransactionSubmissionBRound -- ServiceEvictedRound -- SubscriptionRound -- SynchronizeLateMessagesRound -- ToolSelectionRound -- UpdateBetsRound -- ValidateTransactionRound -transition_func: - (BenchmarkingRandomnessRound, DONE): SamplingRound - (BenchmarkingRandomnessRound, NO_MAJORITY): BenchmarkingRandomnessRound - (BenchmarkingRandomnessRound, ROUND_TIMEOUT): BenchmarkingRandomnessRound - (BetPlacementRound, DONE): PreTxSettlementRound - (BetPlacementRound, INSUFFICIENT_BALANCE): ResetAndPauseRound - (BetPlacementRound, MOCK_TX): RedeemRound - (BetPlacementRound, NONE): ImpossibleRound - (BetPlacementRound, NO_MAJORITY): BetPlacementRound - (BetPlacementRound, ROUND_TIMEOUT): BetPlacementRound - (BlacklistingRound, DONE): RedeemRound - (BlacklistingRound, FETCH_ERROR): ImpossibleRound - (BlacklistingRound, MOCK_TX): RedeemRound - (BlacklistingRound, NONE): ImpossibleRound - (BlacklistingRound, NO_MAJORITY): BlacklistingRound - (BlacklistingRound, ROUND_TIMEOUT): BlacklistingRound - (CallCheckpointRound, DONE): PreTxSettlementRound - (CallCheckpointRound, NEXT_CHECKPOINT_NOT_REACHED_YET): ResetAndPauseRound - (CallCheckpointRound, NO_MAJORITY): CallCheckpointRound - (CallCheckpointRound, ROUND_TIMEOUT): CallCheckpointRound - (CallCheckpointRound, SERVICE_EVICTED): ServiceEvictedRound - (CallCheckpointRound, SERVICE_NOT_STAKED): ResetAndPauseRound - (CheckBenchmarkingModeRound, BENCHMARKING_DISABLED): UpdateBetsRound - (CheckBenchmarkingModeRound, BENCHMARKING_ENABLED): BenchmarkingRandomnessRound - (CheckBenchmarkingModeRound, DONE): ImpossibleRound - (CheckBenchmarkingModeRound, NO_MAJORITY): CheckBenchmarkingModeRound - (CheckBenchmarkingModeRound, ROUND_TIMEOUT): CheckBenchmarkingModeRound - (CheckBenchmarkingModeRound, SUBSCRIPTION_ERROR): ImpossibleRound - (CheckLateTxHashesRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (CheckLateTxHashesRound, CHECK_TIMEOUT): CheckLateTxHashesRound - (CheckLateTxHashesRound, DONE): PostTxSettlementRound - (CheckLateTxHashesRound, NEGATIVE): HandleFailedTxRound - (CheckLateTxHashesRound, NONE): HandleFailedTxRound - (CheckLateTxHashesRound, NO_MAJORITY): HandleFailedTxRound - (CheckStopTradingRound, DONE): RandomnessRound - (CheckStopTradingRound, NONE): CheckStopTradingRound - (CheckStopTradingRound, NO_MAJORITY): CheckStopTradingRound - (CheckStopTradingRound, ROUND_TIMEOUT): CheckStopTradingRound - (CheckStopTradingRound, SKIP_TRADING): RedeemRound - (CheckTransactionHistoryRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (CheckTransactionHistoryRound, CHECK_TIMEOUT): CheckTransactionHistoryRound - (CheckTransactionHistoryRound, DONE): PostTxSettlementRound - (CheckTransactionHistoryRound, NEGATIVE): SelectKeeperTransactionSubmissionBRound - (CheckTransactionHistoryRound, NONE): HandleFailedTxRound - (CheckTransactionHistoryRound, NO_MAJORITY): CheckTransactionHistoryRound - (ClaimRound, DONE): ToolSelectionRound - (ClaimRound, NO_MAJORITY): ClaimRound - (ClaimRound, ROUND_TIMEOUT): ClaimRound - (ClaimRound, SUBSCRIPTION_ERROR): ClaimRound - (CollectSignatureRound, DONE): FinalizationRound - (CollectSignatureRound, NO_MAJORITY): ResetRound - (CollectSignatureRound, ROUND_TIMEOUT): CollectSignatureRound - (DecisionReceiveRound, DONE): BetPlacementRound - (DecisionReceiveRound, MECH_RESPONSE_ERROR): BlacklistingRound - (DecisionReceiveRound, NO_MAJORITY): DecisionReceiveRound - (DecisionReceiveRound, ROUND_TIMEOUT): DecisionReceiveRound - (DecisionReceiveRound, TIE): BlacklistingRound - (DecisionReceiveRound, UNPROFITABLE): BlacklistingRound - (DecisionRequestRound, DONE): MechRequestRound - (DecisionRequestRound, MOCK_MECH_REQUEST): DecisionReceiveRound - (DecisionRequestRound, NO_MAJORITY): DecisionRequestRound - (DecisionRequestRound, ROUND_TIMEOUT): DecisionRequestRound - (DecisionRequestRound, SLOTS_UNSUPPORTED_ERROR): BlacklistingRound - (FinalizationRound, CHECK_HISTORY): CheckTransactionHistoryRound - (FinalizationRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (FinalizationRound, DONE): ValidateTransactionRound - (FinalizationRound, FINALIZATION_FAILED): SelectKeeperTransactionSubmissionBRound - (FinalizationRound, FINALIZE_TIMEOUT): SelectKeeperTransactionSubmissionBAfterTimeoutRound - (FinalizationRound, INSUFFICIENT_FUNDS): SelectKeeperTransactionSubmissionBRound - (HandleFailedTxRound, BLACKLIST): BlacklistingRound - (HandleFailedTxRound, NO_MAJORITY): HandleFailedTxRound - (HandleFailedTxRound, NO_OP): RedeemRound - (MechRequestRound, DONE): PreTxSettlementRound - (MechRequestRound, NO_MAJORITY): MechRequestRound - (MechRequestRound, ROUND_TIMEOUT): MechRequestRound - (MechRequestRound, SKIP_REQUEST): RedeemRound - (MechResponseRound, DONE): DecisionReceiveRound - (MechResponseRound, NO_MAJORITY): MechResponseRound - (MechResponseRound, ROUND_TIMEOUT): MechResponseRound - (PostTxSettlementRound, BET_PLACEMENT_NO_SELL_DONE): RedeemRound - (PostTxSettlementRound, BET_PLACEMENT_SELL_DONE): RedeemRound - (PostTxSettlementRound, MECH_REQUESTING_DONE): MechResponseRound - (PostTxSettlementRound, REDEEMING_DONE): CallCheckpointRound - (PostTxSettlementRound, ROUND_TIMEOUT): PostTxSettlementRound - (PostTxSettlementRound, SELL_OUTCOME_TOKEN_DONE): FinishedSellOutcomeTokenTxRound - (PostTxSettlementRound, STAKING_DONE): ResetAndPauseRound - (PostTxSettlementRound, SUBSCRIPTION_DONE): ClaimRound - (PostTxSettlementRound, UNRECOGNIZED): FailedMultiplexerRound - (PreTxSettlementRound, CHECKS_PASSED): RandomnessTransactionSubmissionRound - (PreTxSettlementRound, NO_MAJORITY): PreTxSettlementRound - (PreTxSettlementRound, REFILL_REQUIRED): PreTxSettlementRound - (PreTxSettlementRound, ROUND_TIMEOUT): PreTxSettlementRound - (RandomnessRound, DONE): SamplingRound - (RandomnessRound, NO_MAJORITY): RandomnessRound - (RandomnessRound, ROUND_TIMEOUT): RandomnessRound - (RandomnessTransactionSubmissionRound, DONE): SelectKeeperTransactionSubmissionARound - (RandomnessTransactionSubmissionRound, NO_MAJORITY): RandomnessTransactionSubmissionRound - (RandomnessTransactionSubmissionRound, ROUND_TIMEOUT): RandomnessTransactionSubmissionRound - (RedeemRound, DONE): PreTxSettlementRound - (RedeemRound, MOCK_TX): SamplingRound - (RedeemRound, NONE): ImpossibleRound - (RedeemRound, NO_MAJORITY): RedeemRound - (RedeemRound, NO_REDEEMING): CallCheckpointRound - (RedeemRound, REDEEM_ROUND_TIMEOUT): CallCheckpointRound - (RegistrationRound, DONE): CheckBenchmarkingModeRound - (RegistrationRound, NO_MAJORITY): RegistrationRound - (RegistrationStartupRound, DONE): CheckBenchmarkingModeRound - (ResetAndPauseRound, DONE): CheckBenchmarkingModeRound - (ResetAndPauseRound, NO_MAJORITY): ResetAndPauseRound - (ResetAndPauseRound, RESET_AND_PAUSE_TIMEOUT): ResetAndPauseRound - (ResetRound, DONE): RandomnessTransactionSubmissionRound - (ResetRound, NO_MAJORITY): HandleFailedTxRound - (ResetRound, RESET_TIMEOUT): HandleFailedTxRound - (SamplingRound, BENCHMARKING_ENABLED): ToolSelectionRound - (SamplingRound, BENCHMARKING_FINISHED): ResetAndPauseRound - (SamplingRound, DONE): SubscriptionRound - (SamplingRound, FETCH_ERROR): ImpossibleRound - (SamplingRound, NEW_SIMULATED_RESAMPLE): SamplingRound - (SamplingRound, NONE): RedeemRound - (SamplingRound, NO_MAJORITY): SamplingRound - (SamplingRound, ROUND_TIMEOUT): SamplingRound - (SelectKeeperTransactionSubmissionARound, DONE): CollectSignatureRound - (SelectKeeperTransactionSubmissionARound, INCORRECT_SERIALIZATION): HandleFailedTxRound - (SelectKeeperTransactionSubmissionARound, NO_MAJORITY): ResetRound - (SelectKeeperTransactionSubmissionARound, ROUND_TIMEOUT): SelectKeeperTransactionSubmissionARound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, CHECK_HISTORY): CheckTransactionHistoryRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, DONE): FinalizationRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, INCORRECT_SERIALIZATION): HandleFailedTxRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, NO_MAJORITY): ResetRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, ROUND_TIMEOUT): SelectKeeperTransactionSubmissionBAfterTimeoutRound - (SelectKeeperTransactionSubmissionBRound, DONE): FinalizationRound - (SelectKeeperTransactionSubmissionBRound, INCORRECT_SERIALIZATION): HandleFailedTxRound - (SelectKeeperTransactionSubmissionBRound, NO_MAJORITY): ResetRound - (SelectKeeperTransactionSubmissionBRound, ROUND_TIMEOUT): SelectKeeperTransactionSubmissionBRound - (SubscriptionRound, DONE): PreTxSettlementRound - (SubscriptionRound, MOCK_TX): ToolSelectionRound - (SubscriptionRound, NONE): SubscriptionRound - (SubscriptionRound, NO_MAJORITY): SubscriptionRound - (SubscriptionRound, NO_SUBSCRIPTION): ToolSelectionRound - (SubscriptionRound, ROUND_TIMEOUT): SubscriptionRound - (SubscriptionRound, SUBSCRIPTION_ERROR): SubscriptionRound - (SynchronizeLateMessagesRound, DONE): CheckLateTxHashesRound - (SynchronizeLateMessagesRound, NONE): SelectKeeperTransactionSubmissionBRound - (SynchronizeLateMessagesRound, ROUND_TIMEOUT): SynchronizeLateMessagesRound - (SynchronizeLateMessagesRound, SUSPICIOUS_ACTIVITY): HandleFailedTxRound - (ToolSelectionRound, DONE): DecisionRequestRound - (ToolSelectionRound, NONE): ToolSelectionRound - (ToolSelectionRound, NO_MAJORITY): ToolSelectionRound - (ToolSelectionRound, ROUND_TIMEOUT): ToolSelectionRound - (UpdateBetsRound, DONE): CheckStopTradingRound - (UpdateBetsRound, FETCH_ERROR): ResetAndPauseRound - (UpdateBetsRound, NO_MAJORITY): UpdateBetsRound - (UpdateBetsRound, ROUND_TIMEOUT): UpdateBetsRound - (ValidateTransactionRound, DONE): PostTxSettlementRound - (ValidateTransactionRound, NEGATIVE): CheckTransactionHistoryRound - (ValidateTransactionRound, NONE): SelectKeeperTransactionSubmissionBRound - (ValidateTransactionRound, NO_MAJORITY): ValidateTransactionRound - (ValidateTransactionRound, VALIDATE_TIMEOUT): CheckTransactionHistoryRound diff --git a/trader_old/vendor/valory/skills/trader_abci/handlers.py b/trader_old/vendor/valory/skills/trader_abci/handlers.py deleted file mode 100644 index 5f35925a0..000000000 --- a/trader_old/vendor/valory/skills/trader_abci/handlers.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 the handlers for the 'trader_abci' skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.decision_maker_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.decision_maker_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) - - -TraderHandler = ABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_old/vendor/valory/skills/trader_abci/models.py b/trader_old/vendor/valory/skills/trader_abci/models.py deleted file mode 100644 index 989c91347..000000000 --- a/trader_old/vendor/valory/skills/trader_abci/models.py +++ /dev/null @@ -1,150 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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. -# -# ------------------------------------------------------------------------------ - -"""Custom objects for the trader ABCI application.""" - -from typing import Dict, Type, Union, cast - -from packages.valory.skills.abstract_round_abci.models import ApiSpecs -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.check_stop_trading_abci.models import CheckStopTradingParams -from packages.valory.skills.decision_maker_abci.models import ( - AccuracyInfoFields as BaseAccuracyInfoFields, -) -from packages.valory.skills.decision_maker_abci.models import ( - AgentToolsSpecs as DecisionMakerAgentToolsSpecs, -) -from packages.valory.skills.decision_maker_abci.models import ( - BenchmarkingMode as BaseBenchmarkingMode, -) -from packages.valory.skills.decision_maker_abci.models import ( - ConditionalTokensSubgraph as DecisionMakerConditionalTokensSubgraph, -) -from packages.valory.skills.decision_maker_abci.models import DecisionMakerParams -from packages.valory.skills.decision_maker_abci.models import ( - RealitioSubgraph as DecisionMakerRealitioSubgraph, -) -from packages.valory.skills.decision_maker_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.decision_maker_abci.models import ( - TradesSubgraph as DecisionMakerTradesSubgraph, -) -from packages.valory.skills.decision_maker_abci.rounds import ( - Event as DecisionMakerEvent, -) -from packages.valory.skills.market_manager_abci.models import ( - NetworkSubgraph as MarketManagerNetworkSubgraph, -) -from packages.valory.skills.market_manager_abci.models import ( - OmenSubgraph as MarketManagerOmenSubgraph, -) -from packages.valory.skills.market_manager_abci.rounds import ( - Event as MarketManagerEvent, -) -from packages.valory.skills.mech_interact_abci.models import ( - MechResponseSpecs as BaseMechResponseSpecs, -) -from packages.valory.skills.reset_pause_abci.rounds import Event as ResetPauseEvent -from packages.valory.skills.termination_abci.models import TerminationParams -from packages.valory.skills.trader_abci.composition import TraderAbciApp -from packages.valory.skills.transaction_settlement_abci.rounds import Event as TSEvent -from packages.valory.skills.tx_settlement_multiplexer_abci.models import ( - TxSettlementMultiplexerParams, -) - - -EventType = Union[ - Type[MarketManagerEvent], - Type[DecisionMakerEvent], - Type[TSEvent], - Type[ResetPauseEvent], -] -EventToTimeoutMappingType = Dict[ - Union[MarketManagerEvent, DecisionMakerEvent, TSEvent, ResetPauseEvent], - float, -] - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool -OmenSubgraph = MarketManagerOmenSubgraph -NetworkSubgraph = MarketManagerNetworkSubgraph -MechResponseSpecs = BaseMechResponseSpecs -AgentToolsSpecs = DecisionMakerAgentToolsSpecs -TradesSubgraph = DecisionMakerTradesSubgraph -ConditionalTokensSubgraph = DecisionMakerConditionalTokensSubgraph -RealitioSubgraph = DecisionMakerRealitioSubgraph -BenchmarkingMode = BaseBenchmarkingMode -AccuracyInfoFields = BaseAccuracyInfoFields - - -MARGIN = 5 - - -class RandomnessApi(ApiSpecs): - """A model for randomness api specifications.""" - - -class TraderParams( - # also contains the `StakingParams`. Must be before `MechInteractParams` because of the mech's contract address - CheckStopTradingParams, - # also contains the `MechInteractParams` - DecisionMakerParams, - TerminationParams, - TxSettlementMultiplexerParams, -): - """A model to represent the trader params.""" - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = TraderAbciApp - - @property - def params(self) -> TraderParams: - """Get the parameters.""" - return cast(TraderParams, self.context.params) - - def setup(self) -> None: - """Set up.""" - super().setup() - - events = (MarketManagerEvent, DecisionMakerEvent, TSEvent, ResetPauseEvent) - round_timeout = self.params.round_timeout_seconds - round_timeout_overrides = { - cast(EventType, event).ROUND_TIMEOUT: round_timeout for event in events - } - reset_pause_timeout = self.params.reset_pause_duration + MARGIN - event_to_timeout_overrides: EventToTimeoutMappingType = { - **round_timeout_overrides, - TSEvent.RESET_TIMEOUT: round_timeout, - TSEvent.VALIDATE_TIMEOUT: self.params.validate_timeout, - TSEvent.FINALIZE_TIMEOUT: self.params.finalize_timeout, - TSEvent.CHECK_TIMEOUT: self.params.history_check_timeout, - DecisionMakerEvent.REDEEM_ROUND_TIMEOUT: self.params.redeem_round_timeout, - ResetPauseEvent.RESET_AND_PAUSE_TIMEOUT: reset_pause_timeout, - } - - for event, override in event_to_timeout_overrides.items(): - TraderAbciApp.event_to_timeout[event] = override diff --git a/trader_old/vendor/valory/skills/trader_abci/skill.yaml b/trader_old/vendor/valory/skills/trader_abci/skill.yaml deleted file mode 100644 index ce6f7db44..000000000 --- a/trader_old/vendor/valory/skills/trader_abci/skill.yaml +++ /dev/null @@ -1,425 +0,0 @@ -name: trader_abci -author: valory -version: 0.1.0 -type: skill -description: This skill implements the trader skill for an AEA. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeiab4xgadptz4mhvno4p6xvkh7p4peg7iuhotabydriu74dmj6ljga - __init__.py: bafybeido7wa33h4dtleap57vzgyb4fsofk4vindsqcekyfo5i56i2rll2a - behaviours.py: bafybeigc6hszbu66ccajny5eh7thfgsrlr36je4mzziwp4mupgvtaeu6aa - composition.py: bafybeifxerfvssuhodqmtvkz6umlmrmdqjv5ptpszhnwlavzxaavdpdyly - dialogues.py: bafybeiebofyykseqp3fmif36cqmmyf3k7d2zbocpl6t6wnlpv4szghrxbm - fsm_specification.yaml: bafybeiab3boumxzlycla4yp7gyfrdncks64gnfdskoatwqsynjtru36kye - handlers.py: bafybeibbxybbi66em63ad33cllymypr3za3f5xvor3m2krhuxoyxnqjnxu - models.py: bafybeih2vkf4ln7n7ar27iemho7w7sdr4clmhbnhbcznmsri6mc2skkky4 - tests/__init__.py: bafybeiadatapyjh3e7ucg2ehz77oms3ihrbutwb2cs2tkjehy54utwvuyi - tests/tests_handlers.py: bafybeifxvd63qblqpsmyvj7k4dbqubab2pshao5zd2zs2srs7rt32zvciu -fingerprint_ignore_patterns: [] -connections: [] -contracts: [] -protocols: [] -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/registration_abci:0.1.0:bafybeibc7duasoaw5b4ene5oxfba2dmdzstsrws6ipi57ymgdtoxjadn54 -- valory/reset_pause_abci:0.1.0:bafybeigrdlxed3xlsnxtjhnsbl3cojruihxcqx4jxhgivkd5i2fkjncgba -- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae -- valory/termination_abci:0.1.0:bafybeib5l7jhew5ic6iq24dd23nidcoimzqkrk556gqywhoziatj33zvwm -- valory/market_manager_abci:0.1.0:bafybeibo63iiziwvqn6fmx36ungyg35z3chfv432kf6spuiszm6na22vdy -- valory/decision_maker_abci:0.1.0:bafybeibqiruzwnj7usv4nmtjiyrzaaukive4wiebdxd5gymwgrlsn2fara -- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeicwknp3cym5n3aig5ykyqwqufeabx3wsu2nk3jv7ftpdhulcr3rou -- valory/staking_abci:0.1.0:bafybeicupccurmrg7qesivonlyt3nryarsmk5qf5yh6auno64wn45bybvq -- valory/check_stop_trading_abci:0.1.0:bafybeieduekpd4zbvjztyxyooppqnmjvup6jfp74uo6hhupvtvzzscdzkq -- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm -behaviours: - main: - args: {} - class_name: TraderConsensusBehaviour -handlers: - abci: - args: {} - class_name: TraderHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - finalize_timeout: 60.0 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - history_check_timeout: 1205 - init_fallback_gas: 0 - keeper_allowed_retries: 3 - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - multisend_batch_size: 1 - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - round_timeout_seconds: 350.0 - service_id: trader - service_registry_address: null - agent_registry_address: '0x0000000000000000000000000000000000000000' - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - sleep_time: 5 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - termination_sleep: 900 - tx_timeout: 10.0 - use_termination: false - termination_from_block: 0 - validate_timeout: 1205 - creator_per_subgraph: - omen_subgraph: [] - slot_count: 2 - opening_margin: 300 - languages: - - en_US - average_block_time: 5 - abt_error_mult: 5 - the_graph_error_message_key: message - the_graph_payment_required_error: payment required for subsequent requests for - this API key - mech_contract_address: '0x77af31de935740567cf4ff1986d04b2c964a786a' - mech_request_price: null - mech_chain_id: gnosis - mech_wrapped_native_token_address: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d' - sample_bets_closing_days: 10 - trading_strategy: strategy_name - use_fallback_strategy: true - bet_threshold: 100000000000000000 - ipfs_address: https://gateway.autonolas.tech/ipfs/ - tools_accuracy_hash: QmR8etyW3TPFadNtNrW54vfnFqmh8vBrMARWV76EmxCZyk - prompt_template: With the given question "@{question}" and the `yes` option - represented by `@{yes}` and the `no` option represented by `@{no}`, what are - the respective probabilities of `p_yes` and `p_no` occurring? - dust_threshold: 10000000000000 - conditional_tokens_address: '0xCeAfDD6bc0bEF976fdCd1112955828E00543c0Ce' - realitio_proxy_address: '0xAB16D643bA051C11962DA645f74632d3130c81E2' - realitio_address: '0x79e32aE03fb27B07C89c0c568F80287C01ca2E57' - event_filtering_batch_size: 5000 - reduce_factor: 0.25 - max_filtering_retries: 6 - minimum_batch_size: 500 - redeeming_batch_size: 5 - slippage: 0.01 - policy_epsilon: 0.1 - store_path: /data/ - policy_store_update_offset: 259200 - use_subgraph_for_redeeming: true - irrelevant_tools: - - openai-text-davinci-002 - - openai-text-davinci-003 - - openai-gpt-3.5-turbo - - openai-gpt-4 - - stabilityai-stable-diffusion-v1-5 - - stabilityai-stable-diffusion-xl-beta-v2-2-2 - - stabilityai-stable-diffusion-512-v2-1 - - stabilityai-stable-diffusion-768-v2-1 - staking_contract_address: '0x2Ef503950Be67a98746F484DA0bBAdA339DF3326' - staking_interaction_sleep_time: 5 - disable_trading: false - stop_trading_if_staking_kpi_met: true - agent_balance_threshold: 10000000000000000 - refill_check_interval: 10 - mech_activity_checker_contract: '0x0000000000000000000000000000000000000000' - redeem_round_timeout: 3600.0 - tool_punishment_multiplier: 1 - use_nevermined: true - mech_to_subscription_params: - - - base_url - - https://marketplace-api.gnosis.nevermined.app/api/v1/metadata/assets/ddo - - - did - - did:nv:0ea01d5de3b34e3792db825f2a5f5595c393c68b19fd5efdacd00fcc63a53483 - - - escrow_payment_condition_address - - '0x9dDC4F1Ea5b94C138A23b60EC48c0d01d172629a' - - - lock_payment_condition_address - - '0xDE85A368Ee6f374d236500d176814365370778dA' - - - transfer_nft_condition_address - - '0xbBa4A25262745a55f020D0a3E9a82c25bb6F4979' - - - token_address - - '0xa30DE8C6aC39B825192e5F1FADe0770332D279A8' - - - order_address - - '0xc7751eff5396a846e7bc83ac31d3cb7d37cb49e4' - - - nft_amount - - '100' - - - payment_token - - '0x0000000000000000000000000000000000000000' - - - order_address - - '0xc7751eff5396a846e7bc83ac31d3cb7d37cb49e4' - - - price - - '1000000000000000000' - contract_timeout: 300.0 - file_hash_to_strategies_json: - - - hash - - - strategy_name - strategies_kwargs: - - - bet_kelly_fraction - - 1.0 - - - floor_balance - - 500000000000000000 - - - bet_amount_per_threshold - - 0.0: 0 - 0.1: 0 - 0.2: 0 - 0.3: 0 - 0.4: 0 - 0.5: 0 - 0.6: 0 - 0.7: 0 - 0.8: 0 - 0.9: 0 - 1.0: 0 - service_endpoint: trader.staging.autonolas.tech/ - rpc_sleep_time: 10 - safe_voting_range: 600 - rebet_chance: 0.6 - mech_interaction_sleep_time: 10 - use_mech_marketplace: false - mech_marketplace_config: - mech_marketplace_address: '0x0000000000000000000000000000000000000000' - priority_mech_address: '0x0000000000000000000000000000000000000000' - priority_mech_staking_instance_address: '0x0000000000000000000000000000000000000000' - priority_mech_service_id: 0 - requester_staking_instance_address: '0x0000000000000000000000000000000000000000' - response_timeout: 300 - expected_mech_response_time: 300 - mech_invalid_response: Invalid Response - mech_consecutive_failures_threshold: 2 - tool_quarantine_duration: 18000 - class_name: TraderParams - benchmarking_mode: - args: - enabled: false - native_balance: 10000000000000000000 - collateral_balance: 10000000000000000000 - mech_cost: 10000000000000000 - pool_fee: 20000000000000000 - outcome_token_amounts: - - 11000000000000000000 - - 9000000000000000000 - outcome_token_marginal_prices: - - 0.4 - - 0.6 - sep: ',' - dataset_filename: benchmark_data.csv - question_field: question - question_id_field: question_id - answer_field: answer - p_yes_field_part: p_yes_ - p_no_field_part: p_no_ - confidence_field_part: confidence_ - info_utility_field_part: info_utility_ - part_prefix_mode: true - bet_amount_field: collateral_amount - results_filename: benchmarking_results.csv - randomness: benchmarking_randomness - nr_mech_calls: 60 - class_name: BenchmarkingMode - acc_info_fields: - args: - tool: tool - requests: total_requests - accuracy: tool_accuracy - sep: ',' - max: max - datetime_format: '%Y-%m-%d %H:%M:%S' - class_name: AccuracyInfoFields - network_subgraph: - args: - api_id: network - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:blocks - response_index: 0 - response_type: dict - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/stakewise/ethereum-gnosis - class_name: NetworkSubgraph - omen_subgraph: - args: - api_id: omen - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:fixedProductMarketMakers - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/protofire/omen-xdai - class_name: OmenSubgraph - randomness_api: - args: - api_id: cloudflare - headers: {} - method: GET - parameters: {} - response_key: null - response_type: dict - retries: 5 - url: https://drand.cloudflare.com/public/latest - class_name: RandomnessApi - mech_response: - args: - api_id: mech_response - headers: - Content-Type: application/json - method: GET - parameters: {} - response_key: result - response_type: str - retries: 5 - url: '' - class_name: MechResponseSpecs - agent_tools: - args: - api_id: agent_tools - headers: - Content-Type: application/json - method: GET - parameters: {} - response_key: tools - response_type: list - retries: 5 - url: '' - class_name: AgentToolsSpecs - trades_subgraph: - args: - api_id: trades - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:fpmmTrades - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/protofire/omen-xdai - class_name: TradesSubgraph - conditional_tokens_subgraph: - args: - api_id: conditional_tokens - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:user:userPositions - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/gnosis/conditional-tokens-gc - class_name: ConditionalTokensSubgraph - realitio_subgraph: - args: - api_id: realitio - headers: - Content-Type: application/json - method: POST - parameters: {} - response_key: data:answers - response_type: list - error_key: errors - error_index: 0 - error_type: dict - retries: 5 - url: https://api.thegraph.com/subgraphs/name/realityeth/realityeth-gnosis - class_name: RealitioSubgraph - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: {} -is_abstract: false diff --git a/trader_old/vendor/valory/skills/trader_abci/tests/__init__.py b/trader_old/vendor/valory/skills/trader_abci/tests/__init__.py deleted file mode 100644 index 18184313e..000000000 --- a/trader_old/vendor/valory/skills/trader_abci/tests/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the tests for trader abci.""" diff --git a/trader_old/vendor/valory/skills/trader_abci/tests/tests_handlers.py b/trader_old/vendor/valory/skills/trader_abci/tests/tests_handlers.py deleted file mode 100644 index 9b62aae4c..000000000 --- a/trader_old/vendor/valory/skills/trader_abci/tests/tests_handlers.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the tests for the handlers for the trader abci.""" - -from unittest.mock import MagicMock - -import pytest -from aea.configurations.data_types import PublicId -from aea.skills.base import Handler - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.decision_maker_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.decision_maker_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.trader_abci.handlers import ( - ContractApiHandler, - HttpHandler, - IpfsHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, - TraderHandler, -) - - -@pytest.mark.parametrize( - "handler, base_handler", - [ - (TraderHandler, ABCIRoundHandler), - (HttpHandler, BaseHttpHandler), - (SigningHandler, BaseSigningHandler), - (LedgerApiHandler, BaseLedgerApiHandler), - (ContractApiHandler, BaseContractApiHandler), - (TendermintHandler, BaseTendermintHandler), - (IpfsHandler, BaseIpfsHandler), - ], -) -def test_handler(handler: Handler, base_handler: Handler) -> None: - """Test that the 'handlers.py' of the TraderAbci can be imported.""" - handler = handler( - name="dummy_handler", - skill_context=MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")), - ) - - assert isinstance(handler, base_handler) diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/README.md b/trader_old/vendor/valory/skills/transaction_settlement_abci/README.md deleted file mode 100644 index 29124a9ec..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Transaction settlement abci - -## Description - -This module contains the ABCI transaction settlement skill for an AEA. - -## Behaviours - -* `BaseResetBehaviour` - - Reset state. - -* `FinalizeBehaviour` - - Finalize state. - -* `RandomnessTransactionSubmissionBehaviour` - - Retrieve randomness. - -* `ResetAndPauseBehaviour` - - Reset and pause state. - -* `ResetBehaviour` - - Reset state. - -* `SelectKeeperTransactionSubmissionBehaviourA` - - Select the keeper agent. - -* `SelectKeeperTransactionSubmissionBehaviourB` - - Select the keeper agent. - -* `SignatureBehaviour` - - Signature state. - -* `TransactionSettlementBaseState` - - Base state behaviour for the common apps' skill. - -* `ValidateTransactionBehaviour` - - Validate a transaction. - - -## Handlers - -No Handlers (the skill is purely behavioural). - diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/__init__.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/__init__.py deleted file mode 100644 index 1df75f1f6..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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 the ABCI transaction settlement skill for an AEA.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/transaction_settlement_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/behaviours.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/behaviours.py deleted file mode 100644 index d3a7ca2a7..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/behaviours.py +++ /dev/null @@ -1,984 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2024 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 the behaviours for the 'abci' skill.""" - -import binascii -import pprint -import re -from abc import ABC -from collections import deque -from typing import ( - Any, - Deque, - Dict, - Generator, - Iterator, - List, - Optional, - Set, - Tuple, - Type, - Union, - cast, -) - -from aea.protocols.base import Message -from web3.types import Nonce, TxData, Wei - -from packages.valory.contracts.gnosis_safe.contract import GnosisSafeContract -from packages.valory.protocols.contract_api.message import ContractApiMessage -from packages.valory.skills.abstract_round_abci.behaviour_utils import RPCResponseStatus -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.abstract_round_abci.common import ( - RandomnessBehaviour, - SelectKeeperBehaviour, -) -from packages.valory.skills.abstract_round_abci.utils import VerifyDrand -from packages.valory.skills.transaction_settlement_abci.models import TransactionParams -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - VerificationStatus, - skill_input_hex_to_payload, - tx_hist_payload_to_hex, -) -from packages.valory.skills.transaction_settlement_abci.payloads import ( - CheckTransactionHistoryPayload, - FinalizationTxPayload, - RandomnessPayload, - ResetPayload, - SelectKeeperPayload, - SignaturePayload, - SynchronizeLateMessagesPayload, - ValidatePayload, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - CheckLateTxHashesRound, - CheckTransactionHistoryRound, - CollectSignatureRound, - FinalizationRound, - RandomnessTransactionSubmissionRound, - ResetRound, - SelectKeeperTransactionSubmissionARound, - SelectKeeperTransactionSubmissionBAfterTimeoutRound, - SelectKeeperTransactionSubmissionBRound, - SynchronizeLateMessagesRound, - SynchronizedData, - TransactionSubmissionAbciApp, - ValidateTransactionRound, -) - - -TxDataType = Dict[str, Union[VerificationStatus, Deque[str], int, Set[str], str]] - -drand_check = VerifyDrand() - -REVERT_CODE_RE = r"\s(GS\d{3})[^\d]" - -# This mapping was copied from: -# https://github.com/safe-global/safe-contracts/blob/ce5cbd256bf7a8a34538c7e5f1f2366a9d685f34/docs/error_codes.md -REVERT_CODES_TO_REASONS: Dict[str, str] = { - "GS000": "Could not finish initialization", - "GS001": "Threshold needs to be defined", - "GS010": "Not enough gas to execute Safe transaction", - "GS011": "Could not pay gas costs with ether", - "GS012": "Could not pay gas costs with token", - "GS013": "Safe transaction failed when gasPrice and safeTxGas were 0", - "GS020": "Signatures data too short", - "GS021": "Invalid contract signature location: inside static part", - "GS022": "Invalid contract signature location: length not present", - "GS023": "Invalid contract signature location: data not complete", - "GS024": "Invalid contract signature provided", - "GS025": "Hash has not been approved", - "GS026": "Invalid owner provided", - "GS030": "Only owners can approve a hash", - "GS031": "Method can only be called from this contract", - "GS100": "Modules have already been initialized", - "GS101": "Invalid module address provided", - "GS102": "Module has already been added", - "GS103": "Invalid prevModule, module pair provided", - "GS104": "Method can only be called from an enabled module", - "GS200": "Owners have already been setup", - "GS201": "Threshold cannot exceed owner count", - "GS202": "Threshold needs to be greater than 0", - "GS203": "Invalid owner address provided", - "GS204": "Address is already an owner", - "GS205": "Invalid prevOwner, owner pair provided", - "GS300": "Guard does not implement IERC165", -} - - -class TransactionSettlementBaseBehaviour(BaseBehaviour, ABC): - """Base behaviour for the common apps' skill.""" - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return cast(SynchronizedData, super().synchronized_data) - - @property - def params(self) -> TransactionParams: - """Return the params.""" - return cast(TransactionParams, super().params) - - @staticmethod - def serialized_keepers(keepers: Deque[str], keeper_retries: int) -> str: - """Get the keepers serialized.""" - if len(keepers) == 0: - return "" - keepers_ = "".join(keepers) - keeper_retries_ = keeper_retries.to_bytes(32, "big").hex() - concatenated = keeper_retries_ + keepers_ - - return concatenated - - def get_gas_price_params(self, tx_body: dict) -> List[str]: - """Guess the gas strategy from the transaction params""" - strategy_to_params: Dict[str, List[str]] = { - "eip": ["maxPriorityFeePerGas", "maxFeePerGas"], - "gas_station": ["gasPrice"], - } - - for strategy, params in strategy_to_params.items(): - if all(param in tx_body for param in params): - self.context.logger.info(f"Detected gas strategy: {strategy}") - return params - - return [] - - def _get_tx_data( - self, - message: ContractApiMessage, - use_flashbots: bool, - manual_gas_limit: int = 0, - raise_on_failed_simulation: bool = False, - chain_id: Optional[str] = None, - ) -> Generator[None, None, TxDataType]: - """Get the transaction data from a `ContractApiMessage`.""" - tx_data: TxDataType = { - "status": VerificationStatus.PENDING, - "keepers": self.synchronized_data.keepers, - "keeper_retries": self.synchronized_data.keeper_retries, - "blacklisted_keepers": self.synchronized_data.blacklisted_keepers, - "tx_digest": "", - } - - # Check for errors in the transaction preparation - if ( - message.performative == ContractApiMessage.Performative.ERROR - and message.message is not None - ): - if self._safe_nonce_reused(message.message): - tx_data["status"] = VerificationStatus.VERIFIED - else: - tx_data["status"] = VerificationStatus.ERROR - self.context.logger.warning(self._parse_revert_reason(message)) - return tx_data - - # Check that we have a RAW_TRANSACTION response - if message.performative != ContractApiMessage.Performative.RAW_TRANSACTION: - self.context.logger.warning( - f"get_raw_safe_transaction unsuccessful! Received: {message}" - ) - return tx_data - - if manual_gas_limit > 0: - message.raw_transaction.body["gas"] = manual_gas_limit - - # Send transaction - tx_digest, rpc_status = yield from self.send_raw_transaction( - message.raw_transaction, - use_flashbots, - raise_on_failed_simulation=raise_on_failed_simulation, - chain_id=chain_id, - ) - - # Handle transaction results - if rpc_status == RPCResponseStatus.ALREADY_KNOWN: - self.context.logger.warning( - "send_raw_transaction unsuccessful! Transaction is already in the mempool! Will attempt to verify it." - ) - - if rpc_status == RPCResponseStatus.INCORRECT_NONCE: - tx_data["status"] = VerificationStatus.ERROR - self.context.logger.warning( - "send_raw_transaction unsuccessful! Incorrect nonce." - ) - - if rpc_status == RPCResponseStatus.INSUFFICIENT_FUNDS: - # blacklist self. - tx_data["status"] = VerificationStatus.INSUFFICIENT_FUNDS - blacklisted = cast(Deque[str], tx_data["keepers"]).popleft() - tx_data["keeper_retries"] = 1 - cast(Set[str], tx_data["blacklisted_keepers"]).add(blacklisted) - self.context.logger.warning( - "send_raw_transaction unsuccessful! Insufficient funds." - ) - - if rpc_status not in { - RPCResponseStatus.SUCCESS, - RPCResponseStatus.ALREADY_KNOWN, - }: - self.context.logger.warning( - f"send_raw_transaction unsuccessful! Received: {rpc_status}" - ) - return tx_data - - tx_data["tx_digest"] = cast(str, tx_digest) - - nonce = Nonce(int(cast(str, message.raw_transaction.body["nonce"]))) - fallback_gas = message.raw_transaction.body["gas"] - - # Get the gas params - gas_price_params = self.get_gas_price_params(message.raw_transaction.body) - - gas_price = { - gas_price_param: Wei( - int( - cast( - str, - message.raw_transaction.body[gas_price_param], - ) - ) - ) - for gas_price_param in gas_price_params - } - - # Set hash, nonce and tip. - self.params.mutable_params.tx_hash = cast(str, tx_data["tx_digest"]) - if nonce == self.params.mutable_params.nonce: - self.context.logger.info( - "Attempting to replace transaction " - f"with old gas price parameters {self.params.mutable_params.gas_price}, using new gas price parameters {gas_price}" - ) - else: - self.context.logger.info( - f"Sent transaction for mining with gas parameters {gas_price}" - ) - self.params.mutable_params.nonce = nonce - self.params.mutable_params.gas_price = gas_price - self.params.mutable_params.fallback_gas = fallback_gas - - return tx_data - - def _verify_tx(self, tx_hash: str) -> Generator[None, None, ContractApiMessage]: - """Verify a transaction.""" - tx_params = skill_input_hex_to_payload( - self.synchronized_data.most_voted_tx_hash - ) - chain_id = self.synchronized_data.get_chain_id(self.params.default_chain_id) - contract_api_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="verify_tx", - tx_hash=tx_hash, - owners=tuple(self.synchronized_data.participants), - to_address=tx_params["to_address"], - value=tx_params["ether_value"], - data=tx_params["data"], - safe_tx_gas=tx_params["safe_tx_gas"], - signatures_by_owner={ - key: payload.signature - for key, payload in self.synchronized_data.participant_to_signature.items() - }, - operation=tx_params["operation"], - chain_id=chain_id, - ) - return contract_api_msg - - @staticmethod - def _safe_nonce_reused(revert_reason: str) -> bool: - """Check for GS026.""" - return "GS026" in revert_reason - - @staticmethod - def _parse_revert_reason(message: ContractApiMessage) -> str: - """Parse a revert reason and log a relevant message.""" - default_message = f"get_raw_safe_transaction unsuccessful! Received: {message}" - - revert_reason = message.message - if not revert_reason: - return default_message - - revert_match = re.findall(REVERT_CODE_RE, revert_reason) - if revert_match is None or len(revert_match) != 1: - return default_message - - revert_code = revert_match.pop() - revert_explanation = REVERT_CODES_TO_REASONS.get(revert_code, None) - if revert_explanation is None: - return default_message - - return f"Received a {revert_code} revert error: {revert_explanation}." - - def _get_safe_nonce(self) -> Generator[None, None, ContractApiMessage]: - """Get the safe nonce.""" - chain_id = self.synchronized_data.get_chain_id(self.params.default_chain_id) - contract_api_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_safe_nonce", - chain_id=chain_id, - ) - return contract_api_msg - - -class RandomnessTransactionSubmissionBehaviour(RandomnessBehaviour): - """Retrieve randomness.""" - - matching_round = RandomnessTransactionSubmissionRound - payload_class = RandomnessPayload - - -class SelectKeeperTransactionSubmissionBehaviourA( # pylint: disable=too-many-ancestors - SelectKeeperBehaviour, TransactionSettlementBaseBehaviour -): - """Select the keeper agent.""" - - matching_round = SelectKeeperTransactionSubmissionARound - payload_class = SelectKeeperPayload - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - keepers = deque((self._select_keeper(),)) - payload = self.payload_class( - self.context.agent_address, self.serialized_keepers(keepers, 1) - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class SelectKeeperTransactionSubmissionBehaviourB( # pylint: disable=too-many-ancestors - SelectKeeperTransactionSubmissionBehaviourA -): - """Select the keeper b agent.""" - - matching_round = SelectKeeperTransactionSubmissionBRound - - def async_act(self) -> Generator: - """ - Do the action. - - Steps: - - If we have not selected enough keepers for the period, - select a keeper randomly and add it to the keepers' queue, with top priority. - - Otherwise, cycle through the keepers' subset, using the following logic: - A `PENDING` verification status means that we have not received any errors, - therefore, all we know is that the tx has not been mined yet due to low pricing. - Consequently, we are going to retry with the same keeper in order to replace the transaction. - However, if we receive a status other than `PENDING`, we need to cycle through the keepers' subset. - Moreover, if the current keeper has reached the allowed number of retries, then we cycle anyway. - - Send the transaction with the keepers and wait for it to be mined. - - Wait until ABCI application transitions to the next round. - - Go to the next behaviour (set done event). - """ - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - keepers = self.synchronized_data.keepers - keeper_retries = 1 - - if self.synchronized_data.keepers_threshold_exceeded: - keepers.rotate(-1) - self.context.logger.info(f"Rotated keepers to: {keepers}.") - elif ( - self.synchronized_data.keeper_retries - != self.params.keeper_allowed_retries - and self.synchronized_data.final_verification_status - == VerificationStatus.PENDING - ): - keeper_retries += self.synchronized_data.keeper_retries - self.context.logger.info( - f"Kept keepers and incremented retries: {keepers}." - ) - else: - keepers.appendleft(self._select_keeper()) - - payload = self.payload_class( - self.context.agent_address, - self.serialized_keepers(keepers, keeper_retries), - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class SelectKeeperTransactionSubmissionBehaviourBAfterTimeout( # pylint: disable=too-many-ancestors - SelectKeeperTransactionSubmissionBehaviourB -): - """Select the keeper b agent after a timeout.""" - - matching_round = SelectKeeperTransactionSubmissionBAfterTimeoutRound - - -class ValidateTransactionBehaviour(TransactionSettlementBaseBehaviour): - """Validate a transaction.""" - - matching_round = ValidateTransactionRound - - def async_act(self) -> Generator: - """ - Do the action. - - Steps: - - Validate that the transaction hash provided by the keeper points to a - valid transaction. - - Send the transaction with the validation result and wait for it to be - mined. - - Wait until ABCI application transitions to the next round. - - Go to the next behaviour (set done event). - """ - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - is_correct = yield from self.has_transaction_been_sent() - if is_correct: - self.context.logger.info( - f"Finalized with transaction hash: {self.synchronized_data.to_be_validated_tx_hash}" - ) - payload = ValidatePayload(self.context.agent_address, is_correct) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - def has_transaction_been_sent(self) -> Generator[None, None, Optional[bool]]: - """Transaction verification.""" - - to_be_validated_tx_hash = self.synchronized_data.to_be_validated_tx_hash - - response = yield from self.get_transaction_receipt( - to_be_validated_tx_hash, - self.params.retry_timeout, - self.params.retry_attempts, - chain_id=self.synchronized_data.get_chain_id(self.params.default_chain_id), - ) - if response is None: # pragma: nocover - self.context.logger.error( - f"tx {to_be_validated_tx_hash} receipt check timed out!" - ) - return None - - contract_api_msg = yield from self._verify_tx(to_be_validated_tx_hash) - if ( - contract_api_msg.performative != ContractApiMessage.Performative.STATE - ): # pragma: nocover - self.context.logger.error( - f"verify_tx unsuccessful! Received: {contract_api_msg}" - ) - return False - - verified = cast(bool, contract_api_msg.state.body["verified"]) - verified_log = ( - f"Verified result: {verified}" - if verified - else f"Verified result: {verified}, all: {contract_api_msg.state.body}" - ) - self.context.logger.info(verified_log) - return verified - - -class CheckTransactionHistoryBehaviour(TransactionSettlementBaseBehaviour): - """Check the transaction history.""" - - matching_round = CheckTransactionHistoryRound - check_expected_to_be_verified = "The next tx check" - - @property - def history(self) -> List[str]: - """Get the history of hashes.""" - return self.synchronized_data.tx_hashes_history - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - verification_status, tx_hash = yield from self._check_tx_history() - if verification_status == VerificationStatus.VERIFIED: - msg = f"A previous transaction {tx_hash} has already been verified " - msg += ( - f"for {self.synchronized_data.to_be_validated_tx_hash}." - if self.synchronized_data.tx_hashes_history - else "and was synced after the finalization round timed out." - ) - self.context.logger.info(msg) - elif verification_status == VerificationStatus.NOT_VERIFIED: - self.context.logger.info( - f"No previous transaction has been verified for " - f"{self.synchronized_data.to_be_validated_tx_hash}." - ) - - verified_res = tx_hist_payload_to_hex(verification_status, tx_hash) - payload = CheckTransactionHistoryPayload( - self.context.agent_address, verified_res - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - def _check_tx_history( # pylint: disable=too-many-return-statements - self, - ) -> Generator[None, None, Tuple[VerificationStatus, Optional[str]]]: - """Check the transaction history.""" - if not self.history: - self.context.logger.error( - "An unexpected error occurred! The synchronized data do not contain any transaction hashes, " - f"but entered the `{self.behaviour_id}` behaviour." - ) - return VerificationStatus.ERROR, None - - contract_api_msg = yield from self._get_safe_nonce() - if ( - contract_api_msg.performative != ContractApiMessage.Performative.STATE - ): # pragma: nocover - self.context.logger.error( - f"get_safe_nonce unsuccessful! Received: {contract_api_msg}" - ) - return VerificationStatus.ERROR, None - - safe_nonce = cast(int, contract_api_msg.state.body["safe_nonce"]) - if safe_nonce == self.params.mutable_params.nonce: - # if we have reached this state it means that the transaction didn't go through in the expected time - # as such we assume it is not verified - self.context.logger.info( - f"Safe nonce is the same as the nonce used in the transaction: {safe_nonce}. " - f"No transaction has gone through yet." - ) - return VerificationStatus.NOT_VERIFIED, None - - self.context.logger.info( - f"A transaction with nonce {safe_nonce} has already been sent. " - ) - self.context.logger.info( - f"Starting check for the transaction history: {self.history}. " - ) - was_nonce_reused = False - for tx_hash in self.history[::-1]: - self.context.logger.info(f"Checking hash {tx_hash}...") - contract_api_msg = yield from self._verify_tx(tx_hash) - - if ( - contract_api_msg.performative != ContractApiMessage.Performative.STATE - ): # pragma: nocover - self.context.logger.error( - f"verify_tx unsuccessful for {tx_hash}! Received: {contract_api_msg}" - ) - return VerificationStatus.ERROR, tx_hash - - verified = cast(bool, contract_api_msg.state.body["verified"]) - verified_log = f"Verified result for {tx_hash}: {verified}" - - if verified: - self.context.logger.info(verified_log) - return VerificationStatus.VERIFIED, tx_hash - - self.context.logger.info( - verified_log + f", all: {contract_api_msg.state.body}" - ) - - status = cast(int, contract_api_msg.state.body["status"]) - if status == -1: - self.context.logger.info(f"Tx hash {tx_hash} has no receipt!") - # this loop might take a long time - # we do not want to starve the rest of the behaviour - # we yield which freezes this loop here until the - # AbstractRoundBehaviour it belongs to, sends a tick to it - yield - continue - - tx_data = cast(TxData, contract_api_msg.state.body["transaction"]) - revert_reason = yield from self._get_revert_reason(tx_data) - - if revert_reason is not None: - if self._safe_nonce_reused(revert_reason): - self.context.logger.info( - f"The safe's nonce has been reused for {tx_hash}. " - f"{self.check_expected_to_be_verified} is expected to be verified!" - ) - was_nonce_reused = True - # this loop might take a long time - # we do not want to starve the rest of the behaviour - # we yield which freezes this loop here until the - # AbstractRoundBehaviour it belongs to, sends a tick to it - yield - continue - - self.context.logger.warning( - f"Payload is invalid for {tx_hash}! Cannot continue. Received: {revert_reason}" - ) - - return VerificationStatus.INVALID_PAYLOAD, tx_hash - - if was_nonce_reused: - self.context.logger.info( - f"Safe nonce {safe_nonce} was used, but no valid transaction was found. " - f"We cannot resend the transaction with the same nonce." - ) - return VerificationStatus.BAD_SAFE_NONCE, None - - return VerificationStatus.NOT_VERIFIED, None - - def _get_revert_reason(self, tx: TxData) -> Generator[None, None, Optional[str]]: - """Get the revert reason of the given transaction.""" - chain_id = self.synchronized_data.get_chain_id(self.params.default_chain_id) - contract_api_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_STATE, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="revert_reason", - tx=tx, - chain_id=chain_id, - ) - - if ( - contract_api_msg.performative != ContractApiMessage.Performative.STATE - ): # pragma: nocover - self.context.logger.error( - f"An unexpected error occurred while checking {tx['hash'].hex()}: {contract_api_msg}" - ) - return None - - return cast(str, contract_api_msg.state.body["revert_reason"]) - - -class CheckLateTxHashesBehaviour( # pylint: disable=too-many-ancestors - CheckTransactionHistoryBehaviour -): - """Check the late-arriving transaction hashes.""" - - matching_round = CheckLateTxHashesRound - check_expected_to_be_verified = "One of the next tx checks" - - @property - def history(self) -> List[str]: - """Get the history of hashes.""" - return [ - hash_ - for hashes in self.synchronized_data.late_arriving_tx_hashes.values() - for hash_ in hashes - ] - - -class SynchronizeLateMessagesBehaviour(TransactionSettlementBaseBehaviour): - """Synchronize late-arriving messages behaviour.""" - - matching_round = SynchronizeLateMessagesRound - - def __init__(self, **kwargs: Any): - """Initialize a `SynchronizeLateMessagesBehaviour`""" - super().__init__(**kwargs) - # if we timed out during finalization, but we managed to receive a tx hash, - # then we sync it here by initializing the `_tx_hashes` with the unsynced hash. - self._tx_hashes: str = self.params.mutable_params.tx_hash - self._messages_iterator: Iterator[ContractApiMessage] = iter( - self.params.mutable_params.late_messages - ) - self.use_flashbots = False - - def setup(self) -> None: - """Setup the `SynchronizeLateMessagesBehaviour`.""" - tx_params = skill_input_hex_to_payload( - self.synchronized_data.most_voted_tx_hash - ) - self.use_flashbots = tx_params["use_flashbots"] - - def async_act(self) -> Generator: - """Do the action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - current_message = next(self._messages_iterator, None) - if current_message is not None: - chain_id = self.synchronized_data.get_chain_id( - self.params.default_chain_id - ) - tx_data = yield from self._get_tx_data( - current_message, - self.use_flashbots, - chain_id=chain_id, - ) - self.context.logger.info( - f"Found a late arriving message {current_message}. Result data: {tx_data}" - ) - # here, we concatenate the tx_hashes of all the late-arriving messages. Later, we will parse them. - self._tx_hashes += cast(str, tx_data["tx_digest"]) - return - - payload = SynchronizeLateMessagesPayload( - self.context.agent_address, self._tx_hashes - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - # reset the local parameters if we were able to send them. - self.params.mutable_params.tx_hash = "" - self.params.mutable_params.late_messages = [] - yield from self.wait_until_round_end() - - self.set_done() - - -class SignatureBehaviour(TransactionSettlementBaseBehaviour): - """Signature behaviour.""" - - matching_round = CollectSignatureRound - - def async_act(self) -> Generator: - """ - Do the action. - - Steps: - - Request the signature of the transaction hash. - - Send the signature as a transaction and wait for it to be mined. - - Wait until ABCI application transitions to the next round. - - Go to the next behaviour (set done event). - """ - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - self.context.logger.info( - f"Agreement reached on tx data: {self.synchronized_data.most_voted_tx_hash}" - ) - signature_hex = yield from self._get_safe_tx_signature() - payload = SignaturePayload(self.context.agent_address, signature_hex) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - def _get_safe_tx_signature(self) -> Generator[None, None, str]: - """Get signature of safe transaction hash.""" - tx_params = skill_input_hex_to_payload( - self.synchronized_data.most_voted_tx_hash - ) - # is_deprecated_mode=True because we want to call Account.signHash, - # which is the same used by gnosis-py - safe_tx_hash_bytes = binascii.unhexlify(tx_params["safe_tx_hash"]) - signature_hex = yield from self.get_signature( - safe_tx_hash_bytes, is_deprecated_mode=True - ) - # remove the leading '0x' - signature_hex = signature_hex[2:] - self.context.logger.info(f"Signature: {signature_hex}") - return signature_hex - - -class FinalizeBehaviour(TransactionSettlementBaseBehaviour): - """Finalize behaviour.""" - - matching_round = FinalizationRound - - def _i_am_not_sending(self) -> bool: - """Indicates if the current agent is the sender or not.""" - return ( - self.context.agent_address - != self.synchronized_data.most_voted_keeper_address - ) - - def async_act(self) -> Generator[None, None, None]: - """ - Do the action. - - Steps: - - If the agent is the keeper, then prepare the transaction and send it. - - Otherwise, wait until the next round. - - If a timeout is hit, set exit A event, otherwise set done event. - """ - if self._i_am_not_sending(): - yield from self._not_sender_act() - else: - yield from self._sender_act() - - def _not_sender_act(self) -> Generator: - """Do the non-sender action.""" - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - self.context.logger.info( - f"Waiting for the keeper to do its keeping: {self.synchronized_data.most_voted_keeper_address}" - ) - yield from self.wait_until_round_end() - self.set_done() - - def _sender_act(self) -> Generator[None, None, None]: - """Do the sender action.""" - - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - self.context.logger.info( - "I am the designated sender, attempting to send the safe transaction..." - ) - tx_data = yield from self._send_safe_transaction() - if ( - tx_data["tx_digest"] == "" - and tx_data["status"] == VerificationStatus.PENDING - ) or tx_data["status"] == VerificationStatus.ERROR: - self.context.logger.error( - "Did not succeed with finalising the transaction!" - ) - elif tx_data["status"] == VerificationStatus.VERIFIED: - self.context.logger.error( - "Trying to finalize a transaction which has been verified already!" - ) - else: # pragma: no cover - self.context.logger.info( - f"Finalization tx digest: {cast(str, tx_data['tx_digest'])}" - ) - self.context.logger.debug( - f"Signatures: {pprint.pformat(self.synchronized_data.participant_to_signature)}" - ) - - tx_hashes_history = self.synchronized_data.tx_hashes_history - - if tx_data["tx_digest"] != "": - tx_hashes_history.append(cast(str, tx_data["tx_digest"])) - - tx_data_serialized = { - "status_value": cast(VerificationStatus, tx_data["status"]).value, - "serialized_keepers": self.serialized_keepers( - cast(Deque[str], tx_data["keepers"]), - cast(int, tx_data["keeper_retries"]), - ), - "blacklisted_keepers": "".join( - cast(Set[str], tx_data["blacklisted_keepers"]) - ), - "tx_hashes_history": "".join(tx_hashes_history), - "received_hash": bool(tx_data["tx_digest"]), - } - - payload = FinalizationTxPayload( - self.context.agent_address, - cast(Dict[str, Union[str, int, bool]], tx_data_serialized), - ) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - # reset the local tx hash parameter if we were able to send it - self.params.mutable_params.tx_hash = "" - yield from self.wait_until_round_end() - - self.set_done() - - def _send_safe_transaction( - self, - ) -> Generator[None, None, TxDataType]: - """Send a Safe transaction using the participants' signatures.""" - tx_params = skill_input_hex_to_payload( - self.synchronized_data.most_voted_tx_hash - ) - chain_id = self.synchronized_data.get_chain_id(self.params.default_chain_id) - contract_api_msg = yield from self.get_contract_api_response( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, # type: ignore - contract_address=self.synchronized_data.safe_contract_address, - contract_id=str(GnosisSafeContract.contract_id), - contract_callable="get_raw_safe_transaction", - sender_address=self.context.agent_address, - owners=tuple(self.synchronized_data.participants), - to_address=tx_params["to_address"], - value=tx_params["ether_value"], - data=tx_params["data"], - safe_tx_gas=tx_params["safe_tx_gas"], - signatures_by_owner={ - key: payload.signature - for key, payload in self.synchronized_data.participant_to_signature.items() - }, - nonce=self.params.mutable_params.nonce, - old_price=self.params.mutable_params.gas_price, - operation=tx_params["operation"], - fallback_gas=self.params.mutable_params.fallback_gas, - gas_price=self.params.gas_params.gas_price, - max_fee_per_gas=self.params.gas_params.max_fee_per_gas, - max_priority_fee_per_gas=self.params.gas_params.max_priority_fee_per_gas, - chain_id=chain_id, - ) - - tx_data = yield from self._get_tx_data( - contract_api_msg, - tx_params["use_flashbots"], - tx_params["gas_limit"], - tx_params["raise_on_failed_simulation"], - chain_id, - ) - return tx_data - - def handle_late_messages(self, behaviour_id: str, message: Message) -> None: - """Store a potentially late-arriving message locally. - - :param behaviour_id: the id of the behaviour in which the message belongs to. - :param message: the late arriving message to handle. - """ - if ( - isinstance(message, ContractApiMessage) - and behaviour_id == self.behaviour_id - ): - self.context.logger.info(f"Late message arrived: {message}") - self.params.mutable_params.late_messages.append(message) - else: - super().handle_late_messages(behaviour_id, message) - - -class ResetBehaviour(TransactionSettlementBaseBehaviour): - """Reset behaviour.""" - - matching_round = ResetRound - - def async_act(self) -> Generator: - """Do the action.""" - self.context.logger.info( - f"Period {self.synchronized_data.period_count} was not finished. Resetting!" - ) - payload = ResetPayload( - self.context.agent_address, self.synchronized_data.period_count - ) - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - self.set_done() - - -class TransactionSettlementRoundBehaviour(AbstractRoundBehaviour): - """This behaviour manages the consensus stages for the basic transaction settlement.""" - - initial_behaviour_cls = RandomnessTransactionSubmissionBehaviour - abci_app_cls = TransactionSubmissionAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - RandomnessTransactionSubmissionBehaviour, # type: ignore - SelectKeeperTransactionSubmissionBehaviourA, # type: ignore - SelectKeeperTransactionSubmissionBehaviourB, # type: ignore - SelectKeeperTransactionSubmissionBehaviourBAfterTimeout, # type: ignore - ValidateTransactionBehaviour, # type: ignore - CheckTransactionHistoryBehaviour, # type: ignore - SignatureBehaviour, # type: ignore - FinalizeBehaviour, # type: ignore - SynchronizeLateMessagesBehaviour, # type: ignore - CheckLateTxHashesBehaviour, # type: ignore - ResetBehaviour, # type: ignore - } diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/dialogues.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/dialogues.py deleted file mode 100644 index e244bde0b..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/dialogues.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/fsm_specification.yaml b/trader_old/vendor/valory/skills/transaction_settlement_abci/fsm_specification.yaml deleted file mode 100644 index 70b6e1f22..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/fsm_specification.yaml +++ /dev/null @@ -1,88 +0,0 @@ -alphabet_in: -- CHECK_HISTORY -- CHECK_LATE_ARRIVING_MESSAGE -- CHECK_TIMEOUT -- DONE -- FINALIZATION_FAILED -- FINALIZE_TIMEOUT -- INCORRECT_SERIALIZATION -- INSUFFICIENT_FUNDS -- NEGATIVE -- NONE -- NO_MAJORITY -- RESET_TIMEOUT -- ROUND_TIMEOUT -- SUSPICIOUS_ACTIVITY -- VALIDATE_TIMEOUT -default_start_state: RandomnessTransactionSubmissionRound -final_states: -- FailedRound -- FinishedTransactionSubmissionRound -label: TransactionSubmissionAbciApp -start_states: -- RandomnessTransactionSubmissionRound -states: -- CheckLateTxHashesRound -- CheckTransactionHistoryRound -- CollectSignatureRound -- FailedRound -- FinalizationRound -- FinishedTransactionSubmissionRound -- RandomnessTransactionSubmissionRound -- ResetRound -- SelectKeeperTransactionSubmissionARound -- SelectKeeperTransactionSubmissionBAfterTimeoutRound -- SelectKeeperTransactionSubmissionBRound -- SynchronizeLateMessagesRound -- ValidateTransactionRound -transition_func: - (CheckLateTxHashesRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (CheckLateTxHashesRound, CHECK_TIMEOUT): CheckLateTxHashesRound - (CheckLateTxHashesRound, DONE): FinishedTransactionSubmissionRound - (CheckLateTxHashesRound, NEGATIVE): FailedRound - (CheckLateTxHashesRound, NONE): FailedRound - (CheckLateTxHashesRound, NO_MAJORITY): FailedRound - (CheckTransactionHistoryRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (CheckTransactionHistoryRound, CHECK_TIMEOUT): CheckTransactionHistoryRound - (CheckTransactionHistoryRound, DONE): FinishedTransactionSubmissionRound - (CheckTransactionHistoryRound, NEGATIVE): SelectKeeperTransactionSubmissionBRound - (CheckTransactionHistoryRound, NONE): FailedRound - (CheckTransactionHistoryRound, NO_MAJORITY): CheckTransactionHistoryRound - (CollectSignatureRound, DONE): FinalizationRound - (CollectSignatureRound, NO_MAJORITY): ResetRound - (CollectSignatureRound, ROUND_TIMEOUT): CollectSignatureRound - (FinalizationRound, CHECK_HISTORY): CheckTransactionHistoryRound - (FinalizationRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (FinalizationRound, DONE): ValidateTransactionRound - (FinalizationRound, FINALIZATION_FAILED): SelectKeeperTransactionSubmissionBRound - (FinalizationRound, FINALIZE_TIMEOUT): SelectKeeperTransactionSubmissionBAfterTimeoutRound - (FinalizationRound, INSUFFICIENT_FUNDS): SelectKeeperTransactionSubmissionBRound - (RandomnessTransactionSubmissionRound, DONE): SelectKeeperTransactionSubmissionARound - (RandomnessTransactionSubmissionRound, NO_MAJORITY): RandomnessTransactionSubmissionRound - (RandomnessTransactionSubmissionRound, ROUND_TIMEOUT): RandomnessTransactionSubmissionRound - (ResetRound, DONE): RandomnessTransactionSubmissionRound - (ResetRound, NO_MAJORITY): FailedRound - (ResetRound, RESET_TIMEOUT): FailedRound - (SelectKeeperTransactionSubmissionARound, DONE): CollectSignatureRound - (SelectKeeperTransactionSubmissionARound, INCORRECT_SERIALIZATION): FailedRound - (SelectKeeperTransactionSubmissionARound, NO_MAJORITY): ResetRound - (SelectKeeperTransactionSubmissionARound, ROUND_TIMEOUT): SelectKeeperTransactionSubmissionARound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, CHECK_HISTORY): CheckTransactionHistoryRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, CHECK_LATE_ARRIVING_MESSAGE): SynchronizeLateMessagesRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, DONE): FinalizationRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, INCORRECT_SERIALIZATION): FailedRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, NO_MAJORITY): ResetRound - (SelectKeeperTransactionSubmissionBAfterTimeoutRound, ROUND_TIMEOUT): SelectKeeperTransactionSubmissionBAfterTimeoutRound - (SelectKeeperTransactionSubmissionBRound, DONE): FinalizationRound - (SelectKeeperTransactionSubmissionBRound, INCORRECT_SERIALIZATION): FailedRound - (SelectKeeperTransactionSubmissionBRound, NO_MAJORITY): ResetRound - (SelectKeeperTransactionSubmissionBRound, ROUND_TIMEOUT): SelectKeeperTransactionSubmissionBRound - (SynchronizeLateMessagesRound, DONE): CheckLateTxHashesRound - (SynchronizeLateMessagesRound, NONE): SelectKeeperTransactionSubmissionBRound - (SynchronizeLateMessagesRound, ROUND_TIMEOUT): SynchronizeLateMessagesRound - (SynchronizeLateMessagesRound, SUSPICIOUS_ACTIVITY): FailedRound - (ValidateTransactionRound, DONE): FinishedTransactionSubmissionRound - (ValidateTransactionRound, NEGATIVE): CheckTransactionHistoryRound - (ValidateTransactionRound, NONE): SelectKeeperTransactionSubmissionBRound - (ValidateTransactionRound, NO_MAJORITY): ValidateTransactionRound - (ValidateTransactionRound, VALIDATE_TIMEOUT): CheckTransactionHistoryRound diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/handlers.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/handlers.py deleted file mode 100644 index 9a4990be8..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/handlers.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the handler for the 'transaction_settlement_abci' skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ( - ABCIRoundHandler as BaseABCIRoundHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -ABCIHandler = BaseABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/models.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/models.py deleted file mode 100644 index e65bb6932..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/models.py +++ /dev/null @@ -1,123 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Custom objects for the transaction settlement ABCI application.""" -from dataclasses import dataclass, field -from typing import Any, Dict, List, Optional - -from web3.types import Nonce, Wei - -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.skills.abstract_round_abci.models import ApiSpecs, BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.abstract_round_abci.models import TypeCheckMixin -from packages.valory.skills.transaction_settlement_abci.rounds import ( - TransactionSubmissionAbciApp, -) - - -_MINIMUM_VALIDATE_TIMEOUT = 300 # 5 minutes -BenchmarkTool = BaseBenchmarkTool - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = TransactionSubmissionAbciApp - - -@dataclass -class MutableParams(TypeCheckMixin): - """Collection for the mutable parameters.""" - - fallback_gas: int - tx_hash: str = "" - nonce: Optional[Nonce] = None - gas_price: Optional[Dict[str, Wei]] = None - late_messages: List[ContractApiMessage] = field(default_factory=list) - - -@dataclass -class GasParams(BaseParams): - """Gas parameters.""" - - gas_price: Optional[int] = None - max_fee_per_gas: Optional[int] = None - max_priority_fee_per_gas: Optional[int] = None - - -class TransactionParams(BaseParams): # pylint: disable=too-many-instance-attributes - """Transaction settlement agent-specific parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """ - Initialize the parameters object. - - We keep track of the nonce and tip across rounds and periods. - We reuse it each time a new raw transaction is generated. If - at the time of the new raw transaction being generated the nonce - on the ledger does not match the nonce on the skill, then we ignore - the skill nonce and tip (effectively we price fresh). Otherwise, we - are in a re-submission scenario where we need to take account of the - old tip. - - :param args: positional arguments - :param kwargs: keyword arguments - """ - self.mutable_params = MutableParams( - fallback_gas=self._ensure("init_fallback_gas", kwargs, int) - ) - self.keeper_allowed_retries: int = self._ensure( - "keeper_allowed_retries", kwargs, int - ) - self.validate_timeout: int = self._ensure_gte( - "validate_timeout", - kwargs, - int, - min_value=_MINIMUM_VALIDATE_TIMEOUT, - ) - self.finalize_timeout: float = self._ensure("finalize_timeout", kwargs, float) - self.history_check_timeout: int = self._ensure( - "history_check_timeout", kwargs, int - ) - self.gas_params = self._get_gas_params(kwargs) - super().__init__(*args, **kwargs) - - @staticmethod - def _get_gas_params(kwargs: Dict[str, Any]) -> GasParams: - """Get the gas parameters.""" - gas_params = kwargs.pop("gas_params", {}) - gas_price = gas_params.get("gas_price", None) - max_fee_per_gas = gas_params.get("max_fee_per_gas", None) - max_priority_fee_per_gas = gas_params.get("max_priority_fee_per_gas", None) - return GasParams( - gas_price=gas_price, - max_fee_per_gas=max_fee_per_gas, - max_priority_fee_per_gas=max_priority_fee_per_gas, - ) - - -RandomnessApi = ApiSpecs -Requests = BaseRequests diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/payload_tools.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/payload_tools.py deleted file mode 100644 index 44a86883f..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/payload_tools.py +++ /dev/null @@ -1,183 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Tools for payload serialization and deserialization.""" - -from enum import Enum -from typing import Any, Optional, Tuple - -from packages.valory.contracts.gnosis_safe.contract import SafeOperation - - -NULL_ADDRESS: str = "0x" + "0" * 40 -MAX_UINT256 = 2**256 - 1 - - -class VerificationStatus(Enum): - """Tx verification status enumeration.""" - - VERIFIED = 1 - NOT_VERIFIED = 2 - INVALID_PAYLOAD = 3 - PENDING = 4 - ERROR = 5 - INSUFFICIENT_FUNDS = 6 - BAD_SAFE_NONCE = 7 - - -class PayloadDeserializationError(Exception): - """Exception for payload deserialization errors.""" - - def __init__(self, *args: Any) -> None: - """Initialize the exception. - - :param args: extra arguments to pass to the constructor of `Exception`. - """ - msg: str = "Cannot decode provided payload!" - if not args: - args = (msg,) - - super().__init__(*args) - - -def tx_hist_payload_to_hex( - verification: VerificationStatus, tx_hash: Optional[str] = None -) -> str: - """Serialise history payload to a hex string.""" - if tx_hash is None: - tx_hash = "" - else: - tx_hash = tx_hash[2:] if tx_hash.startswith("0x") else tx_hash - if len(tx_hash) != 64: - raise ValueError("Cannot encode tx_hash of non-32 bytes") - verification_ = verification.value.to_bytes(32, "big").hex() - concatenated = verification_ + tx_hash - return concatenated - - -def tx_hist_hex_to_payload(payload: str) -> Tuple[VerificationStatus, Optional[str]]: - """Decode history payload.""" - if len(payload) != 64 and len(payload) != 64 * 2: - raise PayloadDeserializationError() - - verification_value = int.from_bytes(bytes.fromhex(payload[:64]), "big") - - try: - verification_status = VerificationStatus(verification_value) - except ValueError as e: - raise PayloadDeserializationError(str(e)) from e - - if len(payload) == 64: - return verification_status, None - - return verification_status, "0x" + payload[64:] - - -def hash_payload_to_hex( # pylint: disable=too-many-arguments, too-many-locals - safe_tx_hash: str, - ether_value: int, - safe_tx_gas: int, - to_address: str, - data: bytes, - operation: int = SafeOperation.CALL.value, - base_gas: int = 0, - safe_gas_price: int = 0, - gas_token: str = NULL_ADDRESS, - refund_receiver: str = NULL_ADDRESS, - use_flashbots: bool = False, - gas_limit: int = 0, - raise_on_failed_simulation: bool = False, -) -> str: - """Serialise to a hex string.""" - if len(safe_tx_hash) != 64: # should be exactly 32 bytes! - raise ValueError( - "cannot encode safe_tx_hash of non-32 bytes" - ) # pragma: nocover - - if len(to_address) != 42 or len(gas_token) != 42 or len(refund_receiver) != 42: - raise ValueError("cannot encode address of non 42 length") # pragma: nocover - - if ( - ether_value > MAX_UINT256 - or safe_tx_gas > MAX_UINT256 - or base_gas > MAX_UINT256 - or safe_gas_price > MAX_UINT256 - or gas_limit > MAX_UINT256 - ): - raise ValueError( - "Value is bigger than the max 256 bit value" - ) # pragma: nocover - - if operation not in [v.value for v in SafeOperation]: - raise ValueError("SafeOperation value is not valid") # pragma: nocover - - if not isinstance(use_flashbots, bool): - raise ValueError( - f"`use_flashbots` value ({use_flashbots}) is not valid. A boolean value was expected instead" - ) - - ether_value_ = ether_value.to_bytes(32, "big").hex() - safe_tx_gas_ = safe_tx_gas.to_bytes(32, "big").hex() - operation_ = operation.to_bytes(1, "big").hex() - base_gas_ = base_gas.to_bytes(32, "big").hex() - safe_gas_price_ = safe_gas_price.to_bytes(32, "big").hex() - use_flashbots_ = use_flashbots.to_bytes(32, "big").hex() - gas_limit_ = gas_limit.to_bytes(32, "big").hex() - raise_on_failed_simulation_ = raise_on_failed_simulation.to_bytes(32, "big").hex() - - concatenated = ( - safe_tx_hash - + ether_value_ - + safe_tx_gas_ - + to_address - + operation_ - + base_gas_ - + safe_gas_price_ - + gas_token - + refund_receiver - + use_flashbots_ - + gas_limit_ - + raise_on_failed_simulation_ - + data.hex() - ) - return concatenated - - -def skill_input_hex_to_payload(payload: str) -> dict: - """Decode payload.""" - if len(payload) < 234: - raise PayloadDeserializationError() # pragma: nocover - tx_params = dict( - safe_tx_hash=payload[:64], - ether_value=int.from_bytes(bytes.fromhex(payload[64:128]), "big"), - safe_tx_gas=int.from_bytes(bytes.fromhex(payload[128:192]), "big"), - to_address=payload[192:234], - operation=int.from_bytes(bytes.fromhex(payload[234:236]), "big"), - base_gas=int.from_bytes(bytes.fromhex(payload[236:300]), "big"), - safe_gas_price=int.from_bytes(bytes.fromhex(payload[300:364]), "big"), - gas_token=payload[364:406], - refund_receiver=payload[406:448], - use_flashbots=bool.from_bytes(bytes.fromhex(payload[448:512]), "big"), - gas_limit=int.from_bytes(bytes.fromhex(payload[512:576]), "big"), - raise_on_failed_simulation=bool.from_bytes( - bytes.fromhex(payload[576:640]), "big" - ), - data=bytes.fromhex(payload[640:]), - ) - return tx_params diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/payloads.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/payloads.py deleted file mode 100644 index 16dad1edc..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/payloads.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the transaction payloads for common apps.""" - -from dataclasses import dataclass -from typing import Dict, Optional, Union - -from packages.valory.skills.abstract_round_abci.base import BaseTxPayload - - -@dataclass(frozen=True) -class RandomnessPayload(BaseTxPayload): - """Represent a transaction payload of type 'randomness'.""" - - round_id: int - randomness: str - - -@dataclass(frozen=True) -class SelectKeeperPayload(BaseTxPayload): - """Represent a transaction payload of type 'select_keeper'.""" - - keepers: str - - -@dataclass(frozen=True) -class ValidatePayload(BaseTxPayload): - """Represent a transaction payload of type 'validate'.""" - - vote: Optional[bool] = None - - -@dataclass(frozen=True) -class CheckTransactionHistoryPayload(BaseTxPayload): - """Represent a transaction payload of type 'check'.""" - - verified_res: str - - -@dataclass(frozen=True) -class SynchronizeLateMessagesPayload(BaseTxPayload): - """Represent a transaction payload of type 'synchronize'.""" - - tx_hashes: str - - -@dataclass(frozen=True) -class SignaturePayload(BaseTxPayload): - """Represent a transaction payload of type 'signature'.""" - - signature: str - - -@dataclass(frozen=True) -class FinalizationTxPayload(BaseTxPayload): - """Represent a transaction payload of type 'finalization'.""" - - tx_data: Optional[Dict[str, Union[str, int, bool]]] = None - - -@dataclass(frozen=True) -class ResetPayload(BaseTxPayload): - """Represent a transaction payload of type 'reset'.""" - - period_count: int diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/rounds.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/rounds.py deleted file mode 100644 index d6231ee3d..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/rounds.py +++ /dev/null @@ -1,831 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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 the data classes for the `transaction settlement` ABCI application.""" - -import textwrap -from abc import ABC -from collections import deque -from enum import Enum -from typing import Deque, Dict, List, Mapping, Optional, Set, Tuple, cast - -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciApp, - AbciAppTransitionFunction, - AppState, - BaseSynchronizedData, - BaseTxPayload, - CollectDifferentUntilThresholdRound, - CollectNonEmptyUntilThresholdRound, - CollectSameUntilThresholdRound, - CollectionRound, - DegenerateRound, - OnlyKeeperSendsRound, - TransactionNotValidError, - VALUE_NOT_PROVIDED, - VotingRound, - get_name, -) -from packages.valory.skills.abstract_round_abci.utils import filter_negative -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - VerificationStatus, - tx_hist_hex_to_payload, -) -from packages.valory.skills.transaction_settlement_abci.payloads import ( - CheckTransactionHistoryPayload, - FinalizationTxPayload, - RandomnessPayload, - ResetPayload, - SelectKeeperPayload, - SignaturePayload, - SynchronizeLateMessagesPayload, - ValidatePayload, -) - - -ADDRESS_LENGTH = 42 -TX_HASH_LENGTH = 66 -RETRIES_LENGTH = 64 - - -class Event(Enum): - """Event enumeration for the price estimation demo.""" - - DONE = "done" - ROUND_TIMEOUT = "round_timeout" - NO_MAJORITY = "no_majority" - NEGATIVE = "negative" - NONE = "none" - FINALIZE_TIMEOUT = "finalize_timeout" - VALIDATE_TIMEOUT = "validate_timeout" - CHECK_TIMEOUT = "check_timeout" - RESET_TIMEOUT = "reset_timeout" - CHECK_HISTORY = "check_history" - CHECK_LATE_ARRIVING_MESSAGE = "check_late_arriving_message" - FINALIZATION_FAILED = "finalization_failed" - SUSPICIOUS_ACTIVITY = "suspicious_activity" - INSUFFICIENT_FUNDS = "insufficient_funds" - INCORRECT_SERIALIZATION = "incorrect_serialization" - - -class SynchronizedData( - BaseSynchronizedData -): # pylint: disable=too-many-instance-attributes - """ - Class to represent the synchronized data. - - This data is replicated by the tendermint application. - """ - - @property - def participant_to_signature(self) -> Mapping[str, SignaturePayload]: - """Get the participant_to_signature.""" - serialized = self.db.get_strict("participant_to_signature") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(Mapping[str, SignaturePayload], deserialized) - - @property - def tx_hashes_history(self) -> List[str]: - """Get the current cycle's tx hashes history, which has not yet been verified.""" - raw = cast(str, self.db.get("tx_hashes_history", "")) - return textwrap.wrap(raw, TX_HASH_LENGTH) - - @property - def keepers(self) -> Deque[str]: - """Get the current cycle's keepers who have tried to submit a transaction.""" - if self.is_keeper_set: - keepers_unparsed = cast(str, self.db.get_strict("keepers")) - keepers_parsed = textwrap.wrap( - keepers_unparsed[RETRIES_LENGTH:], ADDRESS_LENGTH - ) - return deque(keepers_parsed) - return deque() - - @property - def keepers_threshold_exceeded(self) -> bool: - """Check if the number of selected keepers has exceeded the allowed limit.""" - malicious_threshold = self.nb_participants // 3 - return len(self.keepers) > malicious_threshold - - @property - def most_voted_randomness_round(self) -> int: # pragma: no cover - """Get the first in priority keeper to try to re-submit a transaction.""" - round_ = self.db.get_strict("most_voted_randomness_round") - return cast(int, round_) - - @property - def most_voted_keeper_address(self) -> str: - """Get the first in priority keeper to try to re-submit a transaction.""" - return self.keepers[0] - - @property # TODO: overrides base property, investigate - def is_keeper_set(self) -> bool: - """Check whether keeper is set.""" - return bool(self.db.get("keepers", False)) - - @property - def keeper_retries(self) -> int: - """Get the number of times the current keeper has retried.""" - if self.is_keeper_set: - keepers_unparsed = cast(str, self.db.get_strict("keepers")) - keeper_retries = int.from_bytes( - bytes.fromhex(keepers_unparsed[:RETRIES_LENGTH]), "big" - ) - return keeper_retries - return 0 - - @property - def to_be_validated_tx_hash(self) -> str: - """ - Get the tx hash which is ready for validation. - - This will always be the last hash in the `tx_hashes_history`, - due to the way we are inserting the hashes in the array. - We keep the hashes sorted by the time of their finalization. - If this property is accessed before the finalization succeeds, - then it is incorrectly used and raises an error. - - :return: the tx hash which is ready for validation. - """ - if not self.tx_hashes_history: - raise ValueError( - "FSM design error: tx hash should exist" - ) # pragma: no cover - return self.tx_hashes_history[-1] - - @property - def final_tx_hash(self) -> str: - """Get the verified tx hash.""" - return cast(str, self.db.get_strict("final_tx_hash")) - - @property - def final_verification_status(self) -> VerificationStatus: - """Get the final verification status.""" - status_value = self.db.get("final_verification_status", None) - if status_value is None: - return VerificationStatus.NOT_VERIFIED - return VerificationStatus(status_value) - - @property - def most_voted_tx_hash(self) -> str: - """Get the most_voted_tx_hash.""" - return cast(str, self.db.get_strict("most_voted_tx_hash")) - - @property - def missed_messages(self) -> Dict[str, int]: - """The number of missed messages per agent address.""" - default = dict.fromkeys(self.all_participants, 0) - missed_messages = self.db.get("missed_messages", default) - return cast(Dict[str, int], missed_messages) - - @property - def n_missed_messages(self) -> int: - """The number of missed messages in total.""" - return sum(self.missed_messages.values()) - - @property - def should_check_late_messages(self) -> bool: - """Check if we should check for late-arriving messages.""" - return self.n_missed_messages > 0 - - @property - def late_arriving_tx_hashes(self) -> Dict[str, List[str]]: - """Get the late_arriving_tx_hashes.""" - late_arrivals = cast( - Dict[str, str], self.db.get_strict("late_arriving_tx_hashes") - ) - parsed_hashes = { - sender: textwrap.wrap(hashes, TX_HASH_LENGTH) - for sender, hashes in late_arrivals.items() - } - return parsed_hashes - - @property - def suspects(self) -> Tuple[str]: - """Get the suspect agents.""" - return cast(Tuple[str], self.db.get("suspects", tuple())) - - @property - def most_voted_check_result(self) -> str: # pragma: no cover - """Get the most voted checked result.""" - return cast(str, self.db.get_strict("most_voted_check_result")) - - @property - def participant_to_check( - self, - ) -> Mapping[str, CheckTransactionHistoryPayload]: # pragma: no cover - """Get the mapping from participants to checks.""" - serialized = self.db.get_strict("participant_to_check") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(Mapping[str, CheckTransactionHistoryPayload], deserialized) - - @property - def participant_to_late_messages( - self, - ) -> Mapping[str, SynchronizeLateMessagesPayload]: # pragma: no cover - """Get the mapping from participants to checks.""" - serialized = self.db.get_strict("participant_to_late_message") - deserialized = CollectionRound.deserialize_collection(serialized) - return cast(Mapping[str, SynchronizeLateMessagesPayload], deserialized) - - def get_chain_id(self, default_chain_id: str) -> str: - """Get the chain id.""" - return cast(str, self.db.get("chain_id", default_chain_id)) - - -class FailedRound(DegenerateRound, ABC): - """A round that represents that the period failed""" - - -class CollectSignatureRound(CollectDifferentUntilThresholdRound): - """A round in which agents sign the transaction""" - - payload_class = SignaturePayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_signature) - - -class FinalizationRound(OnlyKeeperSendsRound): - """A round that represents transaction signing has finished""" - - keeper_payload: Optional[FinalizationTxPayload] = None - payload_class = FinalizationTxPayload - synchronized_data_class = SynchronizedData - - def end_block( # pylint: disable=too-many-return-statements - self, - ) -> Optional[ - Tuple[BaseSynchronizedData, Enum] - ]: # pylint: disable=too-many-return-statements - """Process the end of the block.""" - if self.keeper_payload is None: - return None - - if self.keeper_payload.tx_data is None: - return self.synchronized_data, Event.FINALIZATION_FAILED - - verification_status = VerificationStatus( - self.keeper_payload.tx_data["status_value"] - ) - synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{ - get_name( - SynchronizedData.tx_hashes_history - ): self.keeper_payload.tx_data["tx_hashes_history"], - get_name( - SynchronizedData.final_verification_status - ): verification_status.value, - get_name(SynchronizedData.keepers): self.keeper_payload.tx_data[ - "serialized_keepers" - ], - get_name( - SynchronizedData.blacklisted_keepers - ): self.keeper_payload.tx_data["blacklisted_keepers"], - }, - ), - ) - - # check if we succeeded in finalization. - # we may fail in any of the following cases: - # 1. Getting raw safe transaction. - # 2. Requesting transaction signature. - # 3. Requesting transaction digest. - if self.keeper_payload.tx_data["received_hash"]: - return synchronized_data, Event.DONE - # If keeper has been blacklisted, return an `INSUFFICIENT_FUNDS` event. - if verification_status == VerificationStatus.INSUFFICIENT_FUNDS: - return synchronized_data, Event.INSUFFICIENT_FUNDS - # This means that getting raw safe transaction succeeded, - # but either requesting tx signature or requesting tx digest failed. - if verification_status not in ( - VerificationStatus.ERROR, - VerificationStatus.VERIFIED, - ): - return synchronized_data, Event.FINALIZATION_FAILED - # if there is a tx hash history, then check it for validated txs. - if synchronized_data.tx_hashes_history: - return synchronized_data, Event.CHECK_HISTORY - # if there could be any late messages, check if any has arrived. - if synchronized_data.should_check_late_messages: - return synchronized_data, Event.CHECK_LATE_ARRIVING_MESSAGE - # otherwise fail. - return synchronized_data, Event.FINALIZATION_FAILED - - -class RandomnessTransactionSubmissionRound(CollectSameUntilThresholdRound): - """A round for generating randomness""" - - payload_class = RandomnessPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_randomness) - selection_key = ( - get_name(SynchronizedData.most_voted_randomness_round), - get_name(SynchronizedData.most_voted_randomness), - ) - - -class SelectKeeperTransactionSubmissionARound(CollectSameUntilThresholdRound): - """A round in which a keeper is selected for transaction submission""" - - payload_class = SelectKeeperPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_selection) - selection_key = get_name(SynchronizedData.keepers) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - - if self.threshold_reached and self.most_voted_payload is not None: - if ( - len(self.most_voted_payload) < RETRIES_LENGTH + ADDRESS_LENGTH - or (len(self.most_voted_payload) - RETRIES_LENGTH) % ADDRESS_LENGTH != 0 - ): - # if we cannot parse the keepers' payload, then the developer has serialized it incorrectly. - return self.synchronized_data, Event.INCORRECT_SERIALIZATION - - return super().end_block() - - -class SelectKeeperTransactionSubmissionBRound(SelectKeeperTransactionSubmissionARound): - """A round in which a new keeper is selected for transaction submission""" - - -class SelectKeeperTransactionSubmissionBAfterTimeoutRound( - SelectKeeperTransactionSubmissionBRound -): - """A round in which a new keeper is selected for tx submission after a round timeout of the previous keeper""" - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.threshold_reached: - synchronized_data = cast(SynchronizedData, self.synchronized_data) - keeper = synchronized_data.most_voted_keeper_address - missed_messages = synchronized_data.missed_messages - missed_messages[keeper] += 1 - - synchronized_data = cast( - SynchronizedData, - self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{get_name(SynchronizedData.missed_messages): missed_messages}, - ), - ) - if synchronized_data.keepers_threshold_exceeded: - # we only stop re-selection if there are any previous transaction hashes or any missed messages. - if len(synchronized_data.tx_hashes_history) > 0: - return synchronized_data, Event.CHECK_HISTORY - if synchronized_data.should_check_late_messages: - return synchronized_data, Event.CHECK_LATE_ARRIVING_MESSAGE - return super().end_block() - - -class ValidateTransactionRound(VotingRound): - """A round in which agents validate the transaction""" - - payload_class = ValidatePayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - negative_event = Event.NEGATIVE - none_event = Event.NONE - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_votes) - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - # if reached participant threshold, set the result - - if self.positive_vote_threshold_reached: - # We obtain the latest tx hash from the `tx_hashes_history`. - # We keep the hashes sorted by their finalization time. - # If this property is accessed before the finalization succeeds, - # then it is incorrectly used. - final_tx_hash = cast( - SynchronizedData, self.synchronized_data - ).to_be_validated_tx_hash - - # We only set the final tx hash if we are about to exit from the transaction settlement skill. - # Then, the skills which use the transaction settlement can check the tx hash - # and if it is None, then it means that the transaction has failed. - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{ - self.collection_key: self.serialized_collection, - get_name( - SynchronizedData.final_verification_status - ): VerificationStatus.VERIFIED.value, - get_name(SynchronizedData.final_tx_hash): final_tx_hash, - }, - ) - return synchronized_data, self.done_event - if self.negative_vote_threshold_reached: - return self.synchronized_data, self.negative_event - if self.none_vote_threshold_reached: - return self.synchronized_data, self.none_event - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, self.no_majority_event - return None - - -class CheckTransactionHistoryRound(CollectSameUntilThresholdRound): - """A round in which agents check the transaction history to see if any previous tx has been validated""" - - payload_class = CheckTransactionHistoryPayload - synchronized_data_class = SynchronizedData - collection_key = get_name(SynchronizedData.participant_to_check) - selection_key = get_name(SynchronizedData.most_voted_check_result) - - def end_block( # pylint: disable=too-many-return-statements - self, - ) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """Process the end of the block.""" - if self.threshold_reached: - return_status, return_tx_hash = tx_hist_hex_to_payload( - self.most_voted_payload - ) - - if return_status == VerificationStatus.NOT_VERIFIED: - # We don't update the synchronized_data as we need to repeat all checks again later - synchronized_data = self.synchronized_data - else: - # We only set the final tx hash if we are about to exit from the transaction settlement skill. - # Then, the skills which use the transaction settlement can check the tx hash - # and if it is None, then it means that the transaction has failed. - synchronized_data = self.synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{ - self.collection_key: self.serialized_collection, - self.selection_key: self.most_voted_payload, - get_name( - SynchronizedData.final_verification_status - ): return_status.value, - get_name(SynchronizedData.final_tx_hash): return_tx_hash, - }, - ) - - if return_status == VerificationStatus.VERIFIED: - return synchronized_data, Event.DONE - if ( - return_status == VerificationStatus.NOT_VERIFIED - and cast( - SynchronizedData, self.synchronized_data - ).should_check_late_messages - ): - return synchronized_data, Event.CHECK_LATE_ARRIVING_MESSAGE - if return_status == VerificationStatus.NOT_VERIFIED: - return synchronized_data, Event.NEGATIVE - if return_status == VerificationStatus.BAD_SAFE_NONCE: - # in case a bad nonce was used, we need to recreate the tx from scratch - return synchronized_data, Event.NONE - - return synchronized_data, Event.NONE - - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, Event.NO_MAJORITY - return None - - -class CheckLateTxHashesRound(CheckTransactionHistoryRound): - """A round in which agents check the late-arriving transaction hashes to see if any of them has been validated""" - - -class SynchronizeLateMessagesRound(CollectNonEmptyUntilThresholdRound): - """A round in which agents synchronize potentially late arriving messages""" - - payload_class = SynchronizeLateMessagesPayload - synchronized_data_class = SynchronizedData - done_event = Event.DONE - none_event = Event.NONE - required_block_confirmations = 3 - selection_key = get_name(SynchronizedData.late_arriving_tx_hashes) - collection_key = get_name(SynchronizedData.participant_to_late_messages) - # if the payload is serialized to bytes, we verify that the length specified matches - _hash_length = TX_HASH_LENGTH - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - result = super().end_block() - if result is None: - return None - - synchronized_data, event = cast(Tuple[SynchronizedData, Event], result) - - late_arriving_tx_hashes_counts = { - sender: len(hashes) - for sender, hashes in synchronized_data.late_arriving_tx_hashes.items() - } - missed_after_sync = { - sender: missed - late_arriving_tx_hashes_counts.get(sender, 0) - for sender, missed in synchronized_data.missed_messages.items() - } - suspects = tuple(filter_negative(missed_after_sync)) - - if suspects: - synchronized_data = cast( - SynchronizedData, - synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{get_name(SynchronizedData.suspects): suspects}, - ), - ) - return synchronized_data, Event.SUSPICIOUS_ACTIVITY - - synchronized_data = cast( - SynchronizedData, - synchronized_data.update( - synchronized_data_class=self.synchronized_data_class, - **{get_name(SynchronizedData.missed_messages): missed_after_sync}, - ), - ) - return synchronized_data, event - - def process_payload(self, payload: BaseTxPayload) -> None: - """Process payload.""" - # TODO: move check into payload definition via `post_init` - payload = cast(SynchronizeLateMessagesPayload, payload) - if self._hash_length: - content = payload.tx_hashes - if not content or len(content) % self._hash_length: - msg = f"Expecting serialized data of chunk size {self._hash_length}" - raise ABCIAppInternalError(f"{msg}, got: {content} in {self.round_id}") - super().process_payload(payload) - - def check_payload(self, payload: BaseTxPayload) -> None: - """Check Payload""" - # TODO: move check into payload definition via `post_init` - payload = cast(SynchronizeLateMessagesPayload, payload) - if self._hash_length: - content = payload.tx_hashes - if not content or len(content) % self._hash_length: - msg = f"Expecting serialized data of chunk size {self._hash_length}" - raise TransactionNotValidError( - f"{msg}, got: {content} in {self.round_id}" - ) - super().check_payload(payload) - - -class FinishedTransactionSubmissionRound(DegenerateRound, ABC): - """A round that represents the transition to the ResetAndPauseRound""" - - -class ResetRound(CollectSameUntilThresholdRound): - """A round that represents the reset of a period""" - - payload_class = ResetPayload - synchronized_data_class = SynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Event]]: - """Process the end of the block.""" - if self.threshold_reached: - synchronized_data = cast(SynchronizedData, self.synchronized_data) - # we could have used the `synchronized_data.create()` here and set the `cross_period_persisted_keys` - # with the corresponding properties' keys. However, the cross period keys would get passed over - # for all the following periods, even those that the tx settlement succeeds. - # Therefore, we need to manually call the db's create method and pass the keys we want to keep only - # for the next period, which comes after a `NO_MAJORITY` event of the tx settlement skill. - # TODO investigate the following: - # This probably indicates an issue with the logic of this skill. We should not increase the period since - # we have a failure. We could instead just remove the `ResetRound` and transition to the - # `RandomnessTransactionSubmissionRound` directly. This would save us one round, would allow us to remove - # this hacky logic for the `create`, and would also not increase the period count in non-successful events - self.synchronized_data.db.create( - **{ - db_key: synchronized_data.db.get(db_key, default) - for db_key, default in { - "all_participants": VALUE_NOT_PROVIDED, - "participants": VALUE_NOT_PROVIDED, - "consensus_threshold": VALUE_NOT_PROVIDED, - "safe_contract_address": VALUE_NOT_PROVIDED, - "tx_hashes_history": "", - "keepers": VALUE_NOT_PROVIDED, - "missed_messages": dict.fromkeys( - synchronized_data.all_participants, 0 - ), - "late_arriving_tx_hashes": VALUE_NOT_PROVIDED, - "suspects": tuple(), - }.items() - } - ) - return self.synchronized_data, Event.DONE - if not self.is_majority_possible( - self.collection, self.synchronized_data.nb_participants - ): - return self.synchronized_data, Event.NO_MAJORITY - return None - - -class TransactionSubmissionAbciApp(AbciApp[Event]): - """TransactionSubmissionAbciApp - - Initial round: RandomnessTransactionSubmissionRound - - Initial states: {RandomnessTransactionSubmissionRound} - - Transition states: - 0. RandomnessTransactionSubmissionRound - - done: 1. - - round timeout: 0. - - no majority: 0. - 1. SelectKeeperTransactionSubmissionARound - - done: 2. - - round timeout: 1. - - no majority: 10. - - incorrect serialization: 12. - 2. CollectSignatureRound - - done: 3. - - round timeout: 2. - - no majority: 10. - 3. FinalizationRound - - done: 4. - - check history: 5. - - finalize timeout: 7. - - finalization failed: 6. - - check late arriving message: 8. - - insufficient funds: 6. - 4. ValidateTransactionRound - - done: 11. - - negative: 5. - - none: 6. - - validate timeout: 5. - - no majority: 4. - 5. CheckTransactionHistoryRound - - done: 11. - - negative: 6. - - none: 12. - - check timeout: 5. - - no majority: 5. - - check late arriving message: 8. - 6. SelectKeeperTransactionSubmissionBRound - - done: 3. - - round timeout: 6. - - no majority: 10. - - incorrect serialization: 12. - 7. SelectKeeperTransactionSubmissionBAfterTimeoutRound - - done: 3. - - check history: 5. - - check late arriving message: 8. - - round timeout: 7. - - no majority: 10. - - incorrect serialization: 12. - 8. SynchronizeLateMessagesRound - - done: 9. - - round timeout: 8. - - none: 6. - - suspicious activity: 12. - 9. CheckLateTxHashesRound - - done: 11. - - negative: 12. - - none: 12. - - check timeout: 9. - - no majority: 12. - - check late arriving message: 8. - 10. ResetRound - - done: 0. - - reset timeout: 12. - - no majority: 12. - 11. FinishedTransactionSubmissionRound - 12. FailedRound - - Final states: {FailedRound, FinishedTransactionSubmissionRound} - - Timeouts: - round timeout: 30.0 - finalize timeout: 30.0 - validate timeout: 30.0 - check timeout: 30.0 - reset timeout: 30.0 - """ - - initial_round_cls: AppState = RandomnessTransactionSubmissionRound - initial_states: Set[AppState] = {RandomnessTransactionSubmissionRound} - transition_function: AbciAppTransitionFunction = { - RandomnessTransactionSubmissionRound: { - Event.DONE: SelectKeeperTransactionSubmissionARound, - Event.ROUND_TIMEOUT: RandomnessTransactionSubmissionRound, - Event.NO_MAJORITY: RandomnessTransactionSubmissionRound, - }, - SelectKeeperTransactionSubmissionARound: { - Event.DONE: CollectSignatureRound, - Event.ROUND_TIMEOUT: SelectKeeperTransactionSubmissionARound, - Event.NO_MAJORITY: ResetRound, - Event.INCORRECT_SERIALIZATION: FailedRound, - }, - CollectSignatureRound: { - Event.DONE: FinalizationRound, - Event.ROUND_TIMEOUT: CollectSignatureRound, - Event.NO_MAJORITY: ResetRound, - }, - FinalizationRound: { - Event.DONE: ValidateTransactionRound, - Event.CHECK_HISTORY: CheckTransactionHistoryRound, - Event.FINALIZE_TIMEOUT: SelectKeeperTransactionSubmissionBAfterTimeoutRound, - Event.FINALIZATION_FAILED: SelectKeeperTransactionSubmissionBRound, - Event.CHECK_LATE_ARRIVING_MESSAGE: SynchronizeLateMessagesRound, - Event.INSUFFICIENT_FUNDS: SelectKeeperTransactionSubmissionBRound, - }, - ValidateTransactionRound: { - Event.DONE: FinishedTransactionSubmissionRound, - Event.NEGATIVE: CheckTransactionHistoryRound, - Event.NONE: SelectKeeperTransactionSubmissionBRound, - # even in case of timeout we might've sent the transaction - # so we need to check the history - Event.VALIDATE_TIMEOUT: CheckTransactionHistoryRound, - Event.NO_MAJORITY: ValidateTransactionRound, - }, - CheckTransactionHistoryRound: { - Event.DONE: FinishedTransactionSubmissionRound, - Event.NEGATIVE: SelectKeeperTransactionSubmissionBRound, - Event.NONE: FailedRound, - Event.CHECK_TIMEOUT: CheckTransactionHistoryRound, - Event.NO_MAJORITY: CheckTransactionHistoryRound, - Event.CHECK_LATE_ARRIVING_MESSAGE: SynchronizeLateMessagesRound, - }, - SelectKeeperTransactionSubmissionBRound: { - Event.DONE: FinalizationRound, - Event.ROUND_TIMEOUT: SelectKeeperTransactionSubmissionBRound, - Event.NO_MAJORITY: ResetRound, - Event.INCORRECT_SERIALIZATION: FailedRound, - }, - SelectKeeperTransactionSubmissionBAfterTimeoutRound: { - Event.DONE: FinalizationRound, - Event.CHECK_HISTORY: CheckTransactionHistoryRound, - Event.CHECK_LATE_ARRIVING_MESSAGE: SynchronizeLateMessagesRound, - Event.ROUND_TIMEOUT: SelectKeeperTransactionSubmissionBAfterTimeoutRound, - Event.NO_MAJORITY: ResetRound, - Event.INCORRECT_SERIALIZATION: FailedRound, - }, - SynchronizeLateMessagesRound: { - Event.DONE: CheckLateTxHashesRound, - Event.ROUND_TIMEOUT: SynchronizeLateMessagesRound, - Event.NONE: SelectKeeperTransactionSubmissionBRound, - Event.SUSPICIOUS_ACTIVITY: FailedRound, - }, - CheckLateTxHashesRound: { - Event.DONE: FinishedTransactionSubmissionRound, - Event.NEGATIVE: FailedRound, - Event.NONE: FailedRound, - Event.CHECK_TIMEOUT: CheckLateTxHashesRound, - Event.NO_MAJORITY: FailedRound, - Event.CHECK_LATE_ARRIVING_MESSAGE: SynchronizeLateMessagesRound, - }, - ResetRound: { - Event.DONE: RandomnessTransactionSubmissionRound, - Event.RESET_TIMEOUT: FailedRound, - Event.NO_MAJORITY: FailedRound, - }, - FinishedTransactionSubmissionRound: {}, - FailedRound: {}, - } - final_states: Set[AppState] = { - FinishedTransactionSubmissionRound, - FailedRound, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - Event.FINALIZE_TIMEOUT: 30.0, - Event.VALIDATE_TIMEOUT: 30.0, - Event.CHECK_TIMEOUT: 30.0, - Event.RESET_TIMEOUT: 30.0, - } - db_pre_conditions: Dict[AppState, Set[str]] = { - RandomnessTransactionSubmissionRound: { - get_name(SynchronizedData.most_voted_tx_hash), - get_name(SynchronizedData.participants), - } - } - db_post_conditions: Dict[AppState, Set[str]] = { - FinishedTransactionSubmissionRound: { - get_name(SynchronizedData.final_tx_hash), - get_name(SynchronizedData.final_verification_status), - }, - FailedRound: set(), - } diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/skill.yaml b/trader_old/vendor/valory/skills/transaction_settlement_abci/skill.yaml deleted file mode 100644 index c526f2da2..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/skill.yaml +++ /dev/null @@ -1,174 +0,0 @@ -name: transaction_settlement_abci -author: valory -version: 0.1.0 -type: skill -description: ABCI application for transaction settlement. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeihvqvbj2tiiyimz3e27gqhb7ku5rut7hycfahi4qle732kvj5fs7q - __init__.py: bafybeicyrp6x2efg43gfdekxuofrlidc3w6aubzmyioqwnryropp6u7sby - behaviours.py: bafybeibv5y34bwaloj455bjws3a2aeh2bgi4dclq2f5d35apm2mloen5xa - dialogues.py: bafybeigabhaykiyzbluu4mk6bbrmqhzld2kyp32pg24bvjmzrrb74einwm - fsm_specification.yaml: bafybeigdj64py4zjihcxdkvtrydbxyeh4slr2kkghltz3upnupdgad4et4 - handlers.py: bafybeie42qa3csgy6oompuqs2qnkat5mnslepbbwmgoxv6ljme4jofa5pe - models.py: bafybeiguxishqvtvlyznok3xjnzm4t6vfflamcvz5vtecq5esbldsxuc5e - payload_tools.py: bafybeiatlbw3vyo5ppjhxf4psdvkwubmrjolsprf44lis5ozfkjo7o3cba - payloads.py: bafybeiclhjnsgylqzfnu2azlqxor3vyldaoof757dnfwz5xbwejk2ro2cm - rounds.py: bafybeieo5l6gh276hhtztphloyknb5ew66hvqhzzjiv26isaz7ptvtqjgu - test_tools/__init__.py: bafybeibj2blgxzvcgdi5gzcnlzs2nt7bpdifzvjjlxlrkeutjy2qrqbwau - test_tools/integration.py: bafybeictb7ym4xsbo3ti5y2a2fpg344graa4d7352oozsea5rbab3kq4ae - tests/__init__.py: bafybeifukcwmf2ewkjqdu7j6xzmaovgrul7jnea5lrl4o3ianoofje6vfa - tests/test_behaviours.py: bafybeia2vob5legv3tdrdj4gjgmnz6enhaterbetkc6ntdemnwgg5or4gq - tests/test_dialogues.py: bafybeictrjf6jzsj4y6u2ftdrb2nyriiipia5b7wc4fsli3lwbjpd3mbam - tests/test_handlers.py: bafybeievntkwacpfaom3qabvrlworjqyd4sgfjknjlhys7f5tuq7725xli - tests/test_models.py: bafybeihvrv7vtaei64nv7okkfz2gg2g4ey4nei27ayc74h5bdlqpbk4xde - tests/test_payload_tools.py: bafybeihmgkcrlqhz4ncak276lnccmilig6gx3crmn33n46jcco6g5pzrje - tests/test_payloads.py: bafybeidvjqvjvnuw5vt4zgnqwzopvprznmefosqy3wcxukvobaiishygze - tests/test_rounds.py: bafybeic3kzqy3pe6d4skntnfc5443y6dshcustiuv2d6cw4z56gw2ewehy - tests/test_tools/__init__.py: bafybeiaq2ftmklvu5vqq6vdfa7mrlmrnusluki35jm5n2yzf57ox5dif74 - tests/test_tools/test_integration.py: bafybeigv6fxogm3aq3extahr75owdqnzepouv3rtxl3m4gai2urtz6u4ea -fingerprint_ignore_patterns: [] -connections: [] -contracts: -- valory/gnosis_safe:0.1.0:bafybeih3ropivth4wn7zbzudisx3qezbht5jyndd4w7az7fq634lpozoge -protocols: -- open_aea/signing:1.0.0:bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi -- valory/abci:0.1.0:bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u -- valory/contract_api:1.0.0:bafybeidgu7o5llh26xp3u3ebq3yluull5lupiyeu6iooi2xyymdrgnzq5i -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -behaviours: - main: - args: {} - class_name: TransactionSettlementRoundBehaviour -handlers: - abci: - args: {} - class_name: ABCIHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - default_chain_id: ethereum - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - finalize_timeout: 60.0 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - history_check_timeout: 1205 - init_fallback_gas: 0 - keeper_allowed_retries: 3 - keeper_timeout: 30.0 - light_slash_unit_amount: 5000000000000000 - max_attempts: 10 - max_healthcheck: 120 - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - retry_timeout: 3 - round_timeout_seconds: 30.0 - serious_slash_unit_amount: 8000000000000000 - service_id: registration - service_registry_address: null - setup: {} - share_tm_config_on_startup: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - sleep_time: 1 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - tx_timeout: 10.0 - use_slashing: false - use_termination: false - validate_timeout: 1205 - class_name: TransactionParams - randomness_api: - args: - api_id: cloudflare - headers: {} - method: GET - parameters: {} - response_key: null - response_type: dict - retries: 5 - url: https://drand.cloudflare.com/public/latest - class_name: RandomnessApi - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState - tendermint_dialogues: - args: {} - class_name: TendermintDialogues -dependencies: - open-aea-test-autonomy: - version: ==0.14.14.post1 - web3: - version: <7,>=6.0.0 -is_abstract: true -customs: [] diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/test_tools/__init__.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/test_tools/__init__.py deleted file mode 100644 index 55be4e300..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/test_tools/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests package for transaction_settlement_abci derived skills.""" diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/test_tools/integration.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/test_tools/integration.py deleted file mode 100644 index deb1c53c5..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/test_tools/integration.py +++ /dev/null @@ -1,338 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Integration tests for various transaction settlement skill's failure modes.""" - - -import binascii -import os -import tempfile -from abc import ABC -from math import ceil -from typing import Any, Dict, Union, cast - -from aea.crypto.base import Crypto -from aea.crypto.registries import make_crypto, make_ledger_api -from aea_ledger_ethereum import EthereumApi -from aea_test_autonomy.helpers.contracts import get_register_contract -from web3.types import Nonce, Wei - -from packages.open_aea.protocols.signing import SigningMessage -from packages.valory.contracts.gnosis_safe.tests.test_contract import ( - PACKAGE_DIR as GNOSIS_SAFE_PACKAGE, -) -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.contract_api.custom_types import RawTransaction, State -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.protocols.ledger_api.custom_types import ( - SignedTransaction, - TransactionDigest, - TransactionReceipt, -) -from packages.valory.skills.abstract_round_abci.test_tools.integration import ( - ExpectedContentType, - ExpectedTypesType, - HandlersType, - IntegrationBaseCase, -) -from packages.valory.skills.transaction_settlement_abci.behaviours import ( - FinalizeBehaviour, - ValidateTransactionBehaviour, -) -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - VerificationStatus, - skill_input_hex_to_payload, -) -from packages.valory.skills.transaction_settlement_abci.payloads import SignaturePayload -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TxSettlementSynchronizedSata, -) - - -# pylint: disable=protected-access,too-many-ancestors,unbalanced-tuple-unpacking,too-many-locals,consider-using-with,unspecified-encoding,too-many-arguments,unidiomatic-typecheck - - -DUMMY_MAX_FEE_PER_GAS = 4000000000 -DUMMY_MAX_PRIORITY_FEE_PER_GAS = 3000000000 -DUMMY_REPRICING_MULTIPLIER = 1.1 - - -class _SafeConfiguredHelperIntegration(IntegrationBaseCase, ABC): # pragma: no cover - """Base test class for integration tests with Gnosis, but no contract, deployed.""" - - safe_owners: Dict[str, Crypto] - keeper_address: str - - @classmethod - def setup_class(cls, **kwargs: Any) -> None: - """Setup.""" - super().setup_class() - - # safe configuration - cls.safe_owners = {} - for address, p_key in cls.agents.items(): - with tempfile.TemporaryDirectory() as temp_dir: - fp = os.path.join(temp_dir, "key.txt") - f = open(fp, "w") - f.write(p_key) - f.close() - crypto = make_crypto("ethereum", private_key_path=str(fp)) - cls.safe_owners[address] = crypto - cls.keeper_address = cls.current_agent - assert cls.keeper_address in cls.safe_owners # nosec - - -class _GnosisHelperIntegration( - _SafeConfiguredHelperIntegration, ABC -): # pragma: no cover - """Class that assists Gnosis instantiation.""" - - safe_contract_address: str = "0x68FCdF52066CcE5612827E872c45767E5a1f6551" - ethereum_api: EthereumApi - gnosis_instance: Any - - @classmethod - def setup_class(cls, **kwargs: Any) -> None: - """Setup.""" - super().setup_class() - - # register gnosis contract - gnosis = get_register_contract(GNOSIS_SAFE_PACKAGE) - - cls.ethereum_api = make_ledger_api("ethereum") - cls.gnosis_instance = gnosis.get_instance( - cls.ethereum_api, cls.safe_contract_address - ) - - -class _TxHelperIntegration(_GnosisHelperIntegration, ABC): # pragma: no cover - """Class that assists tx settlement related operations.""" - - tx_settlement_synchronized_data: TxSettlementSynchronizedSata - - def sign_tx(self) -> None: - """Sign a transaction""" - tx_params = skill_input_hex_to_payload( - self.tx_settlement_synchronized_data.most_voted_tx_hash - ) - safe_tx_hash_bytes = binascii.unhexlify(tx_params["safe_tx_hash"]) - participant_to_signature = {} - for address, crypto in self.safe_owners.items(): - signature_hex = crypto.sign_message( - safe_tx_hash_bytes, - is_deprecated_mode=True, - ) - signature_hex = signature_hex[2:] - participant_to_signature[address] = SignaturePayload( - sender=address, - signature=signature_hex, - ).json - - # FIXME: The following loop is a patch. The - # [_get_python_modules](https://github.com/valory-xyz/open-aea/blob/d0e60881b1371442c3572df86c53fc92dc9228fa/aea/skills/base.py#L907-L925) - # is getting the python modules from the skill directory. - # As we can see from the code, the path will end up being relative, which means that the - # [_metaclass_registry_key](https://github.com/valory-xyz/open-autonomy/blob/5d151f1fff4934f70be8c5f6be77705cc2e6ef4c/packages/valory/skills/abstract_round_abci/base.py#L167) - # inserted in the `_MetaPayload`'s registry will also be relative. However, this is causing issues when calling - # `BaseTxPayload.from_json(payload_json)` later from the property below - # (`self.tx_settlement_synchronized_data.participant_to_signature`) because the `payload_json` will have been - # serialized using an imported payload (the `SignaturePayload` above), and therefore a key error will be - # raised since the imported payload's path is not relative and the registry has a relative path as a key. - for payload in participant_to_signature.values(): - registry_key = "_metaclass_registry_key" - payload_value = payload[registry_key] - payload_cls_name = payload_value.split(".")[-1] - patched_registry_key = f"payloads.{payload_cls_name}" - payload[registry_key] = patched_registry_key - - self.tx_settlement_synchronized_data.update( - participant_to_signature=participant_to_signature, - ) - - actual_safe_owners = self.gnosis_instance.functions.getOwners().call() - expected_safe_owners = ( - self.tx_settlement_synchronized_data.participant_to_signature.keys() - ) - assert len(actual_safe_owners) == len(expected_safe_owners) # nosec - assert all( # nosec - owner == signer - for owner, signer in zip(actual_safe_owners, expected_safe_owners) - ) - - def send_tx(self, simulate_timeout: bool = False) -> None: - """Send a transaction""" - - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=FinalizeBehaviour.auto_behaviour_id(), - synchronized_data=self.tx_settlement_synchronized_data, - ) - behaviour = cast(FinalizeBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == FinalizeBehaviour.auto_behaviour_id() - stored_nonce = behaviour.params.mutable_params.nonce - stored_gas_price = behaviour.params.mutable_params.gas_price - - handlers: HandlersType = [ - self.contract_handler, - self.signing_handler, - self.ledger_handler, - ] - expected_content: ExpectedContentType = [ - {"performative": ContractApiMessage.Performative.RAW_TRANSACTION}, - {"performative": SigningMessage.Performative.SIGNED_TRANSACTION}, - {"performative": LedgerApiMessage.Performative.TRANSACTION_DIGEST}, - ] - expected_types: ExpectedTypesType = [ - { - "raw_transaction": RawTransaction, - }, - { - "signed_transaction": SignedTransaction, - }, - { - "transaction_digest": TransactionDigest, - }, - ] - msg1, _, msg3 = self.process_n_messages( - 3, - self.tx_settlement_synchronized_data, - None, - handlers, - expected_content, - expected_types, - fail_send_a2a=simulate_timeout, - ) - assert msg1 is not None and isinstance(msg1, ContractApiMessage) # nosec - assert msg3 is not None and isinstance(msg3, LedgerApiMessage) # nosec - nonce_used = Nonce(int(cast(str, msg1.raw_transaction.body["nonce"]))) - gas_price_used = { - gas_price_param: Wei( - int( - cast( - str, - msg1.raw_transaction.body[gas_price_param], - ) - ) - ) - for gas_price_param in ("maxPriorityFeePerGas", "maxFeePerGas") - } - tx_digest = msg3.transaction_digest.body - tx_data = { - "status": VerificationStatus.PENDING, - "tx_digest": cast(str, tx_digest), - } - - behaviour = cast(FinalizeBehaviour, self.behaviour.current_behaviour) - assert behaviour.params.mutable_params.gas_price == gas_price_used # nosec - assert behaviour.params.mutable_params.nonce == nonce_used # nosec - if simulate_timeout: - assert behaviour.params.mutable_params.tx_hash == tx_digest # nosec - else: - assert behaviour.params.mutable_params.tx_hash == "" # nosec - - # if we are repricing - if nonce_used == stored_nonce: - assert stored_nonce is not None # nosec - assert stored_gas_price is not None # nosec - assert gas_price_used == { # nosec - gas_price_param: ceil( - stored_gas_price[gas_price_param] * DUMMY_REPRICING_MULTIPLIER - ) - for gas_price_param in ("maxPriorityFeePerGas", "maxFeePerGas") - }, "The repriced parameters do not match the ones returned from the gas pricing method!" - # if we are not repricing - else: - assert gas_price_used == { # nosec - "maxPriorityFeePerGas": DUMMY_MAX_PRIORITY_FEE_PER_GAS, - "maxFeePerGas": DUMMY_MAX_FEE_PER_GAS, - }, "The used parameters do not match the ones returned from the gas pricing method!" - - update_params: Dict[str, Union[int, str, Dict[str, int]]] - if not simulate_timeout: - hashes = self.tx_settlement_synchronized_data.tx_hashes_history - hashes.append(tx_digest) - update_params = dict( - tx_hashes_history="".join(hashes), - final_verification_status=VerificationStatus(tx_data["status"]).value, - ) - else: - # store the tx hash that we have missed and update missed messages. - assert isinstance( # nosec - self.behaviour.current_behaviour, FinalizeBehaviour - ) - self.mock_a2a_transaction() - self.behaviour.current_behaviour.params.mutable_params.tx_hash = tx_digest - missed_messages = self.tx_settlement_synchronized_data.missed_messages - missed_messages[ - self.tx_settlement_synchronized_data.most_voted_keeper_address - ] += 1 - update_params = dict(missed_messages=missed_messages) - - self.tx_settlement_synchronized_data.update( - synchronized_data_class=None, **update_params - ) - - def validate_tx( - self, simulate_timeout: bool = False, mining_interval_secs: float = 0 - ) -> None: - """Validate the sent transaction.""" - - if simulate_timeout: - missed_messages = self.tx_settlement_synchronized_data.missed_messages - missed_messages[ - tuple(self.tx_settlement_synchronized_data.all_participants)[0] - ] += 1 - self.tx_settlement_synchronized_data.update(missed_messages=missed_messages) - else: - handlers: HandlersType = [ - self.ledger_handler, - self.contract_handler, - ] - expected_content: ExpectedContentType = [ - {"performative": LedgerApiMessage.Performative.TRANSACTION_RECEIPT}, - {"performative": ContractApiMessage.Performative.STATE}, - ] - expected_types: ExpectedTypesType = [ - { - "transaction_receipt": TransactionReceipt, - }, - { - "state": State, - }, - ] - _, verif_msg = self.process_n_messages( - 2, - self.tx_settlement_synchronized_data, - ValidateTransactionBehaviour.auto_behaviour_id(), - handlers, - expected_content, - expected_types, - mining_interval_secs=mining_interval_secs, - ) - assert verif_msg is not None and isinstance( # nosec - verif_msg, ContractApiMessage - ) - assert verif_msg.state.body[ # nosec - "verified" - ], f"Message not verified: {verif_msg.state.body}" - - self.tx_settlement_synchronized_data.update( - final_verification_status=VerificationStatus.VERIFIED.value, - final_tx_hash=self.tx_settlement_synchronized_data.to_be_validated_tx_hash, - ) diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/__init__.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/__init__.py deleted file mode 100644 index 932ecb0c4..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/transaction_settlement_abci skill.""" -from pathlib import Path - - -PACKAGE_DIR = Path(__file__).parents[1] diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_behaviours.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_behaviours.py deleted file mode 100644 index fbc6d9f93..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_behaviours.py +++ /dev/null @@ -1,1392 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/registration_abci skill's behaviours.""" - -# pylint: skip-file - -import logging -import time -from collections import deque -from pathlib import Path -from typing import ( - Any, - Callable, - Deque, - Dict, - Generator, - List, - Optional, - Set, - Tuple, - Type, - Union, - cast, -) -from unittest import mock -from unittest.mock import MagicMock - -import pytest -from _pytest.logging import LogCaptureFixture -from _pytest.monkeypatch import MonkeyPatch -from aea.helpers.transaction.base import ( - RawTransaction, - SignedMessage, - SignedTransaction, -) -from aea.helpers.transaction.base import State as TrState -from aea.helpers.transaction.base import TransactionDigest, TransactionReceipt -from aea.skills.base import SkillContext -from web3.types import Nonce - -from packages.open_aea.protocols.signing import SigningMessage -from packages.valory.contracts.gnosis_safe.contract import ( - PUBLIC_ID as GNOSIS_SAFE_CONTRACT_ID, -) -from packages.valory.protocols.abci import AbciMessage # noqa: F401 -from packages.valory.protocols.contract_api.message import ContractApiMessage -from packages.valory.protocols.ledger_api.message import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.behaviour_utils import ( - BaseBehaviour, - RPCResponseStatus, - make_degenerate_behaviour, -) -from packages.valory.skills.abstract_round_abci.test_tools.base import ( - FSMBehaviourBaseCase, -) -from packages.valory.skills.abstract_round_abci.test_tools.common import ( - BaseRandomnessBehaviourTest, - BaseSelectKeeperBehaviourTest, -) -from packages.valory.skills.transaction_settlement_abci import PUBLIC_ID -from packages.valory.skills.transaction_settlement_abci.behaviours import ( - CheckLateTxHashesBehaviour, - CheckTransactionHistoryBehaviour, - FinalizeBehaviour, - REVERT_CODES_TO_REASONS, - RandomnessTransactionSubmissionBehaviour, - ResetBehaviour, - SelectKeeperTransactionSubmissionBehaviourA, - SelectKeeperTransactionSubmissionBehaviourB, - SignatureBehaviour, - SynchronizeLateMessagesBehaviour, - TransactionSettlementBaseBehaviour, - TxDataType, - ValidateTransactionBehaviour, -) -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - VerificationStatus, - hash_payload_to_hex, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - Event as TransactionSettlementEvent, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - FinishedTransactionSubmissionRound, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TransactionSettlementSynchronizedSata, -) - - -PACKAGE_DIR = Path(__file__).parent.parent - - -def mock_yield_and_return( - return_value: Any, -) -> Callable[[], Generator[None, None, Any]]: - """Wrapper for a Dummy generator that returns a `bool`.""" - - def yield_and_return(*_: Any, **__: Any) -> Generator[None, None, Any]: - """Dummy generator that returns a `bool`.""" - yield - return return_value - - return yield_and_return - - -def test_skill_public_id() -> None: - """Test skill module public ID""" - - assert PUBLIC_ID.name == Path(__file__).parents[1].name - assert PUBLIC_ID.author == Path(__file__).parents[3].name - - -class TransactionSettlementFSMBehaviourBaseCase(FSMBehaviourBaseCase): - """Base case for testing TransactionSettlement FSMBehaviour.""" - - path_to_skill = PACKAGE_DIR - - def ffw_signature(self, db_items: Optional[Dict] = None) -> None: - """Fast-forward to the `SignatureBehaviour`.""" - if db_items is None: - db_items = {} - - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=SignatureBehaviour.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists(db_items), - ) - ), - ) - - -class TestTransactionSettlementBaseBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test `TransactionSettlementBaseBehaviour`.""" - - @pytest.mark.parametrize( - "message, tx_digest, rpc_status, expected_data, replacement", - ( - ( - MagicMock( - performative=ContractApiMessage.Performative.ERROR, message="GS026" - ), - None, - RPCResponseStatus.SUCCESS, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.VERIFIED, - "tx_digest": "", - }, - False, - ), - ( - MagicMock( - performative=ContractApiMessage.Performative.ERROR, message="test" - ), - None, - RPCResponseStatus.SUCCESS, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.ERROR, - "tx_digest": "", - }, - False, - ), - ( - MagicMock(performative=ContractApiMessage.Performative.RAW_MESSAGE), - None, - RPCResponseStatus.SUCCESS, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.PENDING, - "tx_digest": "", - }, - False, - ), - ( - MagicMock(performative=ContractApiMessage.Performative.RAW_TRANSACTION), - None, - RPCResponseStatus.INCORRECT_NONCE, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.ERROR, - "tx_digest": "", - }, - False, - ), - ( - MagicMock(performative=ContractApiMessage.Performative.RAW_TRANSACTION), - None, - RPCResponseStatus.INSUFFICIENT_FUNDS, - { - "blacklisted_keepers": {"agent_1" + "-" * 35}, - "keeper_retries": 1, - "keepers": deque(("agent_3" + "-" * 35,)), - "status": VerificationStatus.INSUFFICIENT_FUNDS, - "tx_digest": "", - }, - False, - ), - ( - MagicMock(performative=ContractApiMessage.Performative.RAW_TRANSACTION), - None, - RPCResponseStatus.UNCLASSIFIED_ERROR, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.PENDING, - "tx_digest": "", - }, - False, - ), - ( - MagicMock(performative=ContractApiMessage.Performative.RAW_TRANSACTION), - None, - RPCResponseStatus.UNDERPRICED, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.PENDING, - "tx_digest": "", - }, - False, - ), - ( - MagicMock(performative=ContractApiMessage.Performative.RAW_TRANSACTION), - "test_digest_0", - RPCResponseStatus.ALREADY_KNOWN, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.PENDING, - "tx_digest": "test_digest_0", - }, - False, - ), - ( - MagicMock( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=MagicMock( - body={ - "nonce": 0, - "maxPriorityFeePerGas": 10, - "maxFeePerGas": 20, - "gas": 0, - } - ), - ), - "test_digest_1", - RPCResponseStatus.SUCCESS, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.PENDING, - "tx_digest": "test_digest_1", - }, - False, - ), - ( - MagicMock( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - raw_transaction=MagicMock( - body={ - "nonce": 0, - "maxPriorityFeePerGas": 10, - "maxFeePerGas": 20, - "gas": 0, - } - ), - ), - "test_digest_2", - RPCResponseStatus.SUCCESS, - { - "blacklisted_keepers": set(), - "keeper_retries": 2, - "keepers": deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)), - "status": VerificationStatus.PENDING, - "tx_digest": "test_digest_2", - }, - True, - ), - ), - ) - def test__get_tx_data( - self, - message: ContractApiMessage, - tx_digest: Optional[str], - rpc_status: RPCResponseStatus, - expected_data: TxDataType, - replacement: bool, - monkeypatch: MonkeyPatch, - ) -> None: - """Test `_get_tx_data`.""" - # fast-forward to any behaviour of the tx settlement skill - init_db_items = dict( - most_voted_tx_hash="b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d90000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000002625a000x77E9b2EF921253A171Fa0CB9ba80558648Ff7215b0e6add595e00477c" - "f347d09797b156719dc5233283ac76e4efce2a674fe72d9b0e6add595e00477cf347d09797b156719dc5233283" - "ac76e4efce2a674fe72d9", - keepers=int(2).to_bytes(32, "big").hex() - + "".join(deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35))), - ) - self.ffw_signature(init_db_items) - behaviour = cast(SignatureBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == SignatureBehaviour.auto_behaviour_id() - # Set `nonce` to the same value as the returned, so that we test the tx replacement logging. - if replacement: - behaviour.params.mutable_params.nonce = Nonce(0) - - # patch the `send_raw_transaction` method - def dummy_send_raw_transaction( - *_: Any, **kwargs: Any - ) -> Generator[None, None, Tuple[Optional[str], RPCResponseStatus]]: - """Dummy `send_raw_transaction` method.""" - yield - return tx_digest, rpc_status - - monkeypatch.setattr( - BaseBehaviour, "send_raw_transaction", dummy_send_raw_transaction - ) - # call `_get_tx_data` - tx_data_iterator = cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - )._get_tx_data(message, use_flashbots=False) - - if message.performative == ContractApiMessage.Performative.RAW_TRANSACTION: - next(tx_data_iterator) - - try: - next(tx_data_iterator) - except StopIteration as res: - assert res.value == expected_data - - """Test the serialized_keepers method.""" - behaviour_ = self.behaviour.current_behaviour - assert behaviour_ is not None - assert behaviour_.serialized_keepers(deque([]), 1) == "" - assert ( - behaviour_.serialized_keepers(deque(["-" * 42]), 1) - == "0000000000000000000000000000000000000000000000000000000000000001" - "------------------------------------------" - ) - - @pytest.mark.parametrize( - argnames=["tx_body", "expected_params"], - argvalues=[ - [ - {"maxPriorityFeePerGas": "dummy", "maxFeePerGas": "dummy"}, - ["maxPriorityFeePerGas", "maxFeePerGas"], - ], - [{"gasPrice": "dummy"}, ["gasPrice"]], - [ - {"maxPriorityFeePerGas": "dummy"}, - [], - ], - [ - {"maxFeePerGas": "dummy"}, - [], - ], - [ - {}, - [], - ], - [ - { - "maxPriorityFeePerGas": "dummy", - "maxFeePerGas": "dummy", - "gasPrice": "dummy", - }, - ["maxPriorityFeePerGas", "maxFeePerGas"], - ], - ], - ) - def test_get_gas_price_params( - self, tx_body: dict, expected_params: List[str] - ) -> None: - """Test the get_gas_price_params method""" - # fast-forward to any behaviour of the tx settlement skill - self.ffw_signature() - - assert ( - cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - ).get_gas_price_params(tx_body) - == expected_params - ) - - def test_parse_revert_reason_successful(self) -> None: - """Test `_parse_revert_reason` method.""" - # fast-forward to any behaviour of the tx settlement skill - self.ffw_signature() - - for code, explanation in REVERT_CODES_TO_REASONS.items(): - message = MagicMock( - performative=ContractApiMessage.Performative.ERROR, - message=f"some text {code}.", - ) - - expected = f"Received a {code} revert error: {explanation}." - - assert ( - cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - )._parse_revert_reason(message) - == expected - ) - - @pytest.mark.parametrize( - "message", - ( - MagicMock( - performative=ContractApiMessage.Performative.ERROR, - message="Non existing code should be invalid GS086.", - ), - MagicMock( - performative=ContractApiMessage.Performative.ERROR, - message="Code not matching the regex should be invalid GS0265.", - ), - MagicMock( - performative=ContractApiMessage.Performative.ERROR, - message="No code in the message should be invalid.", - ), - MagicMock( - performative=ContractApiMessage.Performative.ERROR, - message="", # empty message should be invalid - ), - MagicMock( - performative=ContractApiMessage.Performative.ERROR, - message=None, # `None` message should be invalid - ), - ), - ) - def test_parse_revert_reason_unsuccessful( - self, message: ContractApiMessage - ) -> None: - """Test `_parse_revert_reason` method.""" - # fast-forward to any behaviour of the tx settlement skill - self.ffw_signature() - - expected = f"get_raw_safe_transaction unsuccessful! Received: {message}" - - assert ( - cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - )._parse_revert_reason(message) - == expected - ) - - -class TestRandomnessInOperation(BaseRandomnessBehaviourTest): - """Test randomness in operation.""" - - path_to_skill = PACKAGE_DIR - - randomness_behaviour_class = RandomnessTransactionSubmissionBehaviour - next_behaviour_class = SelectKeeperTransactionSubmissionBehaviourA - done_event = TransactionSettlementEvent.DONE - - -class TestSelectKeeperTransactionSubmissionBehaviourA(BaseSelectKeeperBehaviourTest): - """Test SelectKeeperBehaviour.""" - - path_to_skill = PACKAGE_DIR - - select_keeper_behaviour_class = SelectKeeperTransactionSubmissionBehaviourA - next_behaviour_class = SignatureBehaviour - done_event = TransactionSettlementEvent.DONE - _synchronized_data = TransactionSettlementSynchronizedSata - - -class TestSelectKeeperTransactionSubmissionBehaviourB( - TestSelectKeeperTransactionSubmissionBehaviourA -): - """Test SelectKeeperBehaviour.""" - - select_keeper_behaviour_class = SelectKeeperTransactionSubmissionBehaviourB - next_behaviour_class = FinalizeBehaviour - - @mock.patch.object( - TransactionSettlementSynchronizedSata, - "keepers", - new_callable=mock.PropertyMock, - ) - @mock.patch.object( - TransactionSettlementSynchronizedSata, - "keeper_retries", - new_callable=mock.PropertyMock, - ) - @mock.patch.object( - TransactionSettlementSynchronizedSata, - "final_verification_status", - new_callable=mock.PropertyMock, - ) - @pytest.mark.parametrize( - "keepers, keeper_retries, blacklisted_keepers, final_verification_status", - ( - ( - deque(f"keeper_{i}" for i in range(4)), - 1, - set(), - VerificationStatus.NOT_VERIFIED, - ), - (deque(("test_keeper",)), 2, set(), VerificationStatus.PENDING), - (deque(("test_keeper",)), 2, set(), VerificationStatus.NOT_VERIFIED), - (deque(("test_keeper",)), 2, {"a1"}, VerificationStatus.NOT_VERIFIED), - ( - deque(("test_keeper",)), - 2, - {"test_keeper"}, - VerificationStatus.NOT_VERIFIED, - ), - ( - deque(("test_keeper",)), - 2, - {"a_1", "a_2", "test_keeper"}, - VerificationStatus.NOT_VERIFIED, - ), - (deque(("test_keeper",)), 1, set(), VerificationStatus.NOT_VERIFIED), - (deque(("test_keeper",)), 3, set(), VerificationStatus.NOT_VERIFIED), - ), - ) - def test_select_keeper( - self, - final_verification_status_mock: mock.PropertyMock, - keeper_retries_mock: mock.PropertyMock, - keepers_mock: mock.PropertyMock, - keepers: Deque[str], - keeper_retries: int, - blacklisted_keepers: Set[str], - final_verification_status: VerificationStatus, - ) -> None: - """Test select keeper agent.""" - keepers_mock.return_value = keepers - keeper_retries_mock.return_value = keeper_retries - final_verification_status_mock.return_value = final_verification_status - super().test_select_keeper(blacklisted_keepers=blacklisted_keepers) - - @mock.patch.object( - TransactionSettlementSynchronizedSata, - "final_verification_status", - new_callable=mock.PropertyMock, - return_value=VerificationStatus.PENDING, - ) - @pytest.mark.skip # Needs to be investigated, fails in CI only. look at #1710 - def test_select_keeper_tx_pending( - self, _: mock.PropertyMock, caplog: LogCaptureFixture - ) -> None: - """Test select keeper while tx is pending""" - - with caplog.at_level(logging.INFO): - super().test_select_keeper(blacklisted_keepers=set()) - assert "Kept keepers and incremented retries" in caplog.text - - -class TestSignatureBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test SignatureBehaviour.""" - - def test_signature_behaviour( - self, - ) -> None: - """Test signature behaviour.""" - - init_db_items = dict( - most_voted_tx_hash="b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d90000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000002625a000x77E9b2EF921253A171Fa0CB9ba80558648Ff7215b0e6add595e00477c" - "f347d09797b156719dc5233283ac76e4efce2a674fe72d9b0e6add595e00477cf347d09797b156719dc5233283" - "ac76e4efce2a674fe72d9", - ) - self.ffw_signature(init_db_items) - - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == SignatureBehaviour.auto_behaviour_id() - ) - self.behaviour.act_wrapper() - self.mock_signing_request( - request_kwargs=dict( - performative=SigningMessage.Performative.SIGN_MESSAGE, - ), - response_kwargs=dict( - performative=SigningMessage.Performative.SIGNED_MESSAGE, - signed_message=SignedMessage( - ledger_id="ethereum", body="stub_signature" - ), - ), - ) - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == FinalizeBehaviour.auto_behaviour_id() - - -class TestFinalizeBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test FinalizeBehaviour.""" - - behaviour_class = FinalizeBehaviour - - def test_non_sender_act( - self, - ) -> None: - """Test finalize behaviour.""" - participants = (self.skill.skill_context.agent_address, "a_1", "a_2") - retries = 1 - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.behaviour_class.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - most_voted_keeper_address="most_voted_keeper_address", - participants=participants, - # keeper needs to have length == 42 in order to be parsed - keepers=retries.to_bytes(32, "big").hex() - + "other_agent" - + "-" * 31, - ) - ), - ) - ), - ) - assert self.behaviour.current_behaviour is not None - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - cast( - FinalizeBehaviour, self.behaviour.current_behaviour - ).params.mutable_params.tx_hash = "test" - self.behaviour.act_wrapper() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(ValidateTransactionBehaviour, self.behaviour.current_behaviour) - assert ( - behaviour.behaviour_id == ValidateTransactionBehaviour.auto_behaviour_id() - ) - assert behaviour.params.mutable_params.tx_hash == "test" - - @pytest.mark.parametrize( - "resubmitting, response_kwargs", - ( - ( - ( - True, - dict( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - callable="get_deploy_transaction", - raw_transaction=RawTransaction( - ledger_id="ethereum", - body={ - "tx_hash": "0x3b", - "nonce": 0, - "maxFeePerGas": int(10e10), - "maxPriorityFeePerGas": int(10e10), - }, - ), - ), - ) - ), - ( - False, - dict( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - callable="get_deploy_transaction", - raw_transaction=RawTransaction( - ledger_id="ethereum", - body={ - "tx_hash": "0x3b", - "nonce": 0, - "maxFeePerGas": int(10e10), - "maxPriorityFeePerGas": int(10e10), - }, - ), - ), - ), - ( - False, - dict( - performative=ContractApiMessage.Performative.ERROR, - callable="get_deploy_transaction", - code=500, - message="GS026", - data=b"", - ), - ), - ( - False, - dict( - performative=ContractApiMessage.Performative.ERROR, - callable="get_deploy_transaction", - code=500, - message="other error", - data=b"", - ), - ), - ), - ) - @mock.patch.object(SkillContext, "agent_address", new_callable=mock.PropertyMock) - def test_sender_act( - self, - agent_address_mock: mock.PropertyMock, - resubmitting: bool, - response_kwargs: Dict[ - str, - Union[ - int, - str, - bytes, - Dict[str, Union[int, str]], - ContractApiMessage.Performative, - RawTransaction, - ], - ], - ) -> None: - """Test finalize behaviour.""" - nonce: Optional[int] = None - max_priority_fee_per_gas: Optional[int] = None - - if resubmitting: - nonce = 0 - max_priority_fee_per_gas = 1 - - # keepers need to have length == 42 in order to be parsed - agent_address_mock.return_value = "-" * 42 - retries = 1 - participants = ( - self.skill.skill_context.agent_address, - "a_1" + "-" * 39, - "a_2" + "-" * 39, - ) - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.behaviour_class.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - safe_contract_address="safe_contract_address", - participants=participants, - participant_to_signature={}, - most_voted_tx_hash=hash_payload_to_hex( - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - 1, - 1, - "0x77E9b2EF921253A171Fa0CB9ba80558648Ff7215", - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ), - nonce=nonce, - max_priority_fee_per_gas=max_priority_fee_per_gas, - keepers=retries.to_bytes(32, "big").hex() - + self.skill.skill_context.agent_address, - ) - ), - ) - ), - ) - - assert self.behaviour.current_behaviour is not None - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - cast( - FinalizeBehaviour, self.behaviour.current_behaviour - ).params.mutable_params.tx_hash = "test" - self.behaviour.act_wrapper() - - self.mock_contract_api_request( - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=response_kwargs, - ) - - if ( - response_kwargs["performative"] - == ContractApiMessage.Performative.RAW_TRANSACTION - ): - self.mock_signing_request( - request_kwargs=dict( - performative=SigningMessage.Performative.SIGN_TRANSACTION - ), - response_kwargs=dict( - performative=SigningMessage.Performative.SIGNED_TRANSACTION, - signed_transaction=SignedTransaction(ledger_id="ethereum", body={}), - ), - ) - self.mock_ledger_api_request( - request_kwargs=dict( - performative=LedgerApiMessage.Performative.SEND_SIGNED_TRANSACTION - ), - response_kwargs=dict( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, - transaction_digest=TransactionDigest( - ledger_id="ethereum", body="tx_hash" - ), - ), - ) - - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - assert ( - self.behaviour.current_behaviour.behaviour_id - == ValidateTransactionBehaviour.auto_behaviour_id() - ) - assert ( - cast( - ValidateTransactionBehaviour, self.behaviour.current_behaviour - ).params.mutable_params.tx_hash - == "" - ) - - def test_sender_act_tx_data_contains_tx_digest(self) -> None: - """Test finalize behaviour.""" - - max_priority_fee_per_gas: Optional[int] = None - - retries = 1 - participants = ( - self.skill.skill_context.agent_address, - "a_1" + "-" * 39, - "a_2" + "-" * 39, - ) - kwargs = dict( - safe_contract_address="safe_contract_address", - participants=participants, - participant_to_signature={}, - most_voted_tx_hash=hash_payload_to_hex( - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - 1, - 1, - "0x77E9b2EF921253A171Fa0CB9ba80558648Ff7215", - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ), - nonce=None, - max_priority_fee_per_gas=max_priority_fee_per_gas, - keepers=retries.to_bytes(32, "big").hex() - + self.skill.skill_context.agent_address, - ) - - db = AbciAppDB(setup_data=AbciAppDB.data_to_lists(kwargs)) - - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.behaviour_class.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata(db), - ) - - response_kwargs = dict( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, - callable="get_deploy_transaction", - raw_transaction=RawTransaction( - ledger_id="ethereum", - body={ - "tx_hash": "0x3b", - "nonce": 0, - "maxFeePerGas": int(10e10), - "maxPriorityFeePerGas": int(10e10), - }, - ), - ) - - # mock the returned tx_data - return_value = dict( - status=VerificationStatus.PENDING, - keepers=deque(), - keeper_retries=1, - blacklisted_keepers=set(), - tx_digest="dummy_tx_digest", - ) - - current_behaviour = cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - ) - current_behaviour._get_tx_data = mock_yield_and_return(return_value) # type: ignore - - self.behaviour.act_wrapper() - self.mock_contract_api_request( - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_RAW_TRANSACTION, - ), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=response_kwargs, - ) - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - - current_behaviour = cast( - ValidateTransactionBehaviour, self.behaviour.current_behaviour - ) - current_behaviour_id = current_behaviour.behaviour_id - expected_behaviour_id = ValidateTransactionBehaviour.auto_behaviour_id() - assert current_behaviour_id == expected_behaviour_id - - def test_handle_late_messages(self) -> None: - """Test `handle_late_messages.`""" - participants = (self.skill.skill_context.agent_address, "a_1", "a_2") - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.behaviour_class.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - most_voted_keeper_address="most_voted_keeper_address", - participants=participants, - keepers="keepers", - ) - ), - ) - ), - ) - self.behaviour.current_behaviour = cast( - BaseBehaviour, self.behaviour.current_behaviour - ) - assert ( - self.behaviour.current_behaviour.behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - - message = ContractApiMessage(ContractApiMessage.Performative.RAW_MESSAGE) # type: ignore - self.behaviour.current_behaviour.handle_late_messages( - self.behaviour.current_behaviour.behaviour_id, message - ) - assert cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - ).params.mutable_params.late_messages == [message] - - with mock.patch.object(self.behaviour.context.logger, "warning") as mock_info: - self.behaviour.current_behaviour.handle_late_messages( - "other_behaviour_id", message - ) - mock_info.assert_called_with( - f"No callback defined for request with nonce: {message.dialogue_reference[0]}, " - "arriving for behaviour: other_behaviour_id" - ) - message = MagicMock() - self.behaviour.current_behaviour.handle_late_messages( - self.behaviour.current_behaviour.behaviour_id, message - ) - mock_info.assert_called_with( - f"No callback defined for request with nonce: {message.dialogue_reference[0]}, " - f"arriving for behaviour: {FinalizeBehaviour.auto_behaviour_id()}" - ) - - -class TestValidateTransactionBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test ValidateTransactionBehaviour.""" - - def _fast_forward(self) -> None: - """Fast-forward to relevant behaviour.""" - participants = (self.skill.skill_context.agent_address, "a_1", "a_2") - most_voted_keeper_address = self.skill.skill_context.agent_address - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=ValidateTransactionBehaviour.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - safe_contract_address="safe_contract_address", - tx_hashes_history="t" * 66, - final_tx_hash="dummy_hash", - participants=participants, - most_voted_keeper_address=most_voted_keeper_address, - participant_to_signature={}, - most_voted_tx_hash=hash_payload_to_hex( - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - 1, - 1, - "0x77E9b2EF921253A171Fa0CB9ba80558648Ff7215", - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ), - max_priority_fee_per_gas=int(10e10), - ) - ), - ) - ), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == ValidateTransactionBehaviour.auto_behaviour_id() - ) - - def test_validate_transaction_safe_behaviour( - self, - ) -> None: - """Test ValidateTransactionBehaviour.""" - self._fast_forward() - self.behaviour.act_wrapper() - self.mock_ledger_api_request( - request_kwargs=dict( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT - ), - response_kwargs=dict( - performative=LedgerApiMessage.Performative.TRANSACTION_RECEIPT, - transaction_receipt=TransactionReceipt( - ledger_id="ethereum", receipt={"status": 1}, transaction={} - ), - ), - ) - self.mock_contract_api_request( - request_kwargs=dict(performative=ContractApiMessage.Performative.GET_STATE), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=dict( - performative=ContractApiMessage.Performative.STATE, - callable="get_deploy_transaction", - state=TrState(ledger_id="ethereum", body={"verified": True}), - ), - ) - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert ( - behaviour.behaviour_id - == make_degenerate_behaviour( - FinishedTransactionSubmissionRound - ).auto_behaviour_id() - ) - - def test_validate_transaction_safe_behaviour_no_tx_sent( - self, - ) -> None: - """Test ValidateTransactionBehaviour when tx cannot be sent.""" - self._fast_forward() - - with mock.patch.object(self.behaviour.context.logger, "error") as mock_logger: - self.behaviour.act_wrapper() - self.mock_ledger_api_request( - request_kwargs=dict( - performative=LedgerApiMessage.Performative.GET_TRANSACTION_RECEIPT, - ), - response_kwargs=dict( - performative=LedgerApiMessage.Performative.ERROR, - code=1, - ), - ) - behaviour = cast( - TransactionSettlementBaseBehaviour, - self.behaviour.current_behaviour, - ) - latest_tx_hash = behaviour.synchronized_data.tx_hashes_history[-1] - mock_logger.assert_any_call(f"tx {latest_tx_hash} receipt check timed out!") - - -class TestCheckTransactionHistoryBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test CheckTransactionHistoryBehaviour.""" - - def _fast_forward(self, hashes_history: str) -> None: - """Fast-forward to relevant behaviour.""" - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=CheckTransactionHistoryBehaviour.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - safe_contract_address="safe_contract_address", - participants=( - self.skill.skill_context.agent_address, - "a_1", - "a_2", - ), - participant_to_signature={}, - most_voted_tx_hash="b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002625a000x77E9b2EF921253A171Fa0CB9ba80558648Ff7215b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - tx_hashes_history=hashes_history, - ) - ), - ) - ), - ) - assert ( - cast(BaseBehaviour, self.behaviour.current_behaviour).behaviour_id - == CheckTransactionHistoryBehaviour.auto_behaviour_id() - ) - - @pytest.mark.parametrize( - "verified, status, hashes_history, revert_reason", - ( - (False, -1, "0x" + "t" * 64, "test"), - (False, 0, "", "test"), - (False, 0, "0x" + "t" * 64, "test"), - (False, 0, "0x" + "t" * 64, "GS026"), - (True, 1, "0x" + "t" * 64, "test"), - ), - ) - def test_check_tx_history_behaviour( - self, - verified: bool, - status: int, - hashes_history: str, - revert_reason: str, - ) -> None: - """Test CheckTransactionHistoryBehaviour.""" - self._fast_forward(hashes_history) - self.behaviour.act_wrapper() - - if hashes_history: - self.mock_contract_api_request( - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE - ), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=dict( - performative=ContractApiMessage.Performative.STATE, - callable="get_safe_nonce", - state=TrState( - ledger_id="ethereum", - body={ - "safe_nonce": 0, - }, - ), - ), - ) - self.mock_contract_api_request( - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE - ), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=dict( - performative=ContractApiMessage.Performative.STATE, - callable="verify_tx", - state=TrState( - ledger_id="ethereum", - body={ - "verified": verified, - "status": status, - "transaction": {}, - }, - ), - ), - ) - - if not verified and status != -1: - self.mock_contract_api_request( - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE - ), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=dict( - performative=ContractApiMessage.Performative.STATE, - callable="revert_reason", - state=TrState( - ledger_id="ethereum", body={"revert_reason": revert_reason} - ), - ), - ) - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert ( - behaviour.behaviour_id - == make_degenerate_behaviour( - FinishedTransactionSubmissionRound - ).auto_behaviour_id() - ) - - @pytest.mark.parametrize( - "verified, status, hashes_history, revert_reason", - ((False, 0, "0x" + "t" * 64, "test"),), - ) - def test_check_tx_history_behaviour_negative( - self, - verified: bool, - status: int, - hashes_history: str, - revert_reason: str, - ) -> None: - """Test CheckTransactionHistoryBehaviour.""" - self._fast_forward(hashes_history) - self.behaviour.act_wrapper() - self.behaviour.context.params.mutable_params.nonce = 1 - if hashes_history: - self.mock_contract_api_request( - request_kwargs=dict( - performative=ContractApiMessage.Performative.GET_STATE - ), - contract_id=str(GNOSIS_SAFE_CONTRACT_ID), - response_kwargs=dict( - performative=ContractApiMessage.Performative.STATE, - callable="get_safe_nonce", - state=TrState( - ledger_id="ethereum", - body={ - "safe_nonce": 1, - }, - ), - ), - ) - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert ( - behaviour.behaviour_id - == make_degenerate_behaviour( - FinishedTransactionSubmissionRound - ).auto_behaviour_id() - ) - - -class TestCheckLateTxHashesBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test CheckLateTxHashesBehaviour.""" - - def _fast_forward(self, late_arriving_tx_hashes: Dict[str, str]) -> None: - """Fast-forward to relevant behaviour.""" - - agent_address = self.skill.skill_context.agent_address - kwargs = dict( - safe_contract_address="safe_contract_address", - participants=(agent_address, "a_1", "a_2"), - participant_to_signature={}, - most_voted_tx_hash="", - late_arriving_tx_hashes=late_arriving_tx_hashes, - ) - abci_app_db = AbciAppDB(setup_data=AbciAppDB.data_to_lists(kwargs)) - - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=CheckLateTxHashesBehaviour.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata(abci_app_db), - ) - - current_behaviour = self.behaviour.current_behaviour - current_behaviour_id = cast(BaseBehaviour, current_behaviour).behaviour_id - assert current_behaviour_id == CheckLateTxHashesBehaviour.auto_behaviour_id() - - def test_check_tx_history_behaviour(self) -> None: - """Test CheckTransactionHistoryBehaviour.""" - self._fast_forward(late_arriving_tx_hashes={}) - self.behaviour.act_wrapper() - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - next_degen_behaviour = make_degenerate_behaviour( - FinishedTransactionSubmissionRound - ) - assert behaviour.behaviour_id == next_degen_behaviour.auto_behaviour_id() - - -class TestSynchronizeLateMessagesBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test `SynchronizeLateMessagesBehaviour`""" - - def _check_behaviour_id( - self, expected: Type[TransactionSettlementBaseBehaviour] - ) -> None: - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == expected.auto_behaviour_id() - - @pytest.mark.parametrize("late_messages", ([], [MagicMock, MagicMock])) - def test_async_act(self, late_messages: List[MagicMock]) -> None: - """Test `async_act`""" - cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - ).params.mutable_params.late_messages = late_messages - - participants = (self.skill.skill_context.agent_address, "a_1", "a_2") - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=SynchronizeLateMessagesBehaviour.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=dict( - participants=[participants], - participant_to_signature=[{}], - safe_contract_address=["safe_contract_address"], - most_voted_tx_hash=[ - hash_payload_to_hex( - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - 1, - 1, - "0x77E9b2EF921253A171Fa0CB9ba80558648Ff7215", - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9" - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ) - ], - ), - ) - ), - ) - self._check_behaviour_id(SynchronizeLateMessagesBehaviour) # type: ignore - - if not late_messages: - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - self._check_behaviour_id(CheckLateTxHashesBehaviour) # type: ignore - - else: - - def _dummy_get_tx_data( - _current_message: ContractApiMessage, - _use_flashbots: bool, - chain_id: Optional[str] = None, - ) -> Generator[None, None, TxDataType]: - yield - return { - "status": VerificationStatus.PENDING, - "tx_digest": "test", - } - - cast( - TransactionSettlementBaseBehaviour, self.behaviour.current_behaviour - )._get_tx_data = _dummy_get_tx_data # type: ignore - for _ in range(len(late_messages)): - self.behaviour.act_wrapper() - - -class TestResetBehaviour(TransactionSettlementFSMBehaviourBaseCase): - """Test the reset behaviour.""" - - behaviour_class = ResetBehaviour - next_behaviour_class = RandomnessTransactionSubmissionBehaviour - - def test_reset_behaviour( - self, - ) -> None: - """Test reset behaviour.""" - self.fast_forward_to_behaviour( - behaviour=self.behaviour, - behaviour_id=self.behaviour_class.auto_behaviour_id(), - synchronized_data=TransactionSettlementSynchronizedSata( - AbciAppDB(setup_data=dict(estimate=[1.0])), - ), - ) - assert ( - cast( - BaseBehaviour, - cast(BaseBehaviour, self.behaviour.current_behaviour), - ).behaviour_id - == self.behaviour_class.auto_behaviour_id() - ) - self.behaviour.context.params.__dict__["reset_pause_duration"] = 0.1 - self.behaviour.act_wrapper() - time.sleep(0.3) - self.behaviour.act_wrapper() - self.mock_a2a_transaction() - self._test_done_flag_set() - self.end_round(TransactionSettlementEvent.DONE) - behaviour = cast(BaseBehaviour, self.behaviour.current_behaviour) - assert behaviour.behaviour_id == self.next_behaviour_class.auto_behaviour_id() diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_dialogues.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_dialogues.py deleted file mode 100644 index 519ea4df0..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_dialogues.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.transaction_settlement_abci.dialogues # noqa - - -def test_import() -> None: - """Test that the 'dialogues.py' Python module can be imported.""" diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_handlers.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_handlers.py deleted file mode 100644 index c458846bd..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_handlers.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-2022 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. -# -# ------------------------------------------------------------------------------ - -"""Test the dialogues.py module of the skill.""" - -# pylint: skip-file - -import packages.valory.skills.transaction_settlement_abci.handlers # noqa - - -def test_import() -> None: - """Test that the 'handlers.py' Python module can be imported.""" diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_models.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_models.py deleted file mode 100644 index 746f0a312..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_models.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ -# pylint: disable=unused-import - -"""Test the models.py module of the skill.""" -from typing import Any, Dict -from unittest.mock import MagicMock - -import pytest -import yaml -from aea.exceptions import AEAEnforceError - -from packages.valory.skills.abstract_round_abci.test_tools.base import DummyContext -from packages.valory.skills.transaction_settlement_abci.models import ( - TransactionParams, - _MINIMUM_VALIDATE_TIMEOUT, -) -from packages.valory.skills.transaction_settlement_abci.tests import PACKAGE_DIR - - -class TestTransactionParams: # pylint: disable=too-few-public-methods - """Test TransactionParams class.""" - - default_config: Dict - - def setup_class(self) -> None: - """Read the default config only once.""" - skill_yaml = PACKAGE_DIR / "skill.yaml" - with open(skill_yaml, "r", encoding="utf-8") as skill_file: - skill = yaml.safe_load(skill_file) - self.default_config = skill["models"]["params"]["args"] - - def test_ensure_validate_timeout( # pylint: disable=no-self-use - self, - ) -> None: - """Test that `_ensure_validate_timeout` raises when `validate_timeout` is lower than the allowed minimum.""" - dummy_value = 0 - mock_args, mock_kwargs = ( - MagicMock(), - { - **self.default_config, - "validate_timeout": dummy_value, - "skill_context": DummyContext(), - }, - ) - with pytest.raises( - expected_exception=AEAEnforceError, - match=f"`validate_timeout` must be greater than or equal to {_MINIMUM_VALIDATE_TIMEOUT}", - ): - TransactionParams(mock_args, **mock_kwargs) - - @pytest.mark.parametrize( - "gas_params", - [ - {}, - {"gas_price": 1}, - {"max_fee_per_gas": 1}, - {"max_priority_fee_per_gas": 1}, - { - "gas_price": 1, - "max_fee_per_gas": 1, - "max_priority_fee_per_gas": 1, - }, - ], - ) - def test_gas_params(self, gas_params: Dict[str, Any]) -> None: - """Test that gas params are being handled properly.""" - mock_args, mock_kwargs = ( - MagicMock(), - { - **self.default_config, - "gas_params": gas_params, - "skill_context": DummyContext(), - }, - ) - params = TransactionParams(mock_args, **mock_kwargs) - # verify that the gas params are being set properly - for key, value in gas_params.items(): - assert getattr(params.gas_params, key) == value diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_payload_tools.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_payload_tools.py deleted file mode 100644 index 91a90cf81..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_payload_tools.py +++ /dev/null @@ -1,101 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/transaction settlement skill's payload tools.""" - -# pylint: skip-file - -import pytest - -from packages.valory.contracts.gnosis_safe.contract import SafeOperation -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - NULL_ADDRESS, - PayloadDeserializationError, - VerificationStatus, - hash_payload_to_hex, - skill_input_hex_to_payload, - tx_hist_hex_to_payload, - tx_hist_payload_to_hex, -) - - -class TestTxHistPayloadEncodingDecoding: - """Tests for the transaction history's payload encoding - decoding.""" - - @staticmethod - @pytest.mark.parametrize( - "verification_status, tx_hash", - ( - ( - VerificationStatus.VERIFIED, - "0xb0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ), - (VerificationStatus.ERROR, None), - ), - ) - def test_tx_hist_payload_to_hex_and_back( - verification_status: VerificationStatus, tx_hash: str - ) -> None: - """Test `tx_hist_payload_to_hex` and `tx_hist_hex_to_payload` functions.""" - intermediate = tx_hist_payload_to_hex(verification_status, tx_hash) - verification_status_, tx_hash_ = tx_hist_hex_to_payload(intermediate) - assert verification_status == verification_status_ - assert tx_hash == tx_hash_ - - @staticmethod - def test_invalid_tx_hash_during_serialization() -> None: - """Test encoding when transaction hash is invalid.""" - with pytest.raises(ValueError): - tx_hist_payload_to_hex(VerificationStatus.VERIFIED, "") - - @staticmethod - @pytest.mark.parametrize( - "payload", - ("0000000000000000000000000000000000000000000000000000000000000008", ""), - ) - def test_invalid_payloads_during_deserialization(payload: str) -> None: - """Test decoding payload is invalid.""" - with pytest.raises(PayloadDeserializationError): - tx_hist_hex_to_payload(payload) - - -@pytest.mark.parametrize("use_flashbots", (True, False)) -def test_payload_to_hex_and_back(use_flashbots: bool) -> None: - """Test `payload_to_hex` function.""" - tx_params = dict( - safe_tx_hash="b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ether_value=0, - safe_tx_gas=40000000, - to_address="0x77E9b2EF921253A171Fa0CB9ba80558648Ff7215", - data=( - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9" - b"b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9" - ), - operation=SafeOperation.CALL.value, - base_gas=0, - safe_gas_price=0, - gas_token=NULL_ADDRESS, - use_flashbots=use_flashbots, - gas_limit=0, - refund_receiver=NULL_ADDRESS, - raise_on_failed_simulation=False, - ) - - intermediate = hash_payload_to_hex(**tx_params) # type: ignore - assert tx_params == skill_input_hex_to_payload(intermediate) diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_payloads.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_payloads.py deleted file mode 100644 index e53cd26d1..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_payloads.py +++ /dev/null @@ -1,126 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Test the payloads of the skill.""" - -# pylint: skip-file - -from typing import Optional - -import pytest - -from packages.valory.skills.transaction_settlement_abci.payloads import ( - CheckTransactionHistoryPayload, - FinalizationTxPayload, - RandomnessPayload, - ResetPayload, - SelectKeeperPayload, - SignaturePayload, - SynchronizeLateMessagesPayload, - ValidatePayload, -) - - -def test_randomness_payload() -> None: - """Test `RandomnessPayload`.""" - - payload = RandomnessPayload(sender="sender", round_id=1, randomness="test") - - assert payload.round_id == 1 - assert payload.randomness == "test" - assert payload.data == {"round_id": 1, "randomness": "test"} - - -def test_select_keeper_payload() -> None: - """Test `SelectKeeperPayload`.""" - - payload = SelectKeeperPayload(sender="sender", keepers="test") - - assert payload.keepers == "test" - assert payload.data == {"keepers": "test"} - - -@pytest.mark.parametrize("vote", (None, True, False)) -def test_validate_payload(vote: Optional[bool]) -> None: - """Test `ValidatePayload`.""" - - payload = ValidatePayload(sender="sender", vote=vote) - - assert payload.vote is vote - assert payload.data == {"vote": vote} - - -def test_tx_history_payload() -> None: - """Test `CheckTransactionHistoryPayload`.""" - - payload = CheckTransactionHistoryPayload(sender="sender", verified_res="test") - - assert payload.verified_res == "test" - assert payload.data == {"verified_res": "test"} - - -def test_synchronize_payload() -> None: - """Test `SynchronizeLateMessagesPayload`.""" - - tx_hashes = "test" - payload = SynchronizeLateMessagesPayload(sender="sender", tx_hashes=tx_hashes) - - assert payload.tx_hashes == tx_hashes - assert payload.data == {"tx_hashes": tx_hashes} - - -def test_signature_payload() -> None: - """Test `SignaturePayload`.""" - - payload = SignaturePayload(sender="sender", signature="sign") - - assert payload.signature == "sign" - assert payload.data == {"signature": "sign"} - - -def test_finalization_tx_payload() -> None: - """Test `FinalizationTxPayload`.""" - - payload = FinalizationTxPayload( - sender="sender", - tx_data={ - "tx_digest": "hash", - "nonce": 0, - "max_fee_per_gas": 0, - "max_priority_fee_per_gas": 0, - }, - ) - - assert payload.data == { - "tx_data": { - "tx_digest": "hash", - "nonce": 0, - "max_fee_per_gas": 0, - "max_priority_fee_per_gas": 0, - } - } - - -def test_reset_payload() -> None: - """Test `ResetPayload`.""" - - payload = ResetPayload(sender="sender", period_count=1) - - assert payload.period_count == 1 - assert payload.data == {"period_count": 1} diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_rounds.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_rounds.py deleted file mode 100644 index ecdb1af88..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_rounds.py +++ /dev/null @@ -1,1023 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2021-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. -# -# ------------------------------------------------------------------------------ - -"""Tests for valory/registration_abci skill's rounds.""" - -# pylint: skip-file - -import hashlib -import logging # noqa: F401 -from collections import deque -from typing import ( - Any, - Deque, - Dict, - FrozenSet, - List, - Mapping, - Optional, - Type, - Union, - cast, -) -from unittest import mock -from unittest.mock import MagicMock - -import pytest - -from packages.valory.skills.abstract_round_abci.base import ( - ABCIAppInternalError, - AbciAppDB, -) -from packages.valory.skills.abstract_round_abci.base import ( - BaseSynchronizedData as SynchronizedData, -) -from packages.valory.skills.abstract_round_abci.base import ( - BaseTxPayload, - CollectSameUntilThresholdRound, - CollectionRound, - MAX_INT_256, - TransactionNotValidError, - VotingRound, -) -from packages.valory.skills.abstract_round_abci.test_tools.rounds import ( - BaseCollectDifferentUntilThresholdRoundTest, - BaseCollectNonEmptyUntilThresholdRound, - BaseCollectSameUntilThresholdRoundTest, - BaseOnlyKeeperSendsRoundTest, - BaseVotingRoundTest, -) -from packages.valory.skills.transaction_settlement_abci.payload_tools import ( - VerificationStatus, -) -from packages.valory.skills.transaction_settlement_abci.payloads import ( - CheckTransactionHistoryPayload, - FinalizationTxPayload, - RandomnessPayload, - ResetPayload, - SelectKeeperPayload, - SignaturePayload, - SynchronizeLateMessagesPayload, - ValidatePayload, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - CheckTransactionHistoryRound, - CollectSignatureRound, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - Event as TransactionSettlementEvent, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - FinalizationRound, - ResetRound, - SelectKeeperTransactionSubmissionARound, - SelectKeeperTransactionSubmissionBAfterTimeoutRound, - SelectKeeperTransactionSubmissionBRound, - SynchronizeLateMessagesRound, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TransactionSettlementSynchronizedSata, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - TX_HASH_LENGTH, - ValidateTransactionRound, -) - - -MAX_PARTICIPANTS: int = 4 -RANDOMNESS: str = "d1c29dce46f979f9748210d24bce4eae8be91272f5ca1a6aea2832d3dd676f51" -DUMMY_RANDOMNESS = hashlib.sha256("hash".encode() + str(0).encode()).hexdigest() - - -def get_participants() -> FrozenSet[str]: - """Participants""" - return frozenset([f"agent_{i}" for i in range(MAX_PARTICIPANTS)]) - - -def get_participant_to_randomness( - participants: FrozenSet[str], round_id: int -) -> Dict[str, RandomnessPayload]: - """participant_to_randomness""" - return { - participant: RandomnessPayload( - sender=participant, - round_id=round_id, - randomness=RANDOMNESS, - ) - for participant in participants - } - - -def get_most_voted_randomness() -> str: - """most_voted_randomness""" - return RANDOMNESS - - -def get_participant_to_selection( - participants: FrozenSet[str], - keepers: str, -) -> Dict[str, SelectKeeperPayload]: - """participant_to_selection""" - return { - participant: SelectKeeperPayload(sender=participant, keepers=keepers) - for participant in participants - } - - -def get_participant_to_period_count( - participants: FrozenSet[str], period_count: int -) -> Dict[str, ResetPayload]: - """participant_to_selection""" - return { - participant: ResetPayload(sender=participant, period_count=period_count) - for participant in participants - } - - -def get_safe_contract_address() -> str: - """safe_contract_address""" - return "0x6f6ab56aca12" - - -def get_participant_to_votes( - participants: FrozenSet[str], vote: Optional[bool] = True -) -> Dict[str, ValidatePayload]: - """participant_to_votes""" - return { - participant: ValidatePayload(sender=participant, vote=vote) - for participant in participants - } - - -def get_participant_to_votes_serialized( - participants: FrozenSet[str], vote: Optional[bool] = True -) -> Dict[str, Dict[str, Any]]: - """participant_to_votes""" - return CollectionRound.serialize_collection( - get_participant_to_votes(participants, vote) - ) - - -def get_most_voted_tx_hash() -> str: - """most_voted_tx_hash""" - return "tx_hash" - - -def get_participant_to_signature( - participants: FrozenSet[str], -) -> Dict[str, SignaturePayload]: - """participant_to_signature""" - return { - participant: SignaturePayload(sender=participant, signature="signature") - for participant in participants - } - - -def get_final_tx_hash() -> str: - """final_tx_hash""" - return "tx_hash" - - -def get_participant_to_check( - participants: FrozenSet[str], - status: str, - tx_hash: str, -) -> Dict[str, CheckTransactionHistoryPayload]: - """Get participants to check""" - return { - participant: CheckTransactionHistoryPayload( - sender=participant, - verified_res=status + tx_hash, - ) - for participant in participants - } - - -def get_participant_to_late_arriving_tx_hashes( - participants: FrozenSet[str], -) -> Dict[str, SynchronizeLateMessagesPayload]: - """participant_to_selection""" - return { - participant: SynchronizeLateMessagesPayload( - sender=participant, tx_hashes="1" * TX_HASH_LENGTH + "2" * TX_HASH_LENGTH - ) - for participant in participants - } - - -def get_late_arriving_tx_hashes_deserialized() -> Dict[str, List[str]]: - """Get dummy late-arriving tx hashes.""" - # We want the tx hashes to have a size which can be divided by 64 to be able to parse it. - # Otherwise, they are not valid. - return { - "sender": [ - "t" * TX_HASH_LENGTH, - "e" * TX_HASH_LENGTH, - "s" * TX_HASH_LENGTH, - "t" * TX_HASH_LENGTH, - ] - } - - -def get_late_arriving_tx_hashes_serialized() -> Dict[str, str]: - """Get dummy late-arriving tx hashes.""" - # We want the tx hashes to have a size which can be divided by 64 to be able to parse it. - # Otherwise, they are not valid. - deserialized = get_late_arriving_tx_hashes_deserialized() - return {sender: "".join(hash_) for sender, hash_ in deserialized.items()} - - -def get_keepers(keepers: Deque[str], retries: int = 1) -> str: - """Get dummy keepers.""" - return retries.to_bytes(32, "big").hex() + "".join(keepers) - - -class BaseValidateRoundTest(BaseVotingRoundTest): - """Test BaseValidateRound.""" - - test_class: Type[VotingRound] - test_payload: Type[ValidatePayload] - - def test_positive_votes( - self, - ) -> None: - """Test ValidateRound.""" - - self.synchronized_data.update(tx_hashes_history="t" * 66) - - test_round = self.test_class( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_voting_round_positive( - test_round=test_round, - round_payloads=get_participant_to_votes(self.participants), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.update( - participant_to_votes=get_participant_to_votes_serialized( - self.participants - ) - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.participant_to_votes.keys() - ], - exit_event=self._event_class.DONE, - ) - ) - - def test_negative_votes( - self, - ) -> None: - """Test ValidateRound.""" - - test_round = self.test_class( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_voting_round_negative( - test_round=test_round, - round_payloads=get_participant_to_votes(self.participants, vote=False), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.update( - participant_to_votes=get_participant_to_votes_serialized( - self.participants, vote=False - ) - ), - synchronized_data_attr_checks=[], - exit_event=self._event_class.NEGATIVE, - ) - ) - - def test_none_votes( - self, - ) -> None: - """Test ValidateRound.""" - - test_round = self.test_class( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_voting_round_none( - test_round=test_round, - round_payloads=get_participant_to_votes(self.participants, vote=None), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.update( - participant_to_votes=get_participant_to_votes_serialized( - self.participants, vote=None - ) - ), - synchronized_data_attr_checks=[], - exit_event=self._event_class.NONE, - ) - ) - - -class BaseSelectKeeperRoundTest(BaseCollectSameUntilThresholdRoundTest): - """Test SelectKeeperTransactionSubmissionARound""" - - test_class: Type[CollectSameUntilThresholdRound] - test_payload: Type[BaseTxPayload] - - _synchronized_data_class = SynchronizedData - - @staticmethod - def _participant_to_selection( - participants: FrozenSet[str], keepers: str - ) -> Mapping[str, BaseTxPayload]: - """Get participant to selection""" - return get_participant_to_selection(participants, keepers) - - def test_run( - self, - most_voted_payload: str = "keeper", - keepers: str = "", - exit_event: Optional[Any] = None, - ) -> None: - """Run tests.""" - test_round = self.test_class( - synchronized_data=self.synchronized_data.update( - keepers=keepers, - ), - context=MagicMock(), - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=self._participant_to_selection( - self.participants, most_voted_payload - ), - synchronized_data_update_fn=lambda _synchronized_data, _test_round: _synchronized_data.update( - participant_to_selection=CollectionRound.serialize_collection( - self._participant_to_selection( - self.participants, most_voted_payload - ) - ) - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.participant_to_selection.keys() - if exit_event is None - else None - ], - most_voted_payload=most_voted_payload, - exit_event=self._event_class.DONE if exit_event is None else exit_event, - ) - ) - - -class TestSelectKeeperTransactionSubmissionARound(BaseSelectKeeperRoundTest): - """Test SelectKeeperTransactionSubmissionARound""" - - test_class = SelectKeeperTransactionSubmissionARound - test_payload = SelectKeeperPayload - _synchronized_data_class = TransactionSettlementSynchronizedSata - _event_class = TransactionSettlementEvent - - @pytest.mark.parametrize( - "most_voted_payload, keepers, exit_event", - ( - ( - "incorrectly_serialized", - "", - TransactionSettlementEvent.INCORRECT_SERIALIZATION, - ), - ( - int(1).to_bytes(32, "big").hex() + "new_keeper" + "-" * 32, - "", - TransactionSettlementEvent.DONE, - ), - ), - ) - def test_run( - self, - most_voted_payload: str, - keepers: str, - exit_event: TransactionSettlementEvent, - ) -> None: - """Run tests.""" - super().test_run(most_voted_payload, keepers, exit_event) - - -class TestSelectKeeperTransactionSubmissionBRound( - TestSelectKeeperTransactionSubmissionARound -): - """Test SelectKeeperTransactionSubmissionBRound.""" - - test_class = SelectKeeperTransactionSubmissionBRound - - @pytest.mark.parametrize( - "most_voted_payload, keepers, exit_event", - ( - ( - int(1).to_bytes(32, "big").hex() + "new_keeper" + "-" * 32, - "", - TransactionSettlementEvent.DONE, - ), - ( - int(1).to_bytes(32, "big").hex() + "new_keeper" + "-" * 32, - int(1).to_bytes(32, "big").hex() - + "".join( - [keeper + "-" * 30 for keeper in ("test_keeper1", "test_keeper2")] - ), - TransactionSettlementEvent.DONE, - ), - ), - ) - def test_run( - self, - most_voted_payload: str, - keepers: str, - exit_event: TransactionSettlementEvent, - ) -> None: - """Run tests.""" - super().test_run(most_voted_payload, keepers, exit_event) - - -class TestSelectKeeperTransactionSubmissionBAfterTimeoutRound( - TestSelectKeeperTransactionSubmissionBRound -): - """Test SelectKeeperTransactionSubmissionBAfterTimeoutRound.""" - - test_class = SelectKeeperTransactionSubmissionBAfterTimeoutRound - - @mock.patch.object( - TransactionSettlementSynchronizedSata, - "keepers_threshold_exceeded", - new_callable=mock.PropertyMock, - ) - @pytest.mark.parametrize( - "keepers", (f"{int(1).to_bytes(32, 'big').hex()}keeper" + "-" * 36,) - ) - @pytest.mark.parametrize( - "attrs, threshold_exceeded, exit_event", - ( - ( - { - "tx_hashes_history": "t" * 66, - "missed_messages": {f"keeper{'-' * 36}": 10}, - }, - True, - # Since the threshold has been exceeded, we should return a `CHECK_HISTORY` event. - TransactionSettlementEvent.CHECK_HISTORY, - ), - ( - { - "missed_messages": {f"keeper{'-' * 36}": 10}, - }, - True, - TransactionSettlementEvent.CHECK_LATE_ARRIVING_MESSAGE, - ), - ( - { - "missed_messages": {f"keeper{'-' * 36}": 10}, - }, - False, - TransactionSettlementEvent.DONE, - ), - ), - ) - def test_run( - self, - threshold_exceeded_mock: mock.PropertyMock, - keepers: str, - attrs: Dict[str, Union[str, int]], - threshold_exceeded: bool, - exit_event: TransactionSettlementEvent, - ) -> None: - """Test `SelectKeeperTransactionSubmissionBAfterTimeoutRound`.""" - self.synchronized_data.update(participant_to_selection=dict.fromkeys(self.participants), **attrs) # type: ignore - threshold_exceeded_mock.return_value = threshold_exceeded - most_voted_payload = int(1).to_bytes(32, "big").hex() + "new_keeper" + "-" * 32 - super().test_run(most_voted_payload, keepers, exit_event) - initial_missed_messages = cast(Dict[str, int], (attrs["missed_messages"])) - expected_missed_messages = { - sender: missed + 1 for sender, missed in initial_missed_messages.items() - } - synchronized_data = cast( - TransactionSettlementSynchronizedSata, self.synchronized_data - ) - assert synchronized_data.missed_messages == expected_missed_messages - - -class TestFinalizationRound(BaseOnlyKeeperSendsRoundTest): - """Test FinalizationRound.""" - - _synchronized_data_class = TransactionSettlementSynchronizedSata - _event_class = TransactionSettlementEvent - _round_class = FinalizationRound - - @pytest.mark.parametrize( - "tx_hashes_history, tx_digest, missed_messages, status, exit_event", - ( - ( - "", - "", - {"test": 1}, - VerificationStatus.ERROR.value, - TransactionSettlementEvent.CHECK_LATE_ARRIVING_MESSAGE, - ), - ( - "", - "", - {}, - VerificationStatus.ERROR.value, - TransactionSettlementEvent.FINALIZATION_FAILED, - ), - ( - "t" * 66, - "", - {}, - VerificationStatus.VERIFIED.value, - TransactionSettlementEvent.CHECK_HISTORY, - ), - ( - "t" * 66, - "", - {}, - VerificationStatus.ERROR.value, - TransactionSettlementEvent.CHECK_HISTORY, - ), - ( - "", - "", - {}, - VerificationStatus.PENDING.value, - TransactionSettlementEvent.FINALIZATION_FAILED, - ), - ( - "", - "tx_digest" + "t" * 57, - {}, - VerificationStatus.PENDING.value, - TransactionSettlementEvent.DONE, - ), - ( - "t" * 66, - "tx_digest" + "t" * 57, - {}, - VerificationStatus.PENDING.value, - TransactionSettlementEvent.DONE, - ), - ( - "t" * 66, - "", - {}, - VerificationStatus.INSUFFICIENT_FUNDS.value, - TransactionSettlementEvent.INSUFFICIENT_FUNDS, - ), - ), - ) - def test_finalization_round( - self, - tx_hashes_history: str, - tx_digest: str, - missed_messages: int, - status: int, - exit_event: TransactionSettlementEvent, - ) -> None: - """Runs tests.""" - keeper_retries = 2 - blacklisted_keepers = "" - self.participants = frozenset([f"agent_{i}" + "-" * 35 for i in range(4)]) - keepers = deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)) - self.synchronized_data = cast( - TransactionSettlementSynchronizedSata, - self.synchronized_data.update( - participants=tuple(self.participants), - missed_messages=missed_messages, - tx_hashes_history=tx_hashes_history, - keepers=get_keepers(keepers, keeper_retries), - blacklisted_keepers=blacklisted_keepers, - ), - ) - - sender = keepers[0] - tx_hashes_history += ( - tx_digest - if exit_event == TransactionSettlementEvent.DONE - else tx_hashes_history - ) - if status == VerificationStatus.INSUFFICIENT_FUNDS.value: - popped = keepers.popleft() - blacklisted_keepers += popped - keeper_retries = 1 - - test_round = self._round_class( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_round( - test_round=test_round, - keeper_payloads=FinalizationTxPayload( - sender=sender, - tx_data={ - "status_value": status, - "serialized_keepers": get_keepers(keepers, keeper_retries), - "blacklisted_keepers": blacklisted_keepers, - "tx_hashes_history": tx_hashes_history, - "received_hash": bool(tx_digest), - }, - ), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.update( - tx_hashes_history=tx_hashes_history, - blacklisted_keepers=blacklisted_keepers, - keepers=get_keepers(keepers, keeper_retries), - keeper_retries=keeper_retries, - final_verification_status=VerificationStatus(status).value, - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.tx_hashes_history, - lambda _synchronized_data: _synchronized_data.blacklisted_keepers, - lambda _synchronized_data: _synchronized_data.keepers, - lambda _synchronized_data: _synchronized_data.keeper_retries, - lambda _synchronized_data: _synchronized_data.final_verification_status, - ], - exit_event=exit_event, - ) - ) - - def test_finalization_round_no_tx_data(self) -> None: - """Test finalization round when `tx_data` is `None`.""" - keepers = deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35)) - keeper_retries = 2 - self.synchronized_data = cast( - TransactionSettlementSynchronizedSata, - self.synchronized_data.update( - participants=tuple(f"agent_{i}" + "-" * 35 for i in range(4)), - keepers=get_keepers(keepers, keeper_retries), - ), - ) - - sender = keepers[0] - - test_round = self._round_class( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_round( - test_round=test_round, - keeper_payloads=FinalizationTxPayload( - sender=sender, - tx_data=None, - ), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data, - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.tx_hashes_history, - lambda _synchronized_data: _synchronized_data.blacklisted_keepers, - lambda _synchronized_data: _synchronized_data.keepers, - lambda _synchronized_data: _synchronized_data.keeper_retries, - lambda _synchronized_data: _synchronized_data.final_verification_status, - ], - exit_event=TransactionSettlementEvent.FINALIZATION_FAILED, - ) - ) - - -class TestCollectSignatureRound(BaseCollectDifferentUntilThresholdRoundTest): - """Test CollectSignatureRound.""" - - _synchronized_data_class = TransactionSettlementSynchronizedSata - _event_class = TransactionSettlementEvent - - def test_run( - self, - ) -> None: - """Runs tests.""" - - test_round = CollectSignatureRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_signature(self.participants), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data, - synchronized_data_attr_checks=[], - exit_event=self._event_class.DONE, - ) - ) - - -class TestValidateTransactionRound(BaseValidateRoundTest): - """Test ValidateRound.""" - - test_class = ValidateTransactionRound - _event_class = TransactionSettlementEvent - _synchronized_data_class = TransactionSettlementSynchronizedSata - - -class TestCheckTransactionHistoryRound(BaseCollectSameUntilThresholdRoundTest): - """Test CheckTransactionHistoryRound""" - - _event_class = TransactionSettlementEvent - _synchronized_data_class = TransactionSettlementSynchronizedSata - - @pytest.mark.parametrize( - "expected_status, expected_tx_hash, missed_messages, expected_event", - ( - ( - "0000000000000000000000000000000000000000000000000000000000000001", - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - {}, - TransactionSettlementEvent.DONE, - ), - ( - "0000000000000000000000000000000000000000000000000000000000000002", - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - {}, - TransactionSettlementEvent.NEGATIVE, - ), - ( - "0000000000000000000000000000000000000000000000000000000000000003", - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - {}, - TransactionSettlementEvent.NONE, - ), - ( - "0000000000000000000000000000000000000000000000000000000000000007", - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - {}, - TransactionSettlementEvent.NONE, - ), - ( - "0000000000000000000000000000000000000000000000000000000000000002", - "b0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - {"test": 1}, - TransactionSettlementEvent.CHECK_LATE_ARRIVING_MESSAGE, - ), - ), - ) - def test_run( - self, - expected_status: str, - expected_tx_hash: str, - missed_messages: int, - expected_event: TransactionSettlementEvent, - ) -> None: - """Run tests.""" - keepers = get_keepers(deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35))) - self.synchronized_data.update(missed_messages=missed_messages, keepers=keepers) - - test_round = CheckTransactionHistoryRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_check( - self.participants, expected_status, expected_tx_hash - ), - synchronized_data_update_fn=lambda synchronized_data, _: synchronized_data.update( - participant_to_check=CollectionRound.serialize_collection( - get_participant_to_check( - self.participants, expected_status, expected_tx_hash - ) - ), - final_verification_status=int(expected_status), - tx_hashes_history=[expected_tx_hash], - keepers=keepers, - final_tx_hash="0xb0e6add595e00477cf347d09797b156719dc5233283ac76e4efce2a674fe72d9", - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.final_verification_status, - lambda _synchronized_data: _synchronized_data.final_tx_hash, - lambda _synchronized_data: _synchronized_data.keepers, - ] - if expected_event - not in { - TransactionSettlementEvent.NEGATIVE, - TransactionSettlementEvent.CHECK_LATE_ARRIVING_MESSAGE, - } - else [ - lambda _synchronized_data: _synchronized_data.final_verification_status, - lambda _synchronized_data: _synchronized_data.keepers, - ], - most_voted_payload=expected_status + expected_tx_hash, - exit_event=expected_event, - ) - ) - - -class TestSynchronizeLateMessagesRound(BaseCollectNonEmptyUntilThresholdRound): - """Test `SynchronizeLateMessagesRound`.""" - - _event_class = TransactionSettlementEvent - _synchronized_data_class = TransactionSettlementSynchronizedSata - - @pytest.mark.parametrize( - "missed_messages, expected_event", - ( - ( - {f"agent_{i}": 0 for i in range(4)}, - TransactionSettlementEvent.SUSPICIOUS_ACTIVITY, - ), - ({f"agent_{i}": 2 for i in range(4)}, TransactionSettlementEvent.DONE), - ), - ) - def test_runs( - self, missed_messages: int, expected_event: TransactionSettlementEvent - ) -> None: - """Runs tests.""" - self.synchronized_data.update(missed_messages=missed_messages) - test_round = SynchronizeLateMessagesRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - late_arriving_tx_hashes = { - p: "".join(("1" * TX_HASH_LENGTH, "2" * TX_HASH_LENGTH)) - for p in self.participants - } - test_round.required_block_confirmations = 0 - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_late_arriving_tx_hashes( - self.participants - ), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.update( - late_arriving_tx_hashes=late_arriving_tx_hashes, - suspects=tuple() - if expected_event == TransactionSettlementEvent.DONE - else tuple(sorted(late_arriving_tx_hashes.keys())), - ), - synchronized_data_attr_checks=[ - lambda _synchronized_data: _synchronized_data.late_arriving_tx_hashes, - lambda _synchronized_data: _synchronized_data.suspects, - ], - exit_event=expected_event, - ) - ) - - @pytest.mark.parametrize("correct_serialization", (True, False)) - def test_check_payload(self, correct_serialization: bool) -> None: - """Test the `check_payload` method.""" - - test_round = SynchronizeLateMessagesRound( - synchronized_data=self.synchronized_data, - context=MagicMock(), - ) - sender = list(test_round.accepting_payloads_from).pop() - hash_length = TX_HASH_LENGTH - if not correct_serialization: - hash_length -= 1 - tx_hashes = "0" * hash_length - payload = SynchronizeLateMessagesPayload(sender=sender, tx_hashes=tx_hashes) - - if correct_serialization: - test_round.check_payload(payload) - return - - with pytest.raises( - TransactionNotValidError, match="Expecting serialized data of chunk size" - ): - test_round.check_payload(payload) - - with pytest.raises( - ABCIAppInternalError, match="Expecting serialized data of chunk size" - ): - test_round.process_payload(payload) - assert payload not in test_round.collection - - -def test_synchronized_datas() -> None: - """Test SynchronizedData.""" - - participants = get_participants() - participant_to_randomness = get_participant_to_randomness(participants, 1) - participant_to_randomness_serialized = CollectionRound.serialize_collection( - participant_to_randomness - ) - most_voted_randomness = get_most_voted_randomness() - participant_to_selection = get_participant_to_selection(participants, "test") - participant_to_selection_serialized = CollectionRound.serialize_collection( - participant_to_selection - ) - safe_contract_address = get_safe_contract_address() - most_voted_tx_hash = get_most_voted_tx_hash() - participant_to_signature = get_participant_to_signature(participants) - participant_to_signature_serialized = CollectionRound.serialize_collection( - participant_to_signature - ) - final_tx_hash = get_final_tx_hash() - actual_keeper_randomness = int(most_voted_randomness, base=16) / MAX_INT_256 - late_arriving_tx_hashes_serialized = get_late_arriving_tx_hashes_serialized() - late_arriving_tx_hashes_deserialized = get_late_arriving_tx_hashes_deserialized() - keepers = get_keepers(deque(("agent_1" + "-" * 35, "agent_3" + "-" * 35))) - expected_keepers = deque(["agent_1" + "-" * 35, "agent_3" + "-" * 35]) - - # test `keeper_retries` property when no `keepers` are set. - synchronized_data_____ = TransactionSettlementSynchronizedSata( - AbciAppDB(setup_data=dict()) - ) - assert synchronized_data_____.keepers == deque() - assert synchronized_data_____.keeper_retries == 0 - - synchronized_data_____ = TransactionSettlementSynchronizedSata( - AbciAppDB( - setup_data=AbciAppDB.data_to_lists( - dict( - all_participants=tuple(participants), - participants=tuple(participants), - consensus_threshold=3, - participant_to_randomness=participant_to_randomness_serialized, - most_voted_randomness=most_voted_randomness, - participant_to_selection=participant_to_selection_serialized, - safe_contract_address=safe_contract_address, - most_voted_tx_hash=most_voted_tx_hash, - participant_to_signature=participant_to_signature_serialized, - final_tx_hash=final_tx_hash, - late_arriving_tx_hashes=late_arriving_tx_hashes_serialized, - keepers=keepers, - blacklisted_keepers="t" * 42, - ) - ), - ) - ) - assert ( - abs(synchronized_data_____.keeper_randomness - actual_keeper_randomness) < 1e-10 - ) # avoid equality comparisons between floats - assert synchronized_data_____.most_voted_randomness == most_voted_randomness - assert synchronized_data_____.safe_contract_address == safe_contract_address - assert synchronized_data_____.most_voted_tx_hash == most_voted_tx_hash - assert synchronized_data_____.participant_to_randomness == participant_to_randomness - assert synchronized_data_____.participant_to_selection == participant_to_selection - assert synchronized_data_____.participant_to_signature == participant_to_signature - assert synchronized_data_____.final_tx_hash == final_tx_hash - assert ( - synchronized_data_____.late_arriving_tx_hashes - == late_arriving_tx_hashes_deserialized - ) - assert synchronized_data_____.keepers == expected_keepers - assert synchronized_data_____.keeper_retries == 1 - assert ( - synchronized_data_____.most_voted_keeper_address == expected_keepers.popleft() - ) - assert synchronized_data_____.keepers_threshold_exceeded - assert synchronized_data_____.blacklisted_keepers == {"t" * 42} - updated_synchronized_data = synchronized_data_____.create() - assert updated_synchronized_data.blacklisted_keepers == set() - - -class TestResetRound(BaseCollectSameUntilThresholdRoundTest): - """Test ResetRound.""" - - _synchronized_data_class = TransactionSettlementSynchronizedSata - _event_class = TransactionSettlementEvent - - def test_runs( - self, - ) -> None: - """Runs tests.""" - randomness = DUMMY_RANDOMNESS - synchronized_data = self.synchronized_data.update( - most_voted_randomness=randomness, - late_arriving_tx_hashes={}, - keepers="", - ) - synchronized_data._db._cross_period_persisted_keys = frozenset( - {"most_voted_randomness"} - ) - test_round = ResetRound( - synchronized_data=synchronized_data, - context=MagicMock(), - ) - next_period_count = 1 - self._complete_run( - self._test_round( - test_round=test_round, - round_payloads=get_participant_to_period_count( - self.participants, next_period_count - ), - synchronized_data_update_fn=lambda _synchronized_data, _: _synchronized_data.create(), - synchronized_data_attr_checks=[], # [lambda _synchronized_data: _synchronized_data.participants], - most_voted_payload=next_period_count, - exit_event=self._event_class.DONE, - ) - ) diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/__init__.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/__init__.py deleted file mode 100644 index d1ae9fb95..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Package for `test_tools` testing.""" diff --git a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/test_integration.py b/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/test_integration.py deleted file mode 100644 index 84a67929f..000000000 --- a/trader_old/vendor/valory/skills/transaction_settlement_abci/tests/test_tools/test_integration.py +++ /dev/null @@ -1,214 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2022-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. -# -# ------------------------------------------------------------------------------ - -"""Test transaction settlement integration test tool.""" - -from pathlib import Path -from typing import cast -from unittest import mock - -import pytest -from aea.exceptions import AEAActException -from web3.types import Nonce, Wei - -from packages.valory.protocols.contract_api import ContractApiMessage -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.skills import transaction_settlement_abci -from packages.valory.skills.abstract_round_abci.base import AbciAppDB -from packages.valory.skills.abstract_round_abci.tests.test_tools.base import ( - FSMBehaviourTestToolSetup, -) -from packages.valory.skills.transaction_settlement_abci.behaviours import ( - FinalizeBehaviour, -) -from packages.valory.skills.transaction_settlement_abci.rounds import ( - SynchronizedData as TxSettlementSynchronizedSata, -) -from packages.valory.skills.transaction_settlement_abci.test_tools.integration import ( - _GnosisHelperIntegration, - _SafeConfiguredHelperIntegration, - _TxHelperIntegration, -) - - -DUMMY_TX_HASH = "a" * 234 - - -class Test_SafeConfiguredHelperIntegration(FSMBehaviourTestToolSetup): - """Test_SafeConfiguredHelperIntegration""" - - test_cls = _SafeConfiguredHelperIntegration - - def test_instantiation(self) -> None: - """Test instantiation""" - - self.set_path_to_skill() - self.test_cls.make_ledger_api_connection_callable = ( - lambda *_, **__: mock.MagicMock() - ) - test_instance = cast(_SafeConfiguredHelperIntegration, self.setup_test_cls()) - - assert test_instance.keeper_address in test_instance.safe_owners - - -class Test_GnosisHelperIntegration(FSMBehaviourTestToolSetup): - """Test_SafeConfiguredHelperIntegration""" - - test_cls = _GnosisHelperIntegration - - def test_instantiation(self) -> None: - """Test instantiation""" - - self.set_path_to_skill() - self.test_cls.make_ledger_api_connection_callable = ( - lambda *_, **__: mock.MagicMock() - ) - test_instance = cast(_GnosisHelperIntegration, self.setup_test_cls()) - - assert test_instance.safe_contract_address - assert test_instance.gnosis_instance - assert test_instance.ethereum_api - - -class Test_TxHelperIntegration(FSMBehaviourTestToolSetup): - """Test_SafeConfiguredHelperIntegration""" - - test_cls = _TxHelperIntegration - - def instantiate_test(self) -> _TxHelperIntegration: - """Instantiate the test""" - - path_to_skill = Path(transaction_settlement_abci.__file__).parent - self.set_path_to_skill(path_to_skill=path_to_skill) - self.test_cls.make_ledger_api_connection_callable = ( - lambda *_, **__: mock.MagicMock() - ) - - db = AbciAppDB( - setup_data={"all_participants": [f"agent_{i}" for i in range(4)]} - ) - self.test_cls.tx_settlement_synchronized_data = TxSettlementSynchronizedSata(db) - - test_instance = cast(_TxHelperIntegration, self.setup_test_cls()) - return test_instance - - def test_sign_tx(self) -> None: - """Test sign_tx""" - - test_instance = self.instantiate_test() - test_instance.tx_settlement_synchronized_data.db.update( - most_voted_tx_hash=DUMMY_TX_HASH - ) - - target = test_instance.gnosis_instance.functions.getOwners - return_value = test_instance.safe_owners - with mock.patch.object( - target, "call", new_callable=lambda: lambda: return_value - ): - test_instance.sign_tx() - - def test_sign_tx_failure(self) -> None: - """Test sign_tx failure""" - - test_instance = self.instantiate_test() - test_instance.tx_settlement_synchronized_data.db.update( - most_voted_tx_hash=DUMMY_TX_HASH - ) - - target = test_instance.gnosis_instance.functions.getOwners - with mock.patch.object(target, "call", new_callable=lambda: lambda: {}): - with pytest.raises(AssertionError): - test_instance.sign_tx() - - def test_send_tx(self) -> None: - """Test send tx""" - - test_instance = self.instantiate_test() - - nonce = Nonce(0) - gas_price = {"maxPriorityFeePerGas": Wei(0), "maxFeePerGas": Wei(0)} - behaviour = cast(FinalizeBehaviour, test_instance.behaviour.current_behaviour) - behaviour.params.mutable_params.gas_price = gas_price - behaviour.params.mutable_params.nonce = nonce - - contract_api_message = ContractApiMessage( - performative=ContractApiMessage.Performative.RAW_TRANSACTION, # type: ignore - raw_transaction=ContractApiMessage.RawTransaction( - ledger_id="", body={"nonce": str(nonce), **gas_price} - ), - ) - - ledger_api_message = LedgerApiMessage( - performative=LedgerApiMessage.Performative.TRANSACTION_DIGEST, # type: ignore - transaction_digest=LedgerApiMessage.TransactionDigest( - ledger_id="", body="" - ), - ) - - return_value = contract_api_message, None, ledger_api_message - - with mock.patch.object( - test_instance, - "process_n_messages", - new_callable=lambda: lambda *x, **__: return_value, - ): - test_instance.send_tx() - - def test_validate_tx(self) -> None: - """Test validate_tx""" - - test_instance = self.instantiate_test() - test_instance.tx_settlement_synchronized_data.db.update( - tx_hashes_history="a" * 64 - ) - - contract_api_message = ContractApiMessage( - performative=ContractApiMessage.Performative.STATE, # type: ignore - state=ContractApiMessage.State( - ledger_id="", - body={"verified": True}, - ), - ) - return_value = None, contract_api_message - - with mock.patch.object( - test_instance, - "process_n_messages", - new_callable=lambda: lambda *x, **__: return_value, - ): - test_instance.validate_tx() - - def test_validate_tx_timeout(self) -> None: - """Test validate_tx timeout""" - - test_instance = self.instantiate_test() - synchronized_data = test_instance.tx_settlement_synchronized_data - assert synchronized_data.n_missed_messages == 0 - test_instance.validate_tx(simulate_timeout=True) - assert synchronized_data.n_missed_messages == 1 - - def test_validate_tx_failure(self) -> None: - """Test validate tx failure""" - - test_instance = self.instantiate_test() - - with pytest.raises( - AEAActException, match="FSM design error: tx hash should exist" - ): - test_instance.validate_tx() diff --git a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/README.md b/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/README.md deleted file mode 100644 index f726ff7a5..000000000 --- a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Transaction Settlement Multiplexer abci - -## Description - -This module contains a multiplexer for the transaction settlement skill. -This is necessary in order to be able to chain the tx settlement multiple times for the FSM. diff --git a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/__init__.py b/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/__init__.py deleted file mode 100644 index bac79e138..000000000 --- a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- 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 skill that acts as a multiplexer for the transaction settlement skill.""" - -from aea.configurations.base import PublicId - - -PUBLIC_ID = PublicId.from_str("valory/tx_settlement_multiplexer_abci:0.1.0") diff --git a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/behaviours.py b/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/behaviours.py deleted file mode 100644 index c19209f9f..000000000 --- a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/behaviours.py +++ /dev/null @@ -1,184 +0,0 @@ -# -*- 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 package contains the behaviours of the transaction settlement multiplexer.""" - -from typing import Generator, Optional, Set, Type, cast - -from aea.exceptions import AEAEnforceError - -from packages.valory.protocols.ledger_api import LedgerApiMessage -from packages.valory.skills.abstract_round_abci.behaviours import ( - AbstractRoundBehaviour, - BaseBehaviour, -) -from packages.valory.skills.decision_maker_abci.models import RedeemingProgress -from packages.valory.skills.decision_maker_abci.payloads import VotingPayload -from packages.valory.skills.tx_settlement_multiplexer_abci.models import ( - TxSettlementMultiplexerParams, -) -from packages.valory.skills.tx_settlement_multiplexer_abci.rounds import ( - PostTxSettlementRound, - PreTxSettlementRound, - SynchronizedData, - TxSettlementMultiplexerAbciApp, -) - - -class PreTxSettlementBehaviour(BaseBehaviour): - """ - The pre transaction settlement behaviour. - - This behaviour should be executed before a tx is sent via the transaction_settlement_abci. - """ - - matching_round = PreTxSettlementRound - - @property - def params(self) -> TxSettlementMultiplexerParams: - """Return the params.""" - return cast(TxSettlementMultiplexerParams, self.context.params) - - def _get_balance(self, agent: str) -> Generator[None, None, Optional[int]]: - """Get the given agent's balance.""" - self.context.logger.info(f"Checking balance for agent with address {agent}...") - ledger_api_response = yield from self.get_ledger_api_response( - performative=LedgerApiMessage.Performative.GET_STATE, # type: ignore - ledger_callable="get_balance", - account=agent, - ) - - try: - balance = int(ledger_api_response.state.body["get_balance_result"]) - except (AEAEnforceError, KeyError, ValueError, TypeError): - balance = None - - if balance is None: - log_msg = f"Failed to get the balance for agent with address {agent}." - self.context.logger.error(f"{log_msg}: {ledger_api_response}") - return None - - self.context.logger.info(f"The agent with address {agent} has {balance} WEI.") - return balance - - def _check_balance(self, agent: str) -> Generator[None, None, bool]: - """Check if the given agent's balance is sufficient.""" - balance = None - while balance is None: - balance = yield from self._get_balance(agent) - - threshold = self.params.agent_balance_threshold - refill_required = balance < threshold - if refill_required: - msg = f"Please refill agent with address {agent}. Balance is below {threshold}." - self.context.logger.warning(msg) - - return refill_required - - def _refill_required(self) -> Generator[None, None, bool]: - """Check whether a refill is required.""" - refill_required = False - for agent in self.synchronized_data.all_participants: - refill_required |= yield from self._check_balance(agent) - return refill_required - - def async_act(self) -> Generator: - """Check whether the agents' balances are sufficient.""" - with self.context.benchmark_tool.measure(self.behaviour_id).local(): - refill_required = yield from self._refill_required() - if refill_required: - # pause to give the user some time to refill before transitioning to the same round again - yield from self.sleep(self.params.refill_check_interval) - - payload = VotingPayload(self.context.agent_address, not refill_required) - - with self.context.benchmark_tool.measure(self.behaviour_id).consensus(): - yield from self.send_a2a_transaction(payload) - yield from self.wait_until_round_end() - - self.set_done() - - -class PostTxSettlementBehaviour(BaseBehaviour): - """ - The post transaction settlement behaviour. - - This behaviour should be executed after a tx is settled via the transaction_settlement_abci. - """ - - matching_round = PostTxSettlementRound - - @property - def synchronized_data(self) -> SynchronizedData: - """Return the synchronized data.""" - return SynchronizedData(super().synchronized_data.db) - - @property - def redeeming_progress(self) -> RedeemingProgress: - """Get the redeeming progress.""" - return self.shared_state.redeeming_progress # type: ignore - - @redeeming_progress.setter - def redeeming_progress(self, value: RedeemingProgress) -> None: - """Set the redeeming progress.""" - self.shared_state.redeeming_progress = value - - def _on_redeem_round_tx_settled(self) -> None: - """Handle the redeem round.""" - self.context.logger.info( - "Redeeming transaction was settled. Resetting the redeeming progress." - ) - claimed_condition_ids = self.redeeming_progress.claimed_condition_ids - claimed_condition_ids.extend(self.redeeming_progress.claiming_condition_ids) - self.redeeming_progress = RedeemingProgress() - self.redeeming_progress.claimed_condition_ids = claimed_condition_ids - self.context.logger.info( - f"The following condition ids were claimed so far: {claimed_condition_ids}" - ) - - def _on_tx_settled(self) -> None: - """Handle the tx settled event.""" - tx_submitter = self.synchronized_data.tx_submitter - handler_name = f"_on_{tx_submitter}_tx_settled" - handler = getattr(self, handler_name, None) - if handler is None: - self.context.logger.info( - f"No post tx settlement handler exists for {tx_submitter} txs." - ) - return - handler() - - def async_act(self) -> Generator: - """Simply log that a tx is settled and wait for the round end.""" - msg = f"The transaction submitted by {self.synchronized_data.tx_submitter} was successfully settled." - self.context.logger.info(msg) - self._on_tx_settled() - yield from self.wait_until_round_end() - self.set_done() - - -class PostTxSettlementFullBehaviour(AbstractRoundBehaviour): - """The post tx settlement full behaviour.""" - - initial_behaviour_cls = PostTxSettlementBehaviour - abci_app_cls = TxSettlementMultiplexerAbciApp - behaviours: Set[Type[BaseBehaviour]] = { - PreTxSettlementBehaviour, # type: ignore - PostTxSettlementBehaviour, # type: ignore - } diff --git a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/dialogues.py b/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/dialogues.py deleted file mode 100644 index 153b6ce50..000000000 --- a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/dialogues.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- 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 the classes required for dialogue management.""" - -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogue as BaseAbciDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - AbciDialogues as BaseAbciDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogue as BaseContractApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - ContractApiDialogues as BaseContractApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogue as BaseHttpDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - HttpDialogues as BaseHttpDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogue as BaseIpfsDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - IpfsDialogues as BaseIpfsDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogue as BaseLedgerApiDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - LedgerApiDialogues as BaseLedgerApiDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogue as BaseSigningDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - SigningDialogues as BaseSigningDialogues, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogue as BaseTendermintDialogue, -) -from packages.valory.skills.abstract_round_abci.dialogues import ( - TendermintDialogues as BaseTendermintDialogues, -) - - -AbciDialogue = BaseAbciDialogue -AbciDialogues = BaseAbciDialogues - - -HttpDialogue = BaseHttpDialogue -HttpDialogues = BaseHttpDialogues - - -SigningDialogue = BaseSigningDialogue -SigningDialogues = BaseSigningDialogues - - -LedgerApiDialogue = BaseLedgerApiDialogue -LedgerApiDialogues = BaseLedgerApiDialogues - - -ContractApiDialogue = BaseContractApiDialogue -ContractApiDialogues = BaseContractApiDialogues - -TendermintDialogue = BaseTendermintDialogue -TendermintDialogues = BaseTendermintDialogues - - -IpfsDialogue = BaseIpfsDialogue -IpfsDialogues = BaseIpfsDialogues diff --git a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/fsm_specification.yaml b/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/fsm_specification.yaml deleted file mode 100644 index d671e1d6b..000000000 --- a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/fsm_specification.yaml +++ /dev/null @@ -1,52 +0,0 @@ -alphabet_in: -- BET_PLACEMENT_NO_SELL_DONE -- BET_PLACEMENT_SELL_DONE -- CHECKS_PASSED -- MECH_REQUESTING_DONE -- NO_MAJORITY -- REDEEMING_DONE -- REFILL_REQUIRED -- ROUND_TIMEOUT -- SELL_OUTCOME_TOKEN_DONE -- STAKING_DONE -- SUBSCRIPTION_DONE -- UNRECOGNIZED -default_start_state: PreTxSettlementRound -final_states: -- ChecksPassedRound -- FailedMultiplexerRound -- FinishedBetPlacementTxRound -- FinishedMechRequestTxRound -- FinishedRedeemingTxRound -- FinishedSellOutcomeTokenTxRound -- FinishedStakingTxRound -- FinishedSubscriptionTxRound -label: TxSettlementMultiplexerAbciApp -start_states: -- PostTxSettlementRound -- PreTxSettlementRound -states: -- ChecksPassedRound -- FailedMultiplexerRound -- FinishedBetPlacementTxRound -- FinishedMechRequestTxRound -- FinishedRedeemingTxRound -- FinishedSellOutcomeTokenTxRound -- FinishedStakingTxRound -- FinishedSubscriptionTxRound -- PostTxSettlementRound -- PreTxSettlementRound -transition_func: - (PostTxSettlementRound, BET_PLACEMENT_NO_SELL_DONE): FinishedBetPlacementTxRound - (PostTxSettlementRound, BET_PLACEMENT_SELL_DONE): FinishedBetPlacementTxRound - (PostTxSettlementRound, MECH_REQUESTING_DONE): FinishedMechRequestTxRound - (PostTxSettlementRound, REDEEMING_DONE): FinishedRedeemingTxRound - (PostTxSettlementRound, ROUND_TIMEOUT): PostTxSettlementRound - (PostTxSettlementRound, SELL_OUTCOME_TOKEN_DONE): FinishedSellOutcomeTokenTxRound - (PostTxSettlementRound, STAKING_DONE): FinishedStakingTxRound - (PostTxSettlementRound, SUBSCRIPTION_DONE): FinishedSubscriptionTxRound - (PostTxSettlementRound, UNRECOGNIZED): FailedMultiplexerRound - (PreTxSettlementRound, CHECKS_PASSED): ChecksPassedRound - (PreTxSettlementRound, NO_MAJORITY): PreTxSettlementRound - (PreTxSettlementRound, REFILL_REQUIRED): PreTxSettlementRound - (PreTxSettlementRound, ROUND_TIMEOUT): PreTxSettlementRound diff --git a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/handlers.py b/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/handlers.py deleted file mode 100644 index 0f3ed315d..000000000 --- a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/handlers.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- 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 the handlers for the skill.""" - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) - - -TxSettlementMultiplexerHandler = ABCIRoundHandler -HttpHandler = BaseHttpHandler -SigningHandler = BaseSigningHandler -LedgerApiHandler = BaseLedgerApiHandler -ContractApiHandler = BaseContractApiHandler -TendermintHandler = BaseTendermintHandler -IpfsHandler = BaseIpfsHandler diff --git a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/models.py b/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/models.py deleted file mode 100644 index 49c0e5dbd..000000000 --- a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/models.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- 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. -# -# ------------------------------------------------------------------------------ - - -"""Custom objects for the TxSettlementMultiplexer ABCI application.""" - -from typing import Any - -from packages.valory.skills.abstract_round_abci.models import BaseParams -from packages.valory.skills.abstract_round_abci.models import ( - BenchmarkTool as BaseBenchmarkTool, -) -from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests -from packages.valory.skills.abstract_round_abci.models import ( - SharedState as BaseSharedState, -) -from packages.valory.skills.tx_settlement_multiplexer_abci.rounds import ( - TxSettlementMultiplexerAbciApp, -) - - -Requests = BaseRequests -BenchmarkTool = BaseBenchmarkTool - - -class TxSettlementMultiplexerParams(BaseParams): - """Staking parameters.""" - - def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize the parameters' object.""" - self.agent_balance_threshold: int = self._ensure( - "agent_balance_threshold", kwargs, int - ) - self.refill_check_interval: int = self._ensure( - "refill_check_interval", kwargs, int - ) - super().__init__(*args, **kwargs) - - -class SharedState(BaseSharedState): - """Keep the current shared state of the skill.""" - - abci_app_cls = TxSettlementMultiplexerAbciApp diff --git a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/rounds.py b/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/rounds.py deleted file mode 100644 index ec8912db0..000000000 --- a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/rounds.py +++ /dev/null @@ -1,265 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2023-2024 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 package contains the rounds of `TxSettlementMultiplexerAbciApp`.""" - -import json -from enum import Enum -from typing import Any, Dict, Optional, Set, Tuple - -from packages.valory.skills.abstract_round_abci.base import ( - AbciApp, - AbciAppTransitionFunction, - AppState, - BaseSynchronizedData, - CollectSameUntilThresholdRound, - DegenerateRound, - VotingRound, - get_name, -) -from packages.valory.skills.decision_maker_abci.payloads import VotingPayload -from packages.valory.skills.decision_maker_abci.states.base import SynchronizedData -from packages.valory.skills.decision_maker_abci.states.bet_placement import ( - BetPlacementRound, -) -from packages.valory.skills.decision_maker_abci.states.order_subscription import ( - SubscriptionRound, -) -from packages.valory.skills.decision_maker_abci.states.redeem import RedeemRound -from packages.valory.skills.decision_maker_abci.states.sell_outcome_token import ( - SellOutcomeTokenRound, -) -from packages.valory.skills.mech_interact_abci.states.request import MechRequestRound -from packages.valory.skills.staking_abci.rounds import CallCheckpointRound - - -class Event(Enum): - """Multiplexing events.""" - - CHECKS_PASSED = "checks_passed" - REFILL_REQUIRED = "refill_required" - MECH_REQUESTING_DONE = "mech_requesting_done" - BET_PLACEMENT_NO_SELL_DONE = "bet_placement_done_no_sell" - BET_PLACEMENT_SELL_DONE = "bet_placement_done_sell" - REDEEMING_DONE = "redeeming_done" - SELL_OUTCOME_TOKEN_DONE = "sell_outcome_token_done" # nosec - STAKING_DONE = "staking_done" - SUBSCRIPTION_DONE = "subscription_done" - ROUND_TIMEOUT = "round_timeout" - UNRECOGNIZED = "unrecognized" - NO_MAJORITY = "no_majority" - - -class PreTxSettlementRound(VotingRound): - """A round that will be called before the tx settlement.""" - - payload_class = VotingPayload - synchronized_data_class = SynchronizedData - done_event = Event.CHECKS_PASSED - negative_event = Event.REFILL_REQUIRED - no_majority_event = Event.NO_MAJORITY - collection_key = get_name(SynchronizedData.participant_to_votes) - - -class PostTxSettlementRound(CollectSameUntilThresholdRound): - """A round that will be called after tx settlement is done.""" - - payload_class: Any = object() - synchronized_data_class = SynchronizedData - - def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: - """ - The end block. - - This is a special type of round. No consensus is necessary here. - There is no need to send a tx through, nor to check for a majority. - We simply use this round to check which round submitted the tx, - and move to the next state in accordance with that. - - :return: the synchronized data and the event, otherwise `None` if the round is still running. - """ - submitter_to_event: Dict[str, Event] = { - MechRequestRound.auto_round_id(): Event.MECH_REQUESTING_DONE, - BetPlacementRound.auto_round_id(): Event.BET_PLACEMENT_NO_SELL_DONE, - RedeemRound.auto_round_id(): Event.REDEEMING_DONE, - CallCheckpointRound.auto_round_id(): Event.STAKING_DONE, - SubscriptionRound.auto_round_id(): Event.SUBSCRIPTION_DONE, - SellOutcomeTokenRound.auto_round_id(): Event.SELL_OUTCOME_TOKEN_DONE, - } - - synced_data = SynchronizedData(self.synchronized_data.db) - event = submitter_to_event.get(synced_data.tx_submitter, Event.UNRECOGNIZED) - - if synced_data.vote != synced_data.previous_vote: - event = Event.BET_PLACEMENT_SELL_DONE - - # if a mech request was just performed, increase the utilized tool's counter - if event == Event.MECH_REQUESTING_DONE: - policy = synced_data.policy - policy.tool_used(synced_data.mech_tool) - policy_update = policy.serialize() - self.synchronized_data.update(policy=policy_update) - - # if a bet was just placed, edit the utilized tools mapping - if ( - event == Event.BET_PLACEMENT_NO_SELL_DONE - or event == Event.BET_PLACEMENT_SELL_DONE - ): - utilized_tools = synced_data.utilized_tools - utilized_tools[synced_data.final_tx_hash] = synced_data.mech_tool - tools_update = json.dumps(utilized_tools, sort_keys=True) - vote = synced_data.vote - self.synchronized_data.update( - utilized_tools=tools_update, previous_vote=vote - ) - - # if all tokens for an outcome have been sold, set the previous vote to None as we no longer have any - # investment in that outcome - if event == Event.SELL_OUTCOME_TOKEN_DONE: - self.synchronized_data.update(previous_vote=None) - - return synced_data, event - - -class ChecksPassedRound(DegenerateRound): - """Round that represents all the pre tx settlement checks have passed.""" - - -class FinishedMechRequestTxRound(DegenerateRound): - """Finished mech requesting round.""" - - -class FinishedBetPlacementTxRound(DegenerateRound): - """Finished bet placement round.""" - - -class FinishedRedeemingTxRound(DegenerateRound): - """Finished redeeming round.""" - - -class FinishedStakingTxRound(DegenerateRound): - """Finished staking round.""" - - -class FinishedSubscriptionTxRound(DegenerateRound): - """Finished subscription round.""" - - -class FinishedSellOutcomeTokenTxRound(DegenerateRound): - """Finished sell outcome token round.""" - - -class FailedMultiplexerRound(DegenerateRound): - """Round that represents failure in identifying the transmitter round.""" - - -class TxSettlementMultiplexerAbciApp(AbciApp[Event]): - """TxSettlementMultiplexerAbciApp - - Initial round: PreTxSettlementRound - - Initial states: {PostTxSettlementRound, PreTxSettlementRound} - - Transition states: - 0. PreTxSettlementRound - - checks passed: 2. - - refill required: 0. - - no majority: 0. - - round timeout: 0. - 1. PostTxSettlementRound - - mech requesting done: 3. - - bet placement done no sell: 4. - - bet placement done sell: 4. - - redeeming done: 6. - - sell outcome token done: 8. - - staking done: 7. - - subscription done: 5. - - round timeout: 1. - - unrecognized: 9. - 2. ChecksPassedRound - 3. FinishedMechRequestTxRound - 4. FinishedBetPlacementTxRound - 5. FinishedSubscriptionTxRound - 6. FinishedRedeemingTxRound - 7. FinishedStakingTxRound - 8. FinishedSellOutcomeTokenTxRound - 9. FailedMultiplexerRound - - Final states: {ChecksPassedRound, FailedMultiplexerRound, FinishedBetPlacementTxRound, FinishedMechRequestTxRound, FinishedRedeemingTxRound, FinishedSellOutcomeTokenTxRound, FinishedStakingTxRound, FinishedSubscriptionTxRound} - - Timeouts: - round timeout: 30.0 - """ - - initial_round_cls: AppState = PreTxSettlementRound - initial_states: Set[AppState] = {PreTxSettlementRound, PostTxSettlementRound} - transition_function: AbciAppTransitionFunction = { - PreTxSettlementRound: { - Event.CHECKS_PASSED: ChecksPassedRound, - Event.REFILL_REQUIRED: PreTxSettlementRound, - Event.NO_MAJORITY: PreTxSettlementRound, - Event.ROUND_TIMEOUT: PreTxSettlementRound, - }, - PostTxSettlementRound: { - Event.MECH_REQUESTING_DONE: FinishedMechRequestTxRound, - Event.BET_PLACEMENT_NO_SELL_DONE: FinishedBetPlacementTxRound, - Event.BET_PLACEMENT_SELL_DONE: FinishedBetPlacementTxRound, - Event.REDEEMING_DONE: FinishedRedeemingTxRound, - Event.SELL_OUTCOME_TOKEN_DONE: FinishedSellOutcomeTokenTxRound, - Event.STAKING_DONE: FinishedStakingTxRound, - Event.SUBSCRIPTION_DONE: FinishedSubscriptionTxRound, - Event.ROUND_TIMEOUT: PostTxSettlementRound, - Event.UNRECOGNIZED: FailedMultiplexerRound, - }, - ChecksPassedRound: {}, - FinishedMechRequestTxRound: {}, - FinishedBetPlacementTxRound: {}, - FinishedSubscriptionTxRound: {}, - FinishedRedeemingTxRound: {}, - FinishedStakingTxRound: {}, - FinishedSellOutcomeTokenTxRound: {}, - FailedMultiplexerRound: {}, - } - event_to_timeout: Dict[Event, float] = { - Event.ROUND_TIMEOUT: 30.0, - } - final_states: Set[AppState] = { - ChecksPassedRound, - FinishedMechRequestTxRound, - FinishedBetPlacementTxRound, - FinishedRedeemingTxRound, - FinishedStakingTxRound, - FinishedSubscriptionTxRound, - FinishedSellOutcomeTokenTxRound, - FailedMultiplexerRound, - } - db_pre_conditions: Dict[AppState, Set[str]] = { - PreTxSettlementRound: {get_name(SynchronizedData.tx_submitter)}, - PostTxSettlementRound: {get_name(SynchronizedData.tx_submitter)}, - } - db_post_conditions: Dict[AppState, Set[str]] = { - ChecksPassedRound: set(), - FinishedMechRequestTxRound: set(), - FinishedBetPlacementTxRound: set(), - FinishedRedeemingTxRound: set(), - FinishedStakingTxRound: set(), - FailedMultiplexerRound: set(), - FinishedSubscriptionTxRound: set(), - FinishedSellOutcomeTokenTxRound: set(), - } diff --git a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/skill.yaml b/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/skill.yaml deleted file mode 100644 index b7d8f0889..000000000 --- a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/skill.yaml +++ /dev/null @@ -1,144 +0,0 @@ -name: tx_settlement_multiplexer_abci -author: valory -version: 0.1.0 -type: skill -description: This skill implements a multiplexer for the transaction settlement skill. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - README.md: bafybeiegcjg2wjrsqhrmvyulioch3d67rnbzkx5af3ztkaw7kxathjreda - __init__.py: bafybeide6k22zk4f3hyzhpapaoddsnxpw5elqcfvrxxj4nfvpzctv6jqhu - behaviours.py: bafybeictumcqn2pgo7y2duemvzoaafognfhl6s6il3tv53hq66tf7xgpsu - dialogues.py: bafybeiebofyykseqp3fmif36cqmmyf3k7d2zbocpl6t6wnlpv4szghrxbm - fsm_specification.yaml: bafybeieoyrx3nt3qsvd5n2bkryzq6twvrphmbqn3fs4gts6eoy2tvksxoy - handlers.py: bafybeiafbqr7ojfcbwohvee7x4zzswad3ymfrrbjlfz7uuuttmn3qdfs6q - models.py: bafybeigtmxoecoow663hgqnyinxarlrttyyt5ghpbdamdv4tc4kikcfx3a - rounds.py: bafybeihbxi4m7eyvkmenhcdzy3ijzajaxqrcyts3asvqe36l2til7kngzy - tests/__init__.py: bafybeiat74pbtmxvylsz7karp57qp2v7y6wtrsz572jkrghbcssoudgjay - tests/test_handlers.py: bafybeiayuktfupylm3p3ygufjb66swzxhpbmioqoffwuauakfgbkwrv7ma -fingerprint_ignore_patterns: [] -connections: [] -contracts: [] -protocols: -- valory/ledger_api:1.0.0:bafybeihdk6psr4guxmbcrc26jr2cbgzpd5aljkqvpwo64bvaz7tdti2oni -skills: -- valory/abstract_round_abci:0.1.0:bafybeib733xfbndtpvkf44mtk7oyodnficgloo6xhn7xmqxxeos33es65u -- valory/decision_maker_abci:0.1.0:bafybeibqiruzwnj7usv4nmtjiyrzaaukive4wiebdxd5gymwgrlsn2fara -- valory/staking_abci:0.1.0:bafybeicupccurmrg7qesivonlyt3nryarsmk5qf5yh6auno64wn45bybvq -- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm -behaviours: - main: - args: {} - class_name: PostTxSettlementFullBehaviour -handlers: - abci: - args: {} - class_name: TxSettlementMultiplexerHandler - contract_api: - args: {} - class_name: ContractApiHandler - http: - args: {} - class_name: HttpHandler - ipfs: - args: {} - class_name: IpfsHandler - ledger_api: - args: {} - class_name: LedgerApiHandler - signing: - args: {} - class_name: SigningHandler - tendermint: - args: {} - class_name: TendermintHandler -models: - abci_dialogues: - args: {} - class_name: AbciDialogues - benchmark_tool: - args: - log_dir: /logs - class_name: BenchmarkTool - contract_api_dialogues: - args: {} - class_name: ContractApiDialogues - http_dialogues: - args: {} - class_name: HttpDialogues - ipfs_dialogues: - args: {} - class_name: IpfsDialogues - ledger_api_dialogues: - args: {} - class_name: LedgerApiDialogues - params: - args: - cleanup_history_depth: 1 - cleanup_history_depth_current: null - drand_public_key: 868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31 - genesis_config: - genesis_time: '2022-05-20T16:00:21.735122717Z' - chain_id: chain-c4daS1 - consensus_params: - block: - max_bytes: '22020096' - max_gas: '-1' - time_iota_ms: '1000' - evidence: - max_age_num_blocks: '100000' - max_age_duration: '172800000000000' - max_bytes: '1048576' - validator: - pub_key_types: - - ed25519 - version: {} - voting_power: '10' - keeper_timeout: 30.0 - max_attempts: 10 - max_healthcheck: 120 - multisend_address: '0x0000000000000000000000000000000000000000' - on_chain_service_id: null - request_retry_delay: 1.0 - request_timeout: 10.0 - reset_pause_duration: 10 - reset_tendermint_after: 2 - retry_attempts: 400 - use_slashing: false - slash_cooldown_hours: 3 - slash_threshold_amount: 10000000000000000 - light_slash_unit_amount: 5000000000000000 - serious_slash_unit_amount: 8000000000000000 - retry_timeout: 3 - round_timeout_seconds: 350.0 - service_id: tx_settlement_multiplexer - service_registry_address: null - setup: - all_participants: - - '0x0000000000000000000000000000000000000000' - safe_contract_address: '0x0000000000000000000000000000000000000000' - consensus_threshold: null - share_tm_config_on_startup: false - sleep_time: 5 - tendermint_check_sleep_delay: 3 - tendermint_com_url: http://localhost:8080 - tendermint_max_retries: 5 - tendermint_p2p_url: localhost:26656 - tendermint_url: http://localhost:26657 - termination_sleep: 900 - tx_timeout: 10.0 - use_termination: false - agent_balance_threshold: 10000000000000000 - refill_check_interval: 10 - class_name: TxSettlementMultiplexerParams - requests: - args: {} - class_name: Requests - signing_dialogues: - args: {} - class_name: SigningDialogues - state: - args: {} - class_name: SharedState -dependencies: {} -is_abstract: true diff --git a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/__init__.py b/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/__init__.py deleted file mode 100644 index 0d6412538..000000000 --- a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the tests for tx settlement multiplexer abci.""" diff --git a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/test_handlers.py b/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/test_handlers.py deleted file mode 100644 index 3287c3c47..000000000 --- a/trader_old/vendor/valory/skills/tx_settlement_multiplexer_abci/tests/test_handlers.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the tests for the handlers of the tx settlement multiplexer abci.""" -from unittest.mock import MagicMock - -import pytest -from aea.configurations.data_types import PublicId -from aea.skills.base import Handler - -from packages.valory.skills.abstract_round_abci.handlers import ABCIRoundHandler -from packages.valory.skills.abstract_round_abci.handlers import ( - ContractApiHandler as BaseContractApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - HttpHandler as BaseHttpHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - IpfsHandler as BaseIpfsHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - LedgerApiHandler as BaseLedgerApiHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - SigningHandler as BaseSigningHandler, -) -from packages.valory.skills.abstract_round_abci.handlers import ( - TendermintHandler as BaseTendermintHandler, -) -from packages.valory.skills.tx_settlement_multiplexer_abci.handlers import ( - ContractApiHandler, - HttpHandler, - IpfsHandler, - LedgerApiHandler, - SigningHandler, - TendermintHandler, - TxSettlementMultiplexerHandler, -) - - -@pytest.mark.parametrize( - "handler, base_handler", - [ - (TxSettlementMultiplexerHandler, ABCIRoundHandler), - (HttpHandler, BaseHttpHandler), - (SigningHandler, BaseSigningHandler), - (LedgerApiHandler, BaseLedgerApiHandler), - (ContractApiHandler, BaseContractApiHandler), - (TendermintHandler, BaseTendermintHandler), - (IpfsHandler, BaseIpfsHandler), - ], -) -def test_handler(handler: Handler, base_handler: Handler) -> None: - """Test that the 'handlers.py' of the TxSettlementMultiplexerAbci can be imported.""" - handler = handler( - name="dummy_handler", - skill_context=MagicMock(skill_id=PublicId.from_str("dummy/skill:0.1.0")), - ) - - assert isinstance(handler, base_handler) diff --git a/trader_old/vendor/w1kke/customs/__init__.py b/trader_old/vendor/w1kke/customs/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/trader_old/vendor/w1kke/customs/always_blue/__init__.py b/trader_old/vendor/w1kke/customs/always_blue/__init__.py deleted file mode 100644 index e4e892ea4..000000000 --- a/trader_old/vendor/w1kke/customs/always_blue/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the always blue strategy.""" diff --git a/trader_old/vendor/w1kke/customs/always_blue/always_blue.py b/trader_old/vendor/w1kke/customs/always_blue/always_blue.py deleted file mode 100644 index a99654fa3..000000000 --- a/trader_old/vendor/w1kke/customs/always_blue/always_blue.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# ------------------------------------------------------------------------------ -# -# Copyright 2024 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 the always blue strategy.""" - -from typing import Dict, Any, List, Union - - -def get_always_blue() -> Dict[str, Union[int, List[str]]]: - """ALWAYS BLUE.""" - return {"bet_amount": 0, "info": ["ALWAYS BLUE!"]} - - -def run(*_args, **kwargs) -> Dict[str, Union[int, List[str]]]: - """Run the strategy.""" - return get_always_blue() diff --git a/trader_old/vendor/w1kke/customs/always_blue/component.yaml b/trader_old/vendor/w1kke/customs/always_blue/component.yaml deleted file mode 100644 index 0c867096c..000000000 --- a/trader_old/vendor/w1kke/customs/always_blue/component.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: always_blue -author: w1kke -version: 0.1.0 -type: custom -description: A simple testing strategy strategy. -license: Apache-2.0 -aea_version: '>=1.0.0, <2.0.0' -fingerprint: - __init__.py: bafybeibkl7srd6nmuo7p6vcrueviwryjo6y25xfkckndkghnos7okadzpm - always_blue.py: bafybeidyj2m7hwfrufjpzsqdihsvdmbzvqjatqasfs4r7ihxx2pwhoe6li -fingerprint_ignore_patterns: [] -entry_point: always_blue.py -callable: run -dependencies: {}